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 GpStatus WINGDIPAPI
GdipCloneBrush(GpBrush
*brush
, GpBrush
**clone
)
39 TRACE("(%p, %p)\n", brush
, clone
);
42 return InvalidParameter
;
45 case BrushTypeSolidColor
:
46 *clone
= GdipAlloc(sizeof(GpSolidFill
));
47 if (!*clone
) return OutOfMemory
;
49 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
51 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
53 case BrushTypePathGradient
:{
54 GpPathGradient
*src
, *dest
;
57 *clone
= GdipAlloc(sizeof(GpPathGradient
));
58 if (!*clone
) return OutOfMemory
;
60 src
= (GpPathGradient
*) brush
,
61 dest
= (GpPathGradient
*) *clone
;
62 count
= src
->pathdata
.Count
;
64 memcpy(dest
, src
, sizeof(GpPathGradient
));
66 dest
->pathdata
.Count
= count
;
67 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
68 dest
->pathdata
.Types
= GdipAlloc(count
);
70 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
71 GdipFree(dest
->pathdata
.Points
);
72 GdipFree(dest
->pathdata
.Types
);
77 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
78 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
81 count
= src
->blendcount
;
82 dest
->blendcount
= count
;
83 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
84 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
86 if(!dest
->blendfac
|| !dest
->blendpos
){
87 GdipFree(dest
->pathdata
.Points
);
88 GdipFree(dest
->pathdata
.Types
);
89 GdipFree(dest
->blendfac
);
90 GdipFree(dest
->blendpos
);
95 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
96 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
100 case BrushTypeLinearGradient
:
101 *clone
= GdipAlloc(sizeof(GpLineGradient
));
102 if(!*clone
) return OutOfMemory
;
104 memcpy(*clone
, brush
, sizeof(GpLineGradient
));
106 (*clone
)->gdibrush
= CreateSolidBrush((*clone
)->lb
.lbColor
);
108 case BrushTypeTextureFill
:
109 *clone
= GdipAlloc(sizeof(GpTexture
));
110 if(!*clone
) return OutOfMemory
;
112 memcpy(*clone
, brush
, sizeof(GpTexture
));
114 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
117 ERR("not implemented for brush type %d\n", brush
->bt
);
118 return NotImplemented
;
124 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
125 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
126 GpWrapMode wrap
, GpLineGradient
**line
)
128 COLORREF col
= ARGB2COLORREF(startcolor
);
130 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
131 startcolor
, endcolor
, wrap
, line
);
133 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
134 return InvalidParameter
;
136 *line
= GdipAlloc(sizeof(GpLineGradient
));
137 if(!*line
) return OutOfMemory
;
139 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
140 (*line
)->brush
.lb
.lbColor
= col
;
141 (*line
)->brush
.lb
.lbHatch
= 0;
142 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
143 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
145 (*line
)->startpoint
.X
= startpoint
->X
;
146 (*line
)->startpoint
.Y
= startpoint
->Y
;
147 (*line
)->endpoint
.X
= endpoint
->X
;
148 (*line
)->endpoint
.Y
= endpoint
->Y
;
149 (*line
)->startcolor
= startcolor
;
150 (*line
)->endcolor
= endcolor
;
151 (*line
)->wrap
= wrap
;
152 (*line
)->gamma
= FALSE
;
157 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
158 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
159 GpWrapMode wrap
, GpLineGradient
**line
)
164 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
165 startcolor
, endcolor
, wrap
, line
);
167 if(!startpoint
|| !endpoint
)
168 return InvalidParameter
;
170 stF
.X
= (REAL
)startpoint
->X
;
171 stF
.Y
= (REAL
)startpoint
->Y
;
172 endF
.X
= (REAL
)endpoint
->X
;
173 endF
.X
= (REAL
)endpoint
->Y
;
175 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
178 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
179 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
180 GpLineGradient
**line
)
184 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
188 return InvalidParameter
;
192 end
.X
= rect
->X
+ rect
->Width
;
193 end
.Y
= rect
->Y
+ rect
->Height
;
195 return GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
198 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
199 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
200 GpLineGradient
**line
)
204 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
207 rectF
.X
= (REAL
) rect
->X
;
208 rectF
.Y
= (REAL
) rect
->Y
;
209 rectF
.Width
= (REAL
) rect
->Width
;
210 rectF
.Height
= (REAL
) rect
->Height
;
212 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
215 /* FIXME: angle value completely ignored. Don't know how to use it since native
216 always set Brush rectangle to rect (independetly of this angle).
217 Maybe it's used only on drawing. */
218 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
219 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
220 GpLineGradient
**line
)
222 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
225 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
229 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
230 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
231 GpLineGradient
**line
)
233 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
236 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
240 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
241 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
243 COLORREF col
= ARGB2COLORREF(0xffffffff);
245 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
248 return InvalidParameter
;
253 *grad
= GdipAlloc(sizeof(GpPathGradient
));
254 if (!*grad
) return OutOfMemory
;
256 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
257 if(!(*grad
)->blendfac
){
261 (*grad
)->blendfac
[0] = 1.0;
262 (*grad
)->blendpos
= NULL
;
263 (*grad
)->blendcount
= 1;
265 (*grad
)->pathdata
.Count
= count
;
266 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
267 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
269 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
270 GdipFree((*grad
)->pathdata
.Points
);
271 GdipFree((*grad
)->pathdata
.Types
);
276 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
277 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
279 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
280 (*grad
)->brush
.lb
.lbColor
= col
;
281 (*grad
)->brush
.lb
.lbHatch
= 0;
283 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
284 (*grad
)->brush
.bt
= BrushTypePathGradient
;
285 (*grad
)->centercolor
= 0xffffffff;
286 (*grad
)->wrap
= wrap
;
287 (*grad
)->gamma
= FALSE
;
288 (*grad
)->center
.X
= 0.0;
289 (*grad
)->center
.Y
= 0.0;
290 (*grad
)->focus
.X
= 0.0;
291 (*grad
)->focus
.Y
= 0.0;
296 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
297 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
303 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
306 return InvalidParameter
;
311 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
315 for(i
= 0; i
< count
; i
++){
316 pointsF
[i
].X
= (REAL
)points
[i
].X
;
317 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
320 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
326 /* FIXME: path gradient brushes not truly supported (drawn as solid brushes) */
327 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
328 GpPathGradient
**grad
)
330 COLORREF col
= ARGB2COLORREF(0xffffffff);
332 TRACE("(%p, %p)\n", path
, grad
);
335 return InvalidParameter
;
337 *grad
= GdipAlloc(sizeof(GpPathGradient
));
338 if (!*grad
) return OutOfMemory
;
340 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
341 if(!(*grad
)->blendfac
){
345 (*grad
)->blendfac
[0] = 1.0;
346 (*grad
)->blendpos
= NULL
;
347 (*grad
)->blendcount
= 1;
349 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
350 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
351 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
353 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
354 GdipFree((*grad
)->pathdata
.Points
);
355 GdipFree((*grad
)->pathdata
.Types
);
360 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
361 path
->pathdata
.Count
* sizeof(PointF
));
362 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
364 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
365 (*grad
)->brush
.lb
.lbColor
= col
;
366 (*grad
)->brush
.lb
.lbHatch
= 0;
368 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
369 (*grad
)->brush
.bt
= BrushTypePathGradient
;
370 (*grad
)->centercolor
= 0xffffffff;
371 (*grad
)->wrap
= WrapModeClamp
;
372 (*grad
)->gamma
= FALSE
;
373 /* FIXME: this should be set to the "centroid" of the path by default */
374 (*grad
)->center
.X
= 0.0;
375 (*grad
)->center
.Y
= 0.0;
376 (*grad
)->focus
.X
= 0.0;
377 (*grad
)->focus
.Y
= 0.0;
382 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
384 COLORREF col
= ARGB2COLORREF(color
);
386 TRACE("(%x, %p)\n", color
, sf
);
388 if(!sf
) return InvalidParameter
;
390 *sf
= GdipAlloc(sizeof(GpSolidFill
));
391 if (!*sf
) return OutOfMemory
;
393 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
394 (*sf
)->brush
.lb
.lbColor
= col
;
395 (*sf
)->brush
.lb
.lbHatch
= 0;
397 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
398 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
399 (*sf
)->color
= color
;
404 /*******************************************************************************
405 * GdipCreateTexture [GDIPLUS.@]
408 * image [I] image to use
409 * wrapmode [I] optional
410 * texture [O] pointer to the resulting texturebrush
414 * FAILURE: element of GpStatus
416 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
420 GpImageAttributes attributes
;
423 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
425 if (!(image
&& texture
))
426 return InvalidParameter
;
428 stat
= GdipGetImageWidth(image
, &width
);
429 if (stat
!= Ok
) return stat
;
430 stat
= GdipGetImageHeight(image
, &height
);
431 if (stat
!= Ok
) return stat
;
432 attributes
.wrap
= wrapmode
;
434 return GdipCreateTextureIA(image
, &attributes
, 0, 0, width
, height
,
438 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
439 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
441 GpImageAttributes attributes
;
443 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
444 x
, y
, width
, height
, texture
);
446 attributes
.wrap
= wrapmode
;
447 return GdipCreateTextureIA(image
, &attributes
, x
, y
, width
, height
,
451 /* FIXME: imageattr ignored */
452 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
453 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
454 REAL height
, GpTexture
**texture
)
460 BITMAPINFOHEADER
*bmih
;
461 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
463 BYTE
*dibits
, *buff
, *textbits
;
465 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
468 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
469 return InvalidParameter
;
471 if(image
->type
!= ImageTypeBitmap
){
472 FIXME("not implemented for image type %d\n", image
->type
);
473 return NotImplemented
;
478 n_width
= roundr(width
);
479 n_height
= roundr(height
);
481 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
482 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
483 return InvalidParameter
;
485 IPicture_get_Handle(image
->picture
, &hbm
);
486 if(!hbm
) return GenericError
;
487 IPicture_get_CurDC(image
->picture
, &hdc
);
488 bm_is_selected
= (hdc
!= 0);
490 bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
491 bmi
.bmiHeader
.biBitCount
= 0;
494 hdc
= CreateCompatibleDC(0);
495 old
= SelectObject(hdc
, (HBITMAP
)hbm
);
499 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, 0, NULL
, &bmi
, DIB_RGB_COLORS
);
501 bytespp
= bmi
.bmiHeader
.biBitCount
/ 8;
502 abs_height
= abs(bmi
.bmiHeader
.biHeight
);
504 if(n_x
> bmi
.bmiHeader
.biWidth
|| n_x
+ n_width
> bmi
.bmiHeader
.biWidth
||
505 n_y
> abs_height
|| n_y
+ n_height
> abs_height
)
506 return InvalidParameter
;
508 dibits
= GdipAlloc(bmi
.bmiHeader
.biSizeImage
);
510 if(dibits
) /* this is not a good place to error out */
511 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, abs_height
, dibits
, &bmi
, DIB_RGB_COLORS
);
514 SelectObject(hdc
, old
);
521 image_stride
= (bmi
.bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
522 stride
= (n_width
* bytespp
+ 3) & ~3;
523 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
529 bmih
= (BITMAPINFOHEADER
*)buff
;
530 textbits
= (BYTE
*) (bmih
+ 1);
531 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
532 bmih
->biWidth
= n_width
;
533 bmih
->biHeight
= n_height
;
534 bmih
->biCompression
= BI_RGB
;
535 bmih
->biSizeImage
= stride
* n_height
;
536 bmih
->biBitCount
= bmi
.bmiHeader
.biBitCount
;
540 /* image is flipped */
541 if(bmi
.bmiHeader
.biHeight
> 0){
542 dibits
+= bmi
.bmiHeader
.biSizeImage
;
544 textbits
+= stride
* (n_height
- 1);
548 for(i
= 0; i
< n_height
; i
++)
549 memcpy(&textbits
[i
* stride
],
550 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
553 *texture
= GdipAlloc(sizeof(GpTexture
));
554 if (!*texture
) return OutOfMemory
;
556 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
557 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
558 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
560 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
561 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
569 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
570 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
572 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
575 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
578 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
579 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
581 GpImageAttributes imageattr
;
583 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
586 imageattr
.wrap
= wrapmode
;
588 return GdipCreateTextureIA(image
, &imageattr
, x
, y
, width
, height
, texture
);
591 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
593 TRACE("(%p, %p)\n", brush
, type
);
595 if(!brush
|| !type
) return InvalidParameter
;
602 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
604 TRACE("(%p)\n", brush
);
606 if(!brush
) return InvalidParameter
;
610 case BrushTypePathGradient
:
611 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
612 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
613 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
614 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
616 case BrushTypeSolidColor
:
617 case BrushTypeLinearGradient
:
618 case BrushTypeTextureFill
:
623 DeleteObject(brush
->gdibrush
);
629 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
632 TRACE("(%p, %p)\n", line
, usinggamma
);
634 if(!line
|| !usinggamma
)
635 return InvalidParameter
;
637 *usinggamma
= line
->gamma
;
642 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
644 TRACE("(%p, %p)\n", brush
, wrapmode
);
646 if(!brush
|| !wrapmode
)
647 return InvalidParameter
;
649 *wrapmode
= brush
->wrap
;
654 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
655 REAL
*positions
, INT count
)
657 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
659 if(!brush
|| !blend
|| !positions
|| count
<= 0)
660 return InvalidParameter
;
662 if(count
< brush
->blendcount
)
663 return InsufficientBuffer
;
665 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
666 if(brush
->blendcount
> 1){
667 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
673 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
675 TRACE("(%p, %p)\n", brush
, count
);
678 return InvalidParameter
;
680 *count
= brush
->blendcount
;
685 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
688 TRACE("(%p, %p)\n", grad
, point
);
691 return InvalidParameter
;
693 point
->X
= grad
->center
.X
;
694 point
->Y
= grad
->center
.Y
;
699 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
705 TRACE("(%p, %p)\n", grad
, point
);
708 return InvalidParameter
;
710 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
713 point
->X
= roundr(ptf
.X
);
714 point
->Y
= roundr(ptf
.Y
);
720 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
723 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
725 if(!grad
|| !x
|| !y
)
726 return InvalidParameter
;
734 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
737 TRACE("(%p, %p)\n", grad
, gamma
);
740 return InvalidParameter
;
742 *gamma
= grad
->gamma
;
747 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
750 TRACE("(%p, %p)\n", grad
, count
);
753 return InvalidParameter
;
755 *count
= grad
->pathdata
.Count
;
760 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
766 TRACE("(%p, %p)\n", brush
, rect
);
769 return InvalidParameter
;
771 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
772 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
773 if(stat
!= Ok
) return stat
;
775 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
777 GdipDeletePath(path
);
781 memcpy(rect
, &r
, sizeof(GpRectF
));
783 GdipDeletePath(path
);
788 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
793 TRACE("(%p, %p)\n", brush
, rect
);
796 return InvalidParameter
;
798 stat
= GdipGetPathGradientRect(brush
, &rectf
);
799 if(stat
!= Ok
) return stat
;
801 rect
->X
= roundr(rectf
.X
);
802 rect
->Y
= roundr(rectf
.Y
);
803 rect
->Width
= roundr(rectf
.Width
);
804 rect
->Height
= roundr(rectf
.Height
);
809 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
810 *grad
, ARGB
*argb
, INT
*count
)
814 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
815 return InvalidParameter
;
818 FIXME("not implemented\n");
820 return NotImplemented
;
823 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
824 GpWrapMode
*wrapmode
)
826 TRACE("(%p, %p)\n", brush
, wrapmode
);
828 if(!brush
|| !wrapmode
)
829 return InvalidParameter
;
831 *wrapmode
= brush
->wrap
;
836 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
838 TRACE("(%p, %p)\n", sf
, argb
);
841 return InvalidParameter
;
848 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
849 GDIPCONST REAL
*blend
, GDIPCONST REAL
* positions
, INT count
)
853 if(!brush
|| !blend
|| !positions
|| count
<= 0)
854 return InvalidParameter
;
857 FIXME("not implemented\n");
862 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
865 TRACE("(%p, %d)\n", line
, usegamma
);
868 return InvalidParameter
;
870 line
->gamma
= usegamma
;
875 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
880 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
881 return InvalidParameter
;
884 FIXME("not implemented\n");
886 return NotImplemented
;
889 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
892 TRACE("(%p, %d)\n", line
, wrap
);
894 if(!line
|| wrap
== WrapModeClamp
)
895 return InvalidParameter
;
902 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
905 TRACE("(%p, %x)\n", grad
, argb
);
908 return InvalidParameter
;
910 grad
->centercolor
= argb
;
911 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
913 DeleteObject(grad
->brush
.gdibrush
);
914 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
919 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
922 TRACE("(%p, %p)\n", grad
, point
);
925 return InvalidParameter
;
927 grad
->center
.X
= point
->X
;
928 grad
->center
.Y
= point
->Y
;
933 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
938 TRACE("(%p, %p)\n", grad
, point
);
941 return InvalidParameter
;
943 ptf
.X
= (REAL
)point
->X
;
944 ptf
.Y
= (REAL
)point
->Y
;
946 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
949 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
952 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
955 return InvalidParameter
;
963 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
966 TRACE("(%p, %d)\n", grad
, gamma
);
969 return InvalidParameter
;
976 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
977 REAL focus
, REAL scale
)
981 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
982 return InvalidParameter
;
985 FIXME("not implemented\n");
987 return NotImplemented
;
990 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
991 *grad
, ARGB
*argb
, INT
*count
)
995 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
996 (*count
> grad
->pathdata
.Count
))
997 return InvalidParameter
;
1000 FIXME("not implemented\n");
1002 return NotImplemented
;
1005 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1008 TRACE("(%p, %d)\n", grad
, wrap
);
1011 return InvalidParameter
;
1018 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1020 TRACE("(%p, %x)\n", sf
, argb
);
1023 return InvalidParameter
;
1026 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1028 DeleteObject(sf
->brush
.gdibrush
);
1029 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
1034 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1035 GDIPCONST GpMatrix
*matrix
)
1039 if(!texture
|| !matrix
)
1040 return InvalidParameter
;
1043 FIXME("not implemented\n");
1048 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1051 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1054 return InvalidParameter
;
1056 brush
->startcolor
= color1
;
1057 brush
->endcolor
= color2
;
1062 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1064 TRACE("(%p, %p)\n", brush
, colors
);
1066 if(!brush
|| !colors
)
1067 return InvalidParameter
;
1069 colors
[0] = brush
->startcolor
;
1070 colors
[1] = brush
->endcolor
;
1075 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1081 FIXME("not implemented\n");
1083 return NotImplemented
;
1086 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1087 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1092 FIXME("not implemented\n");
1094 return NotImplemented
;
1097 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1098 GDIPCONST GpMatrix
*matrix
)
1103 FIXME("not implemented\n");
1105 return NotImplemented
;
1108 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1109 REAL dx
, REAL dy
, GpMatrixOrder order
)
1111 FIXME("stub: %p %f %f %d\n", brush
, dx
, dy
, order
);
1113 return NotImplemented
;
1116 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1118 TRACE("(%p, %p)\n", brush
, rect
);
1121 return InvalidParameter
;
1123 rect
->X
= (brush
->startpoint
.X
< brush
->endpoint
.X
? brush
->startpoint
.X
: brush
->endpoint
.X
);
1124 rect
->Y
= (brush
->startpoint
.Y
< brush
->endpoint
.Y
? brush
->startpoint
.Y
: brush
->endpoint
.Y
);
1126 rect
->Width
= fabs(brush
->startpoint
.X
- brush
->endpoint
.X
);
1127 rect
->Height
= fabs(brush
->startpoint
.Y
- brush
->endpoint
.Y
);
1132 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1137 TRACE("(%p, %p)\n", brush
, rect
);
1140 return InvalidParameter
;
1142 ret
= GdipGetLineRect(brush
, &rectF
);
1145 rect
->X
= roundr(rectF
.X
);
1146 rect
->Y
= roundr(rectF
.Y
);
1147 rect
->Width
= roundr(rectF
.Width
);
1148 rect
->Height
= roundr(rectF
.Height
);