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
)
40 return InvalidParameter
;
43 case BrushTypeSolidColor
:
44 *clone
= GdipAlloc(sizeof(GpSolidFill
));
45 if (!*clone
) return OutOfMemory
;
47 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
49 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
51 case BrushTypePathGradient
:{
52 GpPathGradient
*src
, *dest
;
55 *clone
= GdipAlloc(sizeof(GpPathGradient
));
56 if (!*clone
) return OutOfMemory
;
58 src
= (GpPathGradient
*) brush
,
59 dest
= (GpPathGradient
*) *clone
;
60 count
= src
->pathdata
.Count
;
62 memcpy(dest
, src
, sizeof(GpPathGradient
));
64 dest
->pathdata
.Count
= count
;
65 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
66 dest
->pathdata
.Types
= GdipAlloc(count
);
68 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
69 GdipFree(dest
->pathdata
.Points
);
70 GdipFree(dest
->pathdata
.Types
);
75 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
76 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
79 count
= src
->blendcount
;
80 dest
->blendcount
= count
;
81 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
82 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
84 if(!dest
->blendfac
|| !dest
->blendpos
){
85 GdipFree(dest
->pathdata
.Points
);
86 GdipFree(dest
->pathdata
.Types
);
87 GdipFree(dest
->blendfac
);
88 GdipFree(dest
->blendpos
);
93 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
94 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
98 case BrushTypeLinearGradient
:
99 *clone
= GdipAlloc(sizeof(GpLineGradient
));
100 if(!*clone
) return OutOfMemory
;
102 memcpy(*clone
, brush
, sizeof(GpLineGradient
));
104 (*clone
)->gdibrush
= CreateSolidBrush((*clone
)->lb
.lbColor
);
106 case BrushTypeTextureFill
:
107 *clone
= GdipAlloc(sizeof(GpTexture
));
108 if(!*clone
) return OutOfMemory
;
110 memcpy(*clone
, brush
, sizeof(GpTexture
));
112 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
115 ERR("not implemented for brush type %d\n", brush
->bt
);
116 return NotImplemented
;
122 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
123 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
124 GpWrapMode wrap
, GpLineGradient
**line
)
126 COLORREF col
= ARGB2COLORREF(startcolor
);
128 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
129 return InvalidParameter
;
131 *line
= GdipAlloc(sizeof(GpLineGradient
));
132 if(!*line
) return OutOfMemory
;
134 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
135 (*line
)->brush
.lb
.lbColor
= col
;
136 (*line
)->brush
.lb
.lbHatch
= 0;
137 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
138 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
140 (*line
)->startpoint
.X
= startpoint
->X
;
141 (*line
)->startpoint
.Y
= startpoint
->Y
;
142 (*line
)->endpoint
.X
= endpoint
->X
;
143 (*line
)->endpoint
.Y
= endpoint
->Y
;
144 (*line
)->startcolor
= startcolor
;
145 (*line
)->endcolor
= endcolor
;
146 (*line
)->wrap
= wrap
;
147 (*line
)->gamma
= FALSE
;
152 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
153 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
154 GpWrapMode wrap
, GpLineGradient
**line
)
159 if(!startpoint
|| !endpoint
)
160 return InvalidParameter
;
162 stF
.X
= (REAL
)startpoint
->X
;
163 stF
.Y
= (REAL
)startpoint
->Y
;
164 endF
.X
= (REAL
)endpoint
->X
;
165 endF
.X
= (REAL
)endpoint
->Y
;
167 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
170 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
171 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
172 GpLineGradient
**line
)
177 return InvalidParameter
;
181 end
.X
= rect
->X
+ rect
->Width
;
182 end
.Y
= rect
->Y
+ rect
->Height
;
184 return GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
187 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
188 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
189 GpLineGradient
**line
)
193 rectF
.X
= (REAL
) rect
->X
;
194 rectF
.Y
= (REAL
) rect
->Y
;
195 rectF
.Width
= (REAL
) rect
->Width
;
196 rectF
.Height
= (REAL
) rect
->Height
;
198 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
201 /* FIXME: angle value completely ignored. Don't know how to use it since native
202 always set Brush rectangle to rect (independetly of this angle).
203 Maybe it's used only on drawing. */
204 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
205 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
206 GpLineGradient
**line
)
208 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
212 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
213 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
214 GpLineGradient
**line
)
216 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
220 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
221 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
223 COLORREF col
= ARGB2COLORREF(0xffffffff);
226 return InvalidParameter
;
231 *grad
= GdipAlloc(sizeof(GpPathGradient
));
232 if (!*grad
) return OutOfMemory
;
234 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
235 if(!(*grad
)->blendfac
){
239 (*grad
)->blendfac
[0] = 1.0;
240 (*grad
)->blendpos
= NULL
;
241 (*grad
)->blendcount
= 1;
243 (*grad
)->pathdata
.Count
= count
;
244 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
245 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
247 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
248 GdipFree((*grad
)->pathdata
.Points
);
249 GdipFree((*grad
)->pathdata
.Types
);
254 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
255 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
257 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
258 (*grad
)->brush
.lb
.lbColor
= col
;
259 (*grad
)->brush
.lb
.lbHatch
= 0;
261 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
262 (*grad
)->brush
.bt
= BrushTypePathGradient
;
263 (*grad
)->centercolor
= 0xffffffff;
264 (*grad
)->wrap
= wrap
;
265 (*grad
)->gamma
= FALSE
;
266 (*grad
)->center
.X
= 0.0;
267 (*grad
)->center
.Y
= 0.0;
268 (*grad
)->focus
.X
= 0.0;
269 (*grad
)->focus
.Y
= 0.0;
274 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
275 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
282 return InvalidParameter
;
287 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
291 for(i
= 0; i
< count
; i
++){
292 pointsF
[i
].X
= (REAL
)points
[i
].X
;
293 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
296 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
302 /* FIXME: path gradient brushes not truly supported (drawn as solid brushes) */
303 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
304 GpPathGradient
**grad
)
306 COLORREF col
= ARGB2COLORREF(0xffffffff);
309 return InvalidParameter
;
311 *grad
= GdipAlloc(sizeof(GpPathGradient
));
312 if (!*grad
) return OutOfMemory
;
314 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
315 if(!(*grad
)->blendfac
){
319 (*grad
)->blendfac
[0] = 1.0;
320 (*grad
)->blendpos
= NULL
;
321 (*grad
)->blendcount
= 1;
323 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
324 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
325 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
327 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
328 GdipFree((*grad
)->pathdata
.Points
);
329 GdipFree((*grad
)->pathdata
.Types
);
334 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
335 path
->pathdata
.Count
* sizeof(PointF
));
336 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
338 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
339 (*grad
)->brush
.lb
.lbColor
= col
;
340 (*grad
)->brush
.lb
.lbHatch
= 0;
342 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
343 (*grad
)->brush
.bt
= BrushTypePathGradient
;
344 (*grad
)->centercolor
= 0xffffffff;
345 (*grad
)->wrap
= WrapModeClamp
;
346 (*grad
)->gamma
= FALSE
;
347 /* FIXME: this should be set to the "centroid" of the path by default */
348 (*grad
)->center
.X
= 0.0;
349 (*grad
)->center
.Y
= 0.0;
350 (*grad
)->focus
.X
= 0.0;
351 (*grad
)->focus
.Y
= 0.0;
356 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
358 COLORREF col
= ARGB2COLORREF(color
);
360 if(!sf
) return InvalidParameter
;
362 *sf
= GdipAlloc(sizeof(GpSolidFill
));
363 if (!*sf
) return OutOfMemory
;
365 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
366 (*sf
)->brush
.lb
.lbColor
= col
;
367 (*sf
)->brush
.lb
.lbHatch
= 0;
369 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
370 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
371 (*sf
)->color
= color
;
376 /* FIXME: imageattr ignored */
377 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
378 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
379 REAL height
, GpTexture
**texture
)
385 BITMAPINFOHEADER
*bmih
;
386 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
388 BYTE
*dibits
, *buff
, *textbits
;
390 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
391 return InvalidParameter
;
393 if(image
->type
!= ImageTypeBitmap
){
394 FIXME("not implemented for image type %d\n", image
->type
);
395 return NotImplemented
;
400 n_width
= roundr(width
);
401 n_height
= roundr(height
);
403 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
404 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
405 return InvalidParameter
;
407 IPicture_get_Handle(image
->picture
, &hbm
);
408 if(!hbm
) return GenericError
;
409 IPicture_get_CurDC(image
->picture
, &hdc
);
410 bm_is_selected
= (hdc
!= 0);
412 bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
413 bmi
.bmiHeader
.biBitCount
= 0;
416 hdc
= CreateCompatibleDC(0);
417 old
= SelectObject(hdc
, (HBITMAP
)hbm
);
421 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, 0, NULL
, &bmi
, DIB_RGB_COLORS
);
423 bytespp
= bmi
.bmiHeader
.biBitCount
/ 8;
424 abs_height
= abs(bmi
.bmiHeader
.biHeight
);
426 if(n_x
> bmi
.bmiHeader
.biWidth
|| n_x
+ n_width
> bmi
.bmiHeader
.biWidth
||
427 n_y
> abs_height
|| n_y
+ n_height
> abs_height
)
428 return InvalidParameter
;
430 dibits
= GdipAlloc(bmi
.bmiHeader
.biSizeImage
);
432 if(dibits
) /* this is not a good place to error out */
433 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, abs_height
, dibits
, &bmi
, DIB_RGB_COLORS
);
436 SelectObject(hdc
, old
);
443 image_stride
= (bmi
.bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
444 stride
= (n_width
* bytespp
+ 3) & ~3;
445 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
451 bmih
= (BITMAPINFOHEADER
*)buff
;
452 textbits
= (BYTE
*) (bmih
+ 1);
453 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
454 bmih
->biWidth
= n_width
;
455 bmih
->biHeight
= n_height
;
456 bmih
->biCompression
= BI_RGB
;
457 bmih
->biSizeImage
= stride
* n_height
;
458 bmih
->biBitCount
= bmi
.bmiHeader
.biBitCount
;
462 /* image is flipped */
463 if(bmi
.bmiHeader
.biHeight
> 0){
464 dibits
+= bmi
.bmiHeader
.biSizeImage
;
466 textbits
+= stride
* (n_height
- 1);
470 for(i
= 0; i
< n_height
; i
++)
471 memcpy(&textbits
[i
* stride
],
472 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
475 *texture
= GdipAlloc(sizeof(GpTexture
));
476 if (!*texture
) return OutOfMemory
;
478 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
479 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
480 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
482 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
483 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
491 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
492 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
494 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
497 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
499 if(!brush
|| !type
) return InvalidParameter
;
506 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
508 if(!brush
) return InvalidParameter
;
512 case BrushTypePathGradient
:
513 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
514 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
515 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
516 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
518 case BrushTypeSolidColor
:
519 case BrushTypeLinearGradient
:
520 case BrushTypeTextureFill
:
525 DeleteObject(brush
->gdibrush
);
531 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
535 return InvalidParameter
;
537 *usinggamma
= line
->gamma
;
542 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
544 if(!brush
|| !wrapmode
)
545 return InvalidParameter
;
547 *wrapmode
= brush
->wrap
;
552 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
553 REAL
*positions
, INT count
)
555 if(!brush
|| !blend
|| !positions
|| count
<= 0)
556 return InvalidParameter
;
558 if(count
< brush
->blendcount
)
559 return InsufficientBuffer
;
561 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
562 if(brush
->blendcount
> 1){
563 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
569 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
572 return InvalidParameter
;
574 *count
= brush
->blendcount
;
579 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
583 return InvalidParameter
;
585 point
->X
= grad
->center
.X
;
586 point
->Y
= grad
->center
.Y
;
591 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
598 return InvalidParameter
;
600 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
603 point
->X
= roundr(ptf
.X
);
604 point
->Y
= roundr(ptf
.Y
);
610 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
613 if(!grad
|| !x
|| !y
)
614 return InvalidParameter
;
622 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
626 return InvalidParameter
;
628 *gamma
= grad
->gamma
;
633 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
637 return InvalidParameter
;
639 *count
= grad
->pathdata
.Count
;
644 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
651 return InvalidParameter
;
653 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
654 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
655 if(stat
!= Ok
) return stat
;
657 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
659 GdipDeletePath(path
);
663 memcpy(rect
, &r
, sizeof(GpRectF
));
665 GdipDeletePath(path
);
670 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
676 return InvalidParameter
;
678 stat
= GdipGetPathGradientRect(brush
, &rectf
);
679 if(stat
!= Ok
) return stat
;
681 rect
->X
= roundr(rectf
.X
);
682 rect
->Y
= roundr(rectf
.Y
);
683 rect
->Width
= roundr(rectf
.Width
);
684 rect
->Height
= roundr(rectf
.Height
);
689 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
690 *grad
, ARGB
*argb
, INT
*count
)
694 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
695 return InvalidParameter
;
698 FIXME("not implemented\n");
700 return NotImplemented
;
703 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
704 GpWrapMode
*wrapmode
)
706 if(!brush
|| !wrapmode
)
707 return InvalidParameter
;
709 *wrapmode
= brush
->wrap
;
714 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
717 return InvalidParameter
;
724 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
725 GDIPCONST REAL
*blend
, GDIPCONST REAL
* positions
, INT count
)
729 if(!brush
|| !blend
|| !positions
|| count
<= 0)
730 return InvalidParameter
;
733 FIXME("not implemented\n");
738 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
742 return InvalidParameter
;
744 line
->gamma
= usegamma
;
749 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
754 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
755 return InvalidParameter
;
758 FIXME("not implemented\n");
760 return NotImplemented
;
763 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
766 if(!line
|| wrap
== WrapModeClamp
)
767 return InvalidParameter
;
774 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
778 return InvalidParameter
;
780 grad
->centercolor
= argb
;
781 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
783 DeleteObject(grad
->brush
.gdibrush
);
784 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
789 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
793 return InvalidParameter
;
795 grad
->center
.X
= point
->X
;
796 grad
->center
.Y
= point
->Y
;
801 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
807 return InvalidParameter
;
809 ptf
.X
= (REAL
)point
->X
;
810 ptf
.Y
= (REAL
)point
->Y
;
812 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
815 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
819 return InvalidParameter
;
827 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
831 return InvalidParameter
;
838 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
839 REAL focus
, REAL scale
)
843 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
844 return InvalidParameter
;
847 FIXME("not implemented\n");
849 return NotImplemented
;
852 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
853 *grad
, ARGB
*argb
, INT
*count
)
857 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
858 (*count
> grad
->pathdata
.Count
))
859 return InvalidParameter
;
862 FIXME("not implemented\n");
864 return NotImplemented
;
867 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
871 return InvalidParameter
;
878 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
881 return InvalidParameter
;
884 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
886 DeleteObject(sf
->brush
.gdibrush
);
887 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
892 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
893 GDIPCONST GpMatrix
*matrix
)
897 if(!texture
|| !matrix
)
898 return InvalidParameter
;
901 FIXME("not implemented\n");
906 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
910 return InvalidParameter
;
912 brush
->startcolor
= color1
;
913 brush
->endcolor
= color2
;
918 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
920 if(!brush
|| !colors
)
921 return InvalidParameter
;
923 colors
[0] = brush
->startcolor
;
924 colors
[1] = brush
->endcolor
;
929 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
935 FIXME("not implemented\n");
937 return NotImplemented
;
940 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
941 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
946 FIXME("not implemented\n");
948 return NotImplemented
;
951 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
952 GDIPCONST GpMatrix
*matrix
)
957 FIXME("not implemented\n");
959 return NotImplemented
;
962 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
965 return InvalidParameter
;
967 rect
->X
= (brush
->startpoint
.X
< brush
->endpoint
.X
? brush
->startpoint
.X
: brush
->endpoint
.X
);
968 rect
->Y
= (brush
->startpoint
.Y
< brush
->endpoint
.Y
? brush
->startpoint
.Y
: brush
->endpoint
.Y
);
970 rect
->Width
= fabs(brush
->startpoint
.X
- brush
->endpoint
.X
);
971 rect
->Height
= fabs(brush
->startpoint
.Y
- brush
->endpoint
.Y
);
976 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
982 return InvalidParameter
;
984 ret
= GdipGetLineRect(brush
, &rectF
);
987 rect
->X
= roundr(rectF
.X
);
988 rect
->Y
= roundr(rectF
.Y
);
989 rect
->Width
= roundr(rectF
.Width
);
990 rect
->Height
= roundr(rectF
.Height
);