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
:
49 *clone
= GdipAlloc(sizeof(GpSolidFill
));
50 if (!*clone
) return OutOfMemory
;
52 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
54 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
56 case BrushTypePathGradient
:{
57 GpPathGradient
*src
, *dest
;
60 *clone
= GdipAlloc(sizeof(GpPathGradient
));
61 if (!*clone
) return OutOfMemory
;
63 src
= (GpPathGradient
*) brush
,
64 dest
= (GpPathGradient
*) *clone
;
65 count
= src
->pathdata
.Count
;
67 memcpy(dest
, src
, sizeof(GpPathGradient
));
69 dest
->pathdata
.Count
= count
;
70 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
71 dest
->pathdata
.Types
= GdipAlloc(count
);
73 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
74 GdipFree(dest
->pathdata
.Points
);
75 GdipFree(dest
->pathdata
.Types
);
80 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
81 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
84 count
= src
->blendcount
;
85 dest
->blendcount
= count
;
86 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
87 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
89 if(!dest
->blendfac
|| !dest
->blendpos
){
90 GdipFree(dest
->pathdata
.Points
);
91 GdipFree(dest
->pathdata
.Types
);
92 GdipFree(dest
->blendfac
);
93 GdipFree(dest
->blendpos
);
98 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
99 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
103 case BrushTypeLinearGradient
:
104 *clone
= GdipAlloc(sizeof(GpLineGradient
));
105 if(!*clone
) return OutOfMemory
;
107 memcpy(*clone
, brush
, sizeof(GpLineGradient
));
109 (*clone
)->gdibrush
= CreateSolidBrush((*clone
)->lb
.lbColor
);
111 case BrushTypeTextureFill
:
112 *clone
= GdipAlloc(sizeof(GpTexture
));
113 if(!*clone
) return OutOfMemory
;
115 memcpy(*clone
, brush
, sizeof(GpTexture
));
117 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
120 ERR("not implemented for brush type %d\n", brush
->bt
);
121 return NotImplemented
;
127 /******************************************************************************
128 * GdipCreateLineBrush [GDIPLUS.@]
130 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
131 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
132 GpWrapMode wrap
, GpLineGradient
**line
)
134 COLORREF col
= ARGB2COLORREF(startcolor
);
136 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
137 startcolor
, endcolor
, wrap
, line
);
139 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
140 return InvalidParameter
;
142 *line
= GdipAlloc(sizeof(GpLineGradient
));
143 if(!*line
) return OutOfMemory
;
145 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
146 (*line
)->brush
.lb
.lbColor
= col
;
147 (*line
)->brush
.lb
.lbHatch
= 0;
148 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
149 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
151 (*line
)->startpoint
.X
= startpoint
->X
;
152 (*line
)->startpoint
.Y
= startpoint
->Y
;
153 (*line
)->endpoint
.X
= endpoint
->X
;
154 (*line
)->endpoint
.Y
= endpoint
->Y
;
155 (*line
)->startcolor
= startcolor
;
156 (*line
)->endcolor
= endcolor
;
157 (*line
)->wrap
= wrap
;
158 (*line
)->gamma
= FALSE
;
163 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
164 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
165 GpWrapMode wrap
, GpLineGradient
**line
)
170 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
171 startcolor
, endcolor
, wrap
, line
);
173 if(!startpoint
|| !endpoint
)
174 return InvalidParameter
;
176 stF
.X
= (REAL
)startpoint
->X
;
177 stF
.Y
= (REAL
)startpoint
->Y
;
178 endF
.X
= (REAL
)endpoint
->X
;
179 endF
.X
= (REAL
)endpoint
->Y
;
181 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
184 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
185 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
186 GpLineGradient
**line
)
190 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
194 return InvalidParameter
;
198 end
.X
= rect
->X
+ rect
->Width
;
199 end
.Y
= rect
->Y
+ rect
->Height
;
201 return GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
204 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
205 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
206 GpLineGradient
**line
)
210 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
213 rectF
.X
= (REAL
) rect
->X
;
214 rectF
.Y
= (REAL
) rect
->Y
;
215 rectF
.Width
= (REAL
) rect
->Width
;
216 rectF
.Height
= (REAL
) rect
->Height
;
218 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
221 /******************************************************************************
222 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
224 * FIXME: angle value completely ignored. Don't know how to use it since native
225 * always set Brush rectangle to rect (independetly of this angle).
226 * Maybe it's used only on drawing.
228 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
229 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
230 GpLineGradient
**line
)
232 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
235 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
239 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
240 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
241 GpLineGradient
**line
)
243 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
246 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
250 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
251 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
253 COLORREF col
= ARGB2COLORREF(0xffffffff);
255 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
258 return InvalidParameter
;
263 *grad
= GdipAlloc(sizeof(GpPathGradient
));
264 if (!*grad
) return OutOfMemory
;
266 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
267 if(!(*grad
)->blendfac
){
271 (*grad
)->blendfac
[0] = 1.0;
272 (*grad
)->blendpos
= NULL
;
273 (*grad
)->blendcount
= 1;
275 (*grad
)->pathdata
.Count
= count
;
276 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
277 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
279 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
280 GdipFree((*grad
)->pathdata
.Points
);
281 GdipFree((*grad
)->pathdata
.Types
);
286 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
287 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
289 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
290 (*grad
)->brush
.lb
.lbColor
= col
;
291 (*grad
)->brush
.lb
.lbHatch
= 0;
293 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
294 (*grad
)->brush
.bt
= BrushTypePathGradient
;
295 (*grad
)->centercolor
= 0xffffffff;
296 (*grad
)->wrap
= wrap
;
297 (*grad
)->gamma
= FALSE
;
298 (*grad
)->center
.X
= 0.0;
299 (*grad
)->center
.Y
= 0.0;
300 (*grad
)->focus
.X
= 0.0;
301 (*grad
)->focus
.Y
= 0.0;
306 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
307 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
313 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
316 return InvalidParameter
;
321 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
325 for(i
= 0; i
< count
; i
++){
326 pointsF
[i
].X
= (REAL
)points
[i
].X
;
327 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
330 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
336 /******************************************************************************
337 * GdipCreatePathGradientFromPath [GDIPLUS.@]
339 * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
341 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
342 GpPathGradient
**grad
)
344 COLORREF col
= ARGB2COLORREF(0xffffffff);
346 TRACE("(%p, %p)\n", path
, grad
);
349 return InvalidParameter
;
351 *grad
= GdipAlloc(sizeof(GpPathGradient
));
352 if (!*grad
) return OutOfMemory
;
354 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
355 if(!(*grad
)->blendfac
){
359 (*grad
)->blendfac
[0] = 1.0;
360 (*grad
)->blendpos
= NULL
;
361 (*grad
)->blendcount
= 1;
363 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
364 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
365 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
367 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
368 GdipFree((*grad
)->pathdata
.Points
);
369 GdipFree((*grad
)->pathdata
.Types
);
374 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
375 path
->pathdata
.Count
* sizeof(PointF
));
376 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
378 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
379 (*grad
)->brush
.lb
.lbColor
= col
;
380 (*grad
)->brush
.lb
.lbHatch
= 0;
382 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
383 (*grad
)->brush
.bt
= BrushTypePathGradient
;
384 (*grad
)->centercolor
= 0xffffffff;
385 (*grad
)->wrap
= WrapModeClamp
;
386 (*grad
)->gamma
= FALSE
;
387 /* FIXME: this should be set to the "centroid" of the path by default */
388 (*grad
)->center
.X
= 0.0;
389 (*grad
)->center
.Y
= 0.0;
390 (*grad
)->focus
.X
= 0.0;
391 (*grad
)->focus
.Y
= 0.0;
396 /******************************************************************************
397 * GdipCreateSolidFill [GDIPLUS.@]
399 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
401 COLORREF col
= ARGB2COLORREF(color
);
403 TRACE("(%x, %p)\n", color
, sf
);
405 if(!sf
) return InvalidParameter
;
407 *sf
= GdipAlloc(sizeof(GpSolidFill
));
408 if (!*sf
) return OutOfMemory
;
410 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
411 (*sf
)->brush
.lb
.lbColor
= col
;
412 (*sf
)->brush
.lb
.lbHatch
= 0;
414 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
415 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
416 (*sf
)->color
= color
;
421 /******************************************************************************
422 * GdipCreateTexture [GDIPLUS.@]
425 * image [I] image to use
426 * wrapmode [I] optional
427 * texture [O] pointer to the resulting texturebrush
431 * FAILURE: element of GpStatus
433 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
437 GpImageAttributes attributes
;
440 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
442 if (!(image
&& texture
))
443 return InvalidParameter
;
445 stat
= GdipGetImageWidth(image
, &width
);
446 if (stat
!= Ok
) return stat
;
447 stat
= GdipGetImageHeight(image
, &height
);
448 if (stat
!= Ok
) return stat
;
449 attributes
.wrap
= wrapmode
;
451 return GdipCreateTextureIA(image
, &attributes
, 0, 0, width
, height
,
455 /******************************************************************************
456 * GdipCreateTexture2 [GDIPLUS.@]
458 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
459 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
461 GpImageAttributes attributes
;
463 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
464 x
, y
, width
, height
, texture
);
466 attributes
.wrap
= wrapmode
;
467 return GdipCreateTextureIA(image
, &attributes
, x
, y
, width
, height
,
471 /******************************************************************************
472 * GdipCreateTextureIA [GDIPLUS.@]
474 * FIXME: imageattr ignored
476 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
477 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
478 REAL height
, GpTexture
**texture
)
481 HBITMAP hbm
, old
= NULL
;
483 BITMAPINFOHEADER
*bmih
;
484 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
486 BYTE
*dibits
, *buff
, *textbits
;
489 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
492 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
493 return InvalidParameter
;
495 if(image
->type
!= ImageTypeBitmap
){
496 FIXME("not implemented for image type %d\n", image
->type
);
497 return NotImplemented
;
502 n_width
= roundr(width
);
503 n_height
= roundr(height
);
505 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
506 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
507 return InvalidParameter
;
509 IPicture_get_Handle(image
->picture
, (OLE_HANDLE
*)&hbm
);
510 if(!hbm
) return GenericError
;
511 IPicture_get_CurDC(image
->picture
, &hdc
);
512 bm_is_selected
= (hdc
!= 0);
514 pbmi
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
517 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
518 pbmi
->bmiHeader
.biBitCount
= 0;
521 hdc
= CreateCompatibleDC(0);
522 old
= SelectObject(hdc
, hbm
);
526 GetDIBits(hdc
, hbm
, 0, 0, NULL
, pbmi
, DIB_RGB_COLORS
);
528 bytespp
= pbmi
->bmiHeader
.biBitCount
/ 8;
529 abs_height
= abs(pbmi
->bmiHeader
.biHeight
);
531 if(n_x
> pbmi
->bmiHeader
.biWidth
|| n_x
+ n_width
> pbmi
->bmiHeader
.biWidth
||
532 n_y
> abs_height
|| n_y
+ n_height
> abs_height
){
534 return InvalidParameter
;
537 dibits
= GdipAlloc(pbmi
->bmiHeader
.biSizeImage
);
539 if(dibits
) /* this is not a good place to error out */
540 GetDIBits(hdc
, hbm
, 0, abs_height
, dibits
, pbmi
, DIB_RGB_COLORS
);
543 SelectObject(hdc
, old
);
552 image_stride
= (pbmi
->bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
553 stride
= (n_width
* bytespp
+ 3) & ~3;
554 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
561 bmih
= (BITMAPINFOHEADER
*)buff
;
562 textbits
= (BYTE
*) (bmih
+ 1);
563 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
564 bmih
->biWidth
= n_width
;
565 bmih
->biHeight
= n_height
;
566 bmih
->biCompression
= BI_RGB
;
567 bmih
->biSizeImage
= stride
* n_height
;
568 bmih
->biBitCount
= pbmi
->bmiHeader
.biBitCount
;
572 /* image is flipped */
573 if(pbmi
->bmiHeader
.biHeight
> 0){
574 dibits
+= pbmi
->bmiHeader
.biSizeImage
;
576 textbits
+= stride
* (n_height
- 1);
582 for(i
= 0; i
< n_height
; i
++)
583 memcpy(&textbits
[i
* stride
],
584 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
587 *texture
= GdipAlloc(sizeof(GpTexture
));
594 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
601 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
602 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
603 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
605 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
606 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
607 (*texture
)->wrap
= imageattr
->wrap
;
615 /******************************************************************************
616 * GdipCreateTextureIAI [GDIPLUS.@]
618 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
619 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
621 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
624 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
627 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
628 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
630 GpImageAttributes imageattr
;
632 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
635 imageattr
.wrap
= wrapmode
;
637 return GdipCreateTextureIA(image
, &imageattr
, x
, y
, width
, height
, texture
);
640 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
642 TRACE("(%p, %p)\n", brush
, type
);
644 if(!brush
|| !type
) return InvalidParameter
;
651 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
653 TRACE("(%p)\n", brush
);
655 if(!brush
) return InvalidParameter
;
659 case BrushTypePathGradient
:
660 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
661 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
662 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
663 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
665 case BrushTypeSolidColor
:
666 case BrushTypeLinearGradient
:
668 case BrushTypeTextureFill
:
669 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
675 DeleteObject(brush
->gdibrush
);
681 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
684 TRACE("(%p, %p)\n", line
, usinggamma
);
686 if(!line
|| !usinggamma
)
687 return InvalidParameter
;
689 *usinggamma
= line
->gamma
;
694 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
696 TRACE("(%p, %p)\n", brush
, wrapmode
);
698 if(!brush
|| !wrapmode
)
699 return InvalidParameter
;
701 *wrapmode
= brush
->wrap
;
706 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
707 REAL
*positions
, INT count
)
709 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
711 if(!brush
|| !blend
|| !positions
|| count
<= 0)
712 return InvalidParameter
;
714 if(count
< brush
->blendcount
)
715 return InsufficientBuffer
;
717 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
718 if(brush
->blendcount
> 1){
719 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
725 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
727 TRACE("(%p, %p)\n", brush
, count
);
730 return InvalidParameter
;
732 *count
= brush
->blendcount
;
737 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
740 TRACE("(%p, %p)\n", grad
, point
);
743 return InvalidParameter
;
745 point
->X
= grad
->center
.X
;
746 point
->Y
= grad
->center
.Y
;
751 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
757 TRACE("(%p, %p)\n", grad
, point
);
760 return InvalidParameter
;
762 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
765 point
->X
= roundr(ptf
.X
);
766 point
->Y
= roundr(ptf
.Y
);
772 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
775 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
777 if(!grad
|| !x
|| !y
)
778 return InvalidParameter
;
786 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
789 TRACE("(%p, %p)\n", grad
, gamma
);
792 return InvalidParameter
;
794 *gamma
= grad
->gamma
;
799 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
802 TRACE("(%p, %p)\n", grad
, count
);
805 return InvalidParameter
;
807 *count
= grad
->pathdata
.Count
;
812 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
818 TRACE("(%p, %p)\n", brush
, rect
);
821 return InvalidParameter
;
823 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
824 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
825 if(stat
!= Ok
) return stat
;
827 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
829 GdipDeletePath(path
);
833 memcpy(rect
, &r
, sizeof(GpRectF
));
835 GdipDeletePath(path
);
840 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
845 TRACE("(%p, %p)\n", brush
, rect
);
848 return InvalidParameter
;
850 stat
= GdipGetPathGradientRect(brush
, &rectf
);
851 if(stat
!= Ok
) return stat
;
853 rect
->X
= roundr(rectf
.X
);
854 rect
->Y
= roundr(rectf
.Y
);
855 rect
->Width
= roundr(rectf
.Width
);
856 rect
->Height
= roundr(rectf
.Height
);
861 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
862 *grad
, ARGB
*argb
, INT
*count
)
866 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
867 return InvalidParameter
;
870 FIXME("not implemented\n");
872 return NotImplemented
;
875 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
876 GpWrapMode
*wrapmode
)
878 TRACE("(%p, %p)\n", brush
, wrapmode
);
880 if(!brush
|| !wrapmode
)
881 return InvalidParameter
;
883 *wrapmode
= brush
->wrap
;
888 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
890 TRACE("(%p, %p)\n", sf
, argb
);
893 return InvalidParameter
;
900 /******************************************************************************
901 * GdipGetTextureTransform [GDIPLUS.@]
903 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
905 TRACE("(%p, %p)\n", brush
, matrix
);
907 if(!brush
|| !matrix
)
908 return InvalidParameter
;
910 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
915 /******************************************************************************
916 * GdipGetTextureWrapMode [GDIPLUS.@]
918 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
920 TRACE("(%p, %p)\n", brush
, wrapmode
);
922 if(!brush
|| !wrapmode
)
923 return InvalidParameter
;
925 *wrapmode
= brush
->wrap
;
930 /******************************************************************************
931 * GdipMultiplyTextureTransform [GDIPLUS.@]
933 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
934 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
936 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
938 if(!brush
|| !matrix
)
939 return InvalidParameter
;
941 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
944 /******************************************************************************
945 * GdipResetTextureTransform [GDIPLUS.@]
947 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
949 TRACE("(%p)\n", brush
);
952 return InvalidParameter
;
954 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
957 /******************************************************************************
958 * GdipScaleTextureTransform [GDIPLUS.@]
960 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
961 REAL sx
, REAL sy
, GpMatrixOrder order
)
963 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
966 return InvalidParameter
;
968 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
971 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
972 GDIPCONST REAL
*blend
, GDIPCONST REAL
* positions
, INT count
)
976 if(!brush
|| !blend
|| !positions
|| count
<= 0)
977 return InvalidParameter
;
980 FIXME("not implemented\n");
985 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
988 TRACE("(%p, %d)\n", line
, usegamma
);
991 return InvalidParameter
;
993 line
->gamma
= usegamma
;
998 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1003 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1004 return InvalidParameter
;
1007 FIXME("not implemented\n");
1009 return NotImplemented
;
1012 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1015 TRACE("(%p, %d)\n", line
, wrap
);
1017 if(!line
|| wrap
== WrapModeClamp
)
1018 return InvalidParameter
;
1025 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1026 GDIPCONST REAL
*pos
, INT count
)
1031 FIXME("not implemented\n");
1033 return NotImplemented
;
1036 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1039 TRACE("(%p, %x)\n", grad
, argb
);
1042 return InvalidParameter
;
1044 grad
->centercolor
= argb
;
1045 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1047 DeleteObject(grad
->brush
.gdibrush
);
1048 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
1053 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1056 TRACE("(%p, %p)\n", grad
, point
);
1059 return InvalidParameter
;
1061 grad
->center
.X
= point
->X
;
1062 grad
->center
.Y
= point
->Y
;
1067 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1072 TRACE("(%p, %p)\n", grad
, point
);
1075 return InvalidParameter
;
1077 ptf
.X
= (REAL
)point
->X
;
1078 ptf
.Y
= (REAL
)point
->Y
;
1080 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1083 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1086 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1089 return InvalidParameter
;
1097 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1100 TRACE("(%p, %d)\n", grad
, gamma
);
1103 return InvalidParameter
;
1105 grad
->gamma
= gamma
;
1110 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1111 REAL focus
, REAL scale
)
1115 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1116 return InvalidParameter
;
1119 FIXME("not implemented\n");
1121 return NotImplemented
;
1124 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1125 *grad
, ARGB
*argb
, INT
*count
)
1129 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1130 (*count
> grad
->pathdata
.Count
))
1131 return InvalidParameter
;
1134 FIXME("not implemented\n");
1136 return NotImplemented
;
1139 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1142 TRACE("(%p, %d)\n", grad
, wrap
);
1145 return InvalidParameter
;
1152 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1154 TRACE("(%p, %x)\n", sf
, argb
);
1157 return InvalidParameter
;
1160 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1162 DeleteObject(sf
->brush
.gdibrush
);
1163 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
1168 /******************************************************************************
1169 * GdipSetTextureTransform [GDIPLUS.@]
1171 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1172 GDIPCONST GpMatrix
*matrix
)
1174 TRACE("(%p, %p)\n", texture
, matrix
);
1176 if(!texture
|| !matrix
)
1177 return InvalidParameter
;
1179 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1184 /******************************************************************************
1185 * GdipSetTextureWrapMode [GDIPLUS.@]
1187 * WrapMode not used, only stored
1189 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1191 TRACE("(%p, %d)\n", brush
, wrapmode
);
1194 return InvalidParameter
;
1196 brush
->wrap
= wrapmode
;
1201 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1204 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1207 return InvalidParameter
;
1209 brush
->startcolor
= color1
;
1210 brush
->endcolor
= color2
;
1215 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1217 TRACE("(%p, %p)\n", brush
, colors
);
1219 if(!brush
|| !colors
)
1220 return InvalidParameter
;
1222 colors
[0] = brush
->startcolor
;
1223 colors
[1] = brush
->endcolor
;
1228 /******************************************************************************
1229 * GdipRotateTextureTransform [GDIPLUS.@]
1231 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1232 GpMatrixOrder order
)
1234 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1237 return InvalidParameter
;
1239 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1242 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1248 FIXME("not implemented\n");
1250 return NotImplemented
;
1253 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1254 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1259 FIXME("not implemented\n");
1261 return NotImplemented
;
1264 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1265 GDIPCONST GpMatrix
*matrix
)
1270 FIXME("not implemented\n");
1272 return NotImplemented
;
1275 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1276 REAL dx
, REAL dy
, GpMatrixOrder order
)
1278 FIXME("stub: %p %f %f %d\n", brush
, dx
, dy
, order
);
1280 return NotImplemented
;
1283 /******************************************************************************
1284 * GdipTranslateTextureTransform [GDIPLUS.@]
1286 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1287 GpMatrixOrder order
)
1289 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1292 return InvalidParameter
;
1294 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1297 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1299 TRACE("(%p, %p)\n", brush
, rect
);
1302 return InvalidParameter
;
1304 rect
->X
= (brush
->startpoint
.X
< brush
->endpoint
.X
? brush
->startpoint
.X
: brush
->endpoint
.X
);
1305 rect
->Y
= (brush
->startpoint
.Y
< brush
->endpoint
.Y
? brush
->startpoint
.Y
: brush
->endpoint
.Y
);
1307 rect
->Width
= fabs(brush
->startpoint
.X
- brush
->endpoint
.X
);
1308 rect
->Height
= fabs(brush
->startpoint
.Y
- brush
->endpoint
.Y
);
1313 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1318 TRACE("(%p, %p)\n", brush
, rect
);
1321 return InvalidParameter
;
1323 ret
= GdipGetLineRect(brush
, &rectF
);
1326 rect
->X
= roundr(rectF
.X
);
1327 rect
->Y
= roundr(rectF
.Y
);
1328 rect
->Width
= roundr(rectF
.Width
);
1329 rect
->Height
= roundr(rectF
.Height
);
1335 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1336 REAL angle
, GpMatrixOrder order
)
1341 return InvalidParameter
;
1344 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1346 return NotImplemented
;