ReactOS  0.4.13-dev-479-gec9c8fd
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 
31 static 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 
47 static void test_constructor_destructor(void)
48 {
50  GpMatrix *matrix = NULL;
51 
52  status = GdipCreateMatrix2(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &matrix);
53  expect(Ok, status);
54  ok(matrix != NULL, "Expected matrix to be initialized\n");
55 
58 
60  expect(Ok, status);
61 }
62 
63 typedef struct{
66 } real_point;
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 
81 static void test_transform(void)
82 {
84  GpMatrix *matrix = NULL;
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 
113 static void test_isinvertible(void)
114 {
116  GpMatrix *matrix = NULL;
117  BOOL result;
118 
119  /* NULL arguments */
122  status = GdipIsMatrixInvertible((GpMatrix*)0xdeadbeef, NULL);
126 
127  /* invertible */
128  GdipCreateMatrix2(1.0, 1.2, 2.3, -1.0, 2.0, 3.0, &matrix);
130  expect(Ok, status);
131  expect(TRUE, result);
133 
134  /* noninvertible */
135  GdipCreateMatrix2(2.0, -1.0, 6.0, -3.0, 2.2, 3.0, &matrix);
137  expect(Ok, status);
138  expect(FALSE, result);
140 }
141 
142 static void test_invert(void)
143 {
145  GpMatrix *matrix = NULL;
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 
185 static void test_shear(void)
186 {
188  GpMatrix *matrix = NULL;
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 
257 static 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. */
261  GpMatrix *matrix;
262  REAL values[6];
263  GpRectF rc;
264  GpPointF pt[3];
265  GpStatus stat;
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 
279  stat = GdipCreateMatrix3(&rc, pt, &matrix);
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 
301  stat = GdipCreateMatrix3(&rc, pt, &matrix);
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 
323  stat = GdipCreateMatrix3(&rc, pt, &matrix);
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 
339 static void test_isidentity(void)
340 {
341  GpMatrix *matrix;
342  GpStatus stat;
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;
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 
393  test_transform();
395  test_invert();
396  test_shear();
398  test_isidentity();
399 
401 }
#define abs(i)
Definition: fconv.c:206
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy)
Definition: matrix.c:316
static void test_isidentity(void)
Definition: matrix.c:339
#define TRUE
Definition: types.h:120
GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix)
Definition: matrix.c:61
static void test_shear(void)
Definition: matrix.c:185
#define Y(I)
Definition: match.c:28
#define pt(x, y)
Definition: drawing.c:79
GLuint GLenum matrix
Definition: glext.h:9407
GpStatus WINGDIPAPI GdipGetMatrixElements(GDIPCONST GpMatrix *matrix, REAL *out)
Definition: matrix.c:172
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
#define equal(x, y)
Definition: reader.cc:56
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
int32_t INT
Definition: typedefs.h:56
GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *pt, GpMatrix **matrix)
Definition: matrix.c:85
GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:225
#define expect(expected, got)
Definition: matrix.c:28
uint32_t ULONG_PTR
Definition: typedefs.h:63
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
GLenum GLint GLuint mask
Definition: glext.h:6028
GpStatus WINGDIPAPI GdipIsMatrixEqual(GDIPCONST GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, BOOL *result)
Definition: matrix.c:499
unsigned int BOOL
Definition: ntddk_ex.h:94
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
static void test_transform(void)
Definition: matrix.c:81
struct match match
Definition: match.c:33
#define expectf(expected, got)
Definition: matrix.c:29
REAL Height
Definition: gdiplustypes.h:264
static void test_isinvertible(void)
Definition: matrix.c:113
int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
Definition: cntrlfp.c:120
DebugEventProc DebugEventCallback
Definition: gdiplusinit.h:35
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat f
Definition: glext.h:7540
static void test_constructor_destructor(void)
Definition: matrix.c:47
BOOL SuppressBackgroundThread
Definition: gdiplusinit.h:36
static real_point transform_points[]
Definition: matrix.c:68
REAL X
Definition: gdiplustypes.h:261
void WINAPI GdiplusShutdown(ULONG_PTR)
Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, struct GdiplusStartupOutput *output)
Definition: gdiplus.c:81
REAL Y
Definition: gdiplustypes.h:249
START_TEST(matrix)
Definition: matrix.c:373
static ULONG_PTR gdiplusToken
Definition: CImage.cpp:99
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:160
Definition: stat.h:55
REAL X
Definition: gdiplustypes.h:248
REAL Y
Definition: matrix.c:65
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:363
Status
Definition: gdiplustypes.h:24
REAL Width
Definition: gdiplustypes.h:263
GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY, GpMatrixOrder order)
Definition: matrix.c:335
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
Definition: matrix.c:185
#define INT_MIN
Definition: limits.h:39
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
#define CDECL
Definition: compat.h:21
static void test_constructor3(void)
Definition: matrix.c:257
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
REAL X
Definition: matrix.c:64
static void test_invert(void)
Definition: matrix.c:142
#define GetProcAddress(x, y)
Definition: compat.h:410
float REAL
Definition: types.h:41
GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:512
REAL Y
Definition: gdiplustypes.h:262
GLuint64EXT * result
Definition: glext.h:11304
static SERVICE_STATUS status
Definition: service.c:31
static BOOL compare_float(float f, float g, unsigned int ulps)
Definition: matrix.c:31
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
Definition: ps.c:97