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