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