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 25 using std::nothrow; 26 27 28 // constructor 29 ContourTransformer::ContourTransformer(VertexSource& source) 30 : Transformer("Contour"), 31 PathTransformer(source), 32 Contour(source) 33 { 34 auto_detect_orientation(true); 35 } 36 37 // constructor 38 ContourTransformer::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 68 ContourTransformer::~ContourTransformer() 69 { 70 } 71 72 // Clone 73 Transformer* 74 ContourTransformer::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 89 void 90 ContourTransformer::rewind(unsigned path_id) 91 { 92 Contour::rewind(path_id); 93 } 94 95 // vertex 96 unsigned 97 ContourTransformer::vertex(double* x, double* y) 98 { 99 return Contour::vertex(x, y); 100 } 101 102 // SetSource 103 void 104 ContourTransformer::SetSource(VertexSource& source) 105 { 106 PathTransformer::SetSource(source); 107 Contour::attach(source); 108 } 109 110 // ApproximationScale 111 double 112 ContourTransformer::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 126 status_t 127 ContourTransformer::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 153 PropertyObject* 154 ContourTransformer::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 184 bool 185 ContourTransformer::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