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
:
51 *clone
= GdipAlloc(sizeof(GpSolidFill
));
52 if (!*clone
) return OutOfMemory
;
54 fill
= (GpSolidFill
*)*clone
;
56 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
58 fill
->bmp
= ARGB2BMP(fill
->color
);
61 case BrushTypeHatchFill
:
63 GpHatch
*hatch
= (GpHatch
*)brush
;
65 return GdipCreateHatchBrush(hatch
->hatchstyle
, hatch
->forecol
, hatch
->backcol
, (GpHatch
**)clone
);
67 case BrushTypePathGradient
:{
68 GpPathGradient
*src
, *dest
;
71 *clone
= GdipAlloc(sizeof(GpPathGradient
));
72 if (!*clone
) return OutOfMemory
;
74 src
= (GpPathGradient
*) brush
,
75 dest
= (GpPathGradient
*) *clone
;
76 count
= src
->pathdata
.Count
;
78 memcpy(dest
, src
, sizeof(GpPathGradient
));
80 dest
->pathdata
.Count
= count
;
81 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
82 dest
->pathdata
.Types
= GdipAlloc(count
);
84 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
85 GdipFree(dest
->pathdata
.Points
);
86 GdipFree(dest
->pathdata
.Types
);
91 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
92 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
95 count
= src
->blendcount
;
96 dest
->blendcount
= count
;
97 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
98 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
100 if(!dest
->blendfac
|| !dest
->blendpos
){
101 GdipFree(dest
->pathdata
.Points
);
102 GdipFree(dest
->pathdata
.Types
);
103 GdipFree(dest
->blendfac
);
104 GdipFree(dest
->blendpos
);
109 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
110 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
114 case BrushTypeLinearGradient
:{
115 GpLineGradient
*dest
, *src
;
118 dest
= GdipAlloc(sizeof(GpLineGradient
));
119 if(!dest
) return OutOfMemory
;
121 src
= (GpLineGradient
*)brush
;
123 memcpy(dest
, src
, sizeof(GpLineGradient
));
125 count
= dest
->blendcount
;
126 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
127 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
128 pcount
= dest
->pblendcount
;
131 dest
->pblendcolor
= GdipAlloc(pcount
* sizeof(ARGB
));
132 dest
->pblendpos
= GdipAlloc(pcount
* sizeof(REAL
));
135 if (!dest
->blendfac
|| !dest
->blendpos
||
136 (pcount
&& (!dest
->pblendcolor
|| !dest
->pblendpos
)))
138 GdipFree(dest
->blendfac
);
139 GdipFree(dest
->blendpos
);
140 GdipFree(dest
->pblendcolor
);
141 GdipFree(dest
->pblendpos
);
146 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
147 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
151 memcpy(dest
->pblendcolor
, src
->pblendcolor
, pcount
* sizeof(ARGB
));
152 memcpy(dest
->pblendpos
, src
->pblendpos
, pcount
* sizeof(REAL
));
155 *clone
= &dest
->brush
;
158 case BrushTypeTextureFill
:
161 GpTexture
*texture
= (GpTexture
*)brush
;
162 GpTexture
*new_texture
;
165 stat
= GdipGetImageWidth(texture
->image
, &width
);
166 if (stat
!= Ok
) return stat
;
167 stat
= GdipGetImageHeight(texture
->image
, &height
);
168 if (stat
!= Ok
) return stat
;
170 stat
= GdipCreateTextureIA(texture
->image
, texture
->imageattributes
, 0, 0, width
, height
, &new_texture
);
174 memcpy(new_texture
->transform
, texture
->transform
, sizeof(GpMatrix
));
175 *clone
= (GpBrush
*)new_texture
;
183 ERR("not implemented for brush type %d\n", brush
->bt
);
184 return NotImplemented
;
187 TRACE("<-- %p\n", *clone
);
191 static const char HatchBrushes
[][8] = {
192 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
193 { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
194 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
195 { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
196 { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
197 { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
198 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
199 { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
200 { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
201 { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
202 { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
203 { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
204 { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
205 { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
206 { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
207 { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
208 { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
209 { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
210 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
211 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
212 { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
213 { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
214 { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
215 { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
216 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
217 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
218 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
219 { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
220 { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
221 { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
224 GpStatus
get_hatch_data(HatchStyle hatchstyle
, const char **result
)
226 if (hatchstyle
< sizeof(HatchBrushes
) / sizeof(HatchBrushes
[0]))
228 *result
= HatchBrushes
[hatchstyle
];
232 return NotImplemented
;
235 /******************************************************************************
236 * GdipCreateHatchBrush [GDIPLUS.@]
238 GpStatus WINGDIPAPI
GdipCreateHatchBrush(HatchStyle hatchstyle
, ARGB forecol
, ARGB backcol
, GpHatch
**brush
)
240 TRACE("(%d, %d, %d, %p)\n", hatchstyle
, forecol
, backcol
, brush
);
242 if(!brush
) return InvalidParameter
;
244 *brush
= GdipAlloc(sizeof(GpHatch
));
245 if (!*brush
) return OutOfMemory
;
247 (*brush
)->brush
.bt
= BrushTypeHatchFill
;
248 (*brush
)->forecol
= forecol
;
249 (*brush
)->backcol
= backcol
;
250 (*brush
)->hatchstyle
= hatchstyle
;
251 TRACE("<-- %p\n", *brush
);
256 /******************************************************************************
257 * GdipCreateLineBrush [GDIPLUS.@]
259 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
260 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
261 GpWrapMode wrap
, GpLineGradient
**line
)
263 TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint
),
264 debugstr_pointf(endpoint
), startcolor
, endcolor
, wrap
, line
);
266 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
267 return InvalidParameter
;
269 if (startpoint
->X
== endpoint
->X
&& startpoint
->Y
== endpoint
->Y
)
272 *line
= GdipAlloc(sizeof(GpLineGradient
));
273 if(!*line
) return OutOfMemory
;
275 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
277 (*line
)->startpoint
.X
= startpoint
->X
;
278 (*line
)->startpoint
.Y
= startpoint
->Y
;
279 (*line
)->endpoint
.X
= endpoint
->X
;
280 (*line
)->endpoint
.Y
= endpoint
->Y
;
281 (*line
)->startcolor
= startcolor
;
282 (*line
)->endcolor
= endcolor
;
283 (*line
)->wrap
= wrap
;
284 (*line
)->gamma
= FALSE
;
286 (*line
)->rect
.X
= (startpoint
->X
< endpoint
->X
? startpoint
->X
: endpoint
->X
);
287 (*line
)->rect
.Y
= (startpoint
->Y
< endpoint
->Y
? startpoint
->Y
: endpoint
->Y
);
288 (*line
)->rect
.Width
= fabs(startpoint
->X
- endpoint
->X
);
289 (*line
)->rect
.Height
= fabs(startpoint
->Y
- endpoint
->Y
);
291 if ((*line
)->rect
.Width
== 0)
293 (*line
)->rect
.X
-= (*line
)->rect
.Height
/ 2.0f
;
294 (*line
)->rect
.Width
= (*line
)->rect
.Height
;
296 else if ((*line
)->rect
.Height
== 0)
298 (*line
)->rect
.Y
-= (*line
)->rect
.Width
/ 2.0f
;
299 (*line
)->rect
.Height
= (*line
)->rect
.Width
;
302 (*line
)->blendcount
= 1;
303 (*line
)->blendfac
= GdipAlloc(sizeof(REAL
));
304 (*line
)->blendpos
= GdipAlloc(sizeof(REAL
));
306 if (!(*line
)->blendfac
|| !(*line
)->blendpos
)
308 GdipFree((*line
)->blendfac
);
309 GdipFree((*line
)->blendpos
);
315 (*line
)->blendfac
[0] = 1.0f
;
316 (*line
)->blendpos
[0] = 1.0f
;
318 (*line
)->pblendcolor
= NULL
;
319 (*line
)->pblendpos
= NULL
;
320 (*line
)->pblendcount
= 0;
322 TRACE("<-- %p\n", *line
);
327 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
328 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
329 GpWrapMode wrap
, GpLineGradient
**line
)
334 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
335 startcolor
, endcolor
, wrap
, line
);
337 if(!startpoint
|| !endpoint
)
338 return InvalidParameter
;
340 stF
.X
= (REAL
)startpoint
->X
;
341 stF
.Y
= (REAL
)startpoint
->Y
;
342 endF
.X
= (REAL
)endpoint
->X
;
343 endF
.Y
= (REAL
)endpoint
->Y
;
345 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
348 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
349 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
350 GpLineGradient
**line
)
355 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
359 return InvalidParameter
;
363 case LinearGradientModeHorizontal
:
366 end
.X
= rect
->X
+ rect
->Width
;
369 case LinearGradientModeVertical
:
373 end
.Y
= rect
->Y
+ rect
->Height
;
375 case LinearGradientModeForwardDiagonal
:
378 end
.X
= rect
->X
+ rect
->Width
;
379 end
.Y
= rect
->Y
+ rect
->Height
;
381 case LinearGradientModeBackwardDiagonal
:
382 start
.X
= rect
->X
+ rect
->Width
;
385 end
.Y
= rect
->Y
+ rect
->Height
;
388 return InvalidParameter
;
391 stat
= GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
394 (*line
)->rect
= *rect
;
399 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
400 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
401 GpLineGradient
**line
)
405 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
408 rectF
.X
= (REAL
) rect
->X
;
409 rectF
.Y
= (REAL
) rect
->Y
;
410 rectF
.Width
= (REAL
) rect
->Width
;
411 rectF
.Height
= (REAL
) rect
->Height
;
413 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
416 /******************************************************************************
417 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
419 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
420 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
421 GpLineGradient
**line
)
424 LinearGradientMode mode
;
425 REAL width
, height
, exofs
, eyofs
;
426 REAL sin_angle
, cos_angle
, sin_cos_angle
;
428 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
431 sin_angle
= sinf(deg2rad(angle
));
432 cos_angle
= cosf(deg2rad(angle
));
433 sin_cos_angle
= sin_angle
* cos_angle
;
437 width
= height
= 1.0;
442 height
= rect
->Height
;
445 if (sin_cos_angle
>= 0)
446 mode
= LinearGradientModeForwardDiagonal
;
448 mode
= LinearGradientModeBackwardDiagonal
;
450 stat
= GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, mode
, wrap
, line
);
454 if (sin_cos_angle
>= 0)
456 exofs
= width
* sin_cos_angle
+ height
* cos_angle
* cos_angle
;
457 eyofs
= width
* sin_angle
* sin_angle
+ height
* sin_cos_angle
;
461 exofs
= width
* sin_angle
* sin_angle
+ height
* sin_cos_angle
;
462 eyofs
= -width
* sin_cos_angle
+ height
* sin_angle
* sin_angle
;
467 exofs
= exofs
* rect
->Width
;
468 eyofs
= eyofs
* rect
->Height
;
473 (*line
)->endpoint
.X
= rect
->X
+ exofs
;
474 (*line
)->endpoint
.Y
= rect
->Y
+ eyofs
;
478 (*line
)->endpoint
.X
= (*line
)->startpoint
.X
;
479 (*line
)->endpoint
.Y
= (*line
)->startpoint
.Y
;
480 (*line
)->startpoint
.X
= rect
->X
+ exofs
;
481 (*line
)->startpoint
.Y
= rect
->Y
+ eyofs
;
488 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
489 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
490 GpLineGradient
**line
)
492 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
495 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
499 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
500 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
502 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
505 return InvalidParameter
;
510 *grad
= GdipAlloc(sizeof(GpPathGradient
));
511 if (!*grad
) return OutOfMemory
;
513 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
514 (*grad
)->blendpos
= GdipAlloc(sizeof(REAL
));
515 if(!(*grad
)->blendfac
|| !(*grad
)->blendpos
){
516 GdipFree((*grad
)->blendfac
);
517 GdipFree((*grad
)->blendpos
);
522 (*grad
)->blendfac
[0] = 1.0;
523 (*grad
)->blendpos
[0] = 1.0;
524 (*grad
)->blendcount
= 1;
526 (*grad
)->pathdata
.Count
= count
;
527 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
528 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
530 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
531 GdipFree((*grad
)->pathdata
.Points
);
532 GdipFree((*grad
)->pathdata
.Types
);
537 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
538 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
540 (*grad
)->brush
.bt
= BrushTypePathGradient
;
541 (*grad
)->centercolor
= 0xffffffff;
542 (*grad
)->wrap
= wrap
;
543 (*grad
)->gamma
= FALSE
;
544 (*grad
)->center
.X
= 0.0;
545 (*grad
)->center
.Y
= 0.0;
546 (*grad
)->focus
.X
= 0.0;
547 (*grad
)->focus
.Y
= 0.0;
549 TRACE("<-- %p\n", *grad
);
554 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
555 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
561 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
564 return InvalidParameter
;
569 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
573 for(i
= 0; i
< count
; i
++){
574 pointsF
[i
].X
= (REAL
)points
[i
].X
;
575 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
578 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
584 /******************************************************************************
585 * GdipCreatePathGradientFromPath [GDIPLUS.@]
587 * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
589 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
590 GpPathGradient
**grad
)
592 TRACE("(%p, %p)\n", path
, grad
);
595 return InvalidParameter
;
597 *grad
= GdipAlloc(sizeof(GpPathGradient
));
598 if (!*grad
) return OutOfMemory
;
600 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
601 (*grad
)->blendpos
= GdipAlloc(sizeof(REAL
));
602 if(!(*grad
)->blendfac
|| !(*grad
)->blendpos
){
603 GdipFree((*grad
)->blendfac
);
604 GdipFree((*grad
)->blendpos
);
609 (*grad
)->blendfac
[0] = 1.0;
610 (*grad
)->blendpos
[0] = 1.0;
611 (*grad
)->blendcount
= 1;
613 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
614 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
615 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
617 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
618 GdipFree((*grad
)->pathdata
.Points
);
619 GdipFree((*grad
)->pathdata
.Types
);
624 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
625 path
->pathdata
.Count
* sizeof(PointF
));
626 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
628 (*grad
)->brush
.bt
= BrushTypePathGradient
;
629 (*grad
)->centercolor
= 0xffffffff;
630 (*grad
)->wrap
= WrapModeClamp
;
631 (*grad
)->gamma
= FALSE
;
632 /* FIXME: this should be set to the "centroid" of the path by default */
633 (*grad
)->center
.X
= 0.0;
634 (*grad
)->center
.Y
= 0.0;
635 (*grad
)->focus
.X
= 0.0;
636 (*grad
)->focus
.Y
= 0.0;
638 TRACE("<-- %p\n", *grad
);
643 /******************************************************************************
644 * GdipCreateSolidFill [GDIPLUS.@]
646 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
648 TRACE("(%x, %p)\n", color
, sf
);
650 if(!sf
) return InvalidParameter
;
652 *sf
= GdipAlloc(sizeof(GpSolidFill
));
653 if (!*sf
) return OutOfMemory
;
655 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
656 (*sf
)->color
= color
;
657 (*sf
)->bmp
= ARGB2BMP(color
);
659 TRACE("<-- %p\n", *sf
);
664 /******************************************************************************
665 * GdipCreateTexture [GDIPLUS.@]
668 * image [I] image to use
669 * wrapmode [I] optional
670 * texture [O] pointer to the resulting texturebrush
674 * FAILURE: element of GpStatus
676 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
680 GpImageAttributes
*attributes
;
683 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
685 if (!(image
&& texture
))
686 return InvalidParameter
;
688 stat
= GdipGetImageWidth(image
, &width
);
689 if (stat
!= Ok
) return stat
;
690 stat
= GdipGetImageHeight(image
, &height
);
691 if (stat
!= Ok
) return stat
;
693 stat
= GdipCreateImageAttributes(&attributes
);
697 attributes
->wrap
= wrapmode
;
699 stat
= GdipCreateTextureIA(image
, attributes
, 0, 0, width
, height
,
702 GdipDisposeImageAttributes(attributes
);
708 /******************************************************************************
709 * GdipCreateTexture2 [GDIPLUS.@]
711 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
712 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
714 GpImageAttributes
*attributes
;
717 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
718 x
, y
, width
, height
, texture
);
720 stat
= GdipCreateImageAttributes(&attributes
);
724 attributes
->wrap
= wrapmode
;
726 stat
= GdipCreateTextureIA(image
, attributes
, x
, y
, width
, height
,
729 GdipDisposeImageAttributes(attributes
);
735 /******************************************************************************
736 * GdipCreateTextureIA [GDIPLUS.@]
738 * FIXME: imageattr ignored
740 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
741 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
742 REAL height
, GpTexture
**texture
)
745 GpImage
*new_image
=NULL
;
747 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
750 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
751 return InvalidParameter
;
755 if(image
->type
!= ImageTypeBitmap
){
756 FIXME("not implemented for image type %d\n", image
->type
);
757 return NotImplemented
;
760 status
= GdipCloneBitmapArea(x
, y
, width
, height
, PixelFormatDontCare
, (GpBitmap
*)image
, (GpBitmap
**)&new_image
);
764 *texture
= GdipAlloc(sizeof(GpTexture
));
766 status
= OutOfMemory
;
770 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
776 status
= GdipCloneImageAttributes(imageattr
, &(*texture
)->imageattributes
);
780 status
= GdipCreateImageAttributes(&(*texture
)->imageattributes
);
782 (*texture
)->imageattributes
->wrap
= WrapModeTile
;
786 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
787 (*texture
)->image
= new_image
;
793 TRACE("<-- %p\n", *texture
);
799 GdipDeleteMatrix((*texture
)->transform
);
800 GdipDisposeImageAttributes((*texture
)->imageattributes
);
804 GdipDisposeImage(new_image
);
805 TRACE("<-- error %u\n", status
);
811 /******************************************************************************
812 * GdipCreateTextureIAI [GDIPLUS.@]
814 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
815 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
817 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
820 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
823 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
824 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
826 GpImageAttributes
*imageattr
;
829 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
832 stat
= GdipCreateImageAttributes(&imageattr
);
836 imageattr
->wrap
= wrapmode
;
838 stat
= GdipCreateTextureIA(image
, imageattr
, x
, y
, width
, height
, texture
);
844 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
846 TRACE("(%p, %p)\n", brush
, type
);
848 if(!brush
|| !type
) return InvalidParameter
;
855 GpStatus WINGDIPAPI
GdipGetHatchBackgroundColor(GpHatch
*brush
, ARGB
*backcol
)
857 TRACE("(%p, %p)\n", brush
, backcol
);
859 if(!brush
|| !backcol
) return InvalidParameter
;
861 *backcol
= brush
->backcol
;
866 GpStatus WINGDIPAPI
GdipGetHatchForegroundColor(GpHatch
*brush
, ARGB
*forecol
)
868 TRACE("(%p, %p)\n", brush
, forecol
);
870 if(!brush
|| !forecol
) return InvalidParameter
;
872 *forecol
= brush
->forecol
;
877 GpStatus WINGDIPAPI
GdipGetHatchStyle(GpHatch
*brush
, HatchStyle
*hatchstyle
)
879 TRACE("(%p, %p)\n", brush
, hatchstyle
);
881 if(!brush
|| !hatchstyle
) return InvalidParameter
;
883 *hatchstyle
= brush
->hatchstyle
;
888 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
890 TRACE("(%p)\n", brush
);
892 if(!brush
) return InvalidParameter
;
896 case BrushTypePathGradient
:
897 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
898 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
899 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
900 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
902 case BrushTypeSolidColor
:
903 if (((GpSolidFill
*)brush
)->bmp
)
904 DeleteObject(((GpSolidFill
*)brush
)->bmp
);
906 case BrushTypeLinearGradient
:
907 GdipFree(((GpLineGradient
*)brush
)->blendfac
);
908 GdipFree(((GpLineGradient
*)brush
)->blendpos
);
909 GdipFree(((GpLineGradient
*)brush
)->pblendcolor
);
910 GdipFree(((GpLineGradient
*)brush
)->pblendpos
);
912 case BrushTypeTextureFill
:
913 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
914 GdipDisposeImage(((GpTexture
*)brush
)->image
);
915 GdipDisposeImageAttributes(((GpTexture
*)brush
)->imageattributes
);
916 GdipFree(((GpTexture
*)brush
)->bitmap_bits
);
927 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
930 TRACE("(%p, %p)\n", line
, usinggamma
);
932 if(!line
|| !usinggamma
)
933 return InvalidParameter
;
935 *usinggamma
= line
->gamma
;
940 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
942 TRACE("(%p, %p)\n", brush
, wrapmode
);
944 if(!brush
|| !wrapmode
)
945 return InvalidParameter
;
947 *wrapmode
= brush
->wrap
;
952 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
953 REAL
*positions
, INT count
)
955 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
957 if(!brush
|| !blend
|| !positions
|| count
<= 0)
958 return InvalidParameter
;
960 if(count
< brush
->blendcount
)
961 return InsufficientBuffer
;
963 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
964 if(brush
->blendcount
> 1){
965 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
971 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
973 TRACE("(%p, %p)\n", brush
, count
);
976 return InvalidParameter
;
978 *count
= brush
->blendcount
;
983 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
986 TRACE("(%p, %p)\n", grad
, point
);
989 return InvalidParameter
;
991 point
->X
= grad
->center
.X
;
992 point
->Y
= grad
->center
.Y
;
997 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
1003 TRACE("(%p, %p)\n", grad
, point
);
1006 return InvalidParameter
;
1008 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
1011 point
->X
= roundr(ptf
.X
);
1012 point
->Y
= roundr(ptf
.Y
);
1018 GpStatus WINGDIPAPI
GdipGetPathGradientCenterColor(GpPathGradient
*grad
,
1023 TRACE("(%p,%p)\n", grad
, colors
);
1026 FIXME("not implemented\n");
1028 return NotImplemented
;
1031 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
1034 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
1036 if(!grad
|| !x
|| !y
)
1037 return InvalidParameter
;
1045 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
1048 TRACE("(%p, %p)\n", grad
, gamma
);
1051 return InvalidParameter
;
1053 *gamma
= grad
->gamma
;
1058 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
1061 TRACE("(%p, %p)\n", grad
, count
);
1064 return InvalidParameter
;
1066 *count
= grad
->pathdata
.Count
;
1071 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
1077 TRACE("(%p, %p)\n", brush
, rect
);
1080 return InvalidParameter
;
1082 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
1083 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
1084 if(stat
!= Ok
) return stat
;
1086 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
1088 GdipDeletePath(path
);
1092 memcpy(rect
, &r
, sizeof(GpRectF
));
1094 GdipDeletePath(path
);
1099 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
1104 TRACE("(%p, %p)\n", brush
, rect
);
1107 return InvalidParameter
;
1109 stat
= GdipGetPathGradientRect(brush
, &rectf
);
1110 if(stat
!= Ok
) return stat
;
1112 rect
->X
= roundr(rectf
.X
);
1113 rect
->Y
= roundr(rectf
.Y
);
1114 rect
->Width
= roundr(rectf
.Width
);
1115 rect
->Height
= roundr(rectf
.Height
);
1120 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
1121 *grad
, ARGB
*argb
, INT
*count
)
1125 TRACE("(%p,%p,%p)\n", grad
, argb
, count
);
1127 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
1128 return InvalidParameter
;
1131 FIXME("not implemented\n");
1133 return NotImplemented
;
1136 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorCount(GpPathGradient
*brush
, INT
*count
)
1140 TRACE("(%p, %p)\n", brush
, count
);
1142 if (!brush
|| !count
)
1143 return InvalidParameter
;
1146 FIXME("not implemented\n");
1148 return NotImplemented
;
1151 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
1152 GpWrapMode
*wrapmode
)
1154 TRACE("(%p, %p)\n", brush
, wrapmode
);
1156 if(!brush
|| !wrapmode
)
1157 return InvalidParameter
;
1159 *wrapmode
= brush
->wrap
;
1164 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
1166 TRACE("(%p, %p)\n", sf
, argb
);
1169 return InvalidParameter
;
1176 /******************************************************************************
1177 * GdipGetTextureImage [GDIPLUS.@]
1179 GpStatus WINGDIPAPI
GdipGetTextureImage(GpTexture
*brush
, GpImage
**image
)
1181 TRACE("(%p, %p)\n", brush
, image
);
1183 if(!brush
|| !image
)
1184 return InvalidParameter
;
1186 return GdipCloneImage(brush
->image
, image
);
1189 /******************************************************************************
1190 * GdipGetTextureTransform [GDIPLUS.@]
1192 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
1194 TRACE("(%p, %p)\n", brush
, matrix
);
1196 if(!brush
|| !matrix
)
1197 return InvalidParameter
;
1199 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
1204 /******************************************************************************
1205 * GdipGetTextureWrapMode [GDIPLUS.@]
1207 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
1209 TRACE("(%p, %p)\n", brush
, wrapmode
);
1211 if(!brush
|| !wrapmode
)
1212 return InvalidParameter
;
1214 *wrapmode
= brush
->imageattributes
->wrap
;
1219 /******************************************************************************
1220 * GdipMultiplyTextureTransform [GDIPLUS.@]
1222 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
1223 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1225 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
1227 if(!brush
|| !matrix
)
1228 return InvalidParameter
;
1230 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
1233 /******************************************************************************
1234 * GdipResetTextureTransform [GDIPLUS.@]
1236 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
1238 TRACE("(%p)\n", brush
);
1241 return InvalidParameter
;
1243 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1246 /******************************************************************************
1247 * GdipScaleTextureTransform [GDIPLUS.@]
1249 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
1250 REAL sx
, REAL sy
, GpMatrixOrder order
)
1252 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
1255 return InvalidParameter
;
1257 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
1260 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
1261 GDIPCONST REAL
*factors
, GDIPCONST REAL
* positions
, INT count
)
1263 REAL
*new_blendfac
, *new_blendpos
;
1265 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1267 if(!brush
|| !factors
|| !positions
|| count
<= 0 ||
1268 (count
>= 2 && (positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)))
1269 return InvalidParameter
;
1271 new_blendfac
= GdipAlloc(count
* sizeof(REAL
));
1272 new_blendpos
= GdipAlloc(count
* sizeof(REAL
));
1274 if (!new_blendfac
|| !new_blendpos
)
1276 GdipFree(new_blendfac
);
1277 GdipFree(new_blendpos
);
1281 memcpy(new_blendfac
, factors
, count
* sizeof(REAL
));
1282 memcpy(new_blendpos
, positions
, count
* sizeof(REAL
));
1284 GdipFree(brush
->blendfac
);
1285 GdipFree(brush
->blendpos
);
1287 brush
->blendcount
= count
;
1288 brush
->blendfac
= new_blendfac
;
1289 brush
->blendpos
= new_blendpos
;
1294 GpStatus WINGDIPAPI
GdipGetLineBlend(GpLineGradient
*brush
, REAL
*factors
,
1295 REAL
*positions
, INT count
)
1297 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1299 if (!brush
|| !factors
|| !positions
|| count
<= 0)
1300 return InvalidParameter
;
1302 if (count
< brush
->blendcount
)
1303 return InsufficientBuffer
;
1305 memcpy(factors
, brush
->blendfac
, brush
->blendcount
* sizeof(REAL
));
1306 memcpy(positions
, brush
->blendpos
, brush
->blendcount
* sizeof(REAL
));
1311 GpStatus WINGDIPAPI
GdipGetLineBlendCount(GpLineGradient
*brush
, INT
*count
)
1313 TRACE("(%p, %p)\n", brush
, count
);
1315 if (!brush
|| !count
)
1316 return InvalidParameter
;
1318 *count
= brush
->blendcount
;
1323 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
1326 TRACE("(%p, %d)\n", line
, usegamma
);
1329 return InvalidParameter
;
1331 line
->gamma
= usegamma
;
1336 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1343 const int precision
= 16;
1344 REAL erf_range
; /* we use values erf(-erf_range) through erf(+erf_range) */
1348 TRACE("(%p, %0.2f, %0.2f)\n", line
, focus
, scale
);
1350 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1351 return InvalidParameter
;
1353 /* we want 2 standard deviations */
1354 erf_range
= 2.0 / sqrt(2);
1356 /* calculate the constants we need to normalize the error function to be
1357 between 0.0 and scale over the range we need */
1358 min_erf
= erf(-erf_range
);
1359 scale_erf
= scale
/ (-2.0 * min_erf
);
1365 for (i
=1; i
<precision
; i
++)
1367 positions
[i
] = focus
* i
/ precision
;
1368 factors
[i
] = scale_erf
* (erf(2 * erf_range
* i
/ precision
- erf_range
) - min_erf
);
1370 num_points
+= precision
;
1373 positions
[num_points
] = focus
;
1374 factors
[num_points
] = scale
;
1379 for (i
=1; i
<precision
; i
++)
1381 positions
[i
+num_points
-1] = (focus
+ ((1.0-focus
) * i
/ precision
));
1382 factors
[i
+num_points
-1] = scale_erf
* (erf(erf_range
- 2 * erf_range
* i
/ precision
) - min_erf
);
1384 num_points
+= precision
;
1385 positions
[num_points
-1] = 1.0;
1386 factors
[num_points
-1] = 0.0;
1389 return GdipSetLineBlend(line
, factors
, positions
, num_points
);
1392 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1395 TRACE("(%p, %d)\n", line
, wrap
);
1397 if(!line
|| wrap
== WrapModeClamp
)
1398 return InvalidParameter
;
1405 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1406 GDIPCONST REAL
*pos
, INT count
)
1410 TRACE("(%p,%p,%p,%i)\n", brush
, blend
, pos
, count
);
1413 FIXME("not implemented\n");
1415 return NotImplemented
;
1418 GpStatus WINGDIPAPI
GdipSetPathGradientLinearBlend(GpPathGradient
*brush
,
1419 REAL focus
, REAL scale
)
1423 TRACE("(%p,%0.2f,%0.2f)\n", brush
, focus
, scale
);
1426 FIXME("not implemented\n");
1428 return NotImplemented
;
1431 GpStatus WINGDIPAPI
GdipSetPathGradientPresetBlend(GpPathGradient
*brush
,
1432 GDIPCONST ARGB
*blend
, GDIPCONST REAL
*pos
, INT count
)
1434 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1435 return NotImplemented
;
1438 GpStatus WINGDIPAPI
GdipGetPathGradientPresetBlend(GpPathGradient
*brush
,
1439 ARGB
*blend
, REAL
*pos
, INT count
)
1441 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1442 return NotImplemented
;
1445 GpStatus WINGDIPAPI
GdipGetPathGradientPresetBlendCount(GpPathGradient
*brush
,
1448 FIXME("(%p,%p): stub\n", brush
, count
);
1449 return NotImplemented
;
1452 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1455 TRACE("(%p, %x)\n", grad
, argb
);
1458 return InvalidParameter
;
1460 grad
->centercolor
= argb
;
1464 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1467 TRACE("(%p, %s)\n", grad
, debugstr_pointf(point
));
1470 return InvalidParameter
;
1472 grad
->center
.X
= point
->X
;
1473 grad
->center
.Y
= point
->Y
;
1478 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1483 TRACE("(%p, %p)\n", grad
, point
);
1486 return InvalidParameter
;
1488 ptf
.X
= (REAL
)point
->X
;
1489 ptf
.Y
= (REAL
)point
->Y
;
1491 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1494 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1497 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1500 return InvalidParameter
;
1508 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1511 TRACE("(%p, %d)\n", grad
, gamma
);
1514 return InvalidParameter
;
1516 grad
->gamma
= gamma
;
1521 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1522 REAL focus
, REAL scale
)
1526 TRACE("(%p,%0.2f,%0.2f)\n", grad
, focus
, scale
);
1528 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1529 return InvalidParameter
;
1532 FIXME("not implemented\n");
1534 return NotImplemented
;
1537 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1538 *grad
, GDIPCONST ARGB
*argb
, INT
*count
)
1542 TRACE("(%p,%p,%p)\n", grad
, argb
, count
);
1544 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1545 (*count
> grad
->pathdata
.Count
))
1546 return InvalidParameter
;
1549 FIXME("not implemented\n");
1551 return NotImplemented
;
1554 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1557 TRACE("(%p, %d)\n", grad
, wrap
);
1560 return InvalidParameter
;
1567 GpStatus WINGDIPAPI
GdipSetPathGradientTransform(GpPathGradient
*grad
,
1572 TRACE("(%p,%p)\n", grad
, matrix
);
1575 FIXME("not implemented\n");
1577 return NotImplemented
;
1580 GpStatus WINGDIPAPI
GdipGetPathGradientTransform(GpPathGradient
*grad
,
1585 TRACE("(%p,%p)\n", grad
, matrix
);
1588 FIXME("not implemented\n");
1590 return NotImplemented
;
1593 GpStatus WINGDIPAPI
GdipMultiplyPathGradientTransform(GpPathGradient
*grad
,
1594 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1598 TRACE("(%p,%p,%i)\n", grad
, matrix
, order
);
1601 FIXME("not implemented\n");
1603 return NotImplemented
;
1606 GpStatus WINGDIPAPI
GdipRotatePathGradientTransform(GpPathGradient
*grad
,
1607 REAL angle
, GpMatrixOrder order
)
1611 TRACE("(%p,%0.2f,%i)\n", grad
, angle
, order
);
1614 FIXME("not implemented\n");
1616 return NotImplemented
;
1619 GpStatus WINGDIPAPI
GdipScalePathGradientTransform(GpPathGradient
*grad
,
1620 REAL sx
, REAL sy
, GpMatrixOrder order
)
1624 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad
, sx
, sy
, order
);
1627 FIXME("not implemented\n");
1629 return NotImplemented
;
1632 GpStatus WINGDIPAPI
GdipTranslatePathGradientTransform(GpPathGradient
*grad
,
1633 REAL dx
, REAL dy
, GpMatrixOrder order
)
1637 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad
, dx
, dy
, order
);
1640 FIXME("not implemented\n");
1642 return NotImplemented
;
1645 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1647 TRACE("(%p, %x)\n", sf
, argb
);
1650 return InvalidParameter
;
1656 /******************************************************************************
1657 * GdipSetTextureTransform [GDIPLUS.@]
1659 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1660 GDIPCONST GpMatrix
*matrix
)
1662 TRACE("(%p, %p)\n", texture
, matrix
);
1664 if(!texture
|| !matrix
)
1665 return InvalidParameter
;
1667 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1672 /******************************************************************************
1673 * GdipSetTextureWrapMode [GDIPLUS.@]
1675 * WrapMode not used, only stored
1677 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1679 TRACE("(%p, %d)\n", brush
, wrapmode
);
1682 return InvalidParameter
;
1684 brush
->imageattributes
->wrap
= wrapmode
;
1689 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1692 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1695 return InvalidParameter
;
1697 brush
->startcolor
= color1
;
1698 brush
->endcolor
= color2
;
1703 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1705 TRACE("(%p, %p)\n", brush
, colors
);
1707 if(!brush
|| !colors
)
1708 return InvalidParameter
;
1710 colors
[0] = brush
->startcolor
;
1711 colors
[1] = brush
->endcolor
;
1716 /******************************************************************************
1717 * GdipRotateTextureTransform [GDIPLUS.@]
1719 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1720 GpMatrixOrder order
)
1722 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1725 return InvalidParameter
;
1727 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1730 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1737 TRACE("(%p,%.2f,%.2f)\n", brush
, focus
, scale
);
1739 if (!brush
) return InvalidParameter
;
1743 factors
[num_points
] = 0.0;
1744 positions
[num_points
] = 0.0;
1748 factors
[num_points
] = scale
;
1749 positions
[num_points
] = focus
;
1754 factors
[num_points
] = 0.0;
1755 positions
[num_points
] = 1.0;
1759 return GdipSetLineBlend(brush
, factors
, positions
, num_points
);
1762 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1763 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1767 TRACE("(%p,%p,%p,%i)\n", brush
, blend
, positions
, count
);
1769 if (!brush
|| !blend
|| !positions
|| count
< 2 ||
1770 positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)
1772 return InvalidParameter
;
1775 new_color
= GdipAlloc(count
* sizeof(ARGB
));
1776 new_pos
= GdipAlloc(count
* sizeof(REAL
));
1777 if (!new_color
|| !new_pos
)
1779 GdipFree(new_color
);
1784 memcpy(new_color
, blend
, sizeof(ARGB
) * count
);
1785 memcpy(new_pos
, positions
, sizeof(REAL
) * count
);
1787 GdipFree(brush
->pblendcolor
);
1788 GdipFree(brush
->pblendpos
);
1790 brush
->pblendcolor
= new_color
;
1791 brush
->pblendpos
= new_pos
;
1792 brush
->pblendcount
= count
;
1797 GpStatus WINGDIPAPI
GdipGetLinePresetBlend(GpLineGradient
*brush
,
1798 ARGB
*blend
, REAL
* positions
, INT count
)
1800 if (!brush
|| !blend
|| !positions
|| count
< 2)
1801 return InvalidParameter
;
1803 if (brush
->pblendcount
== 0)
1804 return GenericError
;
1806 if (count
< brush
->pblendcount
)
1807 return InsufficientBuffer
;
1809 memcpy(blend
, brush
->pblendcolor
, sizeof(ARGB
) * brush
->pblendcount
);
1810 memcpy(positions
, brush
->pblendpos
, sizeof(REAL
) * brush
->pblendcount
);
1815 GpStatus WINGDIPAPI
GdipGetLinePresetBlendCount(GpLineGradient
*brush
,
1818 if (!brush
|| !count
)
1819 return InvalidParameter
;
1821 *count
= brush
->pblendcount
;
1826 GpStatus WINGDIPAPI
GdipResetLineTransform(GpLineGradient
*brush
)
1830 TRACE("(%p)\n", brush
);
1833 FIXME("not implemented\n");
1835 return NotImplemented
;
1838 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1839 GDIPCONST GpMatrix
*matrix
)
1843 TRACE("(%p,%p)\n", brush
, matrix
);
1846 FIXME("not implemented\n");
1848 return NotImplemented
;
1851 GpStatus WINGDIPAPI
GdipGetLineTransform(GpLineGradient
*brush
, GpMatrix
*matrix
)
1855 TRACE("(%p,%p)\n", brush
, matrix
);
1858 FIXME("not implemented\n");
1860 return NotImplemented
;
1863 GpStatus WINGDIPAPI
GdipScaleLineTransform(GpLineGradient
*brush
, REAL sx
, REAL sy
,
1864 GpMatrixOrder order
)
1868 TRACE("(%p,%0.2f,%0.2f,%u)\n", brush
, sx
, sy
, order
);
1871 FIXME("not implemented\n");
1873 return NotImplemented
;
1876 GpStatus WINGDIPAPI
GdipMultiplyLineTransform(GpLineGradient
*brush
,
1877 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1881 TRACE("(%p,%p,%u)\n", brush
, matrix
, order
);
1884 FIXME("not implemented\n");
1886 return NotImplemented
;
1889 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1890 REAL dx
, REAL dy
, GpMatrixOrder order
)
1894 TRACE("(%p,%f,%f,%d)\n", brush
, dx
, dy
, order
);
1897 FIXME("not implemented\n");
1902 /******************************************************************************
1903 * GdipTranslateTextureTransform [GDIPLUS.@]
1905 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1906 GpMatrixOrder order
)
1908 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1911 return InvalidParameter
;
1913 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1916 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1918 TRACE("(%p, %p)\n", brush
, rect
);
1921 return InvalidParameter
;
1923 *rect
= brush
->rect
;
1928 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1933 TRACE("(%p, %p)\n", brush
, rect
);
1936 return InvalidParameter
;
1938 ret
= GdipGetLineRect(brush
, &rectF
);
1941 rect
->X
= roundr(rectF
.X
);
1942 rect
->Y
= roundr(rectF
.Y
);
1943 rect
->Width
= roundr(rectF
.Width
);
1944 rect
->Height
= roundr(rectF
.Height
);
1950 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1951 REAL angle
, GpMatrixOrder order
)
1955 TRACE("(%p,%0.2f,%u)\n", brush
, angle
, order
);
1958 return InvalidParameter
;
1961 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1963 return NotImplemented
;