2 * Copyright 2006-2009, Haiku.
3 * Distributed under the terms of the MIT License.
6 * Stephan Aßmus <superstippi@gmx.de>
9 #include "Transformable.h"
15 Transformable::Transformable()
21 Transformable::Transformable(const Transformable
& other
)
22 : agg::trans_affine(other
)
27 Transformable::~Transformable()
33 Transformable::StoreTo(double matrix
[matrix_size
]) const
40 Transformable::LoadFrom(const double matrix
[matrix_size
])
42 // before calling the potentially heavy TransformationChanged()
43 // hook function, make sure that the transformation
49 TransformationChanged();
55 Transformable::SetTransform(const Transformable
& other
)
59 TransformationChanged();
65 Transformable::operator=(const Transformable
& other
)
70 TransformationChanged();
77 Transformable::Multiply(const Transformable
& other
)
79 if (!other
.IsIdentity()) {
81 TransformationChanged();
88 Transformable::Reset()
92 TransformationChanged();
98 Transformable::Invert()
102 TransformationChanged();
108 Transformable::IsIdentity() const
110 double m
[matrix_size
];
124 Transformable::IsTranslationOnly() const
126 double m
[matrix_size
];
138 Transformable::IsNotDistorted() const
140 double m
[matrix_size
];
142 return (m
[0] == m
[3]);
147 Transformable::IsValid() const
149 double m
[matrix_size
];
151 return ((m
[0] * m
[3] - m
[1] * m
[2]) != 0.0);
156 Transformable::operator==(const Transformable
& other
) const
158 double m1
[matrix_size
];
160 double m2
[matrix_size
];
162 return memcmp(m1
, m2
, sizeof(m1
)) == 0;
167 Transformable::operator!=(const Transformable
& other
) const
169 return !(*this == other
);
174 Transformable::Transform(double* x
, double* y
) const
181 Transformable::Transform(BPoint
* point
) const
196 Transformable::Transform(const BPoint
& point
) const
205 Transformable::InverseTransform(double* x
, double* y
) const
207 inverse_transform(x
, y
);
212 Transformable::InverseTransform(BPoint
* point
) const
218 inverse_transform(&x
, &y
);
227 Transformable::InverseTransform(const BPoint
& point
) const
230 InverseTransform(&p
);
235 min4(float a
, float b
, float c
, float d
)
237 return min_c(a
, min_c(b
, min_c(c
, d
)));
241 max4(float a
, float b
, float c
, float d
)
243 return max_c(a
, max_c(b
, max_c(c
, d
)));
248 Transformable::TransformBounds(BRect bounds
) const
250 if (bounds
.IsValid()) {
251 BPoint
lt(bounds
.left
, bounds
.top
);
252 BPoint
rt(bounds
.right
, bounds
.top
);
253 BPoint
lb(bounds
.left
, bounds
.bottom
);
254 BPoint
rb(bounds
.right
, bounds
.bottom
);
261 return BRect(floorf(min4(lt
.x
, rt
.x
, lb
.x
, rb
.x
)),
262 floorf(min4(lt
.y
, rt
.y
, lb
.y
, rb
.y
)),
263 ceilf(max4(lt
.x
, rt
.x
, lb
.x
, rb
.x
)),
264 ceilf(max4(lt
.y
, rt
.y
, lb
.y
, rb
.y
)));
271 Transformable::TranslateBy(BPoint offset
)
273 if (offset
.x
!= 0.0 || offset
.y
!= 0.0) {
274 multiply(agg::trans_affine_translation(offset
.x
, offset
.y
));
275 TransformationChanged();
281 Transformable::RotateBy(BPoint origin
, double degrees
)
283 if (degrees
!= 0.0) {
284 multiply(agg::trans_affine_translation(-origin
.x
, -origin
.y
));
285 multiply(agg::trans_affine_rotation(degrees
* (M_PI
/ 180.0)));
286 multiply(agg::trans_affine_translation(origin
.x
, origin
.y
));
287 TransformationChanged();
293 Transformable::ScaleBy(BPoint origin
, double xScale
, double yScale
)
295 if (xScale
!= 1.0 || yScale
!= 1.0) {
296 multiply(agg::trans_affine_translation(-origin
.x
, -origin
.y
));
297 multiply(agg::trans_affine_scaling(xScale
, yScale
));
298 multiply(agg::trans_affine_translation(origin
.x
, origin
.y
));
299 TransformationChanged();
305 Transformable::ShearBy(BPoint origin
, double xShear
, double yShear
)
307 if (xShear
!= 0.0 || yShear
!= 0.0) {
308 multiply(agg::trans_affine_translation(-origin
.x
, -origin
.y
));
309 multiply(agg::trans_affine_skewing(xShear
, yShear
));
310 multiply(agg::trans_affine_translation(origin
.x
, origin
.y
));
311 TransformationChanged();
315 // TransformationChanged
317 Transformable::TransformationChanged()
319 // default implementation doesn't care