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