xref: /haiku/src/libs/icon/transformer/ContourTransformer.cpp (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "ContourTransformer.h"
10 
11 #include <new>
12 
13 #ifdef ICON_O_MATIC
14 # include <Message.h>
15 
16 # include "CommonPropertyIDs.h"
17 # include "OptionProperty.h"
18 # include "Property.h"
19 # include "PropertyObject.h"
20 #endif // ICON_O_MATIC
21 
22 using std::nothrow;
23 
24 // constructor
25 ContourTransformer::ContourTransformer(VertexSource& source)
26 	: Transformer(source, "Contour"),
27 	  Contour(source)
28 {
29 	auto_detect_orientation(true);
30 }
31 
32 #ifdef ICON_O_MATIC
33 // constructor
34 ContourTransformer::ContourTransformer(VertexSource& source,
35 									   BMessage* archive)
36 	: Transformer(source, archive),
37 	  Contour(source)
38 {
39 	auto_detect_orientation(true);
40 
41 	if (!archive)
42 		return;
43 
44 	int32 mode;
45 	if (archive->FindInt32("line join", &mode) == B_OK)
46 		line_join((agg::line_join_e)mode);
47 
48 	if (archive->FindInt32("inner join", &mode) == B_OK)
49 		inner_join((agg::inner_join_e)mode);
50 
51 	double value;
52 	if (archive->FindDouble("width", &value) == B_OK)
53 		width(value);
54 
55 	if (archive->FindDouble("miter limit", &value) == B_OK)
56 		miter_limit(value);
57 
58 	if (archive->FindDouble("inner miter limit", &value) == B_OK)
59 		inner_miter_limit(value);
60 }
61 #endif // ICON_O_MATIC
62 
63 // destructor
64 ContourTransformer::~ContourTransformer()
65 {
66 }
67 
68 // Clone
69 Transformer*
70 ContourTransformer::Clone(VertexSource& source) const
71 {
72 	ContourTransformer* clone = new (nothrow) ContourTransformer(source);
73 	if (clone) {
74 		clone->line_join(line_join());
75 		clone->inner_join(inner_join());
76 		clone->width(width());
77 		clone->miter_limit(miter_limit());
78 		clone->inner_miter_limit(inner_miter_limit());
79 		clone->auto_detect_orientation(auto_detect_orientation());
80 	}
81 	return clone;
82 }
83 
84 // rewind
85 void
86 ContourTransformer::rewind(unsigned path_id)
87 {
88 	Contour::rewind(path_id);
89 }
90 
91 // vertex
92 unsigned
93 ContourTransformer::vertex(double* x, double* y)
94 {
95 	return Contour::vertex(x, y);
96 }
97 
98 // SetSource
99 void
100 ContourTransformer::SetSource(VertexSource& source)
101 {
102 	Transformer::SetSource(source);
103 	Contour::attach(source);
104 }
105 
106 // ApproximationScale
107 double
108 ContourTransformer::ApproximationScale() const
109 {
110 	return fSource.ApproximationScale() * width();
111 }
112 
113 // #pragma mark -
114 
115 #ifdef ICON_O_MATIC
116 
117 // Archive
118 status_t
119 ContourTransformer::Archive(BMessage* into, bool deep) const
120 {
121 	status_t ret = Transformer::Archive(into, deep);
122 
123 	if (ret == B_OK)
124 		into->what = archive_code;
125 
126 	if (ret == B_OK)
127 		ret = into->AddInt32("line join", line_join());
128 
129 	if (ret == B_OK)
130 		ret = into->AddInt32("inner join", inner_join());
131 
132 	if (ret == B_OK)
133 		ret = into->AddDouble("width", width());
134 
135 	if (ret == B_OK)
136 		ret = into->AddDouble("miter limit", miter_limit());
137 
138 	if (ret == B_OK)
139 		ret = into->AddDouble("inner miter limit", inner_miter_limit());
140 
141 	return ret;
142 }
143 
144 // MakePropertyObject
145 PropertyObject*
146 ContourTransformer::MakePropertyObject() const
147 {
148 	PropertyObject* object = Transformer::MakePropertyObject();
149 	if (!object)
150 		return NULL;
151 
152 	// width
153 	object->AddProperty(new FloatProperty(PROPERTY_WIDTH, width()));
154 
155 	// auto detect orientation
156 	object->AddProperty(new BoolProperty(PROPERTY_DETECT_ORIENTATION,
157 										 auto_detect_orientation()));
158 
159 	// join mode
160 	OptionProperty* property = new OptionProperty(PROPERTY_JOIN_MODE);
161 	property->AddOption(agg::miter_join, "Miter");
162 	property->AddOption(agg::round_join, "Round");
163 	property->AddOption(agg::bevel_join, "Bevel");
164 	property->SetCurrentOptionID(line_join());
165 
166 	object->AddProperty(property);
167 
168 	// miter limit
169 	object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
170 										  miter_limit()));
171 
172 	return object;
173 }
174 
175 // SetToPropertyObject
176 bool
177 ContourTransformer::SetToPropertyObject(const PropertyObject* object)
178 {
179 	AutoNotificationSuspender _(this);
180 	Transformer::SetToPropertyObject(object);
181 
182 	// width
183 	float w = object->Value(PROPERTY_WIDTH, (float)width());
184 	if (w != width()) {
185 		width(w);
186 		Notify();
187 	}
188 
189 	// auto detect orientation
190 	bool ado = object->Value(PROPERTY_DETECT_ORIENTATION,
191 							 auto_detect_orientation());
192 	if (ado != auto_detect_orientation()) {
193 		auto_detect_orientation(ado);
194 		Notify();
195 	}
196 
197 	// join mode
198 	OptionProperty* property = dynamic_cast<OptionProperty*>(
199 		object->FindProperty(PROPERTY_JOIN_MODE));
200 	if (property && line_join() != property->CurrentOptionID()) {
201 		line_join((agg::line_join_e)property->CurrentOptionID());
202 		Notify();
203 	}
204 
205 	// miter limit
206 	float l = object->Value(PROPERTY_MITER_LIMIT, (float)miter_limit());
207 	if (l != miter_limit()) {
208 		miter_limit(l);
209 		Notify();
210 	}
211 
212 	return HasPendingNotifications();
213 }
214 
215 #endif // ICON_O_MATIC
216 
217 
218 
219