1 | /* Pango |
2 | * testmatrix.c: Test program for PangoMatrix |
3 | * |
4 | * Copyright (C) 2021 Matthias Clasen |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 | * Boston, MA 02111-1307, USA. |
20 | */ |
21 | |
22 | #include <glib.h> |
23 | #include <pango/pango.h> |
24 | #include <math.h> |
25 | |
26 | #define matrix_equal(m1, m2) \ |
27 | (G_APPROX_VALUE ((m1)->xx, (m2)->xx, 0.0001) && \ |
28 | G_APPROX_VALUE ((m1)->xy, (m2)->xy, 0.0001) && \ |
29 | G_APPROX_VALUE ((m1)->yx, (m2)->yx, 0.0001) && \ |
30 | G_APPROX_VALUE ((m1)->yy, (m2)->yy, 0.0001) && \ |
31 | G_APPROX_VALUE ((m1)->x0, (m2)->x0, 0.0001) && \ |
32 | G_APPROX_VALUE ((m1)->y0, (m2)->y0, 0.0001)) |
33 | |
34 | static void |
35 | test_matrix_translate (void) |
36 | { |
37 | PangoMatrix m = PANGO_MATRIX_INIT; |
38 | PangoMatrix m2 = PANGO_MATRIX_INIT; |
39 | |
40 | pango_matrix_translate (matrix: &m, tx: 10, ty: 10); |
41 | pango_matrix_translate (matrix: &m, tx: -10, ty: -10); |
42 | |
43 | g_assert_true (matrix_equal (&m, &m2)); |
44 | } |
45 | |
46 | static void |
47 | test_matrix_rotate (void) |
48 | { |
49 | PangoMatrix m = PANGO_MATRIX_INIT; |
50 | PangoMatrix m2 = PANGO_MATRIX_INIT; |
51 | |
52 | pango_matrix_rotate (matrix: &m, degrees: 90); |
53 | pango_matrix_rotate (matrix: &m, degrees: 90); |
54 | pango_matrix_rotate (matrix: &m, degrees: 90); |
55 | pango_matrix_rotate (matrix: &m, degrees: 90); |
56 | |
57 | g_assert_true (matrix_equal (&m, &m2)); |
58 | } |
59 | |
60 | static void |
61 | test_matrix_scale(void) |
62 | { |
63 | PangoMatrix m = PANGO_MATRIX_INIT; |
64 | PangoMatrix m2 = PANGO_MATRIX_INIT; |
65 | |
66 | pango_matrix_scale (matrix: &m, scale_x: 4, scale_y: 5); |
67 | m2.xx = 4; |
68 | m2.yy = 5; |
69 | |
70 | g_assert_true (matrix_equal (&m, &m2)); |
71 | } |
72 | |
73 | static void |
74 | test_matrix_concat (void) |
75 | { |
76 | PangoMatrix m = PANGO_MATRIX_INIT; |
77 | PangoMatrix id = PANGO_MATRIX_INIT; |
78 | PangoMatrix *m2; |
79 | |
80 | pango_matrix_rotate (matrix: &m, degrees: 120); |
81 | m2 = pango_matrix_copy (matrix: &m); |
82 | pango_matrix_concat (matrix: m2, new_matrix: &m); |
83 | pango_matrix_concat (matrix: m2, new_matrix: &m); |
84 | |
85 | g_assert_true (matrix_equal (&id, m2)); |
86 | |
87 | pango_matrix_free (matrix: m2); |
88 | } |
89 | |
90 | static void |
91 | test_matrix_font_scale (void) |
92 | { |
93 | PangoMatrix m = PANGO_MATRIX_INIT; |
94 | double x, y; |
95 | |
96 | pango_matrix_scale (matrix: &m, scale_x: 2, scale_y: 3); |
97 | |
98 | pango_matrix_get_font_scale_factors (matrix: &m, xscale: &x, yscale: &y); |
99 | g_assert_cmpfloat (x, ==, 2); |
100 | g_assert_cmpfloat (y, ==, 3); |
101 | g_assert_cmpfloat (pango_matrix_get_font_scale_factor (&m), ==, 3); |
102 | |
103 | pango_matrix_rotate (matrix: &m, degrees: 90); |
104 | pango_matrix_get_font_scale_factors (matrix: &m, xscale: &x, yscale: &y); |
105 | g_assert_cmpfloat (x, ==, 3); |
106 | g_assert_cmpfloat (y, ==, 2); |
107 | } |
108 | |
109 | static void |
110 | test_matrix_transform_point (void) |
111 | { |
112 | PangoMatrix m = PANGO_MATRIX_INIT; |
113 | double x, y; |
114 | |
115 | pango_matrix_translate (matrix: &m, tx: 1, ty: 1); |
116 | pango_matrix_scale (matrix: &m, scale_x: 2, scale_y: 4); |
117 | pango_matrix_rotate (matrix: &m, degrees: -90); |
118 | |
119 | x = 1; |
120 | y = 0; |
121 | |
122 | pango_matrix_transform_point (matrix: &m, x: &x, y: &y); |
123 | |
124 | g_assert_cmpfloat_with_epsilon (x, 1, 0.001); |
125 | g_assert_cmpfloat_with_epsilon (y, 5, 0.001); |
126 | } |
127 | |
128 | static void |
129 | test_matrix_transform_distance (void) |
130 | { |
131 | PangoMatrix m = PANGO_MATRIX_INIT; |
132 | double x, y; |
133 | |
134 | pango_matrix_translate (matrix: &m, tx: 1, ty: 1); |
135 | pango_matrix_scale (matrix: &m, scale_x: 2, scale_y: 4); |
136 | pango_matrix_rotate (matrix: &m, degrees: -90); |
137 | |
138 | x = 1; |
139 | y = 0; |
140 | |
141 | pango_matrix_transform_distance (matrix: &m, dx: &x, dy: &y); |
142 | |
143 | g_assert_cmpfloat_with_epsilon (x, 0, 0.001); |
144 | g_assert_cmpfloat_with_epsilon (y, 4, 0.001); |
145 | } |
146 | |
147 | static void |
148 | test_matrix_transform_rect (void) |
149 | { |
150 | PangoMatrix m = PANGO_MATRIX_INIT; |
151 | PangoRectangle rect; |
152 | |
153 | pango_matrix_rotate (matrix: &m, degrees: 45); |
154 | |
155 | rect.x = 0; |
156 | rect.y = 0; |
157 | rect.width = 1 * PANGO_SCALE; |
158 | rect.height = 1 * PANGO_SCALE; |
159 | |
160 | pango_matrix_transform_rectangle (matrix: &m, rect: &rect); |
161 | |
162 | g_assert_cmpfloat_with_epsilon (rect.x, 0, 0.5); |
163 | g_assert_cmpfloat_with_epsilon (rect.y, - G_SQRT2 / 2 * PANGO_SCALE, 0.5); |
164 | g_assert_cmpfloat_with_epsilon (rect.width, G_SQRT2 * PANGO_SCALE, 0.5); |
165 | g_assert_cmpfloat_with_epsilon (rect.height, G_SQRT2 * PANGO_SCALE, 0.5); |
166 | } |
167 | |
168 | static void |
169 | test_matrix_transform_pixel_rect (void) |
170 | { |
171 | PangoMatrix m = PANGO_MATRIX_INIT; |
172 | PangoRectangle rect; |
173 | |
174 | pango_matrix_rotate (matrix: &m, degrees: 45); |
175 | |
176 | rect.x = 0; |
177 | rect.y = 0; |
178 | rect.width = 1; |
179 | rect.height = 1; |
180 | |
181 | pango_matrix_transform_pixel_rectangle (matrix: &m, rect: &rect); |
182 | |
183 | g_assert_cmpfloat_with_epsilon (rect.x, 0, 0.1); |
184 | g_assert_cmpfloat_with_epsilon (rect.y, -1, 0.1); |
185 | g_assert_cmpfloat_with_epsilon (rect.width, 2, 0.1); |
186 | g_assert_cmpfloat_with_epsilon (rect.height, 2, 0.1); |
187 | } |
188 | |
189 | static void |
190 | test_matrix_slant_ratio (void) |
191 | { |
192 | PangoMatrix m = (PangoMatrix) { 1, 0, 0.2, 1, 0, 0 }; |
193 | PangoMatrix m2 = (PangoMatrix) { 1, 0.4, 0, 1, 0, 0 }; |
194 | double r; |
195 | |
196 | r = pango_matrix_get_slant_ratio (matrix: &m); |
197 | g_assert_cmphex (r, ==, 0.2); |
198 | |
199 | pango_matrix_rotate (matrix: &m, degrees: 45); |
200 | |
201 | r = pango_matrix_get_slant_ratio (matrix: &m); |
202 | g_assert_cmphex (r, ==, 0.2); |
203 | |
204 | pango_matrix_scale (matrix: &m, scale_x: 2, scale_y: 3); |
205 | |
206 | r = pango_matrix_get_slant_ratio (matrix: &m); |
207 | g_assert_cmphex (r, ==, 0.2); |
208 | |
209 | r = pango_matrix_get_slant_ratio (matrix: &m2); |
210 | g_assert_cmphex (r, ==, 0.4); |
211 | } |
212 | |
213 | int |
214 | main (int argc, char *argv[]) |
215 | { |
216 | g_test_init (argc: &argc, argv: &argv, NULL); |
217 | |
218 | g_test_add_func (testpath: "/matrix/translate" , test_func: test_matrix_translate); |
219 | g_test_add_func (testpath: "/matrix/rotate" , test_func: test_matrix_rotate); |
220 | g_test_add_func (testpath: "/matrix/scale" , test_func: test_matrix_scale); |
221 | g_test_add_func (testpath: "/matrix/concat" , test_func: test_matrix_concat); |
222 | g_test_add_func (testpath: "/matrix/font-scale" , test_func: test_matrix_font_scale); |
223 | g_test_add_func (testpath: "/matrix/transform-point" , test_func: test_matrix_transform_point); |
224 | g_test_add_func (testpath: "/matrix/transform-distance" , test_func: test_matrix_transform_distance); |
225 | g_test_add_func (testpath: "/matrix/transform-rect" , test_func: test_matrix_transform_rect); |
226 | g_test_add_func (testpath: "/matrix/transform-pixel-rect" , test_func: test_matrix_transform_pixel_rect); |
227 | g_test_add_func (testpath: "/matrix/slant-ratio" , test_func: test_matrix_slant_ratio); |
228 | |
229 | return g_test_run (); |
230 | } |
231 | |