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