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
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
555 return InvalidParameter
;
557 *count
= brush
->blendcount
;
562 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
566 return InvalidParameter
;
568 point
->X
= grad
->center
.X
;
569 point
->Y
= grad
->center
.Y
;
574 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
581 return InvalidParameter
;
583 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
586 point
->X
= roundr(ptf
.X
);
587 point
->Y
= roundr(ptf
.Y
);
593 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
596 if(!grad
|| !x
|| !y
)
597 return InvalidParameter
;
605 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
609 return InvalidParameter
;
611 *gamma
= grad
->gamma
;
616 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
620 return InvalidParameter
;
622 *count
= grad
->pathdata
.Count
;
627 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
628 *grad
, ARGB
*argb
, INT
*count
)
632 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
633 return InvalidParameter
;
636 FIXME("not implemented\n");
638 return NotImplemented
;
641 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
642 GpWrapMode
*wrapmode
)
644 if(!brush
|| !wrapmode
)
645 return InvalidParameter
;
647 *wrapmode
= brush
->wrap
;
652 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
655 return InvalidParameter
;
662 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
663 GDIPCONST REAL
*blend
, GDIPCONST REAL
* positions
, INT count
)
667 if(!brush
|| !blend
|| !positions
|| count
<= 0)
668 return InvalidParameter
;
671 FIXME("not implemented\n");
676 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
680 return InvalidParameter
;
682 line
->gamma
= usegamma
;
687 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
692 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
693 return InvalidParameter
;
696 FIXME("not implemented\n");
698 return NotImplemented
;
701 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
704 if(!line
|| wrap
== WrapModeClamp
)
705 return InvalidParameter
;
712 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
716 return InvalidParameter
;
718 grad
->centercolor
= argb
;
719 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
721 DeleteObject(grad
->brush
.gdibrush
);
722 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
727 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
731 return InvalidParameter
;
733 grad
->center
.X
= point
->X
;
734 grad
->center
.Y
= point
->Y
;
739 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
745 return InvalidParameter
;
747 ptf
.X
= (REAL
)point
->X
;
748 ptf
.Y
= (REAL
)point
->Y
;
750 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
753 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
757 return InvalidParameter
;
765 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
769 return InvalidParameter
;
776 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
777 REAL focus
, REAL scale
)
781 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
782 return InvalidParameter
;
785 FIXME("not implemented\n");
787 return NotImplemented
;
790 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
791 *grad
, ARGB
*argb
, INT
*count
)
795 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
796 (*count
> grad
->pathdata
.Count
))
797 return InvalidParameter
;
800 FIXME("not implemented\n");
802 return NotImplemented
;
805 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
809 return InvalidParameter
;
816 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
819 return InvalidParameter
;
822 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
824 DeleteObject(sf
->brush
.gdibrush
);
825 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
830 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
831 GDIPCONST GpMatrix
*matrix
)
835 if(!texture
|| !matrix
)
836 return InvalidParameter
;
839 FIXME("not implemented\n");
844 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
848 return InvalidParameter
;
850 brush
->startcolor
= color1
;
851 brush
->endcolor
= color2
;
856 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
858 if(!brush
|| !colors
)
859 return InvalidParameter
;
861 colors
[0] = brush
->startcolor
;
862 colors
[1] = brush
->endcolor
;
867 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
873 FIXME("not implemented\n");
875 return NotImplemented
;
878 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
879 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
884 FIXME("not implemented\n");
886 return NotImplemented
;
889 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
890 GDIPCONST GpMatrix
*matrix
)
895 FIXME("not implemented\n");
897 return NotImplemented
;
900 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
903 return InvalidParameter
;
905 rect
->X
= (brush
->startpoint
.X
< brush
->endpoint
.X
? brush
->startpoint
.X
: brush
->endpoint
.X
);
906 rect
->Y
= (brush
->startpoint
.Y
< brush
->endpoint
.Y
? brush
->startpoint
.Y
: brush
->endpoint
.Y
);
908 rect
->Width
= fabs(brush
->startpoint
.X
- brush
->endpoint
.X
);
909 rect
->Height
= fabs(brush
->startpoint
.Y
- brush
->endpoint
.Y
);
914 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
920 return InvalidParameter
;
922 ret
= GdipGetLineRect(brush
, &rectF
);
925 rect
->X
= roundr(rectF
.X
);
926 rect
->Y
= roundr(rectF
.Y
);
927 rect
->Width
= roundr(rectF
.Width
);
928 rect
->Height
= roundr(rectF
.Height
);