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