ReactOS 0.4.17-dev-243-g1369312
matrix.c
Go to the documentation of this file.
1/*
2 * Unit test suite for matrices
3 *
4 * Copyright (C) 2007 Google (Evan Stade)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 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 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <math.h>
22#include <limits.h>
23
24#include "objbase.h"
25#include "gdiplus.h"
26#include "wine/test.h"
27
28#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
29#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
30
31static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
32{
33 unsigned int diff = x > y ? x - y : y - x;
34
35 return diff <= max_diff;
36}
37
38static BOOL compare_float(float f, float g, unsigned int ulps)
39{
40 int x = *(int *)&f;
41 int y = *(int *)&g;
42
43 if (x < 0)
44 x = INT_MIN - x;
45 if (y < 0)
46 y = INT_MIN - y;
47
48 return compare_uint(x, y, ulps);
49}
50
52{
55
56 status = GdipCreateMatrix2(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &matrix);
58 ok(matrix != NULL, "Expected matrix to be initialized\n");
59
62
65}
66
67typedef struct{
71
73 {1000.00, 2600.00}, /*0*/
74 {855.00, 2390.00}, /*1*/
75 {700.00, 2200.00}, /*2*/
76 {565.00, 1970.00}, /*3*/
77 {400.00, 1800.00}, /*4*/
78 {275.00, 1550.00}, /*5*/
79 {100.00, 1400.00}, /*6*/
80 {-15.00, 1130.00}, /*7*/
81 {-200.00, 1000.00}, /*8*/
82 {-305.00, 710.00} /*9*/
83 };
84
85static void test_transform(void)
86{
89 GpPointF pts[10];
90 INT i;
91 BOOL match;
92
93 for(i = 0; i < 10; i ++){
94 pts[i].X = i * 5.0 * (REAL)(i % 2);
95 pts[i].Y = 50.0 - i * 5.0;
96 }
97
98 GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
99
102
104 expect(Ok, status);
105
106 for(i = 0; i < 10; i ++){
107 match = fabs(transform_points[i].X - pts[i].X) < 2.0
108 && fabs(transform_points[i].Y - pts[i].Y) < 2.0;
109
110 ok(match, "Expected #%d to be (%.2f, %.2f) but got (%.2f, %.2f)\n", i,
111 transform_points[i].X, transform_points[i].Y, pts[i].X, pts[i].Y);
112 }
113
115}
116
117static void test_translate(void)
118{
121 REAL elems[6];
122
123 static const REAL expected_elem_append[] = {1.0, -2.0, 30.0, 40.0, -470.0, 620.0};
124 static const REAL expected_elem_prepend[] = {1.0, -2.0, 30.0, 40.0, 130.0, 1340.0};
125
126 GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
127
131 expect(Ok, status);
132
134 expect(Ok, status);
136
137 for(INT i = 0; i < 6; i++)
138 ok(expected_elem_append[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
139 expected_elem_append[i], elems[i]);
140
141 GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
142
144 expect(Ok, status);
145
147 expect(Ok, status);
149
150 for(INT i = 0; i < 6; i++)
151 ok(expected_elem_prepend[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
152 expected_elem_prepend[i], elems[i]);
153
154}
155
156static void test_scale(void)
157{
160 REAL elems[6];
161 int i;
162
163 static const REAL expected_elem[] = {3.0, -4.0, 90.0, 80.0, -1500.0, 1200.0};
164 static const REAL expected_elem2[] = {3.0, -6.0, 60.0, 80.0, -500.0, 600.0};
165
166 GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
167
171 expect(Ok, status);
172
174 expect(Ok, status);
176
177 for(i = 0; i < 6; i++)
178 ok(expected_elem[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
179 expected_elem[i], elems[i]);
180
181 GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
182
184 expect(Ok, status);
185
187 expect(Ok, status);
189
190 for(i = 0; i < 6; i++)
191 ok(expected_elem2[i] == elems[i], "Expected #%d to be (%.1f) but got (%.1f)\n", i,
192 expected_elem2[i], elems[i]);
193
194}
195
196static void test_isinvertible(void)
197{
200 BOOL result;
201
202 /* NULL arguments */
209
210 /* invertible */
211 GdipCreateMatrix2(1.0, 1.2, 2.3, -1.0, 2.0, 3.0, &matrix);
213 expect(Ok, status);
216
217 /* noninvertible */
218 GdipCreateMatrix2(2.0, -1.0, 6.0, -3.0, 2.2, 3.0, &matrix);
220 expect(Ok, status);
223}
224
225static void test_invert(void)
226{
229 GpMatrix *inverted = NULL;
230 BOOL equal = FALSE;
231 REAL elems[6];
232
233 /* NULL */
236
237 /* noninvertible */
238 GdipCreateMatrix2(2.0, -1.0, 6.0, -3.0, 2.2, 3.0, &matrix);
242
243 /* invertible */
244 GdipCreateMatrix2(3.0, -2.0, 5.0, 2.0, 6.0, 3.0, &matrix);
246 expect(Ok, status);
247 GdipCreateMatrix2(2.0/16.0, 2.0/16.0, -5.0/16.0, 3.0/16.0, 3.0/16.0, -21.0/16.0, &inverted);
248 GdipIsMatrixEqual(matrix, inverted, &equal);
249 expect(TRUE, equal);
251
252 GdipCreateMatrix2(0.0006, 0, 0, 0.0006, 400, 400, &matrix);
254 expect(Ok, status);
256 expect(Ok, status);
257 ok(compare_float(elems[0], 1666.666504, 1), "elems[0] = %.10g\n", elems[0]);
258 ok(compare_float(elems[1], 0, 0), "elems[1] = %.10g\n", elems[1]);
259 ok(compare_float(elems[2], 0, 0), "elems[2] = %.10g\n", elems[2]);
260 ok(compare_float(elems[3], 1666.666504, 1), "elems[3] = %.10g\n", elems[3]);
261 ok(compare_float(elems[4], -666666.6875, 1), "elems[4] = %.10g\n", elems[4]);
262 ok(compare_float(elems[5], -666666.6875, 1), "elems[5] = %.10g\n", elems[5]);
263
264 GdipDeleteMatrix(inverted);
266}
267
268static void test_shear(void)
269{
272 GpMatrix *sheared = NULL;
273 BOOL equal;
274
275 /* NULL */
278
279 /* X only shearing, MatrixOrderPrepend */
280 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
282 expect(Ok, status);
283 GdipCreateMatrix2(1.0, 2.0, 5.5, 2.0, 6.0, 3.0, &sheared);
284 GdipIsMatrixEqual(matrix, sheared, &equal);
285 expect(TRUE, equal);
286 GdipDeleteMatrix(sheared);
288
289 /* X only shearing, MatrixOrderAppend */
290 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
292 expect(Ok, status);
293 GdipCreateMatrix2(4.0, 2.0, 2.5, -1.0, 10.5, 3.0, &sheared);
294 GdipIsMatrixEqual(matrix, sheared, &equal);
295 expect(TRUE, equal);
296 GdipDeleteMatrix(sheared);
298
299 /* Y only shearing, MatrixOrderPrepend */
300 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
302 expect(Ok, status);
303 GdipCreateMatrix2(7.0, 0.5, 4.0, -1.0, 6.0, 3.0, &sheared);
304 GdipIsMatrixEqual(matrix, sheared, &equal);
305 expect(TRUE, equal);
306 GdipDeleteMatrix(sheared);
308
309 /* Y only shearing, MatrixOrderAppend */
310 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
312 expect(Ok, status);
313 GdipCreateMatrix2(1.0, 3.5, 4.0, 5.0, 6.0, 12.0, &sheared);
314 GdipIsMatrixEqual(matrix, sheared, &equal);
315 expect(TRUE, equal);
316 GdipDeleteMatrix(sheared);
318
319 /* X,Y shearing, MatrixOrderPrepend */
320 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
322 expect(Ok, status);
323 GdipCreateMatrix2(7.0, 0.5, 8.0, 7.0, 6.0, 3.0, &sheared);
324 GdipIsMatrixEqual(matrix, sheared, &equal);
325 expect(TRUE, equal);
326 GdipDeleteMatrix(sheared);
328
329 /* X,Y shearing, MatrixOrderAppend */
330 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
332 expect(Ok, status);
333 GdipCreateMatrix2(9.0, 3.5, 0.0, 5.0, 18.0, 12.0, &sheared);
334 GdipIsMatrixEqual(matrix, sheared, &equal);
335 expect(TRUE, equal);
336 GdipDeleteMatrix(sheared);
338}
339
340static void test_constructor3(void)
341{
342 /* MSDN is on crack. GdipCreateMatrix3 makes a matrix that transforms the
343 * corners of the given rectangle to the three points given. */
345 REAL values[6];
346 GpRectF rc;
347 GpPointF pt[3];
349
350 rc.X = 10;
351 rc.Y = 10;
352 rc.Width = 10;
353 rc.Height = 10;
354
355 pt[0].X = 10;
356 pt[0].Y = 10;
357 pt[1].X = 20;
358 pt[1].Y = 10;
359 pt[2].X = 10;
360 pt[2].Y = 20;
361
363 expect(Ok, stat);
364
366 expect(Ok, stat);
367
368 expectf(1.0, values[0]);
369 expectf(0.0, values[1]);
370 expectf(0.0, values[2]);
371 expectf(1.0, values[3]);
372 expectf(0.0, values[4]);
373 expectf(0.0, values[5]);
374
376
377 pt[0].X = 20;
378 pt[0].Y = 10;
379 pt[1].X = 40;
380 pt[1].Y = 10;
381 pt[2].X = 20;
382 pt[2].Y = 20;
383
385 expect(Ok, stat);
386
388 expect(Ok, stat);
389
390 expectf(2.0, values[0]);
391 expectf(0.0, values[1]);
392 expectf(0.0, values[2]);
393 expectf(1.0, values[3]);
394 expectf(0.0, values[4]);
395 expectf(0.0, values[5]);
396
398
399 pt[0].X = 10;
400 pt[0].Y = 20;
401 pt[1].X = 20;
402 pt[1].Y = 30;
403 pt[2].X = 10;
404 pt[2].Y = 30;
405
407 expect(Ok, stat);
408
410 expect(Ok, stat);
411
412 expectf(1.0, values[0]);
413 expectf(1.0, values[1]);
414 expectf(0.0, values[2]);
415 expectf(1.0, values[3]);
416 expectf(0.0, values[4]);
417 expectf(0.0, values[5]);
418
420}
421
422static void test_isidentity(void)
423{
426 BOOL result;
427
430
433
434 stat = GdipCreateMatrix2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix);
435 expect(Ok, stat);
436
439
440 result = FALSE;
442 expect(Ok, stat);
443 ok(!!result, "got %d\n", result);
444
445 stat = GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.1, 0.0);
446 expect(Ok, stat);
447
448 result = TRUE;
450 expect(Ok, stat);
451 ok(!result, "got %d\n", result);
452
454}
455
457{
458 struct GdiplusStartupInput gdiplusStartupInput;
459 ULONG_PTR gdiplusToken;
460 HMODULE hmsvcrt;
461 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
462
463 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
464 hmsvcrt = LoadLibraryA("msvcrt");
465 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
466 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
467
468 gdiplusStartupInput.GdiplusVersion = 1;
469 gdiplusStartupInput.DebugEventCallback = NULL;
470 gdiplusStartupInput.SuppressBackgroundThread = 0;
471 gdiplusStartupInput.SuppressExternalCodecs = 0;
472
473 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
474
477 test_scale();
480 test_invert();
481 test_shear();
484
485 GdiplusShutdown(gdiplusToken);
486}
#define stat
Definition: acwin.h:100
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
float REAL
Definition: types.h:41
#define Y(I)
#define CDECL
Definition: compat.h:29
#define GetProcAddress(x, y)
Definition: compat.h:753
GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY, GpMatrixOrder order)
Definition: matrix.c:288
GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix)
Definition: matrix.c:59
GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY, GpMatrixOrder order)
Definition: matrix.c:337
GpStatus WINGDIPAPI GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX, REAL offsetY, GpMatrixOrder order)
Definition: matrix.c:420
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *pt, GpMatrix **matrix)
Definition: matrix.c:83
GpStatus WINGDIPAPI GdipIsMatrixEqual(GDIPCONST GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, BOOL *result)
Definition: matrix.c:500
GpStatus WINGDIPAPI GdipGetMatrixElements(GDIPCONST GpMatrix *matrix, REAL *out)
Definition: matrix.c:168
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy)
Definition: matrix.c:318
GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:513
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:156
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:365
GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
Definition: matrix.c:181
GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:224
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
_ACRTIMP errno_t __cdecl _controlfp_s(unsigned int *, unsigned int, unsigned int)
Definition: math.c:1304
#define INT_MIN
Definition: limits.h:25
_ACRTIMP double __cdecl fabs(double)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define pt(x, y)
Definition: drawing.c:79
unsigned int BOOL
Definition: ntddk_ex.h:94
FxCollectionEntry * cur
Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, struct GdiplusStartupOutput *output)
Definition: gdiplus.c:83
@ MatrixOrderAppend
Definition: gdiplusenums.h:188
@ MatrixOrderPrepend
Definition: gdiplusenums.h:187
void WINAPI GdiplusShutdown(ULONG_PTR)
Status
Definition: gdiplustypes.h:24
@ Ok
Definition: gdiplustypes.h:25
@ InvalidParameter
Definition: gdiplustypes.h:27
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLenum GLint GLuint mask
Definition: glext.h:6028
GLfloat f
Definition: glext.h:7540
GLuint GLenum matrix
Definition: glext.h:9407
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLboolean GLboolean g
Definition: glext.h:6204
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int ulps
Definition: effect.c:4332
#define compare_float(got, exp)
Definition: mesh.c:52
static void test_isinvertible(void)
Definition: matrix.c:196
static real_point transform_points[]
Definition: matrix.c:72
static void test_shear(void)
Definition: matrix.c:268
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
Definition: matrix.c:31
static void test_scale(void)
Definition: matrix.c:156
static void test_translate(void)
Definition: matrix.c:117
static void test_constructor3(void)
Definition: matrix.c:340
#define expect(expected, got)
Definition: matrix.c:28
#define expectf(expected, got)
Definition: matrix.c:29
static void test_isidentity(void)
Definition: matrix.c:422
static void test_constructor_destructor(void)
Definition: matrix.c:51
static void test_invert(void)
Definition: matrix.c:225
static void test_transform(void)
Definition: matrix.c:85
#define equal(x, y)
Definition: reader.cc:56
BOOL SuppressBackgroundThread
Definition: gdiplusinit.h:36
DebugEventProc DebugEventCallback
Definition: gdiplusinit.h:35
REAL Y
Definition: gdiplustypes.h:644
REAL X
Definition: gdiplustypes.h:643
REAL Height
Definition: gdiplustypes.h:659
REAL X
Definition: gdiplustypes.h:656
REAL Width
Definition: gdiplustypes.h:658
REAL Y
Definition: gdiplustypes.h:657
Definition: match.c:28
REAL X
Definition: matrix.c:68
REAL Y
Definition: matrix.c:69
Definition: stat.h:66
Definition: ps.c:97
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65