ReactOS  0.4.13-dev-66-gc714b7f
brush.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Google (Evan Stade)
3  * Copyright (C) 2003-2004,2007 Novell, Inc. http://www.novell.com (Ravindra (rkumar@novell.com))
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include <stdarg.h>
21 
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winuser.h"
25 #include "wingdi.h"
26 
27 #define COBJMACROS
28 #include "objbase.h"
29 #include "olectl.h"
30 #include "ole2.h"
31 
32 #include "gdiplus.h"
33 #include "gdiplus_private.h"
34 #include "wine/debug.h"
35 
37 
38 #ifdef __REACTOS__
39 /*
40  Unix stuff
41  Code from http://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/
42 */
43 double erf(double x)
44 {
45  const float a1 = 0.254829592f;
46  const float a2 = -0.284496736f;
47  const float a3 = 1.421413741f;
48  const float a4 = -1.453152027f;
49  const float a5 = 1.061405429f;
50  const float p = 0.3275911f;
51  float t, y, sign;
52 
53  /* Save the sign of x */
54  sign = 1;
55  if (x < 0)
56  sign = -1;
57  x = abs(x);
58 
59  /* A & S 7.1.26 */
60  t = 1.0/(1.0 + p*x);
61  y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
62 
63  return sign*y;
64 }
65 #endif
66 
67 /******************************************************************************
68  * GdipCloneBrush [GDIPLUS.@]
69  */
71 {
72  TRACE("(%p, %p)\n", brush, clone);
73 
74  if(!brush || !clone)
75  return InvalidParameter;
76 
77  switch(brush->bt){
79  {
80  *clone = heap_alloc_zero(sizeof(GpSolidFill));
81  if (!*clone) return OutOfMemory;
82  memcpy(*clone, brush, sizeof(GpSolidFill));
83  break;
84  }
85  case BrushTypeHatchFill:
86  {
87  GpHatch *hatch = (GpHatch*)brush;
88 
89  return GdipCreateHatchBrush(hatch->hatchstyle, hatch->forecol, hatch->backcol, (GpHatch**)clone);
90  }
93  INT count, pcount;
94  GpStatus stat;
95 
96  *clone = heap_alloc_zero(sizeof(GpPathGradient));
97  if (!*clone) return OutOfMemory;
98 
99  src = (GpPathGradient*) brush,
100  dest = (GpPathGradient*) *clone;
101 
102  memcpy(dest, src, sizeof(GpPathGradient));
103 
104  stat = GdipClonePath(src->path, &dest->path);
105 
106  if(stat != Ok){
107  heap_free(dest);
108  return stat;
109  }
110 
111  dest->transform = src->transform;
112 
113  /* blending */
114  count = src->blendcount;
115  dest->blendcount = count;
116  dest->blendfac = heap_alloc_zero(count * sizeof(REAL));
117  dest->blendpos = heap_alloc_zero(count * sizeof(REAL));
118  dest->surroundcolors = heap_alloc_zero(dest->surroundcolorcount * sizeof(ARGB));
119  pcount = dest->pblendcount;
120  if (pcount)
121  {
122  dest->pblendcolor = heap_alloc_zero(pcount * sizeof(ARGB));
123  dest->pblendpos = heap_alloc_zero(pcount * sizeof(REAL));
124  }
125 
126  if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors ||
127  (pcount && (!dest->pblendcolor || !dest->pblendpos))){
128  GdipDeletePath(dest->path);
129  heap_free(dest->blendfac);
130  heap_free(dest->blendpos);
131  heap_free(dest->surroundcolors);
132  heap_free(dest->pblendcolor);
133  heap_free(dest->pblendpos);
134  heap_free(dest);
135  return OutOfMemory;
136  }
137 
138  memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
139  memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
140  memcpy(dest->surroundcolors, src->surroundcolors, dest->surroundcolorcount * sizeof(ARGB));
141 
142  if (pcount)
143  {
144  memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
145  memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
146  }
147 
148  break;
149  }
152  INT count, pcount;
153 
154  dest = heap_alloc_zero(sizeof(GpLineGradient));
155  if(!dest) return OutOfMemory;
156 
157  src = (GpLineGradient*)brush;
158 
159  memcpy(dest, src, sizeof(GpLineGradient));
160 
161  count = dest->blendcount;
162  dest->blendfac = heap_alloc_zero(count * sizeof(REAL));
163  dest->blendpos = heap_alloc_zero(count * sizeof(REAL));
164  pcount = dest->pblendcount;
165  if (pcount)
166  {
167  dest->pblendcolor = heap_alloc_zero(pcount * sizeof(ARGB));
168  dest->pblendpos = heap_alloc_zero(pcount * sizeof(REAL));
169  }
170 
171  if (!dest->blendfac || !dest->blendpos ||
172  (pcount && (!dest->pblendcolor || !dest->pblendpos)))
173  {
174  heap_free(dest->blendfac);
175  heap_free(dest->blendpos);
176  heap_free(dest->pblendcolor);
177  heap_free(dest->pblendpos);
178  heap_free(dest);
179  return OutOfMemory;
180  }
181 
182  dest->transform = src->transform;
183 
184  memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
185  memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
186 
187  if (pcount)
188  {
189  memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
190  memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
191  }
192 
193  *clone = &dest->brush;
194  break;
195  }
197  {
198  GpStatus stat;
199  GpTexture *texture = (GpTexture*)brush;
200  GpTexture *new_texture;
201  UINT width, height;
202 
203  stat = GdipGetImageWidth(texture->image, &width);
204  if (stat != Ok) return stat;
206  if (stat != Ok) return stat;
207 
208  stat = GdipCreateTextureIA(texture->image, texture->imageattributes, 0, 0, width, height, &new_texture);
209 
210  if (stat == Ok)
211  {
212  new_texture->transform = texture->transform;
213  *clone = &new_texture->brush;
214  }
215  else
216  *clone = NULL;
217 
218  return stat;
219  }
220  default:
221  ERR("not implemented for brush type %d\n", brush->bt);
222  return NotImplemented;
223  }
224 
225  TRACE("<-- %p\n", *clone);
226  return Ok;
227 }
228 
229 static const char HatchBrushes[][8] = {
230  { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
231  { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
232  { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
233  { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
234  { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
235  { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
236  { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
237  { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
238  { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
239  { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
240  { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
241  { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
242  { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
243  { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
244  { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
245  { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
246  { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
247  { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
248  { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
249  { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
250  { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
251  { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
252  { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
253  { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
254  { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
255  { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
256  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
257  { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
258  { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
259  { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
260 };
261 
262 GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
263 {
264  if (hatchstyle < ARRAY_SIZE(HatchBrushes))
265  {
266  *result = HatchBrushes[hatchstyle];
267  return Ok;
268  }
269  else
270  return NotImplemented;
271 }
272 
273 /******************************************************************************
274  * GdipCreateHatchBrush [GDIPLUS.@]
275  */
276 GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
277 {
278  TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
279 
280  if(!brush) return InvalidParameter;
281 
282  if(hatchstyle < HatchStyleMin || hatchstyle > HatchStyleMax)
283  return InvalidParameter;
284 
285  *brush = heap_alloc_zero(sizeof(GpHatch));
286  if (!*brush) return OutOfMemory;
287 
288  (*brush)->brush.bt = BrushTypeHatchFill;
289  (*brush)->forecol = forecol;
290  (*brush)->backcol = backcol;
291  (*brush)->hatchstyle = hatchstyle;
292  TRACE("<-- %p\n", *brush);
293 
294  return Ok;
295 }
296 
297 static GpStatus create_line_brush(const GpRectF *rect, ARGB startcolor, ARGB endcolor,
299 {
300  *line = heap_alloc_zero(sizeof(GpLineGradient));
301  if(!*line) return OutOfMemory;
302 
303  (*line)->brush.bt = BrushTypeLinearGradient;
304  (*line)->startcolor = startcolor;
305  (*line)->endcolor = endcolor;
306  (*line)->wrap = wrap;
307  (*line)->gamma = FALSE;
308  (*line)->rect = *rect;
309  (*line)->blendcount = 1;
310  (*line)->blendfac = heap_alloc_zero(sizeof(REAL));
311  (*line)->blendpos = heap_alloc_zero(sizeof(REAL));
312 
313  if (!(*line)->blendfac || !(*line)->blendpos)
314  {
315  heap_free((*line)->blendfac);
316  heap_free((*line)->blendpos);
317  heap_free(*line);
318  *line = NULL;
319  return OutOfMemory;
320  }
321 
322  (*line)->blendfac[0] = 1.0f;
323  (*line)->blendpos[0] = 1.0f;
324 
325  (*line)->pblendcolor = NULL;
326  (*line)->pblendpos = NULL;
327  (*line)->pblendcount = 0;
328 
329  GdipSetMatrixElements(&(*line)->transform, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
330 
331  return Ok;
332 }
333 
335 {
336  float trans_x = line->rect.X + (line->rect.Width / 2.f);
337  float trans_y = line->rect.Y + (line->rect.Height / 2.f);
338  float dx = endpoint->X - startpoint->X;
339  float dy = endpoint->Y - startpoint->Y;
340  float t_cos, t_sin, w_ratio, h_ratio;
341  float h;
342  GpMatrix rot;
343 
344  h = sqrtf(dx * dx + dy * dy);
345 
346  t_cos = dx / h;
347  t_sin = dy / h;
348 
349  w_ratio = (fabs(t_cos) * line->rect.Width + fabs(t_sin) * line->rect.Height) / line->rect.Width;
350  h_ratio = (fabs(t_sin) * line->rect.Width + fabs(t_cos) * line->rect.Height) / line->rect.Height;
351 
352  GdipSetMatrixElements(&line->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
353 
354  GdipSetMatrixElements(&rot, t_cos, t_sin, -1.f * t_sin, t_cos, 0, 0);
355 
356  /* center about the origin */
357  GdipTranslateMatrix(&line->transform, -trans_x, -trans_y, MatrixOrderAppend);
358 
359  /* scale to normalize gradient along gradient line (?) */
360  GdipScaleMatrix(&line->transform, w_ratio, h_ratio, MatrixOrderAppend);
361 
362  /* rotate so the gradient is horizontal */
364 
365  /* restore original offset in new coords */
366  GdipTranslateMatrix(&line->transform, trans_x, trans_y, MatrixOrderAppend);
367 }
368 
369 /******************************************************************************
370  * GdipCreateLineBrush [GDIPLUS.@]
371  */
373  GDIPCONST GpPointF* endpoint, ARGB startcolor, ARGB endcolor,
375 {
376  GpStatus stat;
377  GpRectF rect;
378 
379  TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint),
380  debugstr_pointf(endpoint), startcolor, endcolor, wrap, line);
381 
382  if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
383  return InvalidParameter;
384 
385  if (startpoint->X == endpoint->X && startpoint->Y == endpoint->Y)
386  return OutOfMemory;
387 
388  rect.X = startpoint->X < endpoint->X ? startpoint->X : endpoint->X;
389  rect.Y = startpoint->Y < endpoint->Y ? startpoint->Y : endpoint->Y;
390  rect.Width = fabs(startpoint->X - endpoint->X);
391  rect.Height = fabs(startpoint->Y - endpoint->Y);
392 
393  if (rect.Width == 0.0f)
394  {
395  rect.X -= rect.Height / 2.0f;
396  rect.Width = rect.Height;
397  }
398  else if (rect.Height == 0.0f)
399  {
400  rect.Y -= rect.Width / 2.0f;
401  rect.Height = rect.Width;
402  }
403 
404  stat = create_line_brush(&rect, startcolor, endcolor, wrap, line);
405  if (stat != Ok)
406  return stat;
407 
409 
410  TRACE("<-- %p\n", *line);
411 
412  return Ok;
413 }
414 
416  GDIPCONST GpPoint* endpoint, ARGB startcolor, ARGB endcolor,
418 {
419  GpPointF stF;
420  GpPointF endF;
421 
422  TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
423  startcolor, endcolor, wrap, line);
424 
425  if(!startpoint || !endpoint)
426  return InvalidParameter;
427 
428  stF.X = (REAL)startpoint->X;
429  stF.Y = (REAL)startpoint->Y;
430  endF.X = (REAL)endpoint->X;
431  endF.Y = (REAL)endpoint->Y;
432 
433  return GdipCreateLineBrush(&stF, &endF, startcolor, endcolor, wrap, line);
434 }
435 
437  ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
439 {
440  float angle;
441 
442  TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
443  wrap, line);
444 
445  if(!line || !rect)
446  return InvalidParameter;
447 
448  switch (mode)
449  {
451  angle = 0.0f;
452  break;
454  angle = 90.0f;
455  break;
457  angle = 45.0f;
458  break;
460  angle = 135.0f;
461  break;
462  default:
463  return InvalidParameter;
464  }
465 
466  return GdipCreateLineBrushFromRectWithAngle(rect, startcolor, endcolor, angle, TRUE, wrap, line);
467 }
468 
470  ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
472 {
473  GpRectF rectF;
474 
475  TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
476  wrap, line);
477 
478  rectF.X = (REAL) rect->X;
479  rectF.Y = (REAL) rect->Y;
480  rectF.Width = (REAL) rect->Width;
481  rectF.Height = (REAL) rect->Height;
482 
483  return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line);
484 }
485 
486 /******************************************************************************
487  * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
488  */
490  ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
492 {
493  GpStatus stat;
494  REAL exofs, eyofs, far_x, far_y;
495  REAL sin_angle, cos_angle, sin_cos_angle;
496  GpPointF start, end;
497 
498  TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
499  wrap, line);
500 
501  if (!rect || !line || wrap == WrapModeClamp)
502  return InvalidParameter;
503 
504  if (!rect->Width || !rect->Height)
505  return OutOfMemory;
506 
507  angle = fmodf(angle, 360);
508  if (angle < 0)
509  angle += 360;
510 
511  if (isAngleScalable)
512  {
513  float add_angle = 0;
514 
515  while(angle >= 90) {
516  angle -= 180;
517  add_angle += M_PI;
518  }
519 
520  if (angle != 90 && angle != -90)
521  angle = atan((rect->Width / rect->Height) * tan(deg2rad(angle)));
522  else
523  angle = deg2rad(angle);
524  angle += add_angle;
525  }
526  else
527  {
528  angle = deg2rad(angle);
529  }
530 
531  sin_angle = sinf(angle);
532  cos_angle = cosf(angle);
533  sin_cos_angle = sin_angle * cos_angle;
534 
535  far_x = rect->X + rect->Width;
536  far_y = rect->Y + rect->Height;
537 
538  if (angle == 0.0f)
539  {
540  start.X = min(rect->X, far_x);
541  start.Y = rect->Y;
542  end.X = max(rect->X, far_x);
543  end.Y = rect->Y;
544  }
545  else if (sin_cos_angle >= 0)
546  {
547  start.X = min(rect->X, far_x);
548  start.Y = min(rect->Y, far_y);
549  end.X = max(rect->X, far_x);
550  end.Y = max(rect->Y, far_y);
551  }
552  else
553  {
554  start.X = max(rect->X, far_x);
555  start.Y = min(rect->Y, far_y);
556  end.X = min(rect->X, far_x);
557  end.Y = max(rect->Y, far_y);
558  }
559 
560  stat = create_line_brush(rect, startcolor, endcolor, wrap, line);
561  if (stat != Ok || angle == 0.0f)
562  return stat;
563 
564  if (sin_cos_angle >= 0)
565  {
566  exofs = rect->Height * sin_cos_angle + rect->Width * cos_angle * cos_angle;
567  eyofs = rect->Height * sin_angle * sin_angle + rect->Width * sin_cos_angle;
568  }
569  else
570  {
571  exofs = rect->Width * sin_angle * sin_angle + rect->Height * sin_cos_angle;
572  eyofs = -rect->Width * sin_cos_angle + rect->Height * sin_angle * sin_angle;
573  }
574 
575  if (sin_angle >= 0)
576  {
577  end.X = rect->X + exofs;
578  end.Y = rect->Y + eyofs;
579  }
580  else
581  {
582  end.X = start.X;
583  end.Y = start.Y;
584  start.X = rect->X + exofs;
585  start.Y = rect->Y + eyofs;
586  }
587 
589 
590  return stat;
591 }
592 
594  ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
596 {
597  TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
598  wrap, line);
599 
601  wrap, line);
602 }
603 
605 {
606  GpRectF bounds;
607 
608  if(!path || !grad)
609  return InvalidParameter;
610 
611  if (path->pathdata.Count < 2)
612  return OutOfMemory;
613 
614  GdipGetPathWorldBounds(path, &bounds, NULL, NULL);
615 
616  *grad = heap_alloc_zero(sizeof(GpPathGradient));
617  if (!*grad)
618  {
619  return OutOfMemory;
620  }
621 
622  GdipSetMatrixElements(&(*grad)->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
623 
624  (*grad)->blendfac = heap_alloc_zero(sizeof(REAL));
625  (*grad)->blendpos = heap_alloc_zero(sizeof(REAL));
626  (*grad)->surroundcolors = heap_alloc_zero(sizeof(ARGB));
627  if(!(*grad)->blendfac || !(*grad)->blendpos || !(*grad)->surroundcolors){
628  heap_free((*grad)->blendfac);
629  heap_free((*grad)->blendpos);
630  heap_free((*grad)->surroundcolors);
631  heap_free(*grad);
632  *grad = NULL;
633  return OutOfMemory;
634  }
635  (*grad)->blendfac[0] = 1.0;
636  (*grad)->blendpos[0] = 1.0;
637  (*grad)->blendcount = 1;
638 
639  (*grad)->path = path;
640 
641  (*grad)->brush.bt = BrushTypePathGradient;
642  (*grad)->centercolor = centercolor;
643  (*grad)->wrap = WrapModeClamp;
644  (*grad)->gamma = FALSE;
645  /* FIXME: this should be set to the "centroid" of the path by default */
646  (*grad)->center.X = bounds.X + bounds.Width / 2;
647  (*grad)->center.Y = bounds.Y + bounds.Height / 2;
648  (*grad)->focus.X = 0.0;
649  (*grad)->focus.Y = 0.0;
650  (*grad)->surroundcolors[0] = 0xffffffff;
651  (*grad)->surroundcolorcount = 1;
652 
653  TRACE("<-- %p\n", *grad);
654 
655  return Ok;
656 }
657 
660 {
661  GpStatus stat;
662  GpPath *path;
663 
664  TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
665 
666  if(!grad)
667  return InvalidParameter;
668 
669  if(!points || count <= 0)
670  return OutOfMemory;
671 
673 
674  if (stat == Ok)
675  {
677 
678  if (stat == Ok)
679  stat = create_path_gradient(path, 0xff000000, grad);
680 
681  if (stat != Ok)
683  }
684 
685  if (stat == Ok)
686  (*grad)->wrap = wrap;
687 
688  return stat;
689 }
690 
693 {
694  GpStatus stat;
695  GpPath *path;
696 
697  TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
698 
699  if(!grad)
700  return InvalidParameter;
701 
702  if(!points || count <= 0)
703  return OutOfMemory;
704 
706 
707  if (stat == Ok)
708  {
710 
711  if (stat == Ok)
712  stat = create_path_gradient(path, 0xff000000, grad);
713 
714  if (stat != Ok)
716  }
717 
718  if (stat == Ok)
719  (*grad)->wrap = wrap;
720 
721  return stat;
722 }
723 
724 /******************************************************************************
725  * GdipCreatePathGradientFromPath [GDIPLUS.@]
726  */
728  GpPathGradient **grad)
729 {
730  GpStatus stat;
731  GpPath *new_path;
732 
733  TRACE("(%p, %p)\n", path, grad);
734 
735  if(!grad)
736  return InvalidParameter;
737 
738  if (!path)
739  return OutOfMemory;
740 
741  stat = GdipClonePath((GpPath*)path, &new_path);
742 
743  if (stat == Ok)
744  {
745  stat = create_path_gradient(new_path, 0xffffffff, grad);
746 
747  if (stat != Ok)
748  GdipDeletePath(new_path);
749  }
750 
751  return stat;
752 }
753 
754 /******************************************************************************
755  * GdipCreateSolidFill [GDIPLUS.@]
756  */
758 {
759  TRACE("(%x, %p)\n", color, sf);
760 
761  if(!sf) return InvalidParameter;
762 
763  *sf = heap_alloc_zero(sizeof(GpSolidFill));
764  if (!*sf) return OutOfMemory;
765 
766  (*sf)->brush.bt = BrushTypeSolidColor;
767  (*sf)->color = color;
768 
769  TRACE("<-- %p\n", *sf);
770 
771  return Ok;
772 }
773 
774 /******************************************************************************
775  * GdipCreateTexture [GDIPLUS.@]
776  *
777  * PARAMS
778  * image [I] image to use
779  * wrapmode [I] optional
780  * texture [O] pointer to the resulting texturebrush
781  *
782  * RETURNS
783  * SUCCESS: Ok
784  * FAILURE: element of GpStatus
785  */
787  GpTexture **texture)
788 {
789  UINT width, height;
790  GpImageAttributes *attributes;
791  GpStatus stat;
792 
793  TRACE("%p, %d %p\n", image, wrapmode, texture);
794 
795  if (!(image && texture))
796  return InvalidParameter;
797 
799  if (stat != Ok) return stat;
801  if (stat != Ok) return stat;
802 
803  stat = GdipCreateImageAttributes(&attributes);
804 
805  if (stat == Ok)
806  {
807  attributes->wrap = wrapmode;
808 
809  stat = GdipCreateTextureIA(image, attributes, 0, 0, width, height,
810  texture);
811 
812  GdipDisposeImageAttributes(attributes);
813  }
814 
815  return stat;
816 }
817 
818 /******************************************************************************
819  * GdipCreateTexture2 [GDIPLUS.@]
820  */
823 {
824  GpImageAttributes *attributes;
825  GpStatus stat;
826 
827  TRACE("%p %d %f %f %f %f %p\n", image, wrapmode,
828  x, y, width, height, texture);
829 
830  stat = GdipCreateImageAttributes(&attributes);
831 
832  if (stat == Ok)
833  {
834  attributes->wrap = wrapmode;
835 
836  stat = GdipCreateTextureIA(image, attributes, x, y, width, height,
837  texture);
838 
839  GdipDisposeImageAttributes(attributes);
840  }
841 
842  return stat;
843 }
844 
845 /******************************************************************************
846  * GdipCreateTextureIA [GDIPLUS.@]
847  */
851 {
853  GpImage *new_image=NULL;
854 
855  TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height,
856  texture);
857 
858  if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
859  return InvalidParameter;
860 
861  *texture = NULL;
862 
863  if(image->type != ImageTypeBitmap){
864  FIXME("not implemented for image type %d\n", image->type);
865  return NotImplemented;
866  }
867 
869  if (status != Ok)
870  return status;
871 
872  *texture = heap_alloc_zero(sizeof(GpTexture));
873  if (!*texture){
875  goto exit;
876  }
877 
878  GdipSetMatrixElements(&(*texture)->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
879 
880  if (imageattr)
881  {
882  status = GdipCloneImageAttributes(imageattr, &(*texture)->imageattributes);
883  }
884  else
885  {
886  status = GdipCreateImageAttributes(&(*texture)->imageattributes);
887  if (status == Ok)
888  (*texture)->imageattributes->wrap = WrapModeTile;
889  }
890  if (status == Ok)
891  {
892  (*texture)->brush.bt = BrushTypeTextureFill;
893  (*texture)->image = new_image;
894  }
895 
896 exit:
897  if (status == Ok)
898  {
899  TRACE("<-- %p\n", *texture);
900  }
901  else
902  {
903  if (*texture)
904  {
905  GdipDisposeImageAttributes((*texture)->imageattributes);
906  heap_free(*texture);
907  *texture = NULL;
908  }
909  GdipDisposeImage(new_image);
910  TRACE("<-- error %u\n", status);
911  }
912 
913  return status;
914 }
915 
916 /******************************************************************************
917  * GdipCreateTextureIAI [GDIPLUS.@]
918  */
921 {
922  TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image, imageattr, x, y, width, height,
923  texture);
924 
925  return GdipCreateTextureIA(image,imageattr,(REAL)x,(REAL)y,(REAL)width,(REAL)height,texture);
926 }
927 
930 {
931  GpImageAttributes *imageattr;
932  GpStatus stat;
933 
934  TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height,
935  texture);
936 
937  stat = GdipCreateImageAttributes(&imageattr);
938 
939  if (stat == Ok)
940  {
941  imageattr->wrap = wrapmode;
942 
943  stat = GdipCreateTextureIA(image, imageattr, x, y, width, height, texture);
944  GdipDisposeImageAttributes(imageattr);
945  }
946 
947  return stat;
948 }
949 
951 {
952  TRACE("(%p, %p)\n", brush, type);
953 
954  if(!brush || !type) return InvalidParameter;
955 
956  *type = brush->bt;
957 
958  return Ok;
959 }
960 
962 {
963  TRACE("(%p, %p)\n", brush, backcol);
964 
965  if(!brush || !backcol) return InvalidParameter;
966 
967  *backcol = brush->backcol;
968 
969  return Ok;
970 }
971 
973 {
974  TRACE("(%p, %p)\n", brush, forecol);
975 
976  if(!brush || !forecol) return InvalidParameter;
977 
978  *forecol = brush->forecol;
979 
980  return Ok;
981 }
982 
984 {
985  TRACE("(%p, %p)\n", brush, hatchstyle);
986 
987  if(!brush || !hatchstyle) return InvalidParameter;
988 
989  *hatchstyle = brush->hatchstyle;
990 
991  return Ok;
992 }
993 
995 {
996  TRACE("(%p)\n", brush);
997 
998  if(!brush) return InvalidParameter;
999 
1000  switch(brush->bt)
1001  {
1002  case BrushTypePathGradient:
1003  GdipDeletePath(((GpPathGradient*) brush)->path);
1004  heap_free(((GpPathGradient*) brush)->blendfac);
1005  heap_free(((GpPathGradient*) brush)->blendpos);
1006  heap_free(((GpPathGradient*) brush)->surroundcolors);
1007  heap_free(((GpPathGradient*) brush)->pblendcolor);
1008  heap_free(((GpPathGradient*) brush)->pblendpos);
1009  break;
1011  heap_free(((GpLineGradient*)brush)->blendfac);
1012  heap_free(((GpLineGradient*)brush)->blendpos);
1013  heap_free(((GpLineGradient*)brush)->pblendcolor);
1014  heap_free(((GpLineGradient*)brush)->pblendpos);
1015  break;
1016  case BrushTypeTextureFill:
1017  GdipDisposeImage(((GpTexture*)brush)->image);
1018  GdipDisposeImageAttributes(((GpTexture*)brush)->imageattributes);
1019  heap_free(((GpTexture*)brush)->bitmap_bits);
1020  break;
1021  default:
1022  break;
1023  }
1024 
1025  heap_free(brush);
1026 
1027  return Ok;
1028 }
1029 
1031  BOOL *usinggamma)
1032 {
1033  TRACE("(%p, %p)\n", line, usinggamma);
1034 
1035  if(!line || !usinggamma)
1036  return InvalidParameter;
1037 
1038  *usinggamma = line->gamma;
1039 
1040  return Ok;
1041 }
1042 
1044 {
1045  TRACE("(%p, %p)\n", brush, wrapmode);
1046 
1047  if(!brush || !wrapmode || brush->brush.bt != BrushTypeLinearGradient)
1048  return InvalidParameter;
1049 
1050  *wrapmode = brush->wrap;
1051 
1052  return Ok;
1053 }
1054 
1056  REAL *positions, INT count)
1057 {
1058  TRACE("(%p, %p, %p, %d)\n", brush, blend, positions, count);
1059 
1060  if(!brush || !blend || !positions || count <= 0 || brush->brush.bt != BrushTypePathGradient)
1061  return InvalidParameter;
1062 
1063  if(count < brush->blendcount)
1064  return InsufficientBuffer;
1065 
1066  memcpy(blend, brush->blendfac, count*sizeof(REAL));
1067  if(brush->blendcount > 1){
1068  memcpy(positions, brush->blendpos, count*sizeof(REAL));
1069  }
1070 
1071  return Ok;
1072 }
1073 
1075 {
1076  TRACE("(%p, %p)\n", brush, count);
1077 
1078  if(!brush || !count || brush->brush.bt != BrushTypePathGradient)
1079  return InvalidParameter;
1080 
1081  *count = brush->blendcount;
1082 
1083  return Ok;
1084 }
1085 
1087  GpPointF *point)
1088 {
1089  TRACE("(%p, %p)\n", grad, point);
1090 
1091  if(!grad || !point || grad->brush.bt != BrushTypePathGradient)
1092  return InvalidParameter;
1093 
1094  point->X = grad->center.X;
1095  point->Y = grad->center.Y;
1096 
1097  return Ok;
1098 }
1099 
1101  GpPoint *point)
1102 {
1103  GpStatus ret;
1104  GpPointF ptf;
1105 
1106  TRACE("(%p, %p)\n", grad, point);
1107 
1108  if(!point)
1109  return InvalidParameter;
1110 
1111  ret = GdipGetPathGradientCenterPoint(grad,&ptf);
1112 
1113  if(ret == Ok){
1114  point->X = gdip_round(ptf.X);
1115  point->Y = gdip_round(ptf.Y);
1116  }
1117 
1118  return ret;
1119 }
1120 
1122  ARGB *colors)
1123 {
1124  TRACE("(%p,%p)\n", grad, colors);
1125 
1126  if (!grad || !colors || grad->brush.bt != BrushTypePathGradient)
1127  return InvalidParameter;
1128 
1129  *colors = grad->centercolor;
1130 
1131  return Ok;
1132 }
1133 
1135  REAL *x, REAL *y)
1136 {
1137  TRACE("(%p, %p, %p)\n", grad, x, y);
1138 
1139  if(!grad || !x || !y || grad->brush.bt != BrushTypePathGradient)
1140  return InvalidParameter;
1141 
1142  *x = grad->focus.X;
1143  *y = grad->focus.Y;
1144 
1145  return Ok;
1146 }
1147 
1149  BOOL *gamma)
1150 {
1151  TRACE("(%p, %p)\n", grad, gamma);
1152 
1153  if(!grad || !gamma || grad->brush.bt != BrushTypePathGradient)
1154  return InvalidParameter;
1155 
1156  *gamma = grad->gamma;
1157 
1158  return Ok;
1159 }
1160 
1162 {
1163  static int calls;
1164 
1165  TRACE("(%p, %p)\n", grad, path);
1166 
1167  if (!(calls++))
1168  FIXME("not implemented\n");
1169 
1170  return NotImplemented;
1171 }
1172 
1174  INT *count)
1175 {
1176  TRACE("(%p, %p)\n", grad, count);
1177 
1178  if(!grad || !count || grad->brush.bt != BrushTypePathGradient)
1179  return InvalidParameter;
1180 
1181  *count = grad->path->pathdata.Count;
1182 
1183  return Ok;
1184 }
1185 
1187 {
1188  GpStatus stat;
1189 
1190  TRACE("(%p, %p)\n", brush, rect);
1191 
1192  if(!brush || !rect || brush->brush.bt != BrushTypePathGradient)
1193  return InvalidParameter;
1194 
1196 
1197  return stat;
1198 }
1199 
1201 {
1202  GpRectF rectf;
1203  GpStatus stat;
1204 
1205  TRACE("(%p, %p)\n", brush, rect);
1206 
1207  if(!brush || !rect)
1208  return InvalidParameter;
1209 
1210  stat = GdipGetPathGradientRect(brush, &rectf);
1211  if(stat != Ok) return stat;
1212 
1213  rect->X = gdip_round(rectf.X);
1214  rect->Y = gdip_round(rectf.Y);
1215  rect->Width = gdip_round(rectf.Width);
1216  rect->Height = gdip_round(rectf.Height);
1217 
1218  return Ok;
1219 }
1220 
1222  *grad, ARGB *argb, INT *count)
1223 {
1224  INT i;
1225 
1226  TRACE("(%p,%p,%p)\n", grad, argb, count);
1227 
1228  if(!grad || !argb || !count || (*count < grad->path->pathdata.Count) || grad->brush.bt != BrushTypePathGradient)
1229  return InvalidParameter;
1230 
1231  for (i=0; i<grad->path->pathdata.Count; i++)
1232  {
1233  if (i < grad->surroundcolorcount)
1234  argb[i] = grad->surroundcolors[i];
1235  else
1236  argb[i] = grad->surroundcolors[grad->surroundcolorcount-1];
1237  }
1238 
1239  *count = grad->surroundcolorcount;
1240 
1241  return Ok;
1242 }
1243 
1245 {
1246  TRACE("(%p, %p)\n", brush, count);
1247 
1248  if (!brush || !count || brush->brush.bt != BrushTypePathGradient)
1249  return InvalidParameter;
1250 
1251  /* Yes, this actually returns the number of points in the path (which is the
1252  * required size of a buffer to get the surround colors), rather than the
1253  * number of surround colors. The real count is returned when getting the
1254  * colors. */
1255  *count = brush->path->pathdata.Count;
1256 
1257  return Ok;
1258 }
1259 
1261  GpWrapMode *wrapmode)
1262 {
1263  TRACE("(%p, %p)\n", brush, wrapmode);
1264 
1265  if(!brush || !wrapmode || brush->brush.bt != BrushTypePathGradient)
1266  return InvalidParameter;
1267 
1268  *wrapmode = brush->wrap;
1269 
1270  return Ok;
1271 }
1272 
1274 {
1275  TRACE("(%p, %p)\n", sf, argb);
1276 
1277  if(!sf || !argb)
1278  return InvalidParameter;
1279 
1280  *argb = sf->color;
1281 
1282  return Ok;
1283 }
1284 
1285 /******************************************************************************
1286  * GdipGetTextureImage [GDIPLUS.@]
1287  */
1289 {
1290  TRACE("(%p, %p)\n", brush, image);
1291 
1292  if(!brush || !image)
1293  return InvalidParameter;
1294 
1295  return GdipCloneImage(brush->image, image);
1296 }
1297 
1298 /******************************************************************************
1299  * GdipGetTextureTransform [GDIPLUS.@]
1300  */
1302 {
1303  TRACE("(%p, %p)\n", brush, matrix);
1304 
1305  if(!brush || !matrix)
1306  return InvalidParameter;
1307 
1308  *matrix = brush->transform;
1309 
1310  return Ok;
1311 }
1312 
1313 /******************************************************************************
1314  * GdipGetTextureWrapMode [GDIPLUS.@]
1315  */
1317 {
1318  TRACE("(%p, %p)\n", brush, wrapmode);
1319 
1320  if(!brush || !wrapmode)
1321  return InvalidParameter;
1322 
1323  *wrapmode = brush->imageattributes->wrap;
1324 
1325  return Ok;
1326 }
1327 
1328 /******************************************************************************
1329  * GdipMultiplyTextureTransform [GDIPLUS.@]
1330  */
1333 {
1334  TRACE("(%p, %p, %d)\n", brush, matrix, order);
1335 
1336  if(!brush || !matrix)
1337  return InvalidParameter;
1338 
1339  return GdipMultiplyMatrix(&brush->transform, matrix, order);
1340 }
1341 
1342 /******************************************************************************
1343  * GdipResetTextureTransform [GDIPLUS.@]
1344  */
1346 {
1347  TRACE("(%p)\n", brush);
1348 
1349  if(!brush)
1350  return InvalidParameter;
1351 
1352  return GdipSetMatrixElements(&brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1353 }
1354 
1355 /******************************************************************************
1356  * GdipScaleTextureTransform [GDIPLUS.@]
1357  */
1359  REAL sx, REAL sy, GpMatrixOrder order)
1360 {
1361  TRACE("(%p, %.2f, %.2f, %d)\n", brush, sx, sy, order);
1362 
1363  if(!brush)
1364  return InvalidParameter;
1365 
1366  return GdipScaleMatrix(&brush->transform, sx, sy, order);
1367 }
1368 
1370  GDIPCONST REAL *factors, GDIPCONST REAL* positions, INT count)
1371 {
1372  REAL *new_blendfac, *new_blendpos;
1373 
1374  TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count);
1375 
1376  if(!brush || !factors || !positions || count <= 0 || brush->brush.bt != BrushTypeLinearGradient ||
1377  (count >= 2 && (positions[0] != 0.0f || positions[count-1] != 1.0f)))
1378  return InvalidParameter;
1379 
1380  new_blendfac = heap_alloc_zero(count * sizeof(REAL));
1381  new_blendpos = heap_alloc_zero(count * sizeof(REAL));
1382 
1383  if (!new_blendfac || !new_blendpos)
1384  {
1385  heap_free(new_blendfac);
1386  heap_free(new_blendpos);
1387  return OutOfMemory;
1388  }
1389 
1390  memcpy(new_blendfac, factors, count * sizeof(REAL));
1391  memcpy(new_blendpos, positions, count * sizeof(REAL));
1392 
1393  heap_free(brush->blendfac);
1394  heap_free(brush->blendpos);
1395 
1396  brush->blendcount = count;
1397  brush->blendfac = new_blendfac;
1398  brush->blendpos = new_blendpos;
1399 
1400  return Ok;
1401 }
1402 
1404  REAL *positions, INT count)
1405 {
1406  TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count);
1407 
1408  if (!brush || !factors || !positions || count <= 0 || brush->brush.bt != BrushTypeLinearGradient)
1409  return InvalidParameter;
1410 
1411  if (count < brush->blendcount)
1412  return InsufficientBuffer;
1413 
1414  memcpy(factors, brush->blendfac, brush->blendcount * sizeof(REAL));
1415  memcpy(positions, brush->blendpos, brush->blendcount * sizeof(REAL));
1416 
1417  return Ok;
1418 }
1419 
1421 {
1422  TRACE("(%p, %p)\n", brush, count);
1423 
1424  if (!brush || !count || brush->brush.bt != BrushTypeLinearGradient)
1425  return InvalidParameter;
1426 
1427  *count = brush->blendcount;
1428 
1429  return Ok;
1430 }
1431 
1433  BOOL usegamma)
1434 {
1435  TRACE("(%p, %d)\n", line, usegamma);
1436 
1437  if(!line || line->brush.bt != BrushTypeLinearGradient)
1438  return InvalidParameter;
1439 
1440  line->gamma = usegamma;
1441 
1442  return Ok;
1443 }
1444 
1446  REAL scale)
1447 {
1448  REAL factors[33];
1449  REAL positions[33];
1450  int num_points = 0;
1451  int i;
1452  const int precision = 16;
1453  REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */
1454  REAL min_erf;
1455  REAL scale_erf;
1456 
1457  TRACE("(%p, %0.2f, %0.2f)\n", line, focus, scale);
1458 
1459  if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0 || line->brush.bt != BrushTypeLinearGradient)
1460  return InvalidParameter;
1461 
1462  /* we want 2 standard deviations */
1463  erf_range = 2.0 / sqrt(2);
1464 
1465  /* calculate the constants we need to normalize the error function to be
1466  between 0.0 and scale over the range we need */
1467  min_erf = erf(-erf_range);
1468  scale_erf = scale / (-2.0 * min_erf);
1469 
1470  if (focus != 0.0)
1471  {
1472  positions[0] = 0.0;
1473  factors[0] = 0.0;
1474  for (i=1; i<precision; i++)
1475  {
1476  positions[i] = focus * i / precision;
1477  factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf);
1478  }
1479  num_points += precision;
1480  }
1481 
1482  positions[num_points] = focus;
1483  factors[num_points] = scale;
1484  num_points += 1;
1485 
1486  if (focus != 1.0)
1487  {
1488  for (i=1; i<precision; i++)
1489  {
1490  positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision));
1491  factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf);
1492  }
1493  num_points += precision;
1494  positions[num_points-1] = 1.0;
1495  factors[num_points-1] = 0.0;
1496  }
1497 
1498  return GdipSetLineBlend(line, factors, positions, num_points);
1499 }
1500 
1502  GpWrapMode wrap)
1503 {
1504  TRACE("(%p, %d)\n", line, wrap);
1505 
1506  if(!line || wrap == WrapModeClamp || line->brush.bt != BrushTypeLinearGradient)
1507  return InvalidParameter;
1508 
1509  line->wrap = wrap;
1510 
1511  return Ok;
1512 }
1513 
1516 {
1517  REAL *new_blendfac, *new_blendpos;
1518 
1519  TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);
1520 
1521  if(!brush || !blend || !pos || count <= 0 || brush->brush.bt != BrushTypePathGradient ||
1522  (count >= 2 && (pos[0] != 0.0f || pos[count-1] != 1.0f)))
1523  return InvalidParameter;
1524 
1525  new_blendfac = heap_alloc_zero(count * sizeof(REAL));
1526  new_blendpos = heap_alloc_zero(count * sizeof(REAL));
1527 
1528  if (!new_blendfac || !new_blendpos)
1529  {
1530  heap_free(new_blendfac);
1531  heap_free(new_blendpos);
1532  return OutOfMemory;
1533  }
1534 
1535  memcpy(new_blendfac, blend, count * sizeof(REAL));
1536  memcpy(new_blendpos, pos, count * sizeof(REAL));
1537 
1538  heap_free(brush->blendfac);
1539  heap_free(brush->blendpos);
1540 
1541  brush->blendcount = count;
1542  brush->blendfac = new_blendfac;
1543  brush->blendpos = new_blendpos;
1544 
1545  return Ok;
1546 }
1547 
1549  REAL focus, REAL scale)
1550 {
1551  REAL factors[3];
1552  REAL positions[3];
1553  int num_points = 0;
1554 
1555  TRACE("(%p,%0.2f,%0.2f)\n", brush, focus, scale);
1556 
1557  if (!brush || brush->brush.bt != BrushTypePathGradient)
1558  return InvalidParameter;
1559 
1560  if (focus != 0.0)
1561  {
1562  factors[num_points] = 0.0;
1563  positions[num_points] = 0.0;
1564  num_points++;
1565  }
1566 
1567  factors[num_points] = scale;
1568  positions[num_points] = focus;
1569  num_points++;
1570 
1571  if (focus != 1.0)
1572  {
1573  factors[num_points] = 0.0;
1574  positions[num_points] = 1.0;
1575  num_points++;
1576  }
1577 
1578  return GdipSetPathGradientBlend(brush, factors, positions, num_points);
1579 }
1580 
1582  GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count)
1583 {
1584  ARGB *new_color;
1585  REAL *new_pos;
1586  TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);
1587 
1588  if (!brush || !blend || !pos || count < 2 || brush->brush.bt != BrushTypePathGradient ||
1589  pos[0] != 0.0f || pos[count-1] != 1.0f)
1590  {
1591  return InvalidParameter;
1592  }
1593 
1594  new_color = heap_alloc_zero(count * sizeof(ARGB));
1595  new_pos = heap_alloc_zero(count * sizeof(REAL));
1596  if (!new_color || !new_pos)
1597  {
1598  heap_free(new_color);
1599  heap_free(new_pos);
1600  return OutOfMemory;
1601  }
1602 
1603  memcpy(new_color, blend, sizeof(ARGB) * count);
1604  memcpy(new_pos, pos, sizeof(REAL) * count);
1605 
1606  heap_free(brush->pblendcolor);
1607  heap_free(brush->pblendpos);
1608 
1609  brush->pblendcolor = new_color;
1610  brush->pblendpos = new_pos;
1611  brush->pblendcount = count;
1612 
1613  return Ok;
1614 }
1615 
1617  ARGB *blend, REAL *pos, INT count)
1618 {
1619  TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count);
1620 
1621  if (count < 0)
1622  return OutOfMemory;
1623 
1624  if (!brush || !blend || !pos || count < 2 || brush->brush.bt != BrushTypePathGradient)
1625  return InvalidParameter;
1626 
1627  if (brush->pblendcount == 0)
1628  return GenericError;
1629 
1630  if (count != brush->pblendcount)
1631  {
1632  /* Native lines up the ends of each array, and copies the destination size. */
1633  FIXME("Braindead behavior on wrong-sized buffer not implemented.\n");
1634  return InvalidParameter;
1635  }
1636 
1637  memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
1638  memcpy(pos, brush->pblendpos, sizeof(REAL) * brush->pblendcount);
1639 
1640  return Ok;
1641 }
1642 
1644  INT *count)
1645 {
1646  TRACE("(%p,%p)\n", brush, count);
1647 
1648  if (!brush || !count || brush->brush.bt != BrushTypePathGradient)
1649  return InvalidParameter;
1650 
1651  *count = brush->pblendcount;
1652 
1653  return Ok;
1654 }
1655 
1657  ARGB argb)
1658 {
1659  TRACE("(%p, %x)\n", grad, argb);
1660 
1661  if(!grad || grad->brush.bt != BrushTypePathGradient)
1662  return InvalidParameter;
1663 
1664  grad->centercolor = argb;
1665  return Ok;
1666 }
1667 
1669  GpPointF *point)
1670 {
1671  TRACE("(%p, %s)\n", grad, debugstr_pointf(point));
1672 
1673  if(!grad || !point || grad->brush.bt != BrushTypePathGradient)
1674  return InvalidParameter;
1675 
1676  grad->center.X = point->X;
1677  grad->center.Y = point->Y;
1678 
1679  return Ok;
1680 }
1681 
1683  GpPoint *point)
1684 {
1685  GpPointF ptf;
1686 
1687  TRACE("(%p, %p)\n", grad, point);
1688 
1689  if(!point)
1690  return InvalidParameter;
1691 
1692  ptf.X = (REAL)point->X;
1693  ptf.Y = (REAL)point->Y;
1694 
1695  return GdipSetPathGradientCenterPoint(grad,&ptf);
1696 }
1697 
1699  REAL x, REAL y)
1700 {
1701  TRACE("(%p, %.2f, %.2f)\n", grad, x, y);
1702 
1703  if(!grad || grad->brush.bt != BrushTypePathGradient)
1704  return InvalidParameter;
1705 
1706  grad->focus.X = x;
1707  grad->focus.Y = y;
1708 
1709  return Ok;
1710 }
1711 
1713  BOOL gamma)
1714 {
1715  TRACE("(%p, %d)\n", grad, gamma);
1716 
1717  if(!grad || grad->brush.bt != BrushTypePathGradient)
1718  return InvalidParameter;
1719 
1720  grad->gamma = gamma;
1721 
1722  return Ok;
1723 }
1724 
1726 {
1727  static int calls;
1728 
1729  TRACE("(%p, %p)\n", grad, path);
1730 
1731  if (!(calls++))
1732  FIXME("not implemented\n");
1733 
1734  return NotImplemented;
1735 }
1736 
1738  REAL focus, REAL scale)
1739 {
1740  REAL factors[33];
1741  REAL positions[33];
1742  int num_points = 0;
1743  int i;
1744  const int precision = 16;
1745  REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */
1746  REAL min_erf;
1747  REAL scale_erf;
1748 
1749  TRACE("(%p,%0.2f,%0.2f)\n", grad, focus, scale);
1750 
1751  if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0 || grad->brush.bt != BrushTypePathGradient)
1752  return InvalidParameter;
1753 
1754  /* we want 2 standard deviations */
1755  erf_range = 2.0 / sqrt(2);
1756 
1757  /* calculate the constants we need to normalize the error function to be
1758  between 0.0 and scale over the range we need */
1759  min_erf = erf(-erf_range);
1760  scale_erf = scale / (-2.0 * min_erf);
1761 
1762  if (focus != 0.0)
1763  {
1764  positions[0] = 0.0;
1765  factors[0] = 0.0;
1766  for (i=1; i<precision; i++)
1767  {
1768  positions[i] = focus * i / precision;
1769  factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf);
1770  }
1771  num_points += precision;
1772  }
1773 
1774  positions[num_points] = focus;
1775  factors[num_points] = scale;
1776  num_points += 1;
1777 
1778  if (focus != 1.0)
1779  {
1780  for (i=1; i<precision; i++)
1781  {
1782  positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision));
1783  factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf);
1784  }
1785  num_points += precision;
1786  positions[num_points-1] = 1.0;
1787  factors[num_points-1] = 0.0;
1788  }
1789 
1790  return GdipSetPathGradientBlend(grad, factors, positions, num_points);
1791 }
1792 
1794  *grad, GDIPCONST ARGB *argb, INT *count)
1795 {
1796  ARGB *new_surroundcolors;
1797  INT i, num_colors;
1798 
1799  TRACE("(%p,%p,%p)\n", grad, argb, count);
1800 
1801  if(!grad || !argb || !count || (*count <= 0) || grad->brush.bt != BrushTypePathGradient ||
1802  (*count > grad->path->pathdata.Count))
1803  return InvalidParameter;
1804 
1805  num_colors = *count;
1806 
1807  /* If all colors are the same, only store 1 color. */
1808  if (*count > 1)
1809  {
1810  for (i=1; i < num_colors; i++)
1811  if (argb[i] != argb[i-1])
1812  break;
1813 
1814  if (i == num_colors)
1815  num_colors = 1;
1816  }
1817 
1818  new_surroundcolors = heap_alloc_zero(num_colors * sizeof(ARGB));
1819  if (!new_surroundcolors)
1820  return OutOfMemory;
1821 
1822  memcpy(new_surroundcolors, argb, num_colors * sizeof(ARGB));
1823 
1824  heap_free(grad->surroundcolors);
1825 
1826  grad->surroundcolors = new_surroundcolors;
1827  grad->surroundcolorcount = num_colors;
1828 
1829  return Ok;
1830 }
1831 
1833  GpWrapMode wrap)
1834 {
1835  TRACE("(%p, %d)\n", grad, wrap);
1836 
1837  if(!grad || grad->brush.bt != BrushTypePathGradient)
1838  return InvalidParameter;
1839 
1840  grad->wrap = wrap;
1841 
1842  return Ok;
1843 }
1844 
1846  GpMatrix *matrix)
1847 {
1848  TRACE("(%p,%p)\n", grad, matrix);
1849 
1850  if (!grad || !matrix || grad->brush.bt != BrushTypePathGradient)
1851  return InvalidParameter;
1852 
1853  grad->transform = *matrix;
1854 
1855  return Ok;
1856 }
1857 
1859  GpMatrix *matrix)
1860 {
1861  TRACE("(%p,%p)\n", grad, matrix);
1862 
1863  if (!grad || !matrix || grad->brush.bt != BrushTypePathGradient)
1864  return InvalidParameter;
1865 
1866  *matrix = grad->transform;
1867 
1868  return Ok;
1869 }
1870 
1873 {
1874  TRACE("(%p,%p,%i)\n", grad, matrix, order);
1875 
1876  if (!grad || grad->brush.bt != BrushTypePathGradient)
1877  return InvalidParameter;
1878 
1879  return GdipMultiplyMatrix(&grad->transform, matrix, order);
1880 }
1881 
1883 {
1884  TRACE("(%p)\n", grad);
1885 
1886  if (!grad || grad->brush.bt != BrushTypePathGradient)
1887  return InvalidParameter;
1888 
1889  return GdipSetMatrixElements(&grad->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1890 }
1891 
1894 {
1895  TRACE("(%p,%0.2f,%i)\n", grad, angle, order);
1896 
1897  if (!grad || grad->brush.bt != BrushTypePathGradient)
1898  return InvalidParameter;
1899 
1900  return GdipRotateMatrix(&grad->transform, angle, order);
1901 }
1902 
1904  REAL sx, REAL sy, GpMatrixOrder order)
1905 {
1906  TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, sx, sy, order);
1907 
1908  if (!grad || grad->brush.bt != BrushTypePathGradient)
1909  return InvalidParameter;
1910 
1911  return GdipScaleMatrix(&grad->transform, sx, sy, order);
1912 }
1913 
1916 {
1917  TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, dx, dy, order);
1918 
1919  if (!grad || grad->brush.bt != BrushTypePathGradient)
1920  return InvalidParameter;
1921 
1922  return GdipTranslateMatrix(&grad->transform, dx, dy, order);
1923 }
1924 
1926 {
1927  TRACE("(%p, %x)\n", sf, argb);
1928 
1929  if(!sf)
1930  return InvalidParameter;
1931 
1932  sf->color = argb;
1933  return Ok;
1934 }
1935 
1936 /******************************************************************************
1937  * GdipSetTextureTransform [GDIPLUS.@]
1938  */
1941 {
1942  TRACE("(%p, %p)\n", texture, matrix);
1943 
1944  if(!texture || !matrix)
1945  return InvalidParameter;
1946 
1947  texture->transform = *matrix;
1948 
1949  return Ok;
1950 }
1951 
1952 /******************************************************************************
1953  * GdipSetTextureWrapMode [GDIPLUS.@]
1954  *
1955  * WrapMode not used, only stored
1956  */
1958 {
1959  TRACE("(%p, %d)\n", brush, wrapmode);
1960 
1961  if(!brush)
1962  return InvalidParameter;
1963 
1964  brush->imageattributes->wrap = wrapmode;
1965 
1966  return Ok;
1967 }
1968 
1970  ARGB color2)
1971 {
1972  TRACE("(%p, %x, %x)\n", brush, color1, color2);
1973 
1974  if(!brush || brush->brush.bt != BrushTypeLinearGradient)
1975  return InvalidParameter;
1976 
1977  brush->startcolor = color1;
1978  brush->endcolor = color2;
1979 
1980  return Ok;
1981 }
1982 
1984 {
1985  TRACE("(%p, %p)\n", brush, colors);
1986 
1987  if(!brush || !colors || brush->brush.bt != BrushTypeLinearGradient)
1988  return InvalidParameter;
1989 
1990  colors[0] = brush->startcolor;
1991  colors[1] = brush->endcolor;
1992 
1993  return Ok;
1994 }
1995 
1996 /******************************************************************************
1997  * GdipRotateTextureTransform [GDIPLUS.@]
1998  */
2001 {
2002  TRACE("(%p, %.2f, %d)\n", brush, angle, order);
2003 
2004  if(!brush)
2005  return InvalidParameter;
2006 
2007  return GdipRotateMatrix(&brush->transform, angle, order);
2008 }
2009 
2011  REAL scale)
2012 {
2013  REAL factors[3];
2014  REAL positions[3];
2015  int num_points = 0;
2016 
2017  TRACE("(%p,%.2f,%.2f)\n", brush, focus, scale);
2018 
2019  if (!brush) return InvalidParameter;
2020 
2021  if (focus != 0.0)
2022  {
2023  factors[num_points] = 0.0;
2024  positions[num_points] = 0.0;
2025  num_points++;
2026  }
2027 
2028  factors[num_points] = scale;
2029  positions[num_points] = focus;
2030  num_points++;
2031 
2032  if (focus != 1.0)
2033  {
2034  factors[num_points] = 0.0;
2035  positions[num_points] = 1.0;
2036  num_points++;
2037  }
2038 
2039  return GdipSetLineBlend(brush, factors, positions, num_points);
2040 }
2041 
2043  GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
2044 {
2045  ARGB *new_color;
2046  REAL *new_pos;
2047  TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count);
2048 
2049  if (!brush || !blend || !positions || count < 2 || brush->brush.bt != BrushTypeLinearGradient ||
2050  positions[0] != 0.0f || positions[count-1] != 1.0f)
2051  {
2052  return InvalidParameter;
2053  }
2054 
2055  new_color = heap_alloc_zero(count * sizeof(ARGB));
2056  new_pos = heap_alloc_zero(count * sizeof(REAL));
2057  if (!new_color || !new_pos)
2058  {
2059  heap_free(new_color);
2060  heap_free(new_pos);
2061  return OutOfMemory;
2062  }
2063 
2064  memcpy(new_color, blend, sizeof(ARGB) * count);
2065  memcpy(new_pos, positions, sizeof(REAL) * count);
2066 
2067  heap_free(brush->pblendcolor);
2068  heap_free(brush->pblendpos);
2069 
2070  brush->pblendcolor = new_color;
2071  brush->pblendpos = new_pos;
2072  brush->pblendcount = count;
2073 
2074  return Ok;
2075 }
2076 
2078  ARGB *blend, REAL* positions, INT count)
2079 {
2080  if (!brush || !blend || !positions || count < 2 || brush->brush.bt != BrushTypeLinearGradient)
2081  return InvalidParameter;
2082 
2083  if (brush->pblendcount == 0)
2084  return GenericError;
2085 
2086  if (count < brush->pblendcount)
2087  return InsufficientBuffer;
2088 
2089  memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
2090  memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount);
2091 
2092  return Ok;
2093 }
2094 
2096  INT *count)
2097 {
2098  if (!brush || !count || brush->brush.bt != BrushTypeLinearGradient)
2099  return InvalidParameter;
2100 
2101  *count = brush->pblendcount;
2102 
2103  return Ok;
2104 }
2105 
2107 {
2108  TRACE("(%p)\n", brush);
2109 
2110  if(!brush)
2111  return InvalidParameter;
2112 
2113  return GdipSetMatrixElements(&brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
2114 }
2115 
2118 {
2119  TRACE("(%p,%p)\n", brush, matrix);
2120 
2121  if(!brush || !matrix)
2122  return InvalidParameter;
2123 
2124  brush->transform = *matrix;
2125 
2126  return Ok;
2127 }
2128 
2130 {
2131  TRACE("(%p,%p)\n", brush, matrix);
2132 
2133  if(!brush || !matrix)
2134  return InvalidParameter;
2135 
2136  *matrix = brush->transform;
2137 
2138  return Ok;
2139 }
2140 
2143 {
2144  TRACE("(%p,%0.2f,%0.2f,%u)\n", brush, sx, sy, order);
2145 
2146  if(!brush)
2147  return InvalidParameter;
2148 
2149  return GdipScaleMatrix(&brush->transform, sx, sy, order);
2150 }
2151 
2154 {
2155  TRACE("(%p,%p,%u)\n", brush, matrix, order);
2156 
2157  if(!brush)
2158  return InvalidParameter;
2159 
2160  if(!matrix)
2161  return Ok;
2162 
2163  return GdipMultiplyMatrix(&brush->transform, matrix, order);
2164 }
2165 
2168 {
2169  TRACE("(%p,%f,%f,%d)\n", brush, dx, dy, order);
2170 
2171  if(!brush)
2172  return InvalidParameter;
2173 
2174  return GdipTranslateMatrix(&brush->transform, dx, dy, order);
2175 }
2176 
2177 /******************************************************************************
2178  * GdipTranslateTextureTransform [GDIPLUS.@]
2179  */
2182 {
2183  TRACE("(%p, %.2f, %.2f, %d)\n", brush, dx, dy, order);
2184 
2185  if(!brush)
2186  return InvalidParameter;
2187 
2188  return GdipTranslateMatrix(&brush->transform, dx, dy, order);
2189 }
2190 
2192 {
2193  TRACE("(%p, %p)\n", brush, rect);
2194 
2195  if(!brush || !rect || brush->brush.bt != BrushTypeLinearGradient)
2196  return InvalidParameter;
2197 
2198  *rect = brush->rect;
2199 
2200  return Ok;
2201 }
2202 
2204 {
2205  GpRectF rectF;
2206  GpStatus ret;
2207 
2208  TRACE("(%p, %p)\n", brush, rect);
2209 
2210  if(!rect)
2211  return InvalidParameter;
2212 
2213  ret = GdipGetLineRect(brush, &rectF);
2214 
2215  if(ret == Ok){
2216  rect->X = gdip_round(rectF.X);
2217  rect->Y = gdip_round(rectF.Y);
2218  rect->Width = gdip_round(rectF.Width);
2219  rect->Height = gdip_round(rectF.Height);
2220  }
2221 
2222  return ret;
2223 }
2224 
2227 {
2228  static int calls;
2229 
2230  TRACE("(%p,%0.2f,%u)\n", brush, angle, order);
2231 
2232  if(!brush || brush->brush.bt != BrushTypeLinearGradient)
2233  return InvalidParameter;
2234 
2235  if(!(calls++))
2236  FIXME("(%p, %.2f, %d) stub\n", brush, angle, order);
2237 
2238  return NotImplemented;
2239 }
_STLP_DECLSPEC complex< float > _STLP_CALL sqrt(const complex< float > &)
Definition: complex.cpp:188
GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb)
Definition: brush.c:1273
static size_t double int int int * sign
Definition: printf.c:64
GpStatus WINGDIPAPI GdipGetTextureImage(GpTexture *brush, GpImage **image)
Definition: brush.c:1288
static const char HatchBrushes[][8]
Definition: brush.c:229
GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture, GDIPCONST GpMatrix *matrix)
Definition: brush.c:1939
#define abs(i)
Definition: fconv.c:206
GpStatus WINGDIPAPI GdipGetPathGradientCenterColor(GpPathGradient *grad, ARGB *colors)
Definition: brush.c:1121
GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy)
Definition: matrix.c:316
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
#define max(a, b)
Definition: svc.c:63
GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy, GpMatrixOrder order)
Definition: brush.c:2141
HatchStyle
Definition: gdiplusenums.h:387
#define TRUE
Definition: types.h:120
GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush)
Definition: brush.c:2106
static const struct update_accum a3
Definition: msg.c:600
LinearGradientMode
Definition: gdiplusenums.h:222
const char * debugstr_pointf(const PointF *pt)
Definition: gdiplus.c:482
GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode)
Definition: brush.c:1043
GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect *rect, ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:593
GpStatus WINGDIPAPI GdipSetPathGradientTransform(GpPathGradient *grad, GpMatrix *matrix)
Definition: brush.c:1845
GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT *count)
Definition: brush.c:1244
GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count)
Definition: brush.c:1074
WrapMode
Definition: gdiplusenums.h:203
GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush, GDIPCONST GpMatrix *matrix)
Definition: brush.c:2116
GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors)
Definition: brush.c:1983
GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint *startpoint, GDIPCONST GpPoint *endpoint, ARGB startcolor, ARGB endcolor, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:415
GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
Definition: image.c:2342
GLsizei const GLchar ** path
Definition: glext.h:7234
GLuint GLenum matrix
Definition: glext.h:9407
GpStatus WINGDIPAPI GdipResetPathGradientTransform(GpPathGradient *grad)
Definition: brush.c:1882
GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath *path, GpRectF *bounds, GDIPCONST GpMatrix *matrix, GDIPCONST GpPen *pen)
static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradient **grad)
Definition: brush.c:604
GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad, REAL focus, REAL scale)
Definition: brush.c:1737
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint dy
Definition: linetemp.h:97
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
static const BYTE bitmap_bits[48 *48/8]
Definition: imagelist.c:135
GpStatus WINGDIPAPI GdipGetPathGradientTransform(GpPathGradient *grad, GpMatrix *matrix)
Definition: brush.c:1858
GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad, GpWrapMode wrap)
Definition: brush.c:1832
GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageattr, INT x, INT y, INT width, INT height, GpTexture **texture)
Definition: brush.c:919
GpPathData pathdata
GLdouble GLdouble t
Definition: gl.h:2047
GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode, GpTexture **texture)
Definition: brush.c:786
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GpStatus WINGDIPAPI GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode)
Definition: brush.c:1957
GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
Definition: brush.c:1925
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient *brush, REAL *factors, REAL *positions, INT count)
Definition: brush.c:1403
static const struct update_accum a4
Definition: msg.c:2285
GLuint GLuint end
Definition: gl.h:1545
GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient *brush, INT *count)
Definition: brush.c:1420
GLfloat angle
Definition: glext.h:10853
GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient *grad, GDIPCONST ARGB *argb, INT *count)
Definition: brush.c:1793
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
Definition: image.c:1308
GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF *points, INT count, GpWrapMode wrap, GpPathGradient **grad)
Definition: brush.c:658
GpStatus WINGDIPAPI GdipGetPathGradientPath(GpPathGradient *grad, GpPath *path)
Definition: brush.c:1161
static REAL deg2rad(REAL degrees)
#define GDIPCONST
Definition: gdiplusflat.h:24
GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush, INT *count)
Definition: brush.c:1643
GpBrushType bt
int32_t INT
Definition: typedefs.h:56
GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect *rect, ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:469
POINTL point
Definition: edittest.c:50
& rect
Definition: startmenu.cpp:1413
GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad, REAL sx, REAL sy, GpMatrixOrder order)
Definition: brush.c:1903
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1, ARGB color2)
Definition: brush.c:1969
#define PixelFormatDontCare
static GpStatus create_line_brush(const GpRectF *rect, ARGB startcolor, ARGB endcolor, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:297
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define cosf
Definition: cosf.c:6
GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint *points, INT count, GpWrapMode wrap, GpPathGradient **grad)
Definition: brush.c:691
GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF *startpoint, GDIPCONST GpPointF *endpoint, ARGB startcolor, ARGB endcolor, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:372
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
GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height)
Definition: image.c:2239
GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad, ARGB argb)
Definition: brush.c:1656
GpHatchStyle hatchstyle
GpImageAttributes * imageattributes
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint color
Definition: glext.h:6243
GpStatus WINGDIPAPI GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imageattr, GpImageAttributes **cloneImageattr)
static void linegradient_init_transform(const GpPointF *startpoint, const GpPointF *endpoint, GpLineGradient *line)
Definition: brush.c:334
GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush, INT *count)
Definition: brush.c:2095
#define FIXME(fmt,...)
Definition: debug.h:110
GLfloat rot
Definition: 3dtext.c:36
GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect)
Definition: brush.c:2191
#define WINGDIPAPI
Definition: gdiplusflat.h:22
GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, GDIPCONST REAL *factors, GDIPCONST REAL *positions, INT count)
Definition: brush.c:1369
GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
Definition: brush.c:70
smooth NULL
Definition: ftsmooth.c:416
GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count)
Definition: brush.c:1581
Definition: parser.c:48
GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad, BOOL gamma)
Definition: brush.c:1712
GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count)
Definition: graphicspath.c:623
REAL Height
Definition: gdiplustypes.h:264
static INT gdip_round(REAL x)
GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad, GpPointF *point)
Definition: brush.c:1086
GLenum GLint GLint * precision
Definition: glext.h:7539
GpStatus WINGDIPAPI GdipMultiplyLineTransform(GpLineGradient *brush, GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
Definition: brush.c:2152
GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
Definition: brush.c:1200
MatrixOrder
Definition: gdiplusenums.h:185
GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
Definition: brush.c:276
GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
Definition: brush.c:994
GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line, GpWrapMode wrap)
Definition: brush.c:1501
GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect)
Definition: brush.c:2203
GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus, REAL scale)
Definition: brush.c:1445
GpMatrix transform
GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height, PixelFormat format, GpBitmap *srcBitmap, GpBitmap **dstBitmap)
Definition: image.c:1237
GLfloat f
Definition: glext.h:7540
#define TRACE(s)
Definition: solgame.cpp:4
GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient *brush, REAL dx, REAL dy, GpMatrixOrder order)
Definition: brush.c:2166
GpStatus WINGDIPAPI GdipMultiplyPathGradientTransform(GpPathGradient *grad, GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
Definition: brush.c:1871
GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST REAL *blend, GDIPCONST REAL *pos, INT count)
Definition: brush.c:1514
GLenum GLuint texture
Definition: glext.h:6295
static const struct update_accum a2
Definition: msg.c:586
double __cdecl erf(double)
REAL X
Definition: gdiplustypes.h:261
GpStatus WINGDIPAPI GdipResetTextureTransform(GpTexture *brush)
Definition: brush.c:1345
GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
Definition: brush.c:950
REAL Y
Definition: gdiplustypes.h:249
GpStatus WINGDIPAPI GdipRotateMatrix(GpMatrix *matrix, REAL angle, GpMatrixOrder order)
Definition: matrix.c:258
GpBrush brush
GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF *rect, ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:436
_Check_return_ __CRT_INLINE float fmodf(_In_ float x, _In_ float y)
Definition: math.h:212
valarray< _Tp > atan(const valarray< _Tp > &__x)
Definition: _valarray.h:919
GpStatus WINGDIPAPI GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode, INT x, INT y, INT width, INT height, GpTexture **texture)
Definition: brush.c:928
GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad, REAL dx, REAL dy, GpMatrixOrder order)
Definition: brush.c:1914
GpStatus WINGDIPAPI GdipGetHatchBackgroundColor(GpHatch *brush, ARGB *backcol)
Definition: brush.c:961
GLsizei const GLfloat * points
Definition: glext.h:8112
GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, INT count)
Definition: graphicspath.c:654
int ret
GpStatus WINGDIPAPI GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmode)
Definition: brush.c:1316
GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, GpHatchStyle *hatchstyle)
Definition: brush.c:983
GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad, REAL *x, REAL *y)
Definition: brush.c:1134
GpStatus WINGDIPAPI GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix)
Definition: brush.c:1301
GpStatus WINGDIPAPI GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY, GpMatrixOrder order)
Definition: matrix.c:289
GpStatus WINGDIPAPI GdipScaleTextureTransform(GpTexture *brush, REAL sx, REAL sy, GpMatrixOrder order)
Definition: brush.c:1358
Definition: stat.h:55
REAL X
Definition: gdiplustypes.h:248
GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line, BOOL *usinggamma)
Definition: brush.c:1030
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath *path, GpPathGradient **grad)
Definition: brush.c:727
GpStatus WINGDIPAPI GdipTranslateTextureTransform(GpTexture *brush, REAL dx, REAL dy, GpMatrixOrder order)
Definition: brush.c:2180
GLenum src
Definition: glext.h:6340
GLenum mode
Definition: glext.h:6217
GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad, REAL x, REAL y)
Definition: brush.c:1698
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus)
GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
Definition: image.c:2107
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient *brush, REAL angle, GpMatrixOrder order)
Definition: brush.c:2225
Status
Definition: gdiplustypes.h:24
REAL Width
Definition: gdiplustypes.h:263
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
GpStatus WINGDIPAPI GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX, REAL offsetY, GpMatrixOrder order)
Definition: matrix.c:418
#define ERR(fmt,...)
Definition: debug.h:109
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
Definition: nis.h:10
GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush, ARGB *blend, REAL *positions, INT count)
Definition: brush.c:2077
GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient *grad, ARGB *argb, INT *count)
Definition: brush.c:1221
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
Definition: brush.c:262
GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol)
Definition: brush.c:972
GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad, REAL angle, GpMatrixOrder order)
Definition: brush.c:1892
GLuint start
Definition: gl.h:1545
#define ARRAY_SIZE(a)
Definition: main.h:24
GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush, ARGB *blend, REAL *pos, INT count)
Definition: brush.c:1616
GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus, REAL scale)
Definition: brush.c:2010
Definition: services.c:325
GpStatus WINGDIPAPI GdipGetLineTransform(GpLineGradient *brush, GpMatrix *matrix)
Definition: brush.c:2129
GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image, GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
Definition: brush.c:848
GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line, BOOL usegamma)
Definition: brush.c:1432
#define M_PI
Definition: macros.h:263
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode, REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
Definition: brush.c:821
DWORD exp
Definition: msg.c:15681
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad, GpPoint *point)
Definition: brush.c:1100
#define sqrtf(x)
Definition: mymath.h:59
GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad, BOOL *gamma)
Definition: brush.c:1148
GpStatus WINGDIPAPI GdipClonePath(GpPath *path, GpPath **clone)
GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
Definition: brush.c:1186
#define wrap(journal, var)
Definition: recovery.c:207
GpStatus WINGDIPAPI GdipMultiplyTextureTransform(GpTexture *brush, GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
Definition: brush.c:1331
static char * dest
Definition: rtl.c:135
#define sinf
Definition: sinf.c:6
static const struct update_accum a1
Definition: msg.c:578
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
BrushType
Definition: gdiplusenums.h:36
GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
Definition: brush.c:757
float REAL
Definition: types.h:41
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL *positions, INT count)
Definition: brush.c:2042
GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF *rect, ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap, GpLineGradient **line)
Definition: brush.c:489
REAL Y
Definition: gdiplustypes.h:262
GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend, REAL *positions, INT count)
Definition: brush.c:1055
_STLP_DECLSPEC complex< float > _STLP_CALL tan(const complex< float > &)
GLuint64EXT * result
Definition: glext.h:11304
GpStatus WINGDIPAPI GdipRotateTextureTransform(GpTexture *brush, REAL angle, GpMatrixOrder order)
Definition: brush.c:1999
static SERVICE_STATUS status
Definition: service.c:31
GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad, GpPointF *point)
Definition: brush.c:1668
GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush, REAL focus, REAL scale)
Definition: brush.c:1548
GpStatus WINGDIPAPI GdipSetPathGradientPath(GpPathGradient *grad, GDIPCONST GpPath *path)
Definition: brush.c:1725
GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush, GpWrapMode *wrapmode)
Definition: brush.c:1260
GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad, INT *count)
Definition: brush.c:1173
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
GpImage * image
Definition: ps.c:97
DWORD ARGB
GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, GpMatrixOrder order)
Definition: matrix.c:240
GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad, GpPoint *point)
Definition: brush.c:1682