ReactOS 0.4.16-dev-92-g0c2cdca
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_float(float f, float g, unsigned int ulps)
32{
33 int x = *(int *)&f;
34 int y = *(int *)&g;
35
36 if (x < 0)
37 x = INT_MIN - x;
38 if (y < 0)
39 y = INT_MIN - y;
40
41 if (abs(x - y) > ulps)
42 return FALSE;
43
44 return TRUE;
45}
46
48{
51
52 status = GdipCreateMatrix2(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &matrix);
54 ok(matrix != NULL, "Expected matrix to be initialized\n");
55
58
61}
62
63typedef struct{
67
69 {1000.00, 2600.00}, /*0*/
70 {855.00, 2390.00}, /*1*/
71 {700.00, 2200.00}, /*2*/
72 {565.00, 1970.00}, /*3*/
73 {400.00, 1800.00}, /*4*/
74 {275.00, 1550.00}, /*5*/
75 {100.00, 1400.00}, /*6*/
76 {-15.00, 1130.00}, /*7*/
77 {-200.00, 1000.00}, /*8*/
78 {-305.00, 710.00} /*9*/
79 };
80
81static void test_transform(void)
82{
85 GpPointF pts[10];
86 INT i;
87 BOOL match;
88
89 for(i = 0; i < 10; i ++){
90 pts[i].X = i * 5.0 * (REAL)(i % 2);
91 pts[i].Y = 50.0 - i * 5.0;
92 }
93
94 GdipCreateMatrix2(1.0, -2.0, 30.0, 40.0, -500.0, 600.0, &matrix);
95
98
100 expect(Ok, status);
101
102 for(i = 0; i < 10; i ++){
103 match = fabs(transform_points[i].X - pts[i].X) < 2.0
104 && fabs(transform_points[i].Y - pts[i].Y) < 2.0;
105
106 ok(match, "Expected #%d to be (%.2f, %.2f) but got (%.2f, %.2f)\n", i,
107 transform_points[i].X, transform_points[i].Y, pts[i].X, pts[i].Y);
108 }
109
111}
112
113static void test_isinvertible(void)
114{
117 BOOL result;
118
119 /* NULL arguments */
126
127 /* invertible */
128 GdipCreateMatrix2(1.0, 1.2, 2.3, -1.0, 2.0, 3.0, &matrix);
130 expect(Ok, status);
133
134 /* noninvertible */
135 GdipCreateMatrix2(2.0, -1.0, 6.0, -3.0, 2.2, 3.0, &matrix);
137 expect(Ok, status);
140}
141
142static void test_invert(void)
143{
146 GpMatrix *inverted = NULL;
147 BOOL equal = FALSE;
148 REAL elems[6];
149
150 /* NULL */
153
154 /* noninvertible */
155 GdipCreateMatrix2(2.0, -1.0, 6.0, -3.0, 2.2, 3.0, &matrix);
159
160 /* invertible */
161 GdipCreateMatrix2(3.0, -2.0, 5.0, 2.0, 6.0, 3.0, &matrix);
163 expect(Ok, status);
164 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);
165 GdipIsMatrixEqual(matrix, inverted, &equal);
166 expect(TRUE, equal);
168
169 GdipCreateMatrix2(0.0006, 0, 0, 0.0006, 400, 400, &matrix);
171 expect(Ok, status);
173 expect(Ok, status);
174 ok(compare_float(elems[0], 1666.666504, 1), "elems[0] = %.10g\n", elems[0]);
175 ok(compare_float(elems[1], 0, 0), "elems[1] = %.10g\n", elems[1]);
176 ok(compare_float(elems[2], 0, 0), "elems[2] = %.10g\n", elems[2]);
177 ok(compare_float(elems[3], 1666.666504, 1), "elems[3] = %.10g\n", elems[3]);
178 ok(compare_float(elems[4], -666666.6875, 1), "elems[4] = %.10g\n", elems[4]);
179 ok(compare_float(elems[5], -666666.6875, 1), "elems[5] = %.10g\n", elems[5]);
180
181 GdipDeleteMatrix(inverted);
183}
184
185static void test_shear(void)
186{
189 GpMatrix *sheared = NULL;
190 BOOL equal;
191
192 /* NULL */
195
196 /* X only shearing, MatrixOrderPrepend */
197 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
199 expect(Ok, status);
200 GdipCreateMatrix2(1.0, 2.0, 5.5, 2.0, 6.0, 3.0, &sheared);
201 GdipIsMatrixEqual(matrix, sheared, &equal);
202 expect(TRUE, equal);
203 GdipDeleteMatrix(sheared);
205
206 /* X only shearing, MatrixOrderAppend */
207 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
209 expect(Ok, status);
210 GdipCreateMatrix2(4.0, 2.0, 2.5, -1.0, 10.5, 3.0, &sheared);
211 GdipIsMatrixEqual(matrix, sheared, &equal);
212 expect(TRUE, equal);
213 GdipDeleteMatrix(sheared);
215
216 /* Y only shearing, MatrixOrderPrepend */
217 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
219 expect(Ok, status);
220 GdipCreateMatrix2(7.0, 0.5, 4.0, -1.0, 6.0, 3.0, &sheared);
221 GdipIsMatrixEqual(matrix, sheared, &equal);
222 expect(TRUE, equal);
223 GdipDeleteMatrix(sheared);
225
226 /* Y only shearing, MatrixOrderAppend */
227 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
229 expect(Ok, status);
230 GdipCreateMatrix2(1.0, 3.5, 4.0, 5.0, 6.0, 12.0, &sheared);
231 GdipIsMatrixEqual(matrix, sheared, &equal);
232 expect(TRUE, equal);
233 GdipDeleteMatrix(sheared);
235
236 /* X,Y shearing, MatrixOrderPrepend */
237 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
239 expect(Ok, status);
240 GdipCreateMatrix2(7.0, 0.5, 8.0, 7.0, 6.0, 3.0, &sheared);
241 GdipIsMatrixEqual(matrix, sheared, &equal);
242 expect(TRUE, equal);
243 GdipDeleteMatrix(sheared);
245
246 /* X,Y shearing, MatrixOrderAppend */
247 GdipCreateMatrix2(1.0, 2.0, 4.0, -1.0, 6.0, 3.0, &matrix);
249 expect(Ok, status);
250 GdipCreateMatrix2(9.0, 3.5, 0.0, 5.0, 18.0, 12.0, &sheared);
251 GdipIsMatrixEqual(matrix, sheared, &equal);
252 expect(TRUE, equal);
253 GdipDeleteMatrix(sheared);
255}
256
257static void test_constructor3(void)
258{
259 /* MSDN is on crack. GdipCreateMatrix3 makes a matrix that transforms the
260 * corners of the given rectangle to the three points given. */
262 REAL values[6];
263 GpRectF rc;
264 GpPointF pt[3];
266
267 rc.X = 10;
268 rc.Y = 10;
269 rc.Width = 10;
270 rc.Height = 10;
271
272 pt[0].X = 10;
273 pt[0].Y = 10;
274 pt[1].X = 20;
275 pt[1].Y = 10;
276 pt[2].X = 10;
277 pt[2].Y = 20;
278
280 expect(Ok, stat);
281
283 expect(Ok, stat);
284
285 expectf(1.0, values[0]);
286 expectf(0.0, values[1]);
287 expectf(0.0, values[2]);
288 expectf(1.0, values[3]);
289 expectf(0.0, values[4]);
290 expectf(0.0, values[5]);
291
293
294 pt[0].X = 20;
295 pt[0].Y = 10;
296 pt[1].X = 40;
297 pt[1].Y = 10;
298 pt[2].X = 20;
299 pt[2].Y = 20;
300
302 expect(Ok, stat);
303
305 expect(Ok, stat);
306
307 expectf(2.0, values[0]);
308 expectf(0.0, values[1]);
309 expectf(0.0, values[2]);
310 expectf(1.0, values[3]);
311 expectf(0.0, values[4]);
312 expectf(0.0, values[5]);
313
315
316 pt[0].X = 10;
317 pt[0].Y = 20;
318 pt[1].X = 20;
319 pt[1].Y = 30;
320 pt[2].X = 10;
321 pt[2].Y = 30;
322
324 expect(Ok, stat);
325
327 expect(Ok, stat);
328
329 expectf(1.0, values[0]);
330 expectf(1.0, values[1]);
331 expectf(0.0, values[2]);
332 expectf(1.0, values[3]);
333 expectf(0.0, values[4]);
334 expectf(0.0, values[5]);
335
337}
338
339static void test_isidentity(void)
340{
343 BOOL result;
344
347
350
351 stat = GdipCreateMatrix2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix);
352 expect(Ok, stat);
353
356
357 result = FALSE;
359 expect(Ok, stat);
360 ok(!!result, "got %d\n", result);
361
362 stat = GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.1, 0.0);
363 expect(Ok, stat);
364
365 result = TRUE;
367 expect(Ok, stat);
368 ok(!result, "got %d\n", result);
369
371}
372
374{
375 struct GdiplusStartupInput gdiplusStartupInput;
376 ULONG_PTR gdiplusToken;
377 HMODULE hmsvcrt;
378 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
379
380 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
381 hmsvcrt = LoadLibraryA("msvcrt");
382 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
383 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
384
385 gdiplusStartupInput.GdiplusVersion = 1;
386 gdiplusStartupInput.DebugEventCallback = NULL;
387 gdiplusStartupInput.SuppressBackgroundThread = 0;
388 gdiplusStartupInput.SuppressExternalCodecs = 0;
389
390 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
391
395 test_invert();
396 test_shear();
399
400 GdiplusShutdown(gdiplusToken);
401}
int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
Definition: _controlfp_s.c:19
#define stat
Definition: acwin.h:99
#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 GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix)
Definition: matrix.c:61
GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY, GpMatrixOrder order)
Definition: matrix.c:335
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *pt, GpMatrix **matrix)
Definition: matrix.c:85
GpStatus WINGDIPAPI GdipIsMatrixEqual(GDIPCONST GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, BOOL *result)
Definition: matrix.c:499
GpStatus WINGDIPAPI GdipGetMatrixElements(GDIPCONST GpMatrix *matrix, REAL *out)
Definition: matrix.c:172
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy)
Definition: matrix.c:316
GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:512
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:160
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:363
GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
Definition: matrix.c:185
GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:225
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define pt(x, y)
Definition: drawing.c:79
#define abs(i)
Definition: fconv.c:206
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:81
@ MatrixOrderAppend
Definition: gdiplusenums.h:189
@ MatrixOrderPrepend
Definition: gdiplusenums.h:188
void WINAPI GdiplusShutdown(ULONG_PTR)
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
@ InvalidParameter
Definition: gdiplustypes.h:28
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
#define INT_MIN
Definition: limits.h:39
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
Definition: fabs.c:17
unsigned int ulps
Definition: effect.c:4332
#define compare_float(got, exp)
Definition: mesh.c:52
static void test_isinvertible(void)
Definition: matrix.c:113
static real_point transform_points[]
Definition: matrix.c:68
static void test_shear(void)
Definition: matrix.c:185
static void test_constructor3(void)
Definition: matrix.c:257
#define expect(expected, got)
Definition: matrix.c:28
#define expectf(expected, got)
Definition: matrix.c:29
static void test_isidentity(void)
Definition: matrix.c:339
static void test_constructor_destructor(void)
Definition: matrix.c:47
static void test_invert(void)
Definition: matrix.c:142
static void test_transform(void)
Definition: matrix.c:81
#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:649
REAL X
Definition: gdiplustypes.h:648
REAL Height
Definition: gdiplustypes.h:664
REAL X
Definition: gdiplustypes.h:661
REAL Width
Definition: gdiplustypes.h:663
REAL Y
Definition: gdiplustypes.h:662
Definition: match.c:28
REAL X
Definition: matrix.c:64
REAL Y
Definition: matrix.c:65
Definition: stat.h:55
Definition: ps.c:97
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65