1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
23 * @Section_Id:AdgMatrix
25 * @short_description: A wrapper for #cairo_matrix_t
27 * AdgMatrix is a wrapper in #GType syntax of the #cairo_matrix_t struct.
33 * Another name for #cairo_matrix_t: check its documentation for the
34 * fields description and visibility details.
38 #include "adg-matrix.h"
46 adg_matrix_get_type(void)
48 static int matrix_type
= 0;
50 if (G_UNLIKELY(matrix_type
== 0))
51 matrix_type
= g_boxed_type_register_static("AdgMatrix",
52 (GBoxedCopyFunc
) adg_matrix_dup
,
59 * adg_matrix_identity:
61 * A convenient constant providing an identity matrix.
63 * Returns: a pointer to the identity matrix
66 adg_matrix_identity(void)
68 static AdgMatrix
*identity_matrix
= NULL
;
70 if (G_UNLIKELY(identity_matrix
== NULL
)) {
71 identity_matrix
= g_new(AdgMatrix
, 1);
72 cairo_matrix_init_identity(identity_matrix
);
75 return identity_matrix
;
81 * A convenient constant providing an null matrix, that is a matrix
82 * where all components are 0.
84 * Returns: a pointer to the null matrix
89 static AdgMatrix
*null_matrix
= NULL
;
91 if (G_UNLIKELY(null_matrix
== NULL
))
92 null_matrix
= g_new0(AdgMatrix
, 1);
99 * @matrix: the destination #AdgMatrix
100 * @src: the source #AdgMatrix
102 * Copies @matrix to @dst.
107 adg_matrix_copy(AdgMatrix
*matrix
, const AdgMatrix
*src
)
109 g_return_val_if_fail(matrix
!= NULL
, matrix
);
110 g_return_val_if_fail(src
!= NULL
, matrix
);
112 memcpy(matrix
, src
, sizeof(AdgMatrix
));
119 * @matrix: the souce #AdgMatrix
121 * Duplicates @matrix.
123 * Returns: the duplicate of @matrix: must be freed with g_free()
124 * when no longer needed.
127 adg_matrix_dup(const AdgMatrix
*matrix
)
129 g_return_val_if_fail(matrix
!= NULL
, NULL
);
131 return g_memdup(matrix
, sizeof(AdgMatrix
));
136 * @matrix1: an #AdgMatrix
137 * @matrix2: an #AdgMatrix
139 * Compares @matrix1 and @matrix2 and returns %TRUE if the matrices are equal.
141 * Returns: %TRUE if @matrix1 is equal to @matrix2, %FALSE otherwise
144 adg_matrix_equal(const AdgMatrix
*matrix1
, const AdgMatrix
*matrix2
)
146 g_return_val_if_fail(matrix1
!= NULL
, FALSE
);
147 g_return_val_if_fail(matrix2
!= NULL
, FALSE
);
149 /* XXX: I don't know if the following is always correct */
150 return memcmp(matrix1
, matrix2
, sizeof(AdgMatrix
)) == 0;
154 * adg_matrix_normalize:
155 * @matrix: the source/destination #AdgMatrix
157 * Gets rid of the scaling component of a matrix. The algorithm used
158 * has been found sperimentally so it could luckely be plain wrong.
160 * Returns: %TRUE on success, %FALSE on errors
163 adg_matrix_normalize(AdgMatrix
*matrix
)
167 g_return_val_if_fail(matrix
!= NULL
, FALSE
);
169 if (matrix
->xx
!= matrix
->yy
|| matrix
->xy
!= -matrix
->yx
) {
170 /* TODO: does normalization make sense on these matrices? */
171 g_warning(_("%s: anamorphic matrices not supported"), G_STRLOC
);
175 if (matrix
->xy
== 0) {
177 } else if (matrix
->xx
== 0) {
180 k
= sqrt(matrix
->xx
* matrix
->xx
+ matrix
->xy
* matrix
->xy
);
183 g_return_val_if_fail(k
!= 0, FALSE
);
194 * adg_matrix_transform:
195 * @matrix: the source/destination #AdgMatrix
196 * @transformation: the transformation to apply
197 * @mode: how @transformation should be applied
199 * Modifies @matrix applying @transformation in the way specified by
203 adg_matrix_transform(AdgMatrix
*matrix
, const AdgMatrix
*transformation
,
204 AdgTransformMode mode
)
206 AdgMatrix normalized
;
208 g_return_if_fail(matrix
!= NULL
);
209 g_return_if_fail(transformation
!= NULL
);
212 case ADG_TRANSFORM_NONE
:
214 case ADG_TRANSFORM_BEFORE
:
215 cairo_matrix_multiply(matrix
, transformation
, matrix
);
217 case ADG_TRANSFORM_AFTER
:
218 cairo_matrix_multiply(matrix
, matrix
, transformation
);
220 case ADG_TRANSFORM_BEFORE_NORMALIZED
:
221 adg_matrix_copy(&normalized
, transformation
);
222 adg_matrix_normalize(&normalized
);
223 cairo_matrix_multiply(matrix
, &normalized
, matrix
);
225 case ADG_TRANSFORM_AFTER_NORMALIZED
:
226 adg_matrix_copy(&normalized
, transformation
);
227 adg_matrix_normalize(&normalized
);
228 cairo_matrix_multiply(matrix
, matrix
, &normalized
);
231 g_assert_not_reached();
237 * @matrix: an #AdgMatrix
239 * Dumps the specified @matrix to stdout. Useful for debugging purposes.
242 adg_matrix_dump(const AdgMatrix
*matrix
)
244 g_print("[%8.3lf %8.3lf] [%8.3lf]\n"
245 "[%8.3lf %8.3lf] [%8.3lf]\n",
246 matrix
->xx
, matrix
->xy
, matrix
->x0
,
247 matrix
->yx
, matrix
->yy
, matrix
->y0
);