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