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_ICON_NAMESPACE 25using std::nothrow; 26 27 28// constructor 29ContourTransformer::ContourTransformer(VertexSource& source) 30 : Transformer("Contour"), 31 PathTransformer(source), 32 Contour(source) 33{ 34 auto_detect_orientation(true); 35} 36 37// constructor 38ContourTransformer::ContourTransformer(VertexSource& source, 39 BMessage* archive) 40 : Transformer(archive), 41 PathTransformer(source), 42 Contour(source) 43{ 44 auto_detect_orientation(true); 45 46 if (!archive) 47 return; 48 49 int32 mode; 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 67// destructor 68ContourTransformer::~ContourTransformer() 69{ 70} 71 72// Clone 73Transformer* 74ContourTransformer::Clone() const 75{ 76 ContourTransformer* clone = new (nothrow) ContourTransformer(*fSource); 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 89void 90ContourTransformer::rewind(unsigned path_id) 91{ 92 Contour::rewind(path_id); 93} 94 95// vertex 96unsigned 97ContourTransformer::vertex(double* x, double* y) 98{ 99 return Contour::vertex(x, y); 100} 101 102// SetSource 103void 104ContourTransformer::SetSource(VertexSource& source) 105{ 106 PathTransformer::SetSource(source); 107 Contour::attach(source); 108} 109 110// ApproximationScale 111double 112ContourTransformer::ApproximationScale() const 113{ 114 double scale = fSource->ApproximationScale(); 115 double factor = fabs(width()); 116 if (factor > 1.0) 117 scale *= factor; 118 return scale; 119} 120 121// #pragma mark - 122 123#ifdef ICON_O_MATIC 124 125// Archive 126status_t 127ContourTransformer::Archive(BMessage* into, bool deep) const 128{ 129 status_t ret = Transformer::Archive(into, deep); 130 131 if (ret == B_OK) 132 into->what = archive_code; 133 134 if (ret == B_OK) 135 ret = into->AddInt32("line join", line_join()); 136 137 if (ret == B_OK) 138 ret = into->AddInt32("inner join", inner_join()); 139 140 if (ret == B_OK) 141 ret = into->AddDouble("width", width()); 142 143 if (ret == B_OK) 144 ret = into->AddDouble("miter limit", miter_limit()); 145 146 if (ret == B_OK) 147 ret = into->AddDouble("inner miter limit", inner_miter_limit()); 148 149 return ret; 150} 151 152// MakePropertyObject 153PropertyObject* 154ContourTransformer::MakePropertyObject() const 155{ 156 PropertyObject* object = Transformer::MakePropertyObject(); 157 if (!object) 158 return NULL; 159 160 // width 161 object->AddProperty(new FloatProperty(PROPERTY_WIDTH, width())); 162 163 // auto detect orientation 164 object->AddProperty(new BoolProperty(PROPERTY_DETECT_ORIENTATION, 165 auto_detect_orientation())); 166 167 // join mode 168 OptionProperty* property = new OptionProperty(PROPERTY_JOIN_MODE); 169 property->AddOption(agg::miter_join, "Miter"); 170 property->AddOption(agg::round_join, "Round"); 171 property->AddOption(agg::bevel_join, "Bevel"); 172 property->SetCurrentOptionID(line_join()); 173 174 object->AddProperty(property); 175 176 // miter limit 177 object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT, 178 miter_limit())); 179 180 return object; 181} 182 183// SetToPropertyObject 184bool 185ContourTransformer::SetToPropertyObject(const PropertyObject* object) 186{ 187 AutoNotificationSuspender _(this); 188 Transformer::SetToPropertyObject(object); 189 190 // width 191 float w = object->Value(PROPERTY_WIDTH, (float)width()); 192 if (w != width()) { 193 width(w); 194 Notify(); 195 } 196 197 // auto detect orientation 198 bool ado = object->Value(PROPERTY_DETECT_ORIENTATION, 199 auto_detect_orientation()); 200 if (ado != auto_detect_orientation()) { 201 auto_detect_orientation(ado); 202 Notify(); 203 } 204 205 // join mode 206 OptionProperty* property = dynamic_cast<OptionProperty*>( 207 object->FindProperty(PROPERTY_JOIN_MODE)); 208 if (property && line_join() != property->CurrentOptionID()) { 209 line_join((agg::line_join_e)property->CurrentOptionID()); 210 Notify(); 211 } 212 213 // miter limit 214 float l = object->Value(PROPERTY_MITER_LIMIT, (float)miter_limit()); 215 if (l != miter_limit()) { 216 miter_limit(l); 217 Notify(); 218 } 219 220 return HasPendingNotifications(); 221} 222 223#endif // ICON_O_MATIC 224 225 226 227