vfs: check userland buffers before reading them.
[haiku.git] / src / libs / icon / transformer / StrokeTransformer.cpp
blob25d64a4504149daaf990f10988aec852b9094f4f
1 /*
2 * Copyright 2006-2007, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 */
10 #include "StrokeTransformer.h"
12 #ifdef ICON_O_MATIC
13 # include <Message.h>
15 # include "CommonPropertyIDs.h"
16 # include "OptionProperty.h"
17 # include "Property.h"
18 # include "PropertyObject.h"
19 #endif // ICON_O_MATIC
21 #include <new>
24 _USING_ICON_NAMESPACE
25 using std::nothrow;
28 // constructor
29 StrokeTransformer::StrokeTransformer(VertexSource& source)
30 : Transformer(source, "Stroke"),
31 Stroke(source)
35 // constructor
36 StrokeTransformer::StrokeTransformer(VertexSource& source,
37 BMessage* archive)
38 : Transformer(source, archive),
39 Stroke(source)
41 if (!archive)
42 return;
44 int32 mode;
45 if (archive->FindInt32("line cap", &mode) == B_OK)
46 line_cap((agg::line_cap_e)mode);
48 if (archive->FindInt32("line join", &mode) == B_OK)
49 line_join((agg::line_join_e)mode);
51 if (archive->FindInt32("inner join", &mode) == B_OK)
52 inner_join((agg::inner_join_e)mode);
54 double value;
55 if (archive->FindDouble("width", &value) == B_OK)
56 width(value);
58 if (archive->FindDouble("miter limit", &value) == B_OK)
59 miter_limit(value);
61 if (archive->FindDouble("inner miter limit", &value) == B_OK)
62 inner_miter_limit(value);
64 if (archive->FindDouble("shorten", &value) == B_OK)
65 shorten(value);
68 // destructor
69 StrokeTransformer::~StrokeTransformer()
73 // Clone
74 Transformer*
75 StrokeTransformer::Clone(VertexSource& source) const
77 StrokeTransformer* clone = new (nothrow) StrokeTransformer(source);
78 if (clone) {
79 clone->line_cap(line_cap());
80 clone->line_join(line_join());
81 clone->inner_join(inner_join());
82 clone->width(width());
83 clone->miter_limit(miter_limit());
84 clone->inner_miter_limit(inner_miter_limit());
85 clone->shorten(shorten());
87 return clone;
90 // rewind
91 void
92 StrokeTransformer::rewind(unsigned path_id)
94 Stroke::rewind(path_id);
97 // vertex
98 unsigned
99 StrokeTransformer::vertex(double* x, double* y)
101 return Stroke::vertex(x, y);
104 // SetSource
105 void
106 StrokeTransformer::SetSource(VertexSource& source)
108 Transformer::SetSource(source);
109 Stroke::attach(source);
112 // WantsOpenPaths
113 bool
114 StrokeTransformer::WantsOpenPaths() const
116 return true;
119 // ApproximationScale
120 double
121 StrokeTransformer::ApproximationScale() const
123 double scale = fSource.ApproximationScale();
124 double factor = fabs(width());
125 if (factor > 1.0)
126 scale *= factor;
127 return scale;
130 // #pragma mark -
132 #ifdef ICON_O_MATIC
134 // Archive
135 status_t
136 StrokeTransformer::Archive(BMessage* into, bool deep) const
138 status_t ret = Transformer::Archive(into, deep);
140 if (ret == B_OK)
141 into->what = archive_code;
143 if (ret == B_OK)
144 ret = into->AddInt32("line cap", line_cap());
146 if (ret == B_OK)
147 ret = into->AddInt32("line join", line_join());
149 if (ret == B_OK)
150 ret = into->AddInt32("inner join", inner_join());
152 if (ret == B_OK)
153 ret = into->AddDouble("width", width());
155 if (ret == B_OK)
156 ret = into->AddDouble("miter limit", miter_limit());
158 if (ret == B_OK)
159 ret = into->AddDouble("inner miter limit", inner_miter_limit());
161 if (ret == B_OK)
162 ret = into->AddDouble("shorten",shorten());
164 return ret;
167 // MakePropertyObject
168 PropertyObject*
169 StrokeTransformer::MakePropertyObject() const
171 PropertyObject* object = Transformer::MakePropertyObject();
172 if (!object)
173 return NULL;
175 // width
176 object->AddProperty(new FloatProperty(PROPERTY_WIDTH, width()));
178 // cap mode
179 OptionProperty* property = new OptionProperty(PROPERTY_CAP_MODE);
180 property->AddOption(agg::butt_cap, "Butt");
181 property->AddOption(agg::square_cap, "Square");
182 property->AddOption(agg::round_cap, "Round");
183 property->SetCurrentOptionID(line_cap());
185 object->AddProperty(property);
187 // join mode
188 property = new OptionProperty(PROPERTY_JOIN_MODE);
189 property->AddOption(agg::miter_join, "Miter");
190 property->AddOption(agg::round_join, "Round");
191 property->AddOption(agg::bevel_join, "Bevel");
192 property->SetCurrentOptionID(line_join());
194 object->AddProperty(property);
196 // miter limit
197 if (line_join() == agg::miter_join) {
198 object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
199 miter_limit()));
202 // // shorten
203 // object->AddProperty(new FloatProperty(PROPERTY_STROKE_SHORTEN,
204 // shorten()));
206 return object;
209 // SetToPropertyObject
210 bool
211 StrokeTransformer::SetToPropertyObject(const PropertyObject* object)
213 AutoNotificationSuspender _(this);
214 Transformer::SetToPropertyObject(object);
216 // width
217 float w = object->Value(PROPERTY_WIDTH, (float)width());
218 if (w != width()) {
219 width(w);
220 Notify();
223 // cap mode
224 OptionProperty* property = dynamic_cast<OptionProperty*>(
225 object->FindProperty(PROPERTY_CAP_MODE));
226 if (property && line_cap() != property->CurrentOptionID()) {
227 line_cap((agg::line_cap_e)property->CurrentOptionID());
228 Notify();
230 // join mode
231 property = dynamic_cast<OptionProperty*>(
232 object->FindProperty(PROPERTY_JOIN_MODE));
233 if (property && line_join() != property->CurrentOptionID()) {
234 line_join((agg::line_join_e)property->CurrentOptionID());
235 Notify();
238 // miter limit
239 float l = object->Value(PROPERTY_MITER_LIMIT, (float)miter_limit());
240 if (l != miter_limit()) {
241 miter_limit(l);
242 Notify();
245 // shorten
246 float s = object->Value(PROPERTY_STROKE_SHORTEN, (float)shorten());
247 if (s != shorten()) {
248 shorten(s);
249 Notify();
252 return HasPendingNotifications();
255 #endif // ICON_O_MATIC