ReactOS 0.4.17-dev-243-g1369312
matrix.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Google (Evan Stade)
3 *
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.1 of the License, or (at your option) any later version.
8 *
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.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <stdarg.h>
20#include <math.h>
21
22#include "windef.h"
23#include "winbase.h"
24#include "wingdi.h"
25
26#include "objbase.h"
27
28#include "gdiplus.h"
29#include "gdiplus_private.h"
30#include "wine/debug.h"
31
33
34/* Multiplies two matrices of the form
35 *
36 * idx:0 idx:1 0
37 * idx:2 idx:3 0
38 * idx:4 idx:5 1
39 *
40 * and puts the output in out.
41 * */
43{
44 REAL temp[6];
45 temp[0] = left[0] * right[0] + left[1] * right[2];
46 temp[1] = left[0] * right[1] + left[1] * right[3];
47 temp[2] = left[2] * right[0] + left[3] * right[2];
48 temp[3] = left[2] * right[1] + left[3] * right[3];
49 temp[4] = left[4] * right[0] + left[5] * right[2] + right[4];
50 temp[5] = left[4] * right[1] + left[5] * right[3] + right[5];
51 memcpy(out, temp, 6 * sizeof(REAL));
52}
53
55{
56 return matrix->matrix[0]*matrix->matrix[3] - matrix->matrix[1]*matrix->matrix[2];
57}
58
61{
62 TRACE("(%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p)\n", m11, m12, m21, m22, dx, dy, matrix);
63
64 if(!matrix)
65 return InvalidParameter;
66
67 *matrix = malloc(sizeof(GpMatrix));
68 if(!*matrix) return OutOfMemory;
69
70 /* first row */
71 (*matrix)->matrix[0] = m11;
72 (*matrix)->matrix[1] = m12;
73 /* second row */
74 (*matrix)->matrix[2] = m21;
75 (*matrix)->matrix[3] = m22;
76 /* third row */
77 (*matrix)->matrix[4] = dx;
78 (*matrix)->matrix[5] = dy;
79
80 return Ok;
81}
82
85{
86 REAL m11, m12, m21, m22, dx, dy;
87
88 TRACE("(%s, %p, %p)\n", debugstr_rectf(rect), pt, matrix);
89
90 if(!matrix || !pt)
91 return InvalidParameter;
92
93 m11 = (pt[1].X - pt[0].X) / rect->Width;
94 m21 = (pt[2].X - pt[0].X) / rect->Height;
95 dx = pt[0].X - m11 * rect->X - m21 * rect->Y;
96 m12 = (pt[1].Y - pt[0].Y) / rect->Width;
97 m22 = (pt[2].Y - pt[0].Y) / rect->Height;
98 dy = pt[0].Y - m12 * rect->X - m22 * rect->Y;
99
100 return GdipCreateMatrix2(m11, m12, m21, m22, dx, dy, matrix);
101}
102
105{
106 GpRectF rectF;
107 GpPointF ptF[3];
108 int i;
109
110 TRACE("(%p, %p, %p)\n", rect, pt, matrix);
111
112 set_rect(&rectF, rect->X, rect->Y, rect->Width, rect->Height);
113
114 for (i = 0; i < 3; i++) {
115 ptF[i].X = (REAL)pt[i].X;
116 ptF[i].Y = (REAL)pt[i].Y;
117 }
118 return GdipCreateMatrix3(&rectF, ptF, matrix);
119}
120
122{
123 TRACE("(%s, %p)\n", debugstr_matrix(matrix), clone);
124
125 if(!matrix || !clone)
126 return InvalidParameter;
127
128 *clone = malloc(sizeof(GpMatrix));
129 if(!*clone) return OutOfMemory;
130
131 **clone = *matrix;
132
133 return Ok;
134}
135
137{
138 TRACE("(%p)\n", matrix);
139
140 if(!matrix)
141 return InvalidParameter;
142
143 *matrix = malloc(sizeof(GpMatrix));
144 if(!*matrix) return OutOfMemory;
145
146 (*matrix)->matrix[0] = 1.0;
147 (*matrix)->matrix[1] = 0.0;
148 (*matrix)->matrix[2] = 0.0;
149 (*matrix)->matrix[3] = 1.0;
150 (*matrix)->matrix[4] = 0.0;
151 (*matrix)->matrix[5] = 0.0;
152
153 return Ok;
154}
155
157{
158 TRACE("(%p)\n", matrix);
159
160 if(!matrix)
161 return InvalidParameter;
162
163 free(matrix);
164
165 return Ok;
166}
167
169 REAL *out)
170{
171 TRACE("(%s, %p)\n", debugstr_matrix(matrix), out);
172
173 if(!matrix || !out)
174 return InvalidParameter;
175
176 memcpy(out, matrix->matrix, sizeof(matrix->matrix));
177
178 return Ok;
179}
180
182{
184 REAL det;
185
186 TRACE("(%s)\n", debugstr_matrix(matrix));
187
188 if(!matrix)
189 return InvalidParameter;
190
191 /* optimize inverting simple scaling and translation matrices */
192 if(matrix->matrix[1] == 0 && matrix->matrix[2] == 0)
193 {
194 if (matrix->matrix[0] != 0 && matrix->matrix[3] != 0)
195 {
196 matrix->matrix[4] = -matrix->matrix[4] / matrix->matrix[0];
197 matrix->matrix[5] = -matrix->matrix[5] / matrix->matrix[3];
198 matrix->matrix[0] = 1 / matrix->matrix[0];
199 matrix->matrix[3] = 1 / matrix->matrix[3];
200
201 return Ok;
202 }
203 else
204 return InvalidParameter;
205 }
206 det = matrix_det(matrix);
207 if (!(fabs(det) >= 1e-5))
208 return InvalidParameter;
209
210 det = 1 / det;
211
212 copy = *matrix;
213 /* store result */
214 matrix->matrix[0] = copy.matrix[3] * det;
215 matrix->matrix[1] = -copy.matrix[1] * det;
216 matrix->matrix[2] = -copy.matrix[2] * det;
217 matrix->matrix[3] = copy.matrix[0] * det;
218 matrix->matrix[4] = (copy.matrix[2]*copy.matrix[5]-copy.matrix[3]*copy.matrix[4]) * det;
219 matrix->matrix[5] = -(copy.matrix[0]*copy.matrix[5]-copy.matrix[1]*copy.matrix[4]) * det;
220
221 return Ok;
222}
223
225{
226 TRACE("(%s, %p)\n", debugstr_matrix(matrix), result);
227
228 if(!matrix || !result)
229 return InvalidParameter;
230
231 if(matrix->matrix[1] == 0 && matrix->matrix[2] == 0)
232 *result = matrix->matrix[0] != 0 && matrix->matrix[3] != 0;
233 else
234 *result = (fabs(matrix_det(matrix)) >= 1e-5);
235
236 return Ok;
237}
238
241{
242 TRACE("(%s, %s, %d)\n", debugstr_matrix(matrix), debugstr_matrix(matrix2), order);
243
244 if(!matrix || !matrix2)
245 return InvalidParameter;
246
248 matrix_multiply(matrix->matrix, matrix2->matrix, matrix->matrix);
249 else if (order == MatrixOrderPrepend)
250 matrix_multiply(matrix2->matrix, matrix->matrix, matrix->matrix);
251 else
252 return InvalidParameter;
253
254 return Ok;
255}
256
259{
260 REAL cos_theta, sin_theta, rotate[6];
261
262 TRACE("(%p, %.2f, %d)\n", debugstr_matrix(matrix), angle, order);
263
264 if(!matrix)
265 return InvalidParameter;
266
268 cos_theta = cos(angle);
269 sin_theta = sin(angle);
270
271 rotate[0] = cos_theta;
272 rotate[1] = sin_theta;
273 rotate[2] = -sin_theta;
274 rotate[3] = cos_theta;
275 rotate[4] = 0.0;
276 rotate[5] = 0.0;
277
279 matrix_multiply(matrix->matrix, rotate, matrix->matrix);
280 else if (order == MatrixOrderPrepend)
281 matrix_multiply(rotate, matrix->matrix, matrix->matrix);
282 else
283 return InvalidParameter;
284
285 return Ok;
286}
287
290{
291 TRACE("(%s, %.2f, %.2f, %d)\n", debugstr_matrix(matrix), scaleX, scaleY, order);
292
293 if(!matrix)
294 return InvalidParameter;
295
297 {
298 matrix->matrix[0] *= scaleX;
299 matrix->matrix[1] *= scaleY;
300 matrix->matrix[2] *= scaleX;
301 matrix->matrix[3] *= scaleY;
302 matrix->matrix[4] *= scaleX;
303 matrix->matrix[5] *= scaleY;
304 }
305 else if (order == MatrixOrderPrepend)
306 {
307 matrix->matrix[0] *= scaleX;
308 matrix->matrix[1] *= scaleX;
309 matrix->matrix[2] *= scaleY;
310 matrix->matrix[3] *= scaleY;
311 }
312 else
313 return InvalidParameter;
314
315 return Ok;
316}
317
320{
321 TRACE("(%s, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", debugstr_matrix(matrix), m11, m12,
322 m21, m22, dx, dy);
323
324 if(!matrix)
325 return InvalidParameter;
326
327 matrix->matrix[0] = m11;
328 matrix->matrix[1] = m12;
329 matrix->matrix[2] = m21;
330 matrix->matrix[3] = m22;
331 matrix->matrix[4] = dx;
332 matrix->matrix[5] = dy;
333
334 return Ok;
335}
336
339{
340 REAL shear[6];
341
342 TRACE("(%s, %.2f, %.2f, %d)\n", debugstr_matrix(matrix), shearX, shearY, order);
343
344 if(!matrix)
345 return InvalidParameter;
346
347 /* prepare transformation matrix */
348 shear[0] = 1.0;
349 shear[1] = shearY;
350 shear[2] = shearX;
351 shear[3] = 1.0;
352 shear[4] = 0.0;
353 shear[5] = 0.0;
354
356 matrix_multiply(matrix->matrix, shear, matrix->matrix);
357 else if (order == MatrixOrderPrepend)
358 matrix_multiply(shear, matrix->matrix, matrix->matrix);
359 else
360 return InvalidParameter;
361
362 return Ok;
363}
364
366 INT count)
367{
368 REAL x, y;
369 INT i;
370
371 TRACE("(%s, %p, %d)\n", debugstr_matrix(matrix), pts, count);
372
373 if(!matrix || !pts || count <= 0)
374 return InvalidParameter;
375
376 for(i = 0; i < count; i++)
377 {
378 x = pts[i].X;
379 y = pts[i].Y;
380
381 pts[i].X = x * matrix->matrix[0] + y * matrix->matrix[2] + matrix->matrix[4];
382 pts[i].Y = x * matrix->matrix[1] + y * matrix->matrix[3] + matrix->matrix[5];
383 }
384
385 return Ok;
386}
387
389{
390 GpPointF *ptsF;
392 INT i;
393
394 TRACE("(%s, %p, %d)\n", debugstr_matrix(matrix), pts, count);
395
396 if(count <= 0)
397 return InvalidParameter;
398
399 ptsF = malloc(sizeof(GpPointF) * count);
400 if(!ptsF)
401 return OutOfMemory;
402
403 for(i = 0; i < count; i++){
404 ptsF[i].X = (REAL)pts[i].X;
405 ptsF[i].Y = (REAL)pts[i].Y;
406 }
407
409
410 if(ret == Ok)
411 for(i = 0; i < count; i++){
412 pts[i].X = gdip_round(ptsF[i].X);
413 pts[i].Y = gdip_round(ptsF[i].Y);
414 }
415 free(ptsF);
416
417 return ret;
418}
419
421 REAL offsetY, GpMatrixOrder order)
422{
423 TRACE("(%s, %.2f, %.2f, %d)\n", debugstr_matrix(matrix), offsetX, offsetY, order);
424
425 if(!matrix)
426 return InvalidParameter;
427
429 {
430 matrix->matrix[4] += offsetX;
431 matrix->matrix[5] += offsetY;
432 }
433 else if (order == MatrixOrderPrepend)
434 {
435 matrix->matrix[4] = offsetX * matrix->matrix[0] + offsetY * matrix->matrix[2]
436 + matrix->matrix[4];
437 matrix->matrix[5] = offsetX * matrix->matrix[1] + offsetY * matrix->matrix[3]
438 + matrix->matrix[5];
439 }
440 else
441 return InvalidParameter;
442
443 return Ok;
444}
445
447{
448 REAL x, y;
449 INT i;
450
451 TRACE("(%s, %p, %d)\n", debugstr_matrix(matrix), pts, count);
452
453 if(!matrix || !pts || count <= 0)
454 return InvalidParameter;
455
456 for(i = 0; i < count; i++)
457 {
458 x = pts[i].X;
459 y = pts[i].Y;
460
461 pts[i].X = x * matrix->matrix[0] + y * matrix->matrix[2];
462 pts[i].Y = x * matrix->matrix[1] + y * matrix->matrix[3];
463 }
464
465 return Ok;
466}
467
469{
470 GpPointF *ptsF;
472 INT i;
473
474 TRACE("(%s, %p, %d)\n", debugstr_matrix(matrix), pts, count);
475
476 if(count <= 0)
477 return InvalidParameter;
478
479 ptsF = malloc(sizeof(GpPointF) * count);
480 if(!ptsF)
481 return OutOfMemory;
482
483 for(i = 0; i < count; i++){
484 ptsF[i].X = (REAL)pts[i].X;
485 ptsF[i].Y = (REAL)pts[i].Y;
486 }
487
489 /* store back */
490 if(ret == Ok)
491 for(i = 0; i < count; i++){
492 pts[i].X = gdip_round(ptsF[i].X);
493 pts[i].Y = gdip_round(ptsF[i].Y);
494 }
495 free(ptsF);
496
497 return ret;
498}
499
501 BOOL *result)
502{
503 TRACE("(%s, %s, %p)\n", debugstr_matrix(matrix), debugstr_matrix(matrix2), result);
504
505 if(!matrix || !matrix2 || !result)
506 return InvalidParameter;
507 /* based on single array member of GpMatrix */
508 *result = (memcmp(matrix->matrix, matrix2->matrix, sizeof(GpMatrix)) == 0);
509
510 return Ok;
511}
512
514{
515 static const GpMatrix identity =
516 {
517 { 1.0, 0.0,
518 0.0, 1.0,
519 0.0, 0.0 }
520 };
521
522 TRACE("(%s, %p)\n", debugstr_matrix(matrix), result);
523
524 if(!matrix || !result)
525 return InvalidParameter;
526
528}
_STLP_MOVE_TO_STD_NAMESPACE void rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last)
Definition: _algo.c:519
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
RECT rect
Definition: combotst.c:67
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
float REAL
Definition: types.h:41
#define Y(I)
#define m22
#define m11
#define m12
#define m21
GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY, GpMatrixOrder order)
Definition: matrix.c:288
GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, GpMatrixOrder order)
Definition: matrix.c:239
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
static void matrix_multiply(GDIPCONST REAL *left, GDIPCONST REAL *right, REAL *out)
Definition: matrix.c:42
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 GdipVectorTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts, INT count)
Definition: matrix.c:468
GpStatus WINGDIPAPI GdipVectorTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:446
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 GdipRotateMatrix(GpMatrix *matrix, REAL angle, GpMatrixOrder order)
Definition: matrix.c:257
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 GdipTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts, INT count)
Definition: matrix.c:388
GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix **matrix)
Definition: matrix.c:136
GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint *pt, GpMatrix **matrix)
Definition: matrix.c:103
GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
Definition: matrix.c:181
GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result)
Definition: matrix.c:224
static REAL matrix_det(GDIPCONST GpMatrix *matrix)
Definition: matrix.c:54
GpStatus WINGDIPAPI GdipCloneMatrix(GpMatrix *matrix, GpMatrix **clone)
Definition: matrix.c:121
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP double __cdecl fabs(double)
_ACRTIMP double __cdecl sin(double)
Definition: sin.c:21
_ACRTIMP double __cdecl cos(double)
Definition: cos.c:21
#define pt(x, y)
Definition: drawing.c:79
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
const char * debugstr_rectf(const RectF *rc)
Definition: gdiplus.c:486
const char * debugstr_matrix(const GpMatrix *matrix)
Definition: gdiplus.c:498
static INT gdip_round(REAL x)
static void set_rect(GpRectF *rect, REAL x, REAL y, REAL width, REAL height)
static REAL deg2rad(REAL degrees)
MatrixOrder
Definition: gdiplusenums.h:186
@ MatrixOrderAppend
Definition: gdiplusenums.h:188
@ MatrixOrderPrepend
Definition: gdiplusenums.h:187
#define GDIPCONST
Definition: gdiplusflat.h:24
#define WINGDIPAPI
Definition: gdiplusflat.h:22
Status
Definition: gdiplustypes.h:24
@ Ok
Definition: gdiplustypes.h:25
@ InvalidParameter
Definition: gdiplustypes.h:27
@ OutOfMemory
Definition: gdiplustypes.h:28
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble right
Definition: glext.h:10859
GLuint GLenum matrix
Definition: glext.h:9407
GLint left
Definition: glext.h:7726
GLfloat angle
Definition: glext.h:10853
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
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 e
Definition: ke_i.h:82
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static calc_node_t temp
Definition: rpn_ieee.c:38
#define TRACE(s)
Definition: solgame.cpp:4
REAL Y
Definition: gdiplustypes.h:644
REAL X
Definition: gdiplustypes.h:643
int32_t INT
Definition: typedefs.h:58
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383