2 * Copyright (C) 2007 Google (Evan Stade)
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.
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.
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
32 #include "gdiplus_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus
);
37 /******************************************************************************
38 * GdipCloneBrush [GDIPLUS.@]
40 GpStatus WINGDIPAPI
GdipCloneBrush(GpBrush
*brush
, GpBrush
**clone
)
42 TRACE("(%p, %p)\n", brush
, clone
);
45 return InvalidParameter
;
48 case BrushTypeSolidColor
:
50 *clone
= GdipAlloc(sizeof(GpSolidFill
));
51 if (!*clone
) return OutOfMemory
;
52 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
55 case BrushTypeHatchFill
:
57 GpHatch
*hatch
= (GpHatch
*)brush
;
59 return GdipCreateHatchBrush(hatch
->hatchstyle
, hatch
->forecol
, hatch
->backcol
, (GpHatch
**)clone
);
61 case BrushTypePathGradient
:{
62 GpPathGradient
*src
, *dest
;
66 *clone
= GdipAlloc(sizeof(GpPathGradient
));
67 if (!*clone
) return OutOfMemory
;
69 src
= (GpPathGradient
*) brush
,
70 dest
= (GpPathGradient
*) *clone
;
72 memcpy(dest
, src
, sizeof(GpPathGradient
));
74 stat
= GdipClonePath(src
->path
, &dest
->path
);
82 count
= src
->blendcount
;
83 dest
->blendcount
= count
;
84 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
85 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
86 dest
->surroundcolors
= GdipAlloc(dest
->surroundcolorcount
* sizeof(ARGB
));
88 if(!dest
->blendfac
|| !dest
->blendpos
|| !dest
->surroundcolors
){
89 GdipDeletePath(dest
->path
);
90 GdipFree(dest
->blendfac
);
91 GdipFree(dest
->blendpos
);
92 GdipFree(dest
->surroundcolors
);
97 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
98 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
99 memcpy(dest
->surroundcolors
, src
->surroundcolors
, dest
->surroundcolorcount
* sizeof(ARGB
));
103 case BrushTypeLinearGradient
:{
104 GpLineGradient
*dest
, *src
;
107 dest
= GdipAlloc(sizeof(GpLineGradient
));
108 if(!dest
) return OutOfMemory
;
110 src
= (GpLineGradient
*)brush
;
112 memcpy(dest
, src
, sizeof(GpLineGradient
));
114 count
= dest
->blendcount
;
115 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
116 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
117 pcount
= dest
->pblendcount
;
120 dest
->pblendcolor
= GdipAlloc(pcount
* sizeof(ARGB
));
121 dest
->pblendpos
= GdipAlloc(pcount
* sizeof(REAL
));
124 if (!dest
->blendfac
|| !dest
->blendpos
||
125 (pcount
&& (!dest
->pblendcolor
|| !dest
->pblendpos
)))
127 GdipFree(dest
->blendfac
);
128 GdipFree(dest
->blendpos
);
129 GdipFree(dest
->pblendcolor
);
130 GdipFree(dest
->pblendpos
);
135 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
136 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
140 memcpy(dest
->pblendcolor
, src
->pblendcolor
, pcount
* sizeof(ARGB
));
141 memcpy(dest
->pblendpos
, src
->pblendpos
, pcount
* sizeof(REAL
));
144 *clone
= &dest
->brush
;
147 case BrushTypeTextureFill
:
150 GpTexture
*texture
= (GpTexture
*)brush
;
151 GpTexture
*new_texture
;
154 stat
= GdipGetImageWidth(texture
->image
, &width
);
155 if (stat
!= Ok
) return stat
;
156 stat
= GdipGetImageHeight(texture
->image
, &height
);
157 if (stat
!= Ok
) return stat
;
159 stat
= GdipCreateTextureIA(texture
->image
, texture
->imageattributes
, 0, 0, width
, height
, &new_texture
);
163 memcpy(new_texture
->transform
, texture
->transform
, sizeof(GpMatrix
));
164 *clone
= (GpBrush
*)new_texture
;
172 ERR("not implemented for brush type %d\n", brush
->bt
);
173 return NotImplemented
;
176 TRACE("<-- %p\n", *clone
);
180 static const char HatchBrushes
[][8] = {
181 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
182 { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
183 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
184 { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
185 { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
186 { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
187 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
188 { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
189 { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
190 { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
191 { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
192 { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
193 { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
194 { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
195 { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
196 { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
197 { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
198 { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
199 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
200 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
201 { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
202 { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
203 { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
204 { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
205 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
206 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
207 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
208 { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
209 { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
210 { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
213 GpStatus
get_hatch_data(HatchStyle hatchstyle
, const char **result
)
215 if (hatchstyle
< sizeof(HatchBrushes
) / sizeof(HatchBrushes
[0]))
217 *result
= HatchBrushes
[hatchstyle
];
221 return NotImplemented
;
224 /******************************************************************************
225 * GdipCreateHatchBrush [GDIPLUS.@]
227 GpStatus WINGDIPAPI
GdipCreateHatchBrush(HatchStyle hatchstyle
, ARGB forecol
, ARGB backcol
, GpHatch
**brush
)
229 TRACE("(%d, %d, %d, %p)\n", hatchstyle
, forecol
, backcol
, brush
);
231 if(!brush
) return InvalidParameter
;
233 *brush
= GdipAlloc(sizeof(GpHatch
));
234 if (!*brush
) return OutOfMemory
;
236 (*brush
)->brush
.bt
= BrushTypeHatchFill
;
237 (*brush
)->forecol
= forecol
;
238 (*brush
)->backcol
= backcol
;
239 (*brush
)->hatchstyle
= hatchstyle
;
240 TRACE("<-- %p\n", *brush
);
245 /******************************************************************************
246 * GdipCreateLineBrush [GDIPLUS.@]
248 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
249 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
250 GpWrapMode wrap
, GpLineGradient
**line
)
252 TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint
),
253 debugstr_pointf(endpoint
), startcolor
, endcolor
, wrap
, line
);
255 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
256 return InvalidParameter
;
258 if (startpoint
->X
== endpoint
->X
&& startpoint
->Y
== endpoint
->Y
)
261 *line
= GdipAlloc(sizeof(GpLineGradient
));
262 if(!*line
) return OutOfMemory
;
264 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
266 (*line
)->startpoint
.X
= startpoint
->X
;
267 (*line
)->startpoint
.Y
= startpoint
->Y
;
268 (*line
)->endpoint
.X
= endpoint
->X
;
269 (*line
)->endpoint
.Y
= endpoint
->Y
;
270 (*line
)->startcolor
= startcolor
;
271 (*line
)->endcolor
= endcolor
;
272 (*line
)->wrap
= wrap
;
273 (*line
)->gamma
= FALSE
;
275 (*line
)->rect
.X
= (startpoint
->X
< endpoint
->X
? startpoint
->X
: endpoint
->X
);
276 (*line
)->rect
.Y
= (startpoint
->Y
< endpoint
->Y
? startpoint
->Y
: endpoint
->Y
);
277 (*line
)->rect
.Width
= fabs(startpoint
->X
- endpoint
->X
);
278 (*line
)->rect
.Height
= fabs(startpoint
->Y
- endpoint
->Y
);
280 if ((*line
)->rect
.Width
== 0)
282 (*line
)->rect
.X
-= (*line
)->rect
.Height
/ 2.0f
;
283 (*line
)->rect
.Width
= (*line
)->rect
.Height
;
285 else if ((*line
)->rect
.Height
== 0)
287 (*line
)->rect
.Y
-= (*line
)->rect
.Width
/ 2.0f
;
288 (*line
)->rect
.Height
= (*line
)->rect
.Width
;
291 (*line
)->blendcount
= 1;
292 (*line
)->blendfac
= GdipAlloc(sizeof(REAL
));
293 (*line
)->blendpos
= GdipAlloc(sizeof(REAL
));
295 if (!(*line
)->blendfac
|| !(*line
)->blendpos
)
297 GdipFree((*line
)->blendfac
);
298 GdipFree((*line
)->blendpos
);
304 (*line
)->blendfac
[0] = 1.0f
;
305 (*line
)->blendpos
[0] = 1.0f
;
307 (*line
)->pblendcolor
= NULL
;
308 (*line
)->pblendpos
= NULL
;
309 (*line
)->pblendcount
= 0;
311 TRACE("<-- %p\n", *line
);
316 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
317 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
318 GpWrapMode wrap
, GpLineGradient
**line
)
323 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
324 startcolor
, endcolor
, wrap
, line
);
326 if(!startpoint
|| !endpoint
)
327 return InvalidParameter
;
329 stF
.X
= (REAL
)startpoint
->X
;
330 stF
.Y
= (REAL
)startpoint
->Y
;
331 endF
.X
= (REAL
)endpoint
->X
;
332 endF
.Y
= (REAL
)endpoint
->Y
;
334 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
337 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
338 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
339 GpLineGradient
**line
)
344 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
348 return InvalidParameter
;
352 case LinearGradientModeHorizontal
:
355 end
.X
= rect
->X
+ rect
->Width
;
358 case LinearGradientModeVertical
:
362 end
.Y
= rect
->Y
+ rect
->Height
;
364 case LinearGradientModeForwardDiagonal
:
367 end
.X
= rect
->X
+ rect
->Width
;
368 end
.Y
= rect
->Y
+ rect
->Height
;
370 case LinearGradientModeBackwardDiagonal
:
371 start
.X
= rect
->X
+ rect
->Width
;
374 end
.Y
= rect
->Y
+ rect
->Height
;
377 return InvalidParameter
;
380 stat
= GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
383 (*line
)->rect
= *rect
;
388 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
389 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
390 GpLineGradient
**line
)
394 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
397 rectF
.X
= (REAL
) rect
->X
;
398 rectF
.Y
= (REAL
) rect
->Y
;
399 rectF
.Width
= (REAL
) rect
->Width
;
400 rectF
.Height
= (REAL
) rect
->Height
;
402 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
405 /******************************************************************************
406 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
408 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
409 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
410 GpLineGradient
**line
)
413 LinearGradientMode mode
;
414 REAL width
, height
, exofs
, eyofs
;
415 REAL sin_angle
, cos_angle
, sin_cos_angle
;
417 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
420 sin_angle
= sinf(deg2rad(angle
));
421 cos_angle
= cosf(deg2rad(angle
));
422 sin_cos_angle
= sin_angle
* cos_angle
;
426 width
= height
= 1.0;
431 height
= rect
->Height
;
434 if (sin_cos_angle
>= 0)
435 mode
= LinearGradientModeForwardDiagonal
;
437 mode
= LinearGradientModeBackwardDiagonal
;
439 stat
= GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, mode
, wrap
, line
);
443 if (sin_cos_angle
>= 0)
445 exofs
= width
* sin_cos_angle
+ height
* cos_angle
* cos_angle
;
446 eyofs
= width
* sin_angle
* sin_angle
+ height
* sin_cos_angle
;
450 exofs
= width
* sin_angle
* sin_angle
+ height
* sin_cos_angle
;
451 eyofs
= -width
* sin_cos_angle
+ height
* sin_angle
* sin_angle
;
456 exofs
= exofs
* rect
->Width
;
457 eyofs
= eyofs
* rect
->Height
;
462 (*line
)->endpoint
.X
= rect
->X
+ exofs
;
463 (*line
)->endpoint
.Y
= rect
->Y
+ eyofs
;
467 (*line
)->endpoint
.X
= (*line
)->startpoint
.X
;
468 (*line
)->endpoint
.Y
= (*line
)->startpoint
.Y
;
469 (*line
)->startpoint
.X
= rect
->X
+ exofs
;
470 (*line
)->startpoint
.Y
= rect
->Y
+ eyofs
;
477 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
478 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
479 GpLineGradient
**line
)
481 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
484 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
488 static GpStatus
create_path_gradient(GpPath
*path
, GpPathGradient
**grad
)
493 return InvalidParameter
;
495 GdipGetPathWorldBounds(path
, &bounds
, NULL
, NULL
);
497 *grad
= GdipAlloc(sizeof(GpPathGradient
));
503 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
504 (*grad
)->blendpos
= GdipAlloc(sizeof(REAL
));
505 (*grad
)->surroundcolors
= GdipAlloc(sizeof(ARGB
));
506 if(!(*grad
)->blendfac
|| !(*grad
)->blendpos
|| !(*grad
)->surroundcolors
){
507 GdipFree((*grad
)->blendfac
);
508 GdipFree((*grad
)->blendpos
);
509 GdipFree((*grad
)->surroundcolors
);
514 (*grad
)->blendfac
[0] = 1.0;
515 (*grad
)->blendpos
[0] = 1.0;
516 (*grad
)->blendcount
= 1;
518 (*grad
)->path
= path
;
520 (*grad
)->brush
.bt
= BrushTypePathGradient
;
521 (*grad
)->centercolor
= 0xffffffff;
522 (*grad
)->wrap
= WrapModeClamp
;
523 (*grad
)->gamma
= FALSE
;
524 /* FIXME: this should be set to the "centroid" of the path by default */
525 (*grad
)->center
.X
= bounds
.X
+ bounds
.Width
/ 2;
526 (*grad
)->center
.Y
= bounds
.Y
+ bounds
.Height
/ 2;
527 (*grad
)->focus
.X
= 0.0;
528 (*grad
)->focus
.Y
= 0.0;
529 (*grad
)->surroundcolors
[0] = 0xffffffff;
530 (*grad
)->surroundcolorcount
= 1;
532 TRACE("<-- %p\n", *grad
);
537 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
538 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
543 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
546 return InvalidParameter
;
551 stat
= GdipCreatePath(FillModeAlternate
, &path
);
555 stat
= GdipAddPathLine2(path
, points
, count
);
558 stat
= create_path_gradient(path
, grad
);
561 GdipDeletePath(path
);
567 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
568 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
573 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
576 return InvalidParameter
;
581 stat
= GdipCreatePath(FillModeAlternate
, &path
);
585 stat
= GdipAddPathLine2I(path
, points
, count
);
588 stat
= create_path_gradient(path
, grad
);
591 GdipDeletePath(path
);
597 /******************************************************************************
598 * GdipCreatePathGradientFromPath [GDIPLUS.@]
600 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
601 GpPathGradient
**grad
)
606 TRACE("(%p, %p)\n", path
, grad
);
609 return InvalidParameter
;
611 stat
= GdipClonePath((GpPath
*)path
, &new_path
);
615 stat
= create_path_gradient(new_path
, grad
);
618 GdipDeletePath(new_path
);
624 /******************************************************************************
625 * GdipCreateSolidFill [GDIPLUS.@]
627 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
629 TRACE("(%x, %p)\n", color
, sf
);
631 if(!sf
) return InvalidParameter
;
633 *sf
= GdipAlloc(sizeof(GpSolidFill
));
634 if (!*sf
) return OutOfMemory
;
636 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
637 (*sf
)->color
= color
;
639 TRACE("<-- %p\n", *sf
);
644 /******************************************************************************
645 * GdipCreateTexture [GDIPLUS.@]
648 * image [I] image to use
649 * wrapmode [I] optional
650 * texture [O] pointer to the resulting texturebrush
654 * FAILURE: element of GpStatus
656 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
660 GpImageAttributes
*attributes
;
663 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
665 if (!(image
&& texture
))
666 return InvalidParameter
;
668 stat
= GdipGetImageWidth(image
, &width
);
669 if (stat
!= Ok
) return stat
;
670 stat
= GdipGetImageHeight(image
, &height
);
671 if (stat
!= Ok
) return stat
;
673 stat
= GdipCreateImageAttributes(&attributes
);
677 attributes
->wrap
= wrapmode
;
679 stat
= GdipCreateTextureIA(image
, attributes
, 0, 0, width
, height
,
682 GdipDisposeImageAttributes(attributes
);
688 /******************************************************************************
689 * GdipCreateTexture2 [GDIPLUS.@]
691 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
692 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
694 GpImageAttributes
*attributes
;
697 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
698 x
, y
, width
, height
, texture
);
700 stat
= GdipCreateImageAttributes(&attributes
);
704 attributes
->wrap
= wrapmode
;
706 stat
= GdipCreateTextureIA(image
, attributes
, x
, y
, width
, height
,
709 GdipDisposeImageAttributes(attributes
);
715 /******************************************************************************
716 * GdipCreateTextureIA [GDIPLUS.@]
718 * FIXME: imageattr ignored
720 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
721 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
722 REAL height
, GpTexture
**texture
)
725 GpImage
*new_image
=NULL
;
727 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
730 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
731 return InvalidParameter
;
735 if(image
->type
!= ImageTypeBitmap
){
736 FIXME("not implemented for image type %d\n", image
->type
);
737 return NotImplemented
;
740 status
= GdipCloneBitmapArea(x
, y
, width
, height
, PixelFormatDontCare
, (GpBitmap
*)image
, (GpBitmap
**)&new_image
);
744 *texture
= GdipAlloc(sizeof(GpTexture
));
746 status
= OutOfMemory
;
750 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
756 status
= GdipCloneImageAttributes(imageattr
, &(*texture
)->imageattributes
);
760 status
= GdipCreateImageAttributes(&(*texture
)->imageattributes
);
762 (*texture
)->imageattributes
->wrap
= WrapModeTile
;
766 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
767 (*texture
)->image
= new_image
;
773 TRACE("<-- %p\n", *texture
);
779 GdipDeleteMatrix((*texture
)->transform
);
780 GdipDisposeImageAttributes((*texture
)->imageattributes
);
784 GdipDisposeImage(new_image
);
785 TRACE("<-- error %u\n", status
);
791 /******************************************************************************
792 * GdipCreateTextureIAI [GDIPLUS.@]
794 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
795 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
797 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
800 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
803 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
804 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
806 GpImageAttributes
*imageattr
;
809 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
812 stat
= GdipCreateImageAttributes(&imageattr
);
816 imageattr
->wrap
= wrapmode
;
818 stat
= GdipCreateTextureIA(image
, imageattr
, x
, y
, width
, height
, texture
);
824 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
826 TRACE("(%p, %p)\n", brush
, type
);
828 if(!brush
|| !type
) return InvalidParameter
;
835 GpStatus WINGDIPAPI
GdipGetHatchBackgroundColor(GpHatch
*brush
, ARGB
*backcol
)
837 TRACE("(%p, %p)\n", brush
, backcol
);
839 if(!brush
|| !backcol
) return InvalidParameter
;
841 *backcol
= brush
->backcol
;
846 GpStatus WINGDIPAPI
GdipGetHatchForegroundColor(GpHatch
*brush
, ARGB
*forecol
)
848 TRACE("(%p, %p)\n", brush
, forecol
);
850 if(!brush
|| !forecol
) return InvalidParameter
;
852 *forecol
= brush
->forecol
;
857 GpStatus WINGDIPAPI
GdipGetHatchStyle(GpHatch
*brush
, HatchStyle
*hatchstyle
)
859 TRACE("(%p, %p)\n", brush
, hatchstyle
);
861 if(!brush
|| !hatchstyle
) return InvalidParameter
;
863 *hatchstyle
= brush
->hatchstyle
;
868 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
870 TRACE("(%p)\n", brush
);
872 if(!brush
) return InvalidParameter
;
876 case BrushTypePathGradient
:
877 GdipDeletePath(((GpPathGradient
*) brush
)->path
);
878 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
879 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
880 GdipFree(((GpPathGradient
*) brush
)->surroundcolors
);
882 case BrushTypeLinearGradient
:
883 GdipFree(((GpLineGradient
*)brush
)->blendfac
);
884 GdipFree(((GpLineGradient
*)brush
)->blendpos
);
885 GdipFree(((GpLineGradient
*)brush
)->pblendcolor
);
886 GdipFree(((GpLineGradient
*)brush
)->pblendpos
);
888 case BrushTypeTextureFill
:
889 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
890 GdipDisposeImage(((GpTexture
*)brush
)->image
);
891 GdipDisposeImageAttributes(((GpTexture
*)brush
)->imageattributes
);
892 GdipFree(((GpTexture
*)brush
)->bitmap_bits
);
903 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
906 TRACE("(%p, %p)\n", line
, usinggamma
);
908 if(!line
|| !usinggamma
)
909 return InvalidParameter
;
911 *usinggamma
= line
->gamma
;
916 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
918 TRACE("(%p, %p)\n", brush
, wrapmode
);
920 if(!brush
|| !wrapmode
)
921 return InvalidParameter
;
923 *wrapmode
= brush
->wrap
;
928 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
929 REAL
*positions
, INT count
)
931 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
933 if(!brush
|| !blend
|| !positions
|| count
<= 0)
934 return InvalidParameter
;
936 if(count
< brush
->blendcount
)
937 return InsufficientBuffer
;
939 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
940 if(brush
->blendcount
> 1){
941 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
947 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
949 TRACE("(%p, %p)\n", brush
, count
);
952 return InvalidParameter
;
954 *count
= brush
->blendcount
;
959 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
962 TRACE("(%p, %p)\n", grad
, point
);
965 return InvalidParameter
;
967 point
->X
= grad
->center
.X
;
968 point
->Y
= grad
->center
.Y
;
973 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
979 TRACE("(%p, %p)\n", grad
, point
);
982 return InvalidParameter
;
984 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
987 point
->X
= roundr(ptf
.X
);
988 point
->Y
= roundr(ptf
.Y
);
994 GpStatus WINGDIPAPI
GdipGetPathGradientCenterColor(GpPathGradient
*grad
,
999 TRACE("(%p,%p)\n", grad
, colors
);
1002 FIXME("not implemented\n");
1004 return NotImplemented
;
1007 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
1010 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
1012 if(!grad
|| !x
|| !y
)
1013 return InvalidParameter
;
1021 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
1024 TRACE("(%p, %p)\n", grad
, gamma
);
1027 return InvalidParameter
;
1029 *gamma
= grad
->gamma
;
1034 GpStatus WINGDIPAPI
GdipGetPathGradientPath(GpPathGradient
*grad
, GpPath
*path
)
1038 TRACE("(%p, %p)\n", grad
, path
);
1041 FIXME("not implemented\n");
1043 return NotImplemented
;
1046 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
1049 TRACE("(%p, %p)\n", grad
, count
);
1052 return InvalidParameter
;
1054 *count
= grad
->path
->pathdata
.Count
;
1059 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
1063 TRACE("(%p, %p)\n", brush
, rect
);
1066 return InvalidParameter
;
1068 stat
= GdipGetPathWorldBounds(brush
->path
, rect
, NULL
, NULL
);
1073 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
1078 TRACE("(%p, %p)\n", brush
, rect
);
1081 return InvalidParameter
;
1083 stat
= GdipGetPathGradientRect(brush
, &rectf
);
1084 if(stat
!= Ok
) return stat
;
1086 rect
->X
= roundr(rectf
.X
);
1087 rect
->Y
= roundr(rectf
.Y
);
1088 rect
->Width
= roundr(rectf
.Width
);
1089 rect
->Height
= roundr(rectf
.Height
);
1094 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
1095 *grad
, ARGB
*argb
, INT
*count
)
1099 TRACE("(%p,%p,%p)\n", grad
, argb
, count
);
1101 if(!grad
|| !argb
|| !count
|| (*count
< grad
->path
->pathdata
.Count
))
1102 return InvalidParameter
;
1104 for (i
=0; i
<grad
->path
->pathdata
.Count
; i
++)
1106 if (i
< grad
->surroundcolorcount
)
1107 argb
[i
] = grad
->surroundcolors
[i
];
1109 argb
[i
] = grad
->surroundcolors
[grad
->surroundcolorcount
-1];
1112 *count
= grad
->surroundcolorcount
;
1117 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorCount(GpPathGradient
*brush
, INT
*count
)
1119 TRACE("(%p, %p)\n", brush
, count
);
1121 if (!brush
|| !count
)
1122 return InvalidParameter
;
1124 /* Yes, this actually returns the number of points in the path (which is the
1125 * required size of a buffer to get the surround colors), rather than the
1126 * number of surround colors. The real count is returned when getting the
1128 *count
= brush
->path
->pathdata
.Count
;
1133 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
1134 GpWrapMode
*wrapmode
)
1136 TRACE("(%p, %p)\n", brush
, wrapmode
);
1138 if(!brush
|| !wrapmode
)
1139 return InvalidParameter
;
1141 *wrapmode
= brush
->wrap
;
1146 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
1148 TRACE("(%p, %p)\n", sf
, argb
);
1151 return InvalidParameter
;
1158 /******************************************************************************
1159 * GdipGetTextureImage [GDIPLUS.@]
1161 GpStatus WINGDIPAPI
GdipGetTextureImage(GpTexture
*brush
, GpImage
**image
)
1163 TRACE("(%p, %p)\n", brush
, image
);
1165 if(!brush
|| !image
)
1166 return InvalidParameter
;
1168 return GdipCloneImage(brush
->image
, image
);
1171 /******************************************************************************
1172 * GdipGetTextureTransform [GDIPLUS.@]
1174 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
1176 TRACE("(%p, %p)\n", brush
, matrix
);
1178 if(!brush
|| !matrix
)
1179 return InvalidParameter
;
1181 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
1186 /******************************************************************************
1187 * GdipGetTextureWrapMode [GDIPLUS.@]
1189 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
1191 TRACE("(%p, %p)\n", brush
, wrapmode
);
1193 if(!brush
|| !wrapmode
)
1194 return InvalidParameter
;
1196 *wrapmode
= brush
->imageattributes
->wrap
;
1201 /******************************************************************************
1202 * GdipMultiplyTextureTransform [GDIPLUS.@]
1204 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
1205 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1207 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
1209 if(!brush
|| !matrix
)
1210 return InvalidParameter
;
1212 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
1215 /******************************************************************************
1216 * GdipResetTextureTransform [GDIPLUS.@]
1218 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
1220 TRACE("(%p)\n", brush
);
1223 return InvalidParameter
;
1225 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1228 /******************************************************************************
1229 * GdipScaleTextureTransform [GDIPLUS.@]
1231 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
1232 REAL sx
, REAL sy
, GpMatrixOrder order
)
1234 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
1237 return InvalidParameter
;
1239 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
1242 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
1243 GDIPCONST REAL
*factors
, GDIPCONST REAL
* positions
, INT count
)
1245 REAL
*new_blendfac
, *new_blendpos
;
1247 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1249 if(!brush
|| !factors
|| !positions
|| count
<= 0 ||
1250 (count
>= 2 && (positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)))
1251 return InvalidParameter
;
1253 new_blendfac
= GdipAlloc(count
* sizeof(REAL
));
1254 new_blendpos
= GdipAlloc(count
* sizeof(REAL
));
1256 if (!new_blendfac
|| !new_blendpos
)
1258 GdipFree(new_blendfac
);
1259 GdipFree(new_blendpos
);
1263 memcpy(new_blendfac
, factors
, count
* sizeof(REAL
));
1264 memcpy(new_blendpos
, positions
, count
* sizeof(REAL
));
1266 GdipFree(brush
->blendfac
);
1267 GdipFree(brush
->blendpos
);
1269 brush
->blendcount
= count
;
1270 brush
->blendfac
= new_blendfac
;
1271 brush
->blendpos
= new_blendpos
;
1276 GpStatus WINGDIPAPI
GdipGetLineBlend(GpLineGradient
*brush
, REAL
*factors
,
1277 REAL
*positions
, INT count
)
1279 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1281 if (!brush
|| !factors
|| !positions
|| count
<= 0)
1282 return InvalidParameter
;
1284 if (count
< brush
->blendcount
)
1285 return InsufficientBuffer
;
1287 memcpy(factors
, brush
->blendfac
, brush
->blendcount
* sizeof(REAL
));
1288 memcpy(positions
, brush
->blendpos
, brush
->blendcount
* sizeof(REAL
));
1293 GpStatus WINGDIPAPI
GdipGetLineBlendCount(GpLineGradient
*brush
, INT
*count
)
1295 TRACE("(%p, %p)\n", brush
, count
);
1297 if (!brush
|| !count
)
1298 return InvalidParameter
;
1300 *count
= brush
->blendcount
;
1305 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
1308 TRACE("(%p, %d)\n", line
, usegamma
);
1311 return InvalidParameter
;
1313 line
->gamma
= usegamma
;
1318 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1325 const int precision
= 16;
1326 REAL erf_range
; /* we use values erf(-erf_range) through erf(+erf_range) */
1330 TRACE("(%p, %0.2f, %0.2f)\n", line
, focus
, scale
);
1332 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1333 return InvalidParameter
;
1335 /* we want 2 standard deviations */
1336 erf_range
= 2.0 / sqrt(2);
1338 /* calculate the constants we need to normalize the error function to be
1339 between 0.0 and scale over the range we need */
1340 min_erf
= erf(-erf_range
);
1341 scale_erf
= scale
/ (-2.0 * min_erf
);
1347 for (i
=1; i
<precision
; i
++)
1349 positions
[i
] = focus
* i
/ precision
;
1350 factors
[i
] = scale_erf
* (erf(2 * erf_range
* i
/ precision
- erf_range
) - min_erf
);
1352 num_points
+= precision
;
1355 positions
[num_points
] = focus
;
1356 factors
[num_points
] = scale
;
1361 for (i
=1; i
<precision
; i
++)
1363 positions
[i
+num_points
-1] = (focus
+ ((1.0-focus
) * i
/ precision
));
1364 factors
[i
+num_points
-1] = scale_erf
* (erf(erf_range
- 2 * erf_range
* i
/ precision
) - min_erf
);
1366 num_points
+= precision
;
1367 positions
[num_points
-1] = 1.0;
1368 factors
[num_points
-1] = 0.0;
1371 return GdipSetLineBlend(line
, factors
, positions
, num_points
);
1374 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1377 TRACE("(%p, %d)\n", line
, wrap
);
1379 if(!line
|| wrap
== WrapModeClamp
)
1380 return InvalidParameter
;
1387 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1388 GDIPCONST REAL
*pos
, INT count
)
1392 TRACE("(%p,%p,%p,%i)\n", brush
, blend
, pos
, count
);
1395 FIXME("not implemented\n");
1397 return NotImplemented
;
1400 GpStatus WINGDIPAPI
GdipSetPathGradientLinearBlend(GpPathGradient
*brush
,
1401 REAL focus
, REAL scale
)
1405 TRACE("(%p,%0.2f,%0.2f)\n", brush
, focus
, scale
);
1408 FIXME("not implemented\n");
1410 return NotImplemented
;
1413 GpStatus WINGDIPAPI
GdipSetPathGradientPresetBlend(GpPathGradient
*brush
,
1414 GDIPCONST ARGB
*blend
, GDIPCONST REAL
*pos
, INT count
)
1416 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1417 return NotImplemented
;
1420 GpStatus WINGDIPAPI
GdipGetPathGradientPresetBlend(GpPathGradient
*brush
,
1421 ARGB
*blend
, REAL
*pos
, INT count
)
1423 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1424 return NotImplemented
;
1427 GpStatus WINGDIPAPI
GdipGetPathGradientPresetBlendCount(GpPathGradient
*brush
,
1430 FIXME("(%p,%p): stub\n", brush
, count
);
1431 return NotImplemented
;
1434 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1437 TRACE("(%p, %x)\n", grad
, argb
);
1440 return InvalidParameter
;
1442 grad
->centercolor
= argb
;
1446 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1449 TRACE("(%p, %s)\n", grad
, debugstr_pointf(point
));
1452 return InvalidParameter
;
1454 grad
->center
.X
= point
->X
;
1455 grad
->center
.Y
= point
->Y
;
1460 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1465 TRACE("(%p, %p)\n", grad
, point
);
1468 return InvalidParameter
;
1470 ptf
.X
= (REAL
)point
->X
;
1471 ptf
.Y
= (REAL
)point
->Y
;
1473 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1476 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1479 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1482 return InvalidParameter
;
1490 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1493 TRACE("(%p, %d)\n", grad
, gamma
);
1496 return InvalidParameter
;
1498 grad
->gamma
= gamma
;
1503 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1504 REAL focus
, REAL scale
)
1508 TRACE("(%p,%0.2f,%0.2f)\n", grad
, focus
, scale
);
1510 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1511 return InvalidParameter
;
1514 FIXME("not implemented\n");
1516 return NotImplemented
;
1519 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1520 *grad
, GDIPCONST ARGB
*argb
, INT
*count
)
1522 ARGB
*new_surroundcolors
;
1524 TRACE("(%p,%p,%p)\n", grad
, argb
, count
);
1526 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1527 (*count
> grad
->path
->pathdata
.Count
))
1528 return InvalidParameter
;
1530 new_surroundcolors
= GdipAlloc(*count
* sizeof(ARGB
));
1531 if (!new_surroundcolors
)
1534 memcpy(new_surroundcolors
, argb
, *count
* sizeof(ARGB
));
1536 GdipFree(grad
->surroundcolors
);
1538 grad
->surroundcolors
= new_surroundcolors
;
1539 grad
->surroundcolorcount
= *count
;
1544 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1547 TRACE("(%p, %d)\n", grad
, wrap
);
1550 return InvalidParameter
;
1557 GpStatus WINGDIPAPI
GdipSetPathGradientTransform(GpPathGradient
*grad
,
1562 TRACE("(%p,%p)\n", grad
, matrix
);
1565 FIXME("not implemented\n");
1567 return NotImplemented
;
1570 GpStatus WINGDIPAPI
GdipGetPathGradientTransform(GpPathGradient
*grad
,
1575 TRACE("(%p,%p)\n", grad
, matrix
);
1578 FIXME("not implemented\n");
1580 return NotImplemented
;
1583 GpStatus WINGDIPAPI
GdipMultiplyPathGradientTransform(GpPathGradient
*grad
,
1584 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1588 TRACE("(%p,%p,%i)\n", grad
, matrix
, order
);
1591 FIXME("not implemented\n");
1593 return NotImplemented
;
1596 GpStatus WINGDIPAPI
GdipRotatePathGradientTransform(GpPathGradient
*grad
,
1597 REAL angle
, GpMatrixOrder order
)
1601 TRACE("(%p,%0.2f,%i)\n", grad
, angle
, order
);
1604 FIXME("not implemented\n");
1606 return NotImplemented
;
1609 GpStatus WINGDIPAPI
GdipScalePathGradientTransform(GpPathGradient
*grad
,
1610 REAL sx
, REAL sy
, GpMatrixOrder order
)
1614 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad
, sx
, sy
, order
);
1617 FIXME("not implemented\n");
1619 return NotImplemented
;
1622 GpStatus WINGDIPAPI
GdipTranslatePathGradientTransform(GpPathGradient
*grad
,
1623 REAL dx
, REAL dy
, GpMatrixOrder order
)
1627 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad
, dx
, dy
, order
);
1630 FIXME("not implemented\n");
1632 return NotImplemented
;
1635 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1637 TRACE("(%p, %x)\n", sf
, argb
);
1640 return InvalidParameter
;
1646 /******************************************************************************
1647 * GdipSetTextureTransform [GDIPLUS.@]
1649 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1650 GDIPCONST GpMatrix
*matrix
)
1652 TRACE("(%p, %p)\n", texture
, matrix
);
1654 if(!texture
|| !matrix
)
1655 return InvalidParameter
;
1657 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1662 /******************************************************************************
1663 * GdipSetTextureWrapMode [GDIPLUS.@]
1665 * WrapMode not used, only stored
1667 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1669 TRACE("(%p, %d)\n", brush
, wrapmode
);
1672 return InvalidParameter
;
1674 brush
->imageattributes
->wrap
= wrapmode
;
1679 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1682 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1685 return InvalidParameter
;
1687 brush
->startcolor
= color1
;
1688 brush
->endcolor
= color2
;
1693 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1695 TRACE("(%p, %p)\n", brush
, colors
);
1697 if(!brush
|| !colors
)
1698 return InvalidParameter
;
1700 colors
[0] = brush
->startcolor
;
1701 colors
[1] = brush
->endcolor
;
1706 /******************************************************************************
1707 * GdipRotateTextureTransform [GDIPLUS.@]
1709 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1710 GpMatrixOrder order
)
1712 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1715 return InvalidParameter
;
1717 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1720 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1727 TRACE("(%p,%.2f,%.2f)\n", brush
, focus
, scale
);
1729 if (!brush
) return InvalidParameter
;
1733 factors
[num_points
] = 0.0;
1734 positions
[num_points
] = 0.0;
1738 factors
[num_points
] = scale
;
1739 positions
[num_points
] = focus
;
1744 factors
[num_points
] = 0.0;
1745 positions
[num_points
] = 1.0;
1749 return GdipSetLineBlend(brush
, factors
, positions
, num_points
);
1752 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1753 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1757 TRACE("(%p,%p,%p,%i)\n", brush
, blend
, positions
, count
);
1759 if (!brush
|| !blend
|| !positions
|| count
< 2 ||
1760 positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)
1762 return InvalidParameter
;
1765 new_color
= GdipAlloc(count
* sizeof(ARGB
));
1766 new_pos
= GdipAlloc(count
* sizeof(REAL
));
1767 if (!new_color
|| !new_pos
)
1769 GdipFree(new_color
);
1774 memcpy(new_color
, blend
, sizeof(ARGB
) * count
);
1775 memcpy(new_pos
, positions
, sizeof(REAL
) * count
);
1777 GdipFree(brush
->pblendcolor
);
1778 GdipFree(brush
->pblendpos
);
1780 brush
->pblendcolor
= new_color
;
1781 brush
->pblendpos
= new_pos
;
1782 brush
->pblendcount
= count
;
1787 GpStatus WINGDIPAPI
GdipGetLinePresetBlend(GpLineGradient
*brush
,
1788 ARGB
*blend
, REAL
* positions
, INT count
)
1790 if (!brush
|| !blend
|| !positions
|| count
< 2)
1791 return InvalidParameter
;
1793 if (brush
->pblendcount
== 0)
1794 return GenericError
;
1796 if (count
< brush
->pblendcount
)
1797 return InsufficientBuffer
;
1799 memcpy(blend
, brush
->pblendcolor
, sizeof(ARGB
) * brush
->pblendcount
);
1800 memcpy(positions
, brush
->pblendpos
, sizeof(REAL
) * brush
->pblendcount
);
1805 GpStatus WINGDIPAPI
GdipGetLinePresetBlendCount(GpLineGradient
*brush
,
1808 if (!brush
|| !count
)
1809 return InvalidParameter
;
1811 *count
= brush
->pblendcount
;
1816 GpStatus WINGDIPAPI
GdipResetLineTransform(GpLineGradient
*brush
)
1820 TRACE("(%p)\n", brush
);
1823 FIXME("not implemented\n");
1825 return NotImplemented
;
1828 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1829 GDIPCONST GpMatrix
*matrix
)
1833 TRACE("(%p,%p)\n", brush
, matrix
);
1836 FIXME("not implemented\n");
1838 return NotImplemented
;
1841 GpStatus WINGDIPAPI
GdipGetLineTransform(GpLineGradient
*brush
, GpMatrix
*matrix
)
1845 TRACE("(%p,%p)\n", brush
, matrix
);
1848 FIXME("not implemented\n");
1850 return NotImplemented
;
1853 GpStatus WINGDIPAPI
GdipScaleLineTransform(GpLineGradient
*brush
, REAL sx
, REAL sy
,
1854 GpMatrixOrder order
)
1858 TRACE("(%p,%0.2f,%0.2f,%u)\n", brush
, sx
, sy
, order
);
1861 FIXME("not implemented\n");
1863 return NotImplemented
;
1866 GpStatus WINGDIPAPI
GdipMultiplyLineTransform(GpLineGradient
*brush
,
1867 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1871 TRACE("(%p,%p,%u)\n", brush
, matrix
, order
);
1874 FIXME("not implemented\n");
1876 return NotImplemented
;
1879 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1880 REAL dx
, REAL dy
, GpMatrixOrder order
)
1884 TRACE("(%p,%f,%f,%d)\n", brush
, dx
, dy
, order
);
1887 FIXME("not implemented\n");
1892 /******************************************************************************
1893 * GdipTranslateTextureTransform [GDIPLUS.@]
1895 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1896 GpMatrixOrder order
)
1898 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1901 return InvalidParameter
;
1903 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1906 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1908 TRACE("(%p, %p)\n", brush
, rect
);
1911 return InvalidParameter
;
1913 *rect
= brush
->rect
;
1918 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1923 TRACE("(%p, %p)\n", brush
, rect
);
1926 return InvalidParameter
;
1928 ret
= GdipGetLineRect(brush
, &rectF
);
1931 rect
->X
= roundr(rectF
.X
);
1932 rect
->Y
= roundr(rectF
.Y
);
1933 rect
->Width
= roundr(rectF
.Width
);
1934 rect
->Height
= roundr(rectF
.Height
);
1940 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1941 REAL angle
, GpMatrixOrder order
)
1945 TRACE("(%p,%0.2f,%u)\n", brush
, angle
, order
);
1948 return InvalidParameter
;
1951 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1953 return NotImplemented
;