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