1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6
* Moonlight List (moonlight-list@lists.ximian.com)
8
* Copyright 2007 Novell, Inc. (http://www.novell.com)
10
* See the LICENSE file included with the distribution for details.
15
#include "transform.h"
24
GeneralTransform::OnPropertyChanged (PropertyChangedEventArgs *args)
26
if (args->property->GetOwnerType() == Type::DEPENDENCY_OBJECT) {
27
DependencyObject::OnPropertyChanged (args);
33
// If the transform changes, we need to notify our owners
34
// that they must repaint (all of our properties have
37
// There is no need to override this on the base classes
38
// as they are sealed, so no new properties can be added
39
// and I do not believe that we can create new instances
40
// of transform from C#, and in that case, we would only
43
NotifyListenersOfPropertyChange (args);
47
GeneralTransform::UpdateTransform ()
49
g_warning ("GeneralTransform::UpdateTransform has been called. The derived class should have overridden it.");
53
GeneralTransform::MaybeUpdateTransform ()
62
GeneralTransform::GetTransform (cairo_matrix_t *value)
64
MaybeUpdateTransform ();
69
GeneralTransform::Transform (Point point)
71
MaybeUpdateTransform ();
72
return point.Transform (&_matrix);
76
general_transform_transform_point (GeneralTransform *t, Point *p, Point *r)
78
*r = t->Transform (*p);
87
RotateTransform::UpdateTransform ()
89
double angle, center_x, center_y;
93
center_x = GetCenterX ();
94
center_y = GetCenterY ();
96
radians = angle / 180.0 * M_PI;
98
if (center_x == 0.0 && center_y == 0.0) {
99
cairo_matrix_init_rotate (&_matrix, radians);
102
cairo_matrix_init_translate (&_matrix, center_x, center_y);
103
cairo_matrix_rotate (&_matrix, radians);
104
cairo_matrix_translate (&_matrix, -center_x, -center_y);
106
//printf ("Returning2 %g %g %g %g %g %g\n", value->xx, value->yx, value->xy, value->yy, value->x0, value->y0);
111
// TranslateTransform
115
TranslateTransform::UpdateTransform ()
120
cairo_matrix_init_translate (&_matrix, x, y);
121
//printf ("translating dx %g dy %g", x, y);
122
//printf ("TranslateTransform %g %g %g %g %g %g\n", value->xx, value->yx, value->xy, value->yy, value->x0, value->y0);
129
ScaleTransform::UpdateTransform ()
131
double sx = GetScaleX ();
132
double sy = GetScaleY ();
134
// XXX you don't want to know. don't make these 0.00001, or
135
// else cairo spits out errors about non-invertable matrices
136
// (or worse, crashes)
138
// the 0.0 scales are caused in at least one instance by us
139
// being too aggressive at starting animations at time=0 when
140
// they're supposed to (unset, or 0:0:0 BeginTime)
142
if (sx == 0.0) sx = 0.00002;
143
if (sy == 0.0) sy = 0.00002;
145
double cx = GetCenterX ();
146
double cy = GetCenterY ();
148
if (cx == 0.0 && cy == 0.0) {
149
cairo_matrix_init_scale (&_matrix, sx, sy);
152
cairo_matrix_init_translate (&_matrix, cx, cy);
153
cairo_matrix_scale (&_matrix, sx, sy);
154
cairo_matrix_translate (&_matrix, -cx, -cy);
156
//printf ("scaling sx %g sy %g at center cx %g cy %g\n", sx, sy, cx, cy);
157
//printf ("ScaleTransform %g %g %g %g %g %g\n", value->xx, value->yx, value->xy, value->yy, value->x0, value->y0);
165
SkewTransform::UpdateTransform ()
167
double cx = GetCenterX ();
168
double cy = GetCenterY ();
170
bool translation = ((cx != 0.0) || (cy != 0.0));
172
cairo_matrix_init_translate (&_matrix, cx, cy);
174
cairo_matrix_init_identity (&_matrix);
176
double ax = GetAngleX ();
178
_matrix.xy = tan (ax * M_PI / 180);
180
double ay = GetAngleY ();
182
_matrix.yx = tan (ay * M_PI / 180);
185
cairo_matrix_translate (&_matrix, -cx, -cy);
187
//printf ("SkewTransform %g %g %g %g %g %g\n", value->xx, value->yx, value->xy, value->yy, value->x0, value->y0);
196
cairo_matrix_init_identity (&matrix);
199
Matrix::Matrix(cairo_matrix_t *m)
205
Matrix::OnPropertyChanged (PropertyChangedEventArgs *args)
207
if (args->property->GetOwnerType() != Type::MATRIX) {
208
DependencyObject::OnPropertyChanged (args);
212
if (args->property == Matrix::M11Property)
213
matrix.xx = args->new_value->AsDouble ();
214
else if (args->property == Matrix::M12Property)
215
matrix.yx = args->new_value->AsDouble ();
216
else if (args->property == Matrix::M21Property)
217
matrix.xy = args->new_value->AsDouble ();
218
else if (args->property == Matrix::M22Property)
219
matrix.yy = args->new_value->AsDouble ();
220
else if (args->property == Matrix::OffsetXProperty)
221
matrix.x0 = args->new_value->AsDouble ();
222
else if (args->property == Matrix::OffsetYProperty)
223
matrix.y0 = args->new_value->AsDouble ();
225
NotifyListenersOfPropertyChange (args);
229
Matrix::GetUnderlyingMatrix ()
239
MatrixTransform::OnSubPropertyChanged (DependencyProperty *prop, DependencyObject *obj, PropertyChangedEventArgs *subobj_args)
243
DependencyObject::OnSubPropertyChanged (prop, obj, subobj_args);
245
NotifyListenersOfPropertyChange (MatrixTransform::MatrixProperty);
249
MatrixTransform::UpdateTransform ()
251
Matrix *matrix = GetMatrix ();
253
_matrix = matrix->GetUnderlyingMatrix();
255
cairo_matrix_init_identity (&_matrix);
262
TransformGroup::TransformGroup ()
264
SetValue (TransformGroup::ChildrenProperty, Value::CreateUnref (new TransformCollection ()));
267
TransformGroup::~TransformGroup ()
272
TransformGroup::OnPropertyChanged (PropertyChangedEventArgs *args)
274
if (args->property->GetOwnerType() != Type::TRANSFORMGROUP) {
275
Transform::OnPropertyChanged (args);
279
if (args->property == TransformGroup::ChildrenProperty) {
283
NotifyListenersOfPropertyChange (args);
287
TransformGroup::OnCollectionChanged (Collection *col, CollectionChangedEventArgs *args)
289
if (col != GetChildren ()) {
290
Transform::OnCollectionChanged (col, args);
295
NotifyListenersOfPropertyChange (TransformGroup::ChildrenProperty);
299
TransformGroup::OnCollectionItemChanged (Collection *col, DependencyObject *obj, PropertyChangedEventArgs *args)
301
if (col != GetChildren ()) {
302
Transform::OnCollectionItemChanged (col, obj, args);
307
NotifyListenersOfPropertyChange (TransformGroup::ChildrenProperty);
311
TransformGroup::UpdateTransform ()
313
TransformCollection *children = GetChildren ();
315
cairo_matrix_init_identity (&_matrix);
317
for (int i = 0; i < children->GetCount (); i++) {
318
Transform *transform = children->GetValueAt (i)->AsTransform ();
319
cairo_matrix_t matrix;
321
transform->GetTransform (&matrix);
322
cairo_matrix_multiply (&_matrix, &_matrix, &matrix);