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
;
65 *clone
= GdipAlloc(sizeof(GpPathGradient
));
66 if (!*clone
) return OutOfMemory
;
68 src
= (GpPathGradient
*) brush
,
69 dest
= (GpPathGradient
*) *clone
;
70 count
= src
->pathdata
.Count
;
72 memcpy(dest
, src
, sizeof(GpPathGradient
));
74 dest
->pathdata
.Count
= count
;
75 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
76 dest
->pathdata
.Types
= GdipAlloc(count
);
78 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
79 GdipFree(dest
->pathdata
.Points
);
80 GdipFree(dest
->pathdata
.Types
);
85 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
86 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
89 count
= src
->blendcount
;
90 dest
->blendcount
= count
;
91 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
92 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
94 if(!dest
->blendfac
|| !dest
->blendpos
){
95 GdipFree(dest
->pathdata
.Points
);
96 GdipFree(dest
->pathdata
.Types
);
97 GdipFree(dest
->blendfac
);
98 GdipFree(dest
->blendpos
);
103 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
104 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
108 case BrushTypeLinearGradient
:{
109 GpLineGradient
*dest
, *src
;
112 dest
= GdipAlloc(sizeof(GpLineGradient
));
113 if(!dest
) return OutOfMemory
;
115 src
= (GpLineGradient
*)brush
;
117 memcpy(dest
, src
, sizeof(GpLineGradient
));
119 count
= dest
->blendcount
;
120 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
121 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
122 pcount
= dest
->pblendcount
;
125 dest
->pblendcolor
= GdipAlloc(pcount
* sizeof(ARGB
));
126 dest
->pblendpos
= GdipAlloc(pcount
* sizeof(REAL
));
129 if (!dest
->blendfac
|| !dest
->blendpos
||
130 (pcount
&& (!dest
->pblendcolor
|| !dest
->pblendpos
)))
132 GdipFree(dest
->blendfac
);
133 GdipFree(dest
->blendpos
);
134 GdipFree(dest
->pblendcolor
);
135 GdipFree(dest
->pblendpos
);
140 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
141 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
145 memcpy(dest
->pblendcolor
, src
->pblendcolor
, pcount
* sizeof(ARGB
));
146 memcpy(dest
->pblendpos
, src
->pblendpos
, pcount
* sizeof(REAL
));
149 *clone
= &dest
->brush
;
152 case BrushTypeTextureFill
:
155 GpTexture
*texture
= (GpTexture
*)brush
;
156 GpTexture
*new_texture
;
159 stat
= GdipGetImageWidth(texture
->image
, &width
);
160 if (stat
!= Ok
) return stat
;
161 stat
= GdipGetImageHeight(texture
->image
, &height
);
162 if (stat
!= Ok
) return stat
;
164 stat
= GdipCreateTextureIA(texture
->image
, texture
->imageattributes
, 0, 0, width
, height
, &new_texture
);
168 memcpy(new_texture
->transform
, texture
->transform
, sizeof(GpMatrix
));
169 *clone
= (GpBrush
*)new_texture
;
177 ERR("not implemented for brush type %d\n", brush
->bt
);
178 return NotImplemented
;
181 TRACE("<-- %p\n", *clone
);
185 static const char HatchBrushes
[][8] = {
186 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
187 { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
188 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
189 { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
190 { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
191 { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
192 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
193 { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
194 { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
195 { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
196 { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
197 { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
198 { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
199 { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
200 { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
201 { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
202 { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
203 { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
204 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
205 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
206 { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
207 { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
208 { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
209 { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
210 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
211 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
212 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
213 { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
214 { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
215 { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
218 GpStatus
get_hatch_data(HatchStyle hatchstyle
, const char **result
)
220 if (hatchstyle
< sizeof(HatchBrushes
) / sizeof(HatchBrushes
[0]))
222 *result
= HatchBrushes
[hatchstyle
];
226 return NotImplemented
;
229 /******************************************************************************
230 * GdipCreateHatchBrush [GDIPLUS.@]
232 GpStatus WINGDIPAPI
GdipCreateHatchBrush(HatchStyle hatchstyle
, ARGB forecol
, ARGB backcol
, GpHatch
**brush
)
234 TRACE("(%d, %d, %d, %p)\n", hatchstyle
, forecol
, backcol
, brush
);
236 if(!brush
) return InvalidParameter
;
238 *brush
= GdipAlloc(sizeof(GpHatch
));
239 if (!*brush
) return OutOfMemory
;
241 (*brush
)->brush
.bt
= BrushTypeHatchFill
;
242 (*brush
)->forecol
= forecol
;
243 (*brush
)->backcol
= backcol
;
244 (*brush
)->hatchstyle
= hatchstyle
;
245 TRACE("<-- %p\n", *brush
);
250 /******************************************************************************
251 * GdipCreateLineBrush [GDIPLUS.@]
253 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
254 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
255 GpWrapMode wrap
, GpLineGradient
**line
)
257 TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint
),
258 debugstr_pointf(endpoint
), startcolor
, endcolor
, wrap
, line
);
260 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
261 return InvalidParameter
;
263 if (startpoint
->X
== endpoint
->X
&& startpoint
->Y
== endpoint
->Y
)
266 *line
= GdipAlloc(sizeof(GpLineGradient
));
267 if(!*line
) return OutOfMemory
;
269 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
271 (*line
)->startpoint
.X
= startpoint
->X
;
272 (*line
)->startpoint
.Y
= startpoint
->Y
;
273 (*line
)->endpoint
.X
= endpoint
->X
;
274 (*line
)->endpoint
.Y
= endpoint
->Y
;
275 (*line
)->startcolor
= startcolor
;
276 (*line
)->endcolor
= endcolor
;
277 (*line
)->wrap
= wrap
;
278 (*line
)->gamma
= FALSE
;
280 (*line
)->rect
.X
= (startpoint
->X
< endpoint
->X
? startpoint
->X
: endpoint
->X
);
281 (*line
)->rect
.Y
= (startpoint
->Y
< endpoint
->Y
? startpoint
->Y
: endpoint
->Y
);
282 (*line
)->rect
.Width
= fabs(startpoint
->X
- endpoint
->X
);
283 (*line
)->rect
.Height
= fabs(startpoint
->Y
- endpoint
->Y
);
285 if ((*line
)->rect
.Width
== 0)
287 (*line
)->rect
.X
-= (*line
)->rect
.Height
/ 2.0f
;
288 (*line
)->rect
.Width
= (*line
)->rect
.Height
;
290 else if ((*line
)->rect
.Height
== 0)
292 (*line
)->rect
.Y
-= (*line
)->rect
.Width
/ 2.0f
;
293 (*line
)->rect
.Height
= (*line
)->rect
.Width
;
296 (*line
)->blendcount
= 1;
297 (*line
)->blendfac
= GdipAlloc(sizeof(REAL
));
298 (*line
)->blendpos
= GdipAlloc(sizeof(REAL
));
300 if (!(*line
)->blendfac
|| !(*line
)->blendpos
)
302 GdipFree((*line
)->blendfac
);
303 GdipFree((*line
)->blendpos
);
309 (*line
)->blendfac
[0] = 1.0f
;
310 (*line
)->blendpos
[0] = 1.0f
;
312 (*line
)->pblendcolor
= NULL
;
313 (*line
)->pblendpos
= NULL
;
314 (*line
)->pblendcount
= 0;
316 TRACE("<-- %p\n", *line
);
321 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
322 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
323 GpWrapMode wrap
, GpLineGradient
**line
)
328 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
329 startcolor
, endcolor
, wrap
, line
);
331 if(!startpoint
|| !endpoint
)
332 return InvalidParameter
;
334 stF
.X
= (REAL
)startpoint
->X
;
335 stF
.Y
= (REAL
)startpoint
->Y
;
336 endF
.X
= (REAL
)endpoint
->X
;
337 endF
.Y
= (REAL
)endpoint
->Y
;
339 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
342 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
343 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
344 GpLineGradient
**line
)
349 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
353 return InvalidParameter
;
357 case LinearGradientModeHorizontal
:
360 end
.X
= rect
->X
+ rect
->Width
;
363 case LinearGradientModeVertical
:
367 end
.Y
= rect
->Y
+ rect
->Height
;
369 case LinearGradientModeForwardDiagonal
:
372 end
.X
= rect
->X
+ rect
->Width
;
373 end
.Y
= rect
->Y
+ rect
->Height
;
375 case LinearGradientModeBackwardDiagonal
:
376 start
.X
= rect
->X
+ rect
->Width
;
379 end
.Y
= rect
->Y
+ rect
->Height
;
382 return InvalidParameter
;
385 stat
= GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
388 (*line
)->rect
= *rect
;
393 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
394 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
395 GpLineGradient
**line
)
399 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
402 rectF
.X
= (REAL
) rect
->X
;
403 rectF
.Y
= (REAL
) rect
->Y
;
404 rectF
.Width
= (REAL
) rect
->Width
;
405 rectF
.Height
= (REAL
) rect
->Height
;
407 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
410 /******************************************************************************
411 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
413 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
414 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
415 GpLineGradient
**line
)
418 LinearGradientMode mode
;
419 REAL width
, height
, exofs
, eyofs
;
420 REAL sin_angle
, cos_angle
, sin_cos_angle
;
422 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
425 sin_angle
= sinf(deg2rad(angle
));
426 cos_angle
= cosf(deg2rad(angle
));
427 sin_cos_angle
= sin_angle
* cos_angle
;
431 width
= height
= 1.0;
436 height
= rect
->Height
;
439 if (sin_cos_angle
>= 0)
440 mode
= LinearGradientModeForwardDiagonal
;
442 mode
= LinearGradientModeBackwardDiagonal
;
444 stat
= GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, mode
, wrap
, line
);
448 if (sin_cos_angle
>= 0)
450 exofs
= width
* sin_cos_angle
+ height
* cos_angle
* cos_angle
;
451 eyofs
= width
* sin_angle
* sin_angle
+ height
* sin_cos_angle
;
455 exofs
= width
* sin_angle
* sin_angle
+ height
* sin_cos_angle
;
456 eyofs
= -width
* sin_cos_angle
+ height
* sin_angle
* sin_angle
;
461 exofs
= exofs
* rect
->Width
;
462 eyofs
= eyofs
* rect
->Height
;
467 (*line
)->endpoint
.X
= rect
->X
+ exofs
;
468 (*line
)->endpoint
.Y
= rect
->Y
+ eyofs
;
472 (*line
)->endpoint
.X
= (*line
)->startpoint
.X
;
473 (*line
)->endpoint
.Y
= (*line
)->startpoint
.Y
;
474 (*line
)->startpoint
.X
= rect
->X
+ exofs
;
475 (*line
)->startpoint
.Y
= rect
->Y
+ eyofs
;
482 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
483 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
484 GpLineGradient
**line
)
486 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
489 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
493 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
494 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
496 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
499 return InvalidParameter
;
504 *grad
= GdipAlloc(sizeof(GpPathGradient
));
505 if (!*grad
) return OutOfMemory
;
507 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
508 (*grad
)->blendpos
= GdipAlloc(sizeof(REAL
));
509 if(!(*grad
)->blendfac
|| !(*grad
)->blendpos
){
510 GdipFree((*grad
)->blendfac
);
511 GdipFree((*grad
)->blendpos
);
516 (*grad
)->blendfac
[0] = 1.0;
517 (*grad
)->blendpos
[0] = 1.0;
518 (*grad
)->blendcount
= 1;
520 (*grad
)->pathdata
.Count
= count
;
521 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
522 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
524 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
525 GdipFree((*grad
)->pathdata
.Points
);
526 GdipFree((*grad
)->pathdata
.Types
);
531 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
532 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
534 (*grad
)->brush
.bt
= BrushTypePathGradient
;
535 (*grad
)->centercolor
= 0xffffffff;
536 (*grad
)->wrap
= wrap
;
537 (*grad
)->gamma
= FALSE
;
538 (*grad
)->center
.X
= 0.0;
539 (*grad
)->center
.Y
= 0.0;
540 (*grad
)->focus
.X
= 0.0;
541 (*grad
)->focus
.Y
= 0.0;
543 TRACE("<-- %p\n", *grad
);
548 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
549 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
555 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
558 return InvalidParameter
;
563 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
567 for(i
= 0; i
< count
; i
++){
568 pointsF
[i
].X
= (REAL
)points
[i
].X
;
569 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
572 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
578 /******************************************************************************
579 * GdipCreatePathGradientFromPath [GDIPLUS.@]
581 * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
583 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
584 GpPathGradient
**grad
)
586 TRACE("(%p, %p)\n", path
, grad
);
589 return InvalidParameter
;
591 *grad
= GdipAlloc(sizeof(GpPathGradient
));
592 if (!*grad
) return OutOfMemory
;
594 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
595 (*grad
)->blendpos
= GdipAlloc(sizeof(REAL
));
596 if(!(*grad
)->blendfac
|| !(*grad
)->blendpos
){
597 GdipFree((*grad
)->blendfac
);
598 GdipFree((*grad
)->blendpos
);
603 (*grad
)->blendfac
[0] = 1.0;
604 (*grad
)->blendpos
[0] = 1.0;
605 (*grad
)->blendcount
= 1;
607 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
608 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
609 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
611 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
612 GdipFree((*grad
)->pathdata
.Points
);
613 GdipFree((*grad
)->pathdata
.Types
);
618 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
619 path
->pathdata
.Count
* sizeof(PointF
));
620 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
622 (*grad
)->brush
.bt
= BrushTypePathGradient
;
623 (*grad
)->centercolor
= 0xffffffff;
624 (*grad
)->wrap
= WrapModeClamp
;
625 (*grad
)->gamma
= FALSE
;
626 /* FIXME: this should be set to the "centroid" of the path by default */
627 (*grad
)->center
.X
= 0.0;
628 (*grad
)->center
.Y
= 0.0;
629 (*grad
)->focus
.X
= 0.0;
630 (*grad
)->focus
.Y
= 0.0;
632 TRACE("<-- %p\n", *grad
);
637 /******************************************************************************
638 * GdipCreateSolidFill [GDIPLUS.@]
640 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
642 TRACE("(%x, %p)\n", color
, sf
);
644 if(!sf
) return InvalidParameter
;
646 *sf
= GdipAlloc(sizeof(GpSolidFill
));
647 if (!*sf
) return OutOfMemory
;
649 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
650 (*sf
)->color
= color
;
652 TRACE("<-- %p\n", *sf
);
657 /******************************************************************************
658 * GdipCreateTexture [GDIPLUS.@]
661 * image [I] image to use
662 * wrapmode [I] optional
663 * texture [O] pointer to the resulting texturebrush
667 * FAILURE: element of GpStatus
669 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
673 GpImageAttributes
*attributes
;
676 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
678 if (!(image
&& texture
))
679 return InvalidParameter
;
681 stat
= GdipGetImageWidth(image
, &width
);
682 if (stat
!= Ok
) return stat
;
683 stat
= GdipGetImageHeight(image
, &height
);
684 if (stat
!= Ok
) return stat
;
686 stat
= GdipCreateImageAttributes(&attributes
);
690 attributes
->wrap
= wrapmode
;
692 stat
= GdipCreateTextureIA(image
, attributes
, 0, 0, width
, height
,
695 GdipDisposeImageAttributes(attributes
);
701 /******************************************************************************
702 * GdipCreateTexture2 [GDIPLUS.@]
704 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
705 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
707 GpImageAttributes
*attributes
;
710 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
711 x
, y
, width
, height
, texture
);
713 stat
= GdipCreateImageAttributes(&attributes
);
717 attributes
->wrap
= wrapmode
;
719 stat
= GdipCreateTextureIA(image
, attributes
, x
, y
, width
, height
,
722 GdipDisposeImageAttributes(attributes
);
728 /******************************************************************************
729 * GdipCreateTextureIA [GDIPLUS.@]
731 * FIXME: imageattr ignored
733 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
734 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
735 REAL height
, GpTexture
**texture
)
738 GpImage
*new_image
=NULL
;
740 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
743 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
744 return InvalidParameter
;
748 if(image
->type
!= ImageTypeBitmap
){
749 FIXME("not implemented for image type %d\n", image
->type
);
750 return NotImplemented
;
753 status
= GdipCloneBitmapArea(x
, y
, width
, height
, PixelFormatDontCare
, (GpBitmap
*)image
, (GpBitmap
**)&new_image
);
757 *texture
= GdipAlloc(sizeof(GpTexture
));
759 status
= OutOfMemory
;
763 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
769 status
= GdipCloneImageAttributes(imageattr
, &(*texture
)->imageattributes
);
773 status
= GdipCreateImageAttributes(&(*texture
)->imageattributes
);
775 (*texture
)->imageattributes
->wrap
= WrapModeTile
;
779 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
780 (*texture
)->image
= new_image
;
786 TRACE("<-- %p\n", *texture
);
792 GdipDeleteMatrix((*texture
)->transform
);
793 GdipDisposeImageAttributes((*texture
)->imageattributes
);
797 GdipDisposeImage(new_image
);
798 TRACE("<-- error %u\n", status
);
804 /******************************************************************************
805 * GdipCreateTextureIAI [GDIPLUS.@]
807 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
808 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
810 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
813 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
816 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
817 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
819 GpImageAttributes
*imageattr
;
822 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
825 stat
= GdipCreateImageAttributes(&imageattr
);
829 imageattr
->wrap
= wrapmode
;
831 stat
= GdipCreateTextureIA(image
, imageattr
, x
, y
, width
, height
, texture
);
837 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
839 TRACE("(%p, %p)\n", brush
, type
);
841 if(!brush
|| !type
) return InvalidParameter
;
848 GpStatus WINGDIPAPI
GdipGetHatchBackgroundColor(GpHatch
*brush
, ARGB
*backcol
)
850 TRACE("(%p, %p)\n", brush
, backcol
);
852 if(!brush
|| !backcol
) return InvalidParameter
;
854 *backcol
= brush
->backcol
;
859 GpStatus WINGDIPAPI
GdipGetHatchForegroundColor(GpHatch
*brush
, ARGB
*forecol
)
861 TRACE("(%p, %p)\n", brush
, forecol
);
863 if(!brush
|| !forecol
) return InvalidParameter
;
865 *forecol
= brush
->forecol
;
870 GpStatus WINGDIPAPI
GdipGetHatchStyle(GpHatch
*brush
, HatchStyle
*hatchstyle
)
872 TRACE("(%p, %p)\n", brush
, hatchstyle
);
874 if(!brush
|| !hatchstyle
) return InvalidParameter
;
876 *hatchstyle
= brush
->hatchstyle
;
881 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
883 TRACE("(%p)\n", brush
);
885 if(!brush
) return InvalidParameter
;
889 case BrushTypePathGradient
:
890 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
891 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
892 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
893 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
895 case BrushTypeLinearGradient
:
896 GdipFree(((GpLineGradient
*)brush
)->blendfac
);
897 GdipFree(((GpLineGradient
*)brush
)->blendpos
);
898 GdipFree(((GpLineGradient
*)brush
)->pblendcolor
);
899 GdipFree(((GpLineGradient
*)brush
)->pblendpos
);
901 case BrushTypeTextureFill
:
902 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
903 GdipDisposeImage(((GpTexture
*)brush
)->image
);
904 GdipDisposeImageAttributes(((GpTexture
*)brush
)->imageattributes
);
905 GdipFree(((GpTexture
*)brush
)->bitmap_bits
);
916 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
919 TRACE("(%p, %p)\n", line
, usinggamma
);
921 if(!line
|| !usinggamma
)
922 return InvalidParameter
;
924 *usinggamma
= line
->gamma
;
929 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
931 TRACE("(%p, %p)\n", brush
, wrapmode
);
933 if(!brush
|| !wrapmode
)
934 return InvalidParameter
;
936 *wrapmode
= brush
->wrap
;
941 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
942 REAL
*positions
, INT count
)
944 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
946 if(!brush
|| !blend
|| !positions
|| count
<= 0)
947 return InvalidParameter
;
949 if(count
< brush
->blendcount
)
950 return InsufficientBuffer
;
952 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
953 if(brush
->blendcount
> 1){
954 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
960 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
962 TRACE("(%p, %p)\n", brush
, count
);
965 return InvalidParameter
;
967 *count
= brush
->blendcount
;
972 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
975 TRACE("(%p, %p)\n", grad
, point
);
978 return InvalidParameter
;
980 point
->X
= grad
->center
.X
;
981 point
->Y
= grad
->center
.Y
;
986 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
992 TRACE("(%p, %p)\n", grad
, point
);
995 return InvalidParameter
;
997 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
1000 point
->X
= roundr(ptf
.X
);
1001 point
->Y
= roundr(ptf
.Y
);
1007 GpStatus WINGDIPAPI
GdipGetPathGradientCenterColor(GpPathGradient
*grad
,
1012 TRACE("(%p,%p)\n", grad
, colors
);
1015 FIXME("not implemented\n");
1017 return NotImplemented
;
1020 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
1023 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
1025 if(!grad
|| !x
|| !y
)
1026 return InvalidParameter
;
1034 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
1037 TRACE("(%p, %p)\n", grad
, gamma
);
1040 return InvalidParameter
;
1042 *gamma
= grad
->gamma
;
1047 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
1050 TRACE("(%p, %p)\n", grad
, count
);
1053 return InvalidParameter
;
1055 *count
= grad
->pathdata
.Count
;
1060 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
1066 TRACE("(%p, %p)\n", brush
, rect
);
1069 return InvalidParameter
;
1071 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
1072 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
1073 if(stat
!= Ok
) return stat
;
1075 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
1077 GdipDeletePath(path
);
1081 memcpy(rect
, &r
, sizeof(GpRectF
));
1083 GdipDeletePath(path
);
1088 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
1093 TRACE("(%p, %p)\n", brush
, rect
);
1096 return InvalidParameter
;
1098 stat
= GdipGetPathGradientRect(brush
, &rectf
);
1099 if(stat
!= Ok
) return stat
;
1101 rect
->X
= roundr(rectf
.X
);
1102 rect
->Y
= roundr(rectf
.Y
);
1103 rect
->Width
= roundr(rectf
.Width
);
1104 rect
->Height
= roundr(rectf
.Height
);
1109 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
1110 *grad
, ARGB
*argb
, INT
*count
)
1114 TRACE("(%p,%p,%p)\n", grad
, argb
, count
);
1116 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
1117 return InvalidParameter
;
1120 FIXME("not implemented\n");
1122 return NotImplemented
;
1125 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorCount(GpPathGradient
*brush
, INT
*count
)
1129 TRACE("(%p, %p)\n", brush
, count
);
1131 if (!brush
|| !count
)
1132 return InvalidParameter
;
1135 FIXME("not implemented\n");
1137 return NotImplemented
;
1140 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
1141 GpWrapMode
*wrapmode
)
1143 TRACE("(%p, %p)\n", brush
, wrapmode
);
1145 if(!brush
|| !wrapmode
)
1146 return InvalidParameter
;
1148 *wrapmode
= brush
->wrap
;
1153 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
1155 TRACE("(%p, %p)\n", sf
, argb
);
1158 return InvalidParameter
;
1165 /******************************************************************************
1166 * GdipGetTextureImage [GDIPLUS.@]
1168 GpStatus WINGDIPAPI
GdipGetTextureImage(GpTexture
*brush
, GpImage
**image
)
1170 TRACE("(%p, %p)\n", brush
, image
);
1172 if(!brush
|| !image
)
1173 return InvalidParameter
;
1175 return GdipCloneImage(brush
->image
, image
);
1178 /******************************************************************************
1179 * GdipGetTextureTransform [GDIPLUS.@]
1181 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
1183 TRACE("(%p, %p)\n", brush
, matrix
);
1185 if(!brush
|| !matrix
)
1186 return InvalidParameter
;
1188 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
1193 /******************************************************************************
1194 * GdipGetTextureWrapMode [GDIPLUS.@]
1196 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
1198 TRACE("(%p, %p)\n", brush
, wrapmode
);
1200 if(!brush
|| !wrapmode
)
1201 return InvalidParameter
;
1203 *wrapmode
= brush
->imageattributes
->wrap
;
1208 /******************************************************************************
1209 * GdipMultiplyTextureTransform [GDIPLUS.@]
1211 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
1212 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1214 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
1216 if(!brush
|| !matrix
)
1217 return InvalidParameter
;
1219 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
1222 /******************************************************************************
1223 * GdipResetTextureTransform [GDIPLUS.@]
1225 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
1227 TRACE("(%p)\n", brush
);
1230 return InvalidParameter
;
1232 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1235 /******************************************************************************
1236 * GdipScaleTextureTransform [GDIPLUS.@]
1238 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
1239 REAL sx
, REAL sy
, GpMatrixOrder order
)
1241 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
1244 return InvalidParameter
;
1246 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
1249 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
1250 GDIPCONST REAL
*factors
, GDIPCONST REAL
* positions
, INT count
)
1252 REAL
*new_blendfac
, *new_blendpos
;
1254 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1256 if(!brush
|| !factors
|| !positions
|| count
<= 0 ||
1257 (count
>= 2 && (positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)))
1258 return InvalidParameter
;
1260 new_blendfac
= GdipAlloc(count
* sizeof(REAL
));
1261 new_blendpos
= GdipAlloc(count
* sizeof(REAL
));
1263 if (!new_blendfac
|| !new_blendpos
)
1265 GdipFree(new_blendfac
);
1266 GdipFree(new_blendpos
);
1270 memcpy(new_blendfac
, factors
, count
* sizeof(REAL
));
1271 memcpy(new_blendpos
, positions
, count
* sizeof(REAL
));
1273 GdipFree(brush
->blendfac
);
1274 GdipFree(brush
->blendpos
);
1276 brush
->blendcount
= count
;
1277 brush
->blendfac
= new_blendfac
;
1278 brush
->blendpos
= new_blendpos
;
1283 GpStatus WINGDIPAPI
GdipGetLineBlend(GpLineGradient
*brush
, REAL
*factors
,
1284 REAL
*positions
, INT count
)
1286 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1288 if (!brush
|| !factors
|| !positions
|| count
<= 0)
1289 return InvalidParameter
;
1291 if (count
< brush
->blendcount
)
1292 return InsufficientBuffer
;
1294 memcpy(factors
, brush
->blendfac
, brush
->blendcount
* sizeof(REAL
));
1295 memcpy(positions
, brush
->blendpos
, brush
->blendcount
* sizeof(REAL
));
1300 GpStatus WINGDIPAPI
GdipGetLineBlendCount(GpLineGradient
*brush
, INT
*count
)
1302 TRACE("(%p, %p)\n", brush
, count
);
1304 if (!brush
|| !count
)
1305 return InvalidParameter
;
1307 *count
= brush
->blendcount
;
1312 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
1315 TRACE("(%p, %d)\n", line
, usegamma
);
1318 return InvalidParameter
;
1320 line
->gamma
= usegamma
;
1325 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1332 const int precision
= 16;
1333 REAL erf_range
; /* we use values erf(-erf_range) through erf(+erf_range) */
1337 TRACE("(%p, %0.2f, %0.2f)\n", line
, focus
, scale
);
1339 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1340 return InvalidParameter
;
1342 /* we want 2 standard deviations */
1343 erf_range
= 2.0 / sqrt(2);
1345 /* calculate the constants we need to normalize the error function to be
1346 between 0.0 and scale over the range we need */
1347 min_erf
= erf(-erf_range
);
1348 scale_erf
= scale
/ (-2.0 * min_erf
);
1354 for (i
=1; i
<precision
; i
++)
1356 positions
[i
] = focus
* i
/ precision
;
1357 factors
[i
] = scale_erf
* (erf(2 * erf_range
* i
/ precision
- erf_range
) - min_erf
);
1359 num_points
+= precision
;
1362 positions
[num_points
] = focus
;
1363 factors
[num_points
] = scale
;
1368 for (i
=1; i
<precision
; i
++)
1370 positions
[i
+num_points
-1] = (focus
+ ((1.0-focus
) * i
/ precision
));
1371 factors
[i
+num_points
-1] = scale_erf
* (erf(erf_range
- 2 * erf_range
* i
/ precision
) - min_erf
);
1373 num_points
+= precision
;
1374 positions
[num_points
-1] = 1.0;
1375 factors
[num_points
-1] = 0.0;
1378 return GdipSetLineBlend(line
, factors
, positions
, num_points
);
1381 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1384 TRACE("(%p, %d)\n", line
, wrap
);
1386 if(!line
|| wrap
== WrapModeClamp
)
1387 return InvalidParameter
;
1394 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1395 GDIPCONST REAL
*pos
, INT count
)
1399 TRACE("(%p,%p,%p,%i)\n", brush
, blend
, pos
, count
);
1402 FIXME("not implemented\n");
1404 return NotImplemented
;
1407 GpStatus WINGDIPAPI
GdipSetPathGradientLinearBlend(GpPathGradient
*brush
,
1408 REAL focus
, REAL scale
)
1412 TRACE("(%p,%0.2f,%0.2f)\n", brush
, focus
, scale
);
1415 FIXME("not implemented\n");
1417 return NotImplemented
;
1420 GpStatus WINGDIPAPI
GdipSetPathGradientPresetBlend(GpPathGradient
*brush
,
1421 GDIPCONST ARGB
*blend
, GDIPCONST REAL
*pos
, INT count
)
1423 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1424 return NotImplemented
;
1427 GpStatus WINGDIPAPI
GdipGetPathGradientPresetBlend(GpPathGradient
*brush
,
1428 ARGB
*blend
, REAL
*pos
, INT count
)
1430 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1431 return NotImplemented
;
1434 GpStatus WINGDIPAPI
GdipGetPathGradientPresetBlendCount(GpPathGradient
*brush
,
1437 FIXME("(%p,%p): stub\n", brush
, count
);
1438 return NotImplemented
;
1441 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1444 TRACE("(%p, %x)\n", grad
, argb
);
1447 return InvalidParameter
;
1449 grad
->centercolor
= argb
;
1453 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1456 TRACE("(%p, %s)\n", grad
, debugstr_pointf(point
));
1459 return InvalidParameter
;
1461 grad
->center
.X
= point
->X
;
1462 grad
->center
.Y
= point
->Y
;
1467 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1472 TRACE("(%p, %p)\n", grad
, point
);
1475 return InvalidParameter
;
1477 ptf
.X
= (REAL
)point
->X
;
1478 ptf
.Y
= (REAL
)point
->Y
;
1480 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1483 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1486 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1489 return InvalidParameter
;
1497 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1500 TRACE("(%p, %d)\n", grad
, gamma
);
1503 return InvalidParameter
;
1505 grad
->gamma
= gamma
;
1510 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1511 REAL focus
, REAL scale
)
1515 TRACE("(%p,%0.2f,%0.2f)\n", grad
, focus
, scale
);
1517 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1518 return InvalidParameter
;
1521 FIXME("not implemented\n");
1523 return NotImplemented
;
1526 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1527 *grad
, GDIPCONST ARGB
*argb
, INT
*count
)
1531 TRACE("(%p,%p,%p)\n", grad
, argb
, count
);
1533 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1534 (*count
> grad
->pathdata
.Count
))
1535 return InvalidParameter
;
1538 FIXME("not implemented\n");
1540 return NotImplemented
;
1543 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1546 TRACE("(%p, %d)\n", grad
, wrap
);
1549 return InvalidParameter
;
1556 GpStatus WINGDIPAPI
GdipSetPathGradientTransform(GpPathGradient
*grad
,
1561 TRACE("(%p,%p)\n", grad
, matrix
);
1564 FIXME("not implemented\n");
1566 return NotImplemented
;
1569 GpStatus WINGDIPAPI
GdipGetPathGradientTransform(GpPathGradient
*grad
,
1574 TRACE("(%p,%p)\n", grad
, matrix
);
1577 FIXME("not implemented\n");
1579 return NotImplemented
;
1582 GpStatus WINGDIPAPI
GdipMultiplyPathGradientTransform(GpPathGradient
*grad
,
1583 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1587 TRACE("(%p,%p,%i)\n", grad
, matrix
, order
);
1590 FIXME("not implemented\n");
1592 return NotImplemented
;
1595 GpStatus WINGDIPAPI
GdipRotatePathGradientTransform(GpPathGradient
*grad
,
1596 REAL angle
, GpMatrixOrder order
)
1600 TRACE("(%p,%0.2f,%i)\n", grad
, angle
, order
);
1603 FIXME("not implemented\n");
1605 return NotImplemented
;
1608 GpStatus WINGDIPAPI
GdipScalePathGradientTransform(GpPathGradient
*grad
,
1609 REAL sx
, REAL sy
, GpMatrixOrder order
)
1613 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad
, sx
, sy
, order
);
1616 FIXME("not implemented\n");
1618 return NotImplemented
;
1621 GpStatus WINGDIPAPI
GdipTranslatePathGradientTransform(GpPathGradient
*grad
,
1622 REAL dx
, REAL dy
, GpMatrixOrder order
)
1626 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad
, dx
, dy
, order
);
1629 FIXME("not implemented\n");
1631 return NotImplemented
;
1634 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1636 TRACE("(%p, %x)\n", sf
, argb
);
1639 return InvalidParameter
;
1645 /******************************************************************************
1646 * GdipSetTextureTransform [GDIPLUS.@]
1648 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1649 GDIPCONST GpMatrix
*matrix
)
1651 TRACE("(%p, %p)\n", texture
, matrix
);
1653 if(!texture
|| !matrix
)
1654 return InvalidParameter
;
1656 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1661 /******************************************************************************
1662 * GdipSetTextureWrapMode [GDIPLUS.@]
1664 * WrapMode not used, only stored
1666 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1668 TRACE("(%p, %d)\n", brush
, wrapmode
);
1671 return InvalidParameter
;
1673 brush
->imageattributes
->wrap
= wrapmode
;
1678 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1681 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1684 return InvalidParameter
;
1686 brush
->startcolor
= color1
;
1687 brush
->endcolor
= color2
;
1692 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1694 TRACE("(%p, %p)\n", brush
, colors
);
1696 if(!brush
|| !colors
)
1697 return InvalidParameter
;
1699 colors
[0] = brush
->startcolor
;
1700 colors
[1] = brush
->endcolor
;
1705 /******************************************************************************
1706 * GdipRotateTextureTransform [GDIPLUS.@]
1708 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1709 GpMatrixOrder order
)
1711 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1714 return InvalidParameter
;
1716 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1719 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1726 TRACE("(%p,%.2f,%.2f)\n", brush
, focus
, scale
);
1728 if (!brush
) return InvalidParameter
;
1732 factors
[num_points
] = 0.0;
1733 positions
[num_points
] = 0.0;
1737 factors
[num_points
] = scale
;
1738 positions
[num_points
] = focus
;
1743 factors
[num_points
] = 0.0;
1744 positions
[num_points
] = 1.0;
1748 return GdipSetLineBlend(brush
, factors
, positions
, num_points
);
1751 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1752 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1756 TRACE("(%p,%p,%p,%i)\n", brush
, blend
, positions
, count
);
1758 if (!brush
|| !blend
|| !positions
|| count
< 2 ||
1759 positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)
1761 return InvalidParameter
;
1764 new_color
= GdipAlloc(count
* sizeof(ARGB
));
1765 new_pos
= GdipAlloc(count
* sizeof(REAL
));
1766 if (!new_color
|| !new_pos
)
1768 GdipFree(new_color
);
1773 memcpy(new_color
, blend
, sizeof(ARGB
) * count
);
1774 memcpy(new_pos
, positions
, sizeof(REAL
) * count
);
1776 GdipFree(brush
->pblendcolor
);
1777 GdipFree(brush
->pblendpos
);
1779 brush
->pblendcolor
= new_color
;
1780 brush
->pblendpos
= new_pos
;
1781 brush
->pblendcount
= count
;
1786 GpStatus WINGDIPAPI
GdipGetLinePresetBlend(GpLineGradient
*brush
,
1787 ARGB
*blend
, REAL
* positions
, INT count
)
1789 if (!brush
|| !blend
|| !positions
|| count
< 2)
1790 return InvalidParameter
;
1792 if (brush
->pblendcount
== 0)
1793 return GenericError
;
1795 if (count
< brush
->pblendcount
)
1796 return InsufficientBuffer
;
1798 memcpy(blend
, brush
->pblendcolor
, sizeof(ARGB
) * brush
->pblendcount
);
1799 memcpy(positions
, brush
->pblendpos
, sizeof(REAL
) * brush
->pblendcount
);
1804 GpStatus WINGDIPAPI
GdipGetLinePresetBlendCount(GpLineGradient
*brush
,
1807 if (!brush
|| !count
)
1808 return InvalidParameter
;
1810 *count
= brush
->pblendcount
;
1815 GpStatus WINGDIPAPI
GdipResetLineTransform(GpLineGradient
*brush
)
1819 TRACE("(%p)\n", brush
);
1822 FIXME("not implemented\n");
1824 return NotImplemented
;
1827 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1828 GDIPCONST GpMatrix
*matrix
)
1832 TRACE("(%p,%p)\n", brush
, matrix
);
1835 FIXME("not implemented\n");
1837 return NotImplemented
;
1840 GpStatus WINGDIPAPI
GdipGetLineTransform(GpLineGradient
*brush
, GpMatrix
*matrix
)
1844 TRACE("(%p,%p)\n", brush
, matrix
);
1847 FIXME("not implemented\n");
1849 return NotImplemented
;
1852 GpStatus WINGDIPAPI
GdipScaleLineTransform(GpLineGradient
*brush
, REAL sx
, REAL sy
,
1853 GpMatrixOrder order
)
1857 TRACE("(%p,%0.2f,%0.2f,%u)\n", brush
, sx
, sy
, order
);
1860 FIXME("not implemented\n");
1862 return NotImplemented
;
1865 GpStatus WINGDIPAPI
GdipMultiplyLineTransform(GpLineGradient
*brush
,
1866 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1870 TRACE("(%p,%p,%u)\n", brush
, matrix
, order
);
1873 FIXME("not implemented\n");
1875 return NotImplemented
;
1878 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1879 REAL dx
, REAL dy
, GpMatrixOrder order
)
1883 TRACE("(%p,%f,%f,%d)\n", brush
, dx
, dy
, order
);
1886 FIXME("not implemented\n");
1891 /******************************************************************************
1892 * GdipTranslateTextureTransform [GDIPLUS.@]
1894 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1895 GpMatrixOrder order
)
1897 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1900 return InvalidParameter
;
1902 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1905 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1907 TRACE("(%p, %p)\n", brush
, rect
);
1910 return InvalidParameter
;
1912 *rect
= brush
->rect
;
1917 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1922 TRACE("(%p, %p)\n", brush
, rect
);
1925 return InvalidParameter
;
1927 ret
= GdipGetLineRect(brush
, &rectF
);
1930 rect
->X
= roundr(rectF
.X
);
1931 rect
->Y
= roundr(rectF
.Y
);
1932 rect
->Width
= roundr(rectF
.Width
);
1933 rect
->Height
= roundr(rectF
.Height
);
1939 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1940 REAL angle
, GpMatrixOrder order
)
1944 TRACE("(%p,%0.2f,%u)\n", brush
, angle
, order
);
1947 return InvalidParameter
;
1950 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1952 return NotImplemented
;