diff --git a/headers/os/interface/Polygon.h b/headers/os/interface/Polygon.h index e61082cce7..0ae18235a2 100644 --- a/headers/os/interface/Polygon.h +++ b/headers/os/interface/Polygon.h @@ -13,21 +13,27 @@ #include #include +namespace BPrivate { class BAffineTransform; } +using namespace BPrivate; class BPolygon { public: - BPolygon(const BPoint *ptArray, int32 numPoints); - BPolygon(const BPolygon *polygon); - BPolygon(); - virtual ~BPolygon(); + BPolygon(const BPoint *ptArray, int32 numPoints); + BPolygon(const BPolygon *polygon); + BPolygon(); + virtual ~BPolygon(); - BPolygon &operator=(const BPolygon &from); + BPolygon &operator=(const BPolygon &from); - BRect Frame() const; - void AddPoints(const BPoint *ptArray, int32 numPoints); - int32 CountPoints() const; - void MapTo(BRect srcRect, BRect dstRect); - void PrintToStream() const; + BRect Frame() const; + void AddPoints(const BPoint *ptArray, int32 numPoints); + int32 CountPoints() const; + void MapTo(BRect srcRect, BRect dstRect); + void PrintToStream() const; + + void Transform(const BAffineTransform& transform); + BPolygon& TransformBySelf(const BAffineTransform& transform); + BPolygon* TransformByCopy(const BAffineTransform& transform) const; private: friend class BView; diff --git a/headers/private/shared/AffineTransform.h b/headers/private/shared/AffineTransform.h new file mode 100644 index 0000000000..1a5e900d11 --- /dev/null +++ b/headers/private/shared/AffineTransform.h @@ -0,0 +1,104 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephen Deken, stephen.deken@gmail.com + */ +#ifndef _AFFINETRANSFORM_H +#define _AFFINETRANSFORM_H + +#include + +#include + +class BPoint; + +namespace BPrivate { + +class BAffineTransform { +public: + BAffineTransform(); + BAffineTransform(const BAffineTransform& copyFrom); + virtual ~BAffineTransform(); + virtual BAffineTransform& operator=(const BAffineTransform& copyFrom); + + virtual bool operator==( + const BAffineTransform& other) const; + virtual bool operator!=( + const BAffineTransform& other) const; + + // Callbacks + virtual void TransformationChanged() const; + + // Application + BPoint Apply(const BPoint& point) const; + void Apply(BPoint* points, uint32 count) const; + + // Rotation + void Rotate(float angle); + void Rotate(const BPoint& center, float angle); + BAffineTransform& RotateBySelf(float angle); + BAffineTransform& RotateBySelf(const BPoint& center, float angle); + BAffineTransform RotateByCopy(float angle) const; + BAffineTransform RotateByCopy(const BPoint& center, float angle) const; + + // Translation + void Translate(float deltaX, float deltaY); + void Translate(const BPoint& delta); + BAffineTransform& TranslateBySelf(float deltaX, float deltaY); + BAffineTransform& TranslateBySelf(const BPoint& delta); + BAffineTransform TranslateByCopy(float deltaX, float deltaY) const; + BAffineTransform TranslateByCopy(const BPoint& delta) const; + + // Scaling + void Scale(float scale); + void Scale(const BPoint& center, float scale); + void Scale(float scaleX, float scaleY); + void Scale(const BPoint& center, float scaleX, float scaleY); + void Scale(const BPoint& scale); + void Scale(const BPoint& center, const BPoint& scale); + BAffineTransform& ScaleBySelf(float scale); + BAffineTransform& ScaleBySelf(const BPoint& center, float scale); + BAffineTransform& ScaleBySelf(float scaleX, float scaleY); + BAffineTransform& ScaleBySelf(const BPoint& center, float scaleX, float scaleY); + BAffineTransform& ScaleBySelf(const BPoint& scale); + BAffineTransform& ScaleBySelf(const BPoint& center, const BPoint& scale); + BAffineTransform ScaleByCopy(float scale) const; + BAffineTransform ScaleByCopy(const BPoint& center, float scale) const; + BAffineTransform ScaleByCopy(float scaleX, float scaleY) const; + BAffineTransform ScaleByCopy(const BPoint& center, float scaleX, float scaleY) const; + BAffineTransform ScaleByCopy(const BPoint& scale) const; + BAffineTransform ScaleByCopy(const BPoint& center, const BPoint& scale) const; + + // Shearing + void Shear(float shearX, float shearY); + void Shear(const BPoint& center, float shearX, float shearY); + void Shear(const BPoint& shear); + void Shear(const BPoint& center, const BPoint& shear); + + BAffineTransform& ShearBySelf(float shearX, float shearY); + BAffineTransform& ShearBySelf(const BPoint& center, float shearX, float shearY); + BAffineTransform& ShearBySelf(const BPoint& shear); + BAffineTransform& ShearBySelf(const BPoint& center, const BPoint& shear); + BAffineTransform ShearByCopy(float shearX, float shearY) const; + BAffineTransform ShearByCopy(const BPoint& center, float shearX, float shearY) const; + BAffineTransform ShearByCopy(const BPoint& shear) const; + BAffineTransform ShearByCopy(const BPoint& center, const BPoint& shear) const; + +private: + void _Rotate(float angle); + void _Scale(float scaleX, float scaleY); + void _Translate(float deltaX, float deltaY); + void _Shear(float shearX, float shearY); + + void _TransformPoint(BPoint& point) const; + + agg::trans_affine fTransformMatrix; +}; + +} // namespace BPrivate + +using namespace BPrivate; + +#endif // _AFFINETRANSFORM_H diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index 69496da05c..48534a3771 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -25,6 +25,7 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { SetSubDirSupportedPlatforms haiku libbe_test ; +UseLibraryHeaders agg ; UsePrivateHeaders app input print interface shared tracker ; local pngDump ; @@ -140,6 +141,7 @@ MergeObject interface_kit.o : # required on R5 $(pngDump) + : libshared.a ; StaticLibrary libcolumnlistview.a : diff --git a/src/kits/interface/Polygon.cpp b/src/kits/interface/Polygon.cpp index b7d27afed6..5baab663bd 100644 --- a/src/kits/interface/Polygon.cpp +++ b/src/kits/interface/Polygon.cpp @@ -8,6 +8,7 @@ */ +#include #include #include @@ -155,6 +156,31 @@ BPolygon::PrintToStream () const } +void +BPolygon::Transform(const BAffineTransform& transform) +{ + transform.Apply(fPoints, (int32)fCount); + _ComputeBounds(); +} + + +BPolygon& +BPolygon::TransformBySelf(const BAffineTransform& transform) +{ + Transform(transform); + return *this; +} + + +BPolygon* +BPolygon::TransformByCopy(const BAffineTransform& transform) const +{ + BPolygon* copy = new BPolygon(this); + copy->Transform(transform); + return copy; +} + + void BPolygon::_ComputeBounds() { diff --git a/src/kits/shared/AffineTransform.cpp b/src/kits/shared/AffineTransform.cpp new file mode 100644 index 0000000000..5b7811fb4a --- /dev/null +++ b/src/kits/shared/AffineTransform.cpp @@ -0,0 +1,453 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephen Deken, stephen.deken@gmail.com + */ + +#include +#include + +BAffineTransform::BAffineTransform() + : fTransformMatrix() +{ +} + + +BAffineTransform::BAffineTransform(const BAffineTransform& copyFrom) + : fTransformMatrix(copyFrom.fTransformMatrix) +{ +} + + +BAffineTransform::~BAffineTransform() +{ +} + + +BAffineTransform& +BAffineTransform::operator=(const BAffineTransform& copyFrom) +{ + if (copyFrom != *this) { + fTransformMatrix.reset(); + fTransformMatrix.multiply(copyFrom.fTransformMatrix); + TransformationChanged(); + } + return *this; +} + + +bool +BAffineTransform::operator==(const BAffineTransform& other) const +{ + return fTransformMatrix == other.fTransformMatrix; +} + + +bool +BAffineTransform::operator!=(const BAffineTransform& other) const +{ + return fTransformMatrix != other.fTransformMatrix; +} + + +void +BAffineTransform::TransformationChanged() const +{ + // default implementation does nothing +} + + +BPoint +BAffineTransform::Apply(const BPoint& point) const +{ + BPoint rval(point); + _TransformPoint(rval); + return rval; +} + + +void +BAffineTransform::Apply(BPoint* points, uint32 count) const +{ + for (uint32 i = 0; i < count; ++i) + _TransformPoint(points[i]); +} + + +void +BAffineTransform::_Rotate(float angle) +{ + if (angle != 0.0) + fTransformMatrix.multiply(agg::trans_affine_rotation(angle)); +} + + +void +BAffineTransform::_Scale(float scaleX, float scaleY) +{ + if (scaleX != 0.0 || scaleY != 0.0) + fTransformMatrix.multiply(agg::trans_affine_scaling(scaleX, scaleY)); +} + + +void +BAffineTransform::_Translate(float deltaX, float deltaY) +{ + if (deltaX != 0.0 || deltaY != 0.0) + fTransformMatrix.multiply(agg::trans_affine_translation(deltaX, deltaY)); +} + + +void +BAffineTransform::_Shear(float shearX, float shearY) +{ + if (shearX != 0.0 || shearY != 0.0) + fTransformMatrix.multiply(agg::trans_affine_skewing(shearX, shearY)); +} + + +void +BAffineTransform::Rotate(float angle) +{ + _Rotate(angle); + TransformationChanged(); +} + + +void +BAffineTransform::Rotate(const BPoint& center, float angle) +{ + _Translate(-center.x, -center.y); + _Rotate(angle); + _Translate(center.x, center.y); + TransformationChanged(); +} + + +BAffineTransform& +BAffineTransform::RotateBySelf(float angle) +{ + Rotate(angle); + return *this; +} + + +BAffineTransform& +BAffineTransform::RotateBySelf(const BPoint& center, float angle) +{ + Rotate(center, angle); + return *this; +} + + +BAffineTransform +BAffineTransform::RotateByCopy(float angle) const +{ + BAffineTransform copy(*this); + copy.Rotate(angle); + return copy; +} + + +BAffineTransform +BAffineTransform::RotateByCopy(const BPoint& center, float angle) const +{ + BAffineTransform copy(*this); + copy.Rotate(center, angle); + return copy; +} + + +void +BAffineTransform::Translate(float deltaX, float deltaY) +{ + _Translate(deltaX, deltaY); + TransformationChanged(); +} + + +void +BAffineTransform::Translate(const BPoint& delta) +{ + Translate(delta.x, delta.y); +} + + +BAffineTransform& +BAffineTransform::TranslateBySelf(float deltaX, float deltaY) +{ + Translate(deltaX, deltaY); + return *this; +} + + +BAffineTransform& +BAffineTransform::TranslateBySelf(const BPoint& delta) +{ + return TranslateBySelf(delta.x, delta.y); +} + + +BAffineTransform +BAffineTransform::TranslateByCopy(float deltaX, float deltaY) const +{ + BAffineTransform copy(*this); + copy.Translate(deltaX, deltaY); + return copy; +} + + +BAffineTransform +BAffineTransform::TranslateByCopy(const BPoint& delta) const +{ + return TranslateByCopy(delta.x, delta.y); +} + + +void +BAffineTransform::Scale(float scale) +{ + Scale(scale, scale); +} + + +void +BAffineTransform::Scale(const BPoint& center, float scale) +{ + Scale(center, scale, scale); +} + + +void +BAffineTransform::Scale(float scaleX, float scaleY) +{ + _Scale(scaleX, scaleY); + TransformationChanged(); +} + + +void +BAffineTransform::Scale(const BPoint& center, float scaleX, float scaleY) +{ + _Translate(-center.x, -center.y); + _Scale(scaleX, scaleY); + _Translate(center.x, center.y); + TransformationChanged(); +} + + +void +BAffineTransform::Scale(const BPoint& scale) +{ + Scale(scale.x, scale.y); +} + + +void +BAffineTransform::Scale(const BPoint& center, const BPoint& scale) +{ + Scale(center, scale.x, scale.y); +} + + +BAffineTransform& +BAffineTransform::ScaleBySelf(float scale) +{ + return ScaleBySelf(scale, scale); +} + + +BAffineTransform& +BAffineTransform::ScaleBySelf(const BPoint& center, float scale) +{ + return ScaleBySelf(center, scale, scale); +} + + +BAffineTransform& +BAffineTransform::ScaleBySelf(float scaleX, float scaleY) +{ + Scale(scaleX, scaleY); + return *this; +} + + +BAffineTransform& +BAffineTransform::ScaleBySelf(const BPoint& center, float scaleX, float scaleY) +{ + Scale(center, scaleX, scaleY); + return *this; +} + + +BAffineTransform& +BAffineTransform::ScaleBySelf(const BPoint& scale) +{ + return ScaleBySelf(scale.x, scale.y); +} + + +BAffineTransform& +BAffineTransform::ScaleBySelf(const BPoint& center, const BPoint& scale) +{ + return ScaleBySelf(center, scale.x, scale.y); +} + + +BAffineTransform +BAffineTransform::ScaleByCopy(float scale) const +{ + return ScaleByCopy(scale, scale); +} + + +BAffineTransform +BAffineTransform::ScaleByCopy(const BPoint& center, float scale) const +{ + return ScaleByCopy(center, scale, scale); +} + + +BAffineTransform +BAffineTransform::ScaleByCopy(float scaleX, float scaleY) const +{ + BAffineTransform copy(*this); + copy.Scale(scaleX, scaleY); + return copy; +} + + +BAffineTransform +BAffineTransform::ScaleByCopy(const BPoint& center, float scaleX, float scaleY) const +{ + BAffineTransform copy(*this); + copy.Scale(center, scaleX, scaleY); + return copy; +} + + +BAffineTransform +BAffineTransform::ScaleByCopy(const BPoint& scale) const +{ + return ScaleByCopy(scale.x, scale.y); +} + + +BAffineTransform +BAffineTransform::ScaleByCopy(const BPoint& center, const BPoint& scale) const +{ + return ScaleByCopy(center, scale.x, scale.y); +} + + +void +BAffineTransform::Shear(float shearX, float shearY) +{ + _Shear(shearX, shearY); + TransformationChanged(); +} + + +void +BAffineTransform::Shear(const BPoint& center, float shearX, float shearY) +{ + _Translate(-center.x, -center.y); + _Shear(shearX, shearY); + _Translate(center.x, center.y); + TransformationChanged(); +} + + +void +BAffineTransform::Shear(const BPoint& shear) +{ + Shear(shear.x, shear.y); +} + + +void +BAffineTransform::Shear(const BPoint& center, const BPoint& shear) +{ + Shear(center, shear.x, shear.y); +} + + +BAffineTransform& +BAffineTransform::ShearBySelf(float shearX, float shearY) +{ + Shear(shearX, shearY); + return *this; +} + + +BAffineTransform& +BAffineTransform::ShearBySelf(const BPoint& center, float shearX, float shearY) +{ + Shear(center, shearX, shearY); + return *this; +} + + +BAffineTransform& +BAffineTransform::ShearBySelf(const BPoint& shear) +{ + Shear(shear); + return *this; +} + + +BAffineTransform& +BAffineTransform::ShearBySelf(const BPoint& center, const BPoint& shear) +{ + Shear(center, shear); + return *this; +} + + +BAffineTransform +BAffineTransform::ShearByCopy(float shearX, float shearY) const +{ + BAffineTransform copy(*this); + copy.Shear(shearX, shearY); + return copy; +} + + +BAffineTransform +BAffineTransform::ShearByCopy(const BPoint& center, float shearX, float shearY) const +{ + BAffineTransform copy(*this); + copy.Shear(center, shearX, shearY); + return copy; +} + + +BAffineTransform +BAffineTransform::ShearByCopy(const BPoint& shear) const +{ + BAffineTransform copy(*this); + copy.Shear(shear); + return copy; +} + + +BAffineTransform +BAffineTransform::ShearByCopy(const BPoint& center, const BPoint& shear) const +{ + BAffineTransform copy(*this); + copy.Shear(center, shear); + return copy; +} + + +void +BAffineTransform::_TransformPoint(BPoint& point) const +{ + double x = point.x; + double y = point.y; + fTransformMatrix.transform(&x, &y); + point.x = x; + point.y = y; +} diff --git a/src/kits/shared/Jamfile b/src/kits/shared/Jamfile index fa6072c826..b6b26ad03f 100644 --- a/src/kits/shared/Jamfile +++ b/src/kits/shared/Jamfile @@ -3,10 +3,12 @@ SubDir HAIKU_TOP src kits shared ; SetSubDirSupportedPlatformsBeOSCompatible ; AddSubDirSupportedPlatforms libbe_test ; +UseLibraryHeaders agg ; UsePrivateHeaders shared ; StaticLibrary libshared.a : AboutWindow.cpp + AffineTransform.cpp CalendarView.cpp ColorQuantizer.cpp CommandPipe.cpp