1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2015 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.
25 * @short_description: cairo matrix enhancements and utilities
27 * The following functions augment the cairo_matrix_t available methods
28 * providing some useful addition.
34 #include "adg-internal.h"
40 * adg_matrix_identity:
42 * A convenient constant providing an identity matrix.
44 * Returns: (transfer none): a pointer to the identity matrix
48 const cairo_matrix_t
*
49 adg_matrix_identity(void)
51 static cairo_matrix_t
*identity_matrix
= NULL
;
53 if (G_UNLIKELY(identity_matrix
== NULL
)) {
54 identity_matrix
= g_new(cairo_matrix_t
, 1);
55 cairo_matrix_init_identity(identity_matrix
);
58 return identity_matrix
;
64 * A convenient constant providing an null matrix, that is a matrix
65 * where all components are 0.
67 * Returns: (transfer none): a pointer to the null matrix
71 const cairo_matrix_t
*
74 static cairo_matrix_t
*null_matrix
= NULL
;
76 if (G_UNLIKELY(null_matrix
== NULL
))
77 null_matrix
= g_new0(cairo_matrix_t
, 1);
84 * @matrix: (out caller-allocates): the destination #cairo_matrix_t
85 * @src: the source #cairo_matrix_t
87 * Copies @src to @matrix.
92 adg_matrix_copy(cairo_matrix_t
*matrix
, const cairo_matrix_t
*src
)
94 g_return_if_fail(matrix
!= NULL
);
95 g_return_if_fail(src
!= NULL
);
97 memcpy(matrix
, src
, sizeof(cairo_matrix_t
));
102 * @matrix: the souce #cairo_matrix_t
104 * Duplicates @matrix.
106 * Returns: (transfer full): a duplicate of @matrix that must be freed with g_free() when no longer needed.
111 adg_matrix_dup(const cairo_matrix_t
*matrix
)
113 g_return_val_if_fail(matrix
!= NULL
, NULL
);
115 return g_memdup(matrix
, sizeof(cairo_matrix_t
));
120 * @matrix1: the first operand
121 * @matrix2: the second operand
123 * Compares @matrix1 and @matrix2 and returns <constant>TRUE</constant>
124 * if the matrices are equal.
126 * Returns: <constant>TRUE</constant> if @matrix1 is equal to @matrix2, <constant>FALSE</constant> otherwise.
131 adg_matrix_equal(const cairo_matrix_t
*matrix1
, const cairo_matrix_t
*matrix2
)
133 g_return_val_if_fail(matrix1
!= NULL
, FALSE
);
134 g_return_val_if_fail(matrix2
!= NULL
, FALSE
);
137 matrix1
->xx
== matrix2
->xx
&&
138 matrix1
->yx
== matrix2
->yx
&&
139 matrix1
->xy
== matrix2
->xy
&&
140 matrix1
->yy
== matrix2
->yy
&&
141 matrix1
->x0
== matrix2
->x0
&&
142 matrix1
->y0
== matrix2
->y0
;
146 * adg_matrix_normalize:
147 * @matrix: (inout): the source/destination #cairo_matrix_t
149 * Gets rid of the scaling component of a matrix.
151 * Returns: <constant>TRUE</constant> on success, <constant>FALSE</constant> on errors.
156 adg_matrix_normalize(cairo_matrix_t
*matrix
)
160 g_return_val_if_fail(matrix
!= NULL
, FALSE
);
162 if (matrix
->xx
!= matrix
->yy
|| matrix
->xy
!= -matrix
->yx
) {
163 g_warning(_("%s: normalization of anamorphic matrices not supported"),
168 if (matrix
->xy
== 0) {
170 } else if (matrix
->xx
== 0) {
173 k
= sqrt(matrix
->xx
* matrix
->xx
+ matrix
->xy
* matrix
->xy
);
176 g_return_val_if_fail(k
!= 0, FALSE
);
187 * adg_matrix_transform:
188 * @matrix: (inout): the source/destination #cairo_matrix_t
189 * @transformation: the transformation to apply
190 * @mode: (in): how @transformation should be applied
192 * Modifies @matrix applying @transformation in the way specified by
198 adg_matrix_transform(cairo_matrix_t
*matrix
,
199 const cairo_matrix_t
*transformation
, AdgTransformMode mode
)
201 cairo_matrix_t normalized
;
203 g_return_if_fail(matrix
!= NULL
);
204 g_return_if_fail(transformation
!= NULL
);
207 case ADG_TRANSFORM_NONE
:
209 case ADG_TRANSFORM_BEFORE
:
210 cairo_matrix_multiply(matrix
, transformation
, matrix
);
212 case ADG_TRANSFORM_AFTER
:
213 cairo_matrix_multiply(matrix
, matrix
, transformation
);
215 case ADG_TRANSFORM_BEFORE_NORMALIZED
:
216 adg_matrix_copy(&normalized
, transformation
);
217 adg_matrix_normalize(&normalized
);
218 cairo_matrix_multiply(matrix
, &normalized
, matrix
);
220 case ADG_TRANSFORM_AFTER_NORMALIZED
:
221 adg_matrix_copy(&normalized
, transformation
);
222 adg_matrix_normalize(&normalized
);
223 cairo_matrix_multiply(matrix
, matrix
, &normalized
);
226 g_return_if_reached();
232 * @matrix: an #cairo_matrix_t
234 * Dumps the specified @matrix to stdout. Useful for debugging purposes.
239 adg_matrix_dump(const cairo_matrix_t
*matrix
)
241 g_return_if_fail(matrix
!= NULL
);
243 g_print("[%8.3lf %8.3lf] [%8.3lf]\n"
244 "[%8.3lf %8.3lf] [%8.3lf]\n",
245 matrix
->xx
, matrix
->xy
, matrix
->x0
,
246 matrix
->yx
, matrix
->yy
, matrix
->y0
);