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
);
80 case BrushTypeLinearGradient
:
81 *clone
= GdipAlloc(sizeof(GpLineGradient
));
82 if(!*clone
) return OutOfMemory
;
84 memcpy(*clone
, brush
, sizeof(GpLineGradient
));
86 (*clone
)->gdibrush
= CreateSolidBrush((*clone
)->lb
.lbColor
);
88 case BrushTypeTextureFill
:
89 *clone
= GdipAlloc(sizeof(GpTexture
));
90 if(!*clone
) return OutOfMemory
;
92 memcpy(*clone
, brush
, sizeof(GpTexture
));
94 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
97 ERR("not implemented for brush type %d\n", brush
->bt
);
98 return NotImplemented
;
104 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
105 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
106 GpWrapMode wrap
, GpLineGradient
**line
)
108 COLORREF col
= ARGB2COLORREF(startcolor
);
110 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
111 return InvalidParameter
;
113 *line
= GdipAlloc(sizeof(GpLineGradient
));
114 if(!*line
) return OutOfMemory
;
116 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
117 (*line
)->brush
.lb
.lbColor
= col
;
118 (*line
)->brush
.lb
.lbHatch
= 0;
119 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
120 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
122 (*line
)->startpoint
.X
= startpoint
->X
;
123 (*line
)->startpoint
.Y
= startpoint
->Y
;
124 (*line
)->endpoint
.X
= endpoint
->X
;
125 (*line
)->endpoint
.Y
= endpoint
->Y
;
126 (*line
)->startcolor
= startcolor
;
127 (*line
)->endcolor
= endcolor
;
128 (*line
)->wrap
= wrap
;
129 (*line
)->gamma
= FALSE
;
134 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
135 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
136 GpWrapMode wrap
, GpLineGradient
**line
)
141 if(!startpoint
|| !endpoint
)
142 return InvalidParameter
;
144 stF
.X
= (REAL
)startpoint
->X
;
145 stF
.Y
= (REAL
)startpoint
->Y
;
146 endF
.X
= (REAL
)endpoint
->X
;
147 endF
.X
= (REAL
)endpoint
->Y
;
149 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
152 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
153 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
154 GpLineGradient
**line
)
159 return InvalidParameter
;
163 end
.X
= rect
->X
+ rect
->Width
;
164 end
.Y
= rect
->Y
+ rect
->Height
;
166 return GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
169 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
170 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
171 GpLineGradient
**line
)
175 rectF
.X
= (REAL
) rect
->X
;
176 rectF
.Y
= (REAL
) rect
->Y
;
177 rectF
.Width
= (REAL
) rect
->Width
;
178 rectF
.Height
= (REAL
) rect
->Height
;
180 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
183 /* FIXME: angle value completely ignored. Don't know how to use it since native
184 always set Brush rectangle to rect (independetly of this angle).
185 Maybe it's used only on drawing. */
186 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
187 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
188 GpLineGradient
**line
)
190 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
194 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
195 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
196 GpLineGradient
**line
)
198 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
202 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
203 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
205 COLORREF col
= ARGB2COLORREF(0xffffffff);
208 return InvalidParameter
;
213 *grad
= GdipAlloc(sizeof(GpPathGradient
));
214 if (!*grad
) return OutOfMemory
;
216 (*grad
)->pathdata
.Count
= count
;
217 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
218 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
220 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
221 GdipFree((*grad
)->pathdata
.Points
);
222 GdipFree((*grad
)->pathdata
.Types
);
227 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
228 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
230 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
231 (*grad
)->brush
.lb
.lbColor
= col
;
232 (*grad
)->brush
.lb
.lbHatch
= 0;
234 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
235 (*grad
)->brush
.bt
= BrushTypePathGradient
;
236 (*grad
)->centercolor
= 0xffffffff;
237 (*grad
)->wrap
= wrap
;
238 (*grad
)->gamma
= FALSE
;
239 (*grad
)->center
.X
= 0.0;
240 (*grad
)->center
.Y
= 0.0;
241 (*grad
)->focus
.X
= 0.0;
242 (*grad
)->focus
.Y
= 0.0;
247 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
248 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
255 return InvalidParameter
;
260 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
264 for(i
= 0; i
< count
; i
++){
265 pointsF
[i
].X
= (REAL
)points
[i
].X
;
266 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
269 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
275 /* FIXME: path gradient brushes not truly supported (drawn as solid brushes) */
276 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
277 GpPathGradient
**grad
)
279 COLORREF col
= ARGB2COLORREF(0xffffffff);
282 return InvalidParameter
;
284 *grad
= GdipAlloc(sizeof(GpPathGradient
));
285 if (!*grad
) return OutOfMemory
;
287 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
288 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
289 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
291 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
292 GdipFree((*grad
)->pathdata
.Points
);
293 GdipFree((*grad
)->pathdata
.Types
);
298 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
299 path
->pathdata
.Count
* sizeof(PointF
));
300 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
302 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
303 (*grad
)->brush
.lb
.lbColor
= col
;
304 (*grad
)->brush
.lb
.lbHatch
= 0;
306 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
307 (*grad
)->brush
.bt
= BrushTypePathGradient
;
308 (*grad
)->centercolor
= 0xffffffff;
309 (*grad
)->wrap
= WrapModeClamp
;
310 (*grad
)->gamma
= FALSE
;
311 /* FIXME: this should be set to the "centroid" of the path by default */
312 (*grad
)->center
.X
= 0.0;
313 (*grad
)->center
.Y
= 0.0;
314 (*grad
)->focus
.X
= 0.0;
315 (*grad
)->focus
.Y
= 0.0;
320 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
322 COLORREF col
= ARGB2COLORREF(color
);
324 if(!sf
) return InvalidParameter
;
326 *sf
= GdipAlloc(sizeof(GpSolidFill
));
327 if (!*sf
) return OutOfMemory
;
329 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
330 (*sf
)->brush
.lb
.lbColor
= col
;
331 (*sf
)->brush
.lb
.lbHatch
= 0;
333 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
334 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
335 (*sf
)->color
= color
;
340 /* FIXME: imageattr ignored */
341 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
342 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
343 REAL height
, GpTexture
**texture
)
349 BITMAPINFOHEADER
*bmih
;
350 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
352 BYTE
*dibits
, *buff
, *textbits
;
354 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
355 return InvalidParameter
;
357 if(image
->type
!= ImageTypeBitmap
){
358 FIXME("not implemented for image type %d\n", image
->type
);
359 return NotImplemented
;
364 n_width
= roundr(width
);
365 n_height
= roundr(height
);
367 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
368 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
369 return InvalidParameter
;
371 IPicture_get_Handle(image
->picture
, &hbm
);
372 if(!hbm
) return GenericError
;
373 IPicture_get_CurDC(image
->picture
, &hdc
);
374 bm_is_selected
= (hdc
!= 0);
376 bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
377 bmi
.bmiHeader
.biBitCount
= 0;
380 hdc
= CreateCompatibleDC(0);
381 old
= SelectObject(hdc
, (HBITMAP
)hbm
);
385 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, 0, NULL
, &bmi
, DIB_RGB_COLORS
);
387 bytespp
= bmi
.bmiHeader
.biBitCount
/ 8;
388 abs_height
= abs(bmi
.bmiHeader
.biHeight
);
390 if(n_x
> bmi
.bmiHeader
.biWidth
|| n_x
+ n_width
> bmi
.bmiHeader
.biWidth
||
391 n_y
> abs_height
|| n_y
+ n_height
> abs_height
)
392 return InvalidParameter
;
394 dibits
= GdipAlloc(bmi
.bmiHeader
.biSizeImage
);
396 if(dibits
) /* this is not a good place to error out */
397 GetDIBits(hdc
, (HBITMAP
)hbm
, 0, abs_height
, dibits
, &bmi
, DIB_RGB_COLORS
);
400 SelectObject(hdc
, old
);
407 image_stride
= (bmi
.bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
408 stride
= (n_width
* bytespp
+ 3) & ~3;
409 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
415 bmih
= (BITMAPINFOHEADER
*)buff
;
416 textbits
= (BYTE
*) (bmih
+ 1);
417 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
418 bmih
->biWidth
= n_width
;
419 bmih
->biHeight
= n_height
;
420 bmih
->biCompression
= BI_RGB
;
421 bmih
->biSizeImage
= stride
* n_height
;
422 bmih
->biBitCount
= bmi
.bmiHeader
.biBitCount
;
426 /* image is flipped */
427 if(bmi
.bmiHeader
.biHeight
> 0){
428 dibits
+= bmi
.bmiHeader
.biSizeImage
;
430 textbits
+= stride
* (n_height
- 1);
434 for(i
= 0; i
< n_height
; i
++)
435 memcpy(&textbits
[i
* stride
],
436 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
439 *texture
= GdipAlloc(sizeof(GpTexture
));
440 if (!*texture
) return OutOfMemory
;
442 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
443 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
444 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
446 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
447 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
455 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
456 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
458 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
461 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
463 if(!brush
|| !type
) return InvalidParameter
;
470 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
472 if(!brush
) return InvalidParameter
;
476 case BrushTypePathGradient
:
477 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
478 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
480 case BrushTypeSolidColor
:
481 case BrushTypeLinearGradient
:
482 case BrushTypeTextureFill
:
487 DeleteObject(brush
->gdibrush
);
493 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
497 return InvalidParameter
;
499 *usinggamma
= line
->gamma
;
504 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
506 if(!brush
|| !wrapmode
)
507 return InvalidParameter
;
509 *wrapmode
= brush
->wrap
;
514 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
518 return InvalidParameter
;
520 point
->X
= grad
->center
.X
;
521 point
->Y
= grad
->center
.Y
;
526 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
533 return InvalidParameter
;
535 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
538 point
->X
= roundr(ptf
.X
);
539 point
->Y
= roundr(ptf
.Y
);
545 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
548 if(!grad
|| !x
|| !y
)
549 return InvalidParameter
;
557 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
561 return InvalidParameter
;
563 *gamma
= grad
->gamma
;
568 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
572 return InvalidParameter
;
574 *count
= grad
->pathdata
.Count
;
579 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
580 *grad
, ARGB
*argb
, INT
*count
)
584 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
585 return InvalidParameter
;
588 FIXME("not implemented\n");
590 return NotImplemented
;
593 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
594 GpWrapMode
*wrapmode
)
596 if(!brush
|| !wrapmode
)
597 return InvalidParameter
;
599 *wrapmode
= brush
->wrap
;
604 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
607 return InvalidParameter
;
614 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
615 GDIPCONST REAL
*blend
, GDIPCONST REAL
* positions
, INT count
)
619 if(!brush
|| !blend
|| !positions
|| count
<= 0)
620 return InvalidParameter
;
623 FIXME("not implemented\n");
628 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
632 return InvalidParameter
;
634 line
->gamma
= usegamma
;
639 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
644 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
645 return InvalidParameter
;
648 FIXME("not implemented\n");
650 return NotImplemented
;
653 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
656 if(!line
|| wrap
== WrapModeClamp
)
657 return InvalidParameter
;
664 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
668 return InvalidParameter
;
670 grad
->centercolor
= argb
;
671 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
673 DeleteObject(grad
->brush
.gdibrush
);
674 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
679 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
683 return InvalidParameter
;
685 grad
->center
.X
= point
->X
;
686 grad
->center
.Y
= point
->Y
;
691 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
697 return InvalidParameter
;
699 ptf
.X
= (REAL
)point
->X
;
700 ptf
.Y
= (REAL
)point
->Y
;
702 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
705 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
709 return InvalidParameter
;
717 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
721 return InvalidParameter
;
728 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
729 REAL focus
, REAL scale
)
733 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
734 return InvalidParameter
;
737 FIXME("not implemented\n");
739 return NotImplemented
;
742 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
743 *grad
, ARGB
*argb
, INT
*count
)
747 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
748 (*count
> grad
->pathdata
.Count
))
749 return InvalidParameter
;
752 FIXME("not implemented\n");
754 return NotImplemented
;
757 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
761 return InvalidParameter
;
768 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
771 return InvalidParameter
;
774 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
776 DeleteObject(sf
->brush
.gdibrush
);
777 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
782 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
783 GDIPCONST GpMatrix
*matrix
)
787 if(!texture
|| !matrix
)
788 return InvalidParameter
;
791 FIXME("not implemented\n");
796 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
800 return InvalidParameter
;
802 brush
->startcolor
= color1
;
803 brush
->endcolor
= color2
;
808 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
810 if(!brush
|| !colors
)
811 return InvalidParameter
;
813 colors
[0] = brush
->startcolor
;
814 colors
[1] = brush
->endcolor
;
819 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
825 FIXME("not implemented\n");
827 return NotImplemented
;
830 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
831 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
836 FIXME("not implemented\n");
838 return NotImplemented
;
841 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
842 GDIPCONST GpMatrix
*matrix
)
847 FIXME("not implemented\n");
849 return NotImplemented
;
852 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
855 return InvalidParameter
;
857 rect
->X
= (brush
->startpoint
.X
< brush
->endpoint
.X
? brush
->startpoint
.X
: brush
->endpoint
.X
);
858 rect
->Y
= (brush
->startpoint
.Y
< brush
->endpoint
.Y
? brush
->startpoint
.Y
: brush
->endpoint
.Y
);
860 rect
->Width
= fabs(brush
->startpoint
.X
- brush
->endpoint
.X
);
861 rect
->Height
= fabs(brush
->startpoint
.Y
- brush
->endpoint
.Y
);
866 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
872 return InvalidParameter
;
874 ret
= GdipGetLineRect(brush
, &rectF
);
877 rect
->X
= roundr(rectF
.X
);
878 rect
->Y
= roundr(rectF
.Y
);
879 rect
->Width
= roundr(rectF
.Width
);
880 rect
->Height
= roundr(rectF
.Height
);