/* * Copyright 2006-2007, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus */ #include "AffineTransformer.h" #ifdef ICON_O_MATIC # include # include "CommonPropertyIDs.h" # include "Property.h" # include "PropertyObject.h" #endif #include _USING_ICON_NAMESPACE using std::nothrow; // constructor AffineTransformer::AffineTransformer(VertexSource& source) : Transformer("Transformation"), PathTransformer(source), Affine(source, *this) { } // constructor AffineTransformer::AffineTransformer(VertexSource& source, BMessage* archive) : Transformer(archive), PathTransformer(source), Affine(source, *this) { if (!archive) return; int32 size = 6; const void* matrix; ssize_t dataSize = size * sizeof(double); if (archive->FindData("matrix", B_DOUBLE_TYPE, &matrix, &dataSize) == B_OK) { if (dataSize == (ssize_t)(size * sizeof(double))) load_from((const double*)matrix); } } // destructor AffineTransformer::~AffineTransformer() { } // Clone Transformer* AffineTransformer::Clone() const { AffineTransformer* clone = new (nothrow) AffineTransformer(*fSource); if (clone) clone->multiply(*this); return clone; } // rewind void AffineTransformer::rewind(unsigned path_id) { Affine::rewind(path_id); } // vertex unsigned AffineTransformer::vertex(double* x, double* y) { return Affine::vertex(x, y); } // SetSource void AffineTransformer::SetSource(VertexSource& source) { PathTransformer::SetSource(source); Affine::attach(source); } // ApproximationScale double AffineTransformer::ApproximationScale() const { return fabs(fSource->ApproximationScale() * scale()); } // #pragma mark - #ifdef ICON_O_MATIC // Archive status_t AffineTransformer::Archive(BMessage* into, bool deep) const { status_t ret = Transformer::Archive(into, deep); if (ret == B_OK) into->what = archive_code; if (ret == B_OK) { double matrix[6]; store_to(matrix); ret = into->AddData("matrix", B_DOUBLE_TYPE, matrix, 6 * sizeof(double)); } return ret; } // MakePropertyObject PropertyObject* AffineTransformer::MakePropertyObject() const { PropertyObject* object = Transformer::MakePropertyObject(); if (!object) return NULL; // translation double tx; double ty; translation(&tx, &ty); object->AddProperty(new FloatProperty(PROPERTY_TRANSLATION_X, tx)); object->AddProperty(new FloatProperty(PROPERTY_TRANSLATION_Y, ty)); // rotation object->AddProperty(new FloatProperty(PROPERTY_ROTATION, agg::rad2deg(rotation()))); // scale double scaleX; double scaleY; scaling(&scaleX, &scaleY); object->AddProperty(new FloatProperty(PROPERTY_SCALE_X, scaleX)); object->AddProperty(new FloatProperty(PROPERTY_SCALE_Y, scaleY)); return object; } // SetToPropertyObject bool AffineTransformer::SetToPropertyObject(const PropertyObject* object) { AutoNotificationSuspender _(this); Transformer::SetToPropertyObject(object); // current affine parameters double tx; double ty; translation(&tx, &ty); double r = rotation(); double scaleX; double scaleY; scaling(&scaleX, &scaleY); // properties double newTX = object->Value(PROPERTY_TRANSLATION_X, (float)tx); double newTY = object->Value(PROPERTY_TRANSLATION_Y, (float)ty); double newR = object->Value(PROPERTY_ROTATION, (float)agg::rad2deg(r)); newR = agg::deg2rad(newR); double newScaleX = object->Value(PROPERTY_SCALE_X, (float)scaleX); double newScaleY = object->Value(PROPERTY_SCALE_Y, (float)scaleY); if (newTX != tx || newTY != ty || newR != r || newScaleX != scaleX || newScaleY != scaleY) { reset(); multiply(agg::trans_affine_scaling(newScaleX, newScaleY)); multiply(agg::trans_affine_rotation(newR)); multiply(agg::trans_affine_translation(newTX, newTY)); Notify(); } return HasPendingNotifications(); } #endif // ICON_O_MATIC