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