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
:
51 *clone
= GdipAlloc(sizeof(GpSolidFill
));
52 if (!*clone
) return OutOfMemory
;
54 fill
= (GpSolidFill
*)*clone
;
56 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
58 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
59 fill
->bmp
= ARGB2BMP(fill
->color
);
62 case BrushTypeHatchFill
:
63 *clone
= GdipAlloc(sizeof(GpHatch
));
64 if (!*clone
) return OutOfMemory
;
66 memcpy(*clone
, brush
, sizeof(GpHatch
));
68 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
70 case BrushTypePathGradient
:{
71 GpPathGradient
*src
, *dest
;
74 *clone
= GdipAlloc(sizeof(GpPathGradient
));
75 if (!*clone
) return OutOfMemory
;
77 src
= (GpPathGradient
*) brush
,
78 dest
= (GpPathGradient
*) *clone
;
79 count
= src
->pathdata
.Count
;
81 memcpy(dest
, src
, sizeof(GpPathGradient
));
83 dest
->pathdata
.Count
= count
;
84 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
85 dest
->pathdata
.Types
= GdipAlloc(count
);
87 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
88 GdipFree(dest
->pathdata
.Points
);
89 GdipFree(dest
->pathdata
.Types
);
94 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
95 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
98 count
= src
->blendcount
;
99 dest
->blendcount
= count
;
100 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
101 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
103 if(!dest
->blendfac
|| !dest
->blendpos
){
104 GdipFree(dest
->pathdata
.Points
);
105 GdipFree(dest
->pathdata
.Types
);
106 GdipFree(dest
->blendfac
);
107 GdipFree(dest
->blendpos
);
112 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
113 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
117 case BrushTypeLinearGradient
:{
118 GpLineGradient
*dest
, *src
;
121 dest
= GdipAlloc(sizeof(GpLineGradient
));
122 if(!dest
) return OutOfMemory
;
124 src
= (GpLineGradient
*)brush
;
126 memcpy(dest
, src
, sizeof(GpLineGradient
));
128 dest
->brush
.gdibrush
= CreateSolidBrush(dest
->brush
.lb
.lbColor
);
130 count
= dest
->blendcount
;
131 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
132 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
134 if (!dest
->blendfac
|| !dest
->blendpos
)
136 GdipFree(dest
->blendfac
);
137 GdipFree(dest
->blendpos
);
138 DeleteObject(dest
->brush
.gdibrush
);
143 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
144 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
146 *clone
= &dest
->brush
;
149 case BrushTypeTextureFill
:
150 *clone
= GdipAlloc(sizeof(GpTexture
));
151 if(!*clone
) return OutOfMemory
;
153 memcpy(*clone
, brush
, sizeof(GpTexture
));
155 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
158 ERR("not implemented for brush type %d\n", brush
->bt
);
159 return NotImplemented
;
165 static LONG
HatchStyleToHatch(HatchStyle hatchstyle
)
169 case HatchStyleHorizontal
: return HS_HORIZONTAL
;
170 case HatchStyleVertical
: return HS_VERTICAL
;
171 case HatchStyleForwardDiagonal
: return HS_FDIAGONAL
;
172 case HatchStyleBackwardDiagonal
: return HS_BDIAGONAL
;
173 case HatchStyleCross
: return HS_CROSS
;
174 case HatchStyleDiagonalCross
: return HS_DIAGCROSS
;
179 /******************************************************************************
180 * GdipCreateHatchBrush [GDIPLUS.@]
182 GpStatus WINGDIPAPI
GdipCreateHatchBrush(HatchStyle hatchstyle
, ARGB forecol
, ARGB backcol
, GpHatch
**brush
)
184 COLORREF fgcol
= ARGB2COLORREF(forecol
);
186 TRACE("(%d, %d, %d, %p)\n", hatchstyle
, forecol
, backcol
, brush
);
188 if(!brush
) return InvalidParameter
;
190 *brush
= GdipAlloc(sizeof(GpHatch
));
191 if (!*brush
) return OutOfMemory
;
195 case HatchStyleHorizontal
:
196 case HatchStyleVertical
:
197 case HatchStyleForwardDiagonal
:
198 case HatchStyleBackwardDiagonal
:
199 case HatchStyleCross
:
200 case HatchStyleDiagonalCross
:
201 /* Brushes that map to BS_HATCHED */
202 (*brush
)->brush
.lb
.lbStyle
= BS_HATCHED
;
203 (*brush
)->brush
.lb
.lbColor
= fgcol
;
204 (*brush
)->brush
.lb
.lbHatch
= HatchStyleToHatch(hatchstyle
);
208 FIXME("Unimplemented hatch style %d\n", hatchstyle
);
210 (*brush
)->brush
.lb
.lbStyle
= BS_SOLID
;
211 (*brush
)->brush
.lb
.lbColor
= fgcol
;
212 (*brush
)->brush
.lb
.lbHatch
= 0;
217 (*brush
)->brush
.gdibrush
= CreateBrushIndirect(&(*brush
)->brush
.lb
);
218 (*brush
)->brush
.bt
= BrushTypeHatchFill
;
219 (*brush
)->forecol
= forecol
;
220 (*brush
)->backcol
= backcol
;
221 (*brush
)->hatchstyle
= hatchstyle
;
226 /******************************************************************************
227 * GdipCreateLineBrush [GDIPLUS.@]
229 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
230 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
231 GpWrapMode wrap
, GpLineGradient
**line
)
233 COLORREF col
= ARGB2COLORREF(startcolor
);
235 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
236 startcolor
, endcolor
, wrap
, line
);
238 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
239 return InvalidParameter
;
241 *line
= GdipAlloc(sizeof(GpLineGradient
));
242 if(!*line
) return OutOfMemory
;
244 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
245 (*line
)->brush
.lb
.lbColor
= col
;
246 (*line
)->brush
.lb
.lbHatch
= 0;
247 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
248 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
250 (*line
)->startpoint
.X
= startpoint
->X
;
251 (*line
)->startpoint
.Y
= startpoint
->Y
;
252 (*line
)->endpoint
.X
= endpoint
->X
;
253 (*line
)->endpoint
.Y
= endpoint
->Y
;
254 (*line
)->startcolor
= startcolor
;
255 (*line
)->endcolor
= endcolor
;
256 (*line
)->wrap
= wrap
;
257 (*line
)->gamma
= FALSE
;
259 (*line
)->rect
.X
= (startpoint
->X
< endpoint
->X
? startpoint
->X
: endpoint
->X
);
260 (*line
)->rect
.Y
= (startpoint
->Y
< endpoint
->Y
? startpoint
->Y
: endpoint
->Y
);
261 (*line
)->rect
.Width
= fabs(startpoint
->X
- endpoint
->X
);
262 (*line
)->rect
.Height
= fabs(startpoint
->Y
- endpoint
->Y
);
264 (*line
)->blendcount
= 1;
265 (*line
)->blendfac
= GdipAlloc(sizeof(REAL
));
266 (*line
)->blendpos
= GdipAlloc(sizeof(REAL
));
268 if (!(*line
)->blendfac
|| !(*line
)->blendpos
)
270 GdipFree((*line
)->blendfac
);
271 GdipFree((*line
)->blendpos
);
272 DeleteObject((*line
)->brush
.gdibrush
);
278 (*line
)->blendfac
[0] = 1.0f
;
279 (*line
)->blendpos
[0] = 1.0f
;
284 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
285 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
286 GpWrapMode wrap
, GpLineGradient
**line
)
291 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
292 startcolor
, endcolor
, wrap
, line
);
294 if(!startpoint
|| !endpoint
)
295 return InvalidParameter
;
297 stF
.X
= (REAL
)startpoint
->X
;
298 stF
.Y
= (REAL
)startpoint
->Y
;
299 endF
.X
= (REAL
)endpoint
->X
;
300 endF
.X
= (REAL
)endpoint
->Y
;
302 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
305 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
306 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
307 GpLineGradient
**line
)
312 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
316 return InvalidParameter
;
320 case LinearGradientModeHorizontal
:
323 end
.X
= rect
->X
+ rect
->Width
;
326 case LinearGradientModeVertical
:
330 end
.Y
= rect
->Y
+ rect
->Height
;
332 case LinearGradientModeForwardDiagonal
:
335 end
.X
= rect
->X
+ rect
->Width
;
336 end
.Y
= rect
->Y
+ rect
->Height
;
338 case LinearGradientModeBackwardDiagonal
:
339 start
.X
= rect
->X
+ rect
->Width
;
342 end
.Y
= rect
->Y
+ rect
->Height
;
345 return InvalidParameter
;
348 stat
= GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
351 (*line
)->rect
= *rect
;
356 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
357 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
358 GpLineGradient
**line
)
362 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
365 rectF
.X
= (REAL
) rect
->X
;
366 rectF
.Y
= (REAL
) rect
->Y
;
367 rectF
.Width
= (REAL
) rect
->Width
;
368 rectF
.Height
= (REAL
) rect
->Height
;
370 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
373 /******************************************************************************
374 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
376 * FIXME: angle value completely ignored. Don't know how to use it since native
377 * always set Brush rectangle to rect (independetly of this angle).
378 * Maybe it's used only on drawing.
380 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
381 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
382 GpLineGradient
**line
)
384 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
387 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
391 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
392 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
393 GpLineGradient
**line
)
395 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
398 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
402 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
403 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
405 COLORREF col
= ARGB2COLORREF(0xffffffff);
407 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
410 return InvalidParameter
;
415 *grad
= GdipAlloc(sizeof(GpPathGradient
));
416 if (!*grad
) return OutOfMemory
;
418 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
419 if(!(*grad
)->blendfac
){
423 (*grad
)->blendfac
[0] = 1.0;
424 (*grad
)->blendpos
= NULL
;
425 (*grad
)->blendcount
= 1;
427 (*grad
)->pathdata
.Count
= count
;
428 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
429 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
431 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
432 GdipFree((*grad
)->pathdata
.Points
);
433 GdipFree((*grad
)->pathdata
.Types
);
438 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
439 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
441 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
442 (*grad
)->brush
.lb
.lbColor
= col
;
443 (*grad
)->brush
.lb
.lbHatch
= 0;
445 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
446 (*grad
)->brush
.bt
= BrushTypePathGradient
;
447 (*grad
)->centercolor
= 0xffffffff;
448 (*grad
)->wrap
= wrap
;
449 (*grad
)->gamma
= FALSE
;
450 (*grad
)->center
.X
= 0.0;
451 (*grad
)->center
.Y
= 0.0;
452 (*grad
)->focus
.X
= 0.0;
453 (*grad
)->focus
.Y
= 0.0;
458 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
459 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
465 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
468 return InvalidParameter
;
473 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
477 for(i
= 0; i
< count
; i
++){
478 pointsF
[i
].X
= (REAL
)points
[i
].X
;
479 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
482 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
488 /******************************************************************************
489 * GdipCreatePathGradientFromPath [GDIPLUS.@]
491 * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
493 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
494 GpPathGradient
**grad
)
496 COLORREF col
= ARGB2COLORREF(0xffffffff);
498 TRACE("(%p, %p)\n", path
, grad
);
501 return InvalidParameter
;
503 *grad
= GdipAlloc(sizeof(GpPathGradient
));
504 if (!*grad
) return OutOfMemory
;
506 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
507 if(!(*grad
)->blendfac
){
511 (*grad
)->blendfac
[0] = 1.0;
512 (*grad
)->blendpos
= NULL
;
513 (*grad
)->blendcount
= 1;
515 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
516 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
517 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
519 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
520 GdipFree((*grad
)->pathdata
.Points
);
521 GdipFree((*grad
)->pathdata
.Types
);
526 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
527 path
->pathdata
.Count
* sizeof(PointF
));
528 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
530 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
531 (*grad
)->brush
.lb
.lbColor
= col
;
532 (*grad
)->brush
.lb
.lbHatch
= 0;
534 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
535 (*grad
)->brush
.bt
= BrushTypePathGradient
;
536 (*grad
)->centercolor
= 0xffffffff;
537 (*grad
)->wrap
= WrapModeClamp
;
538 (*grad
)->gamma
= FALSE
;
539 /* FIXME: this should be set to the "centroid" of the path by default */
540 (*grad
)->center
.X
= 0.0;
541 (*grad
)->center
.Y
= 0.0;
542 (*grad
)->focus
.X
= 0.0;
543 (*grad
)->focus
.Y
= 0.0;
548 /******************************************************************************
549 * GdipCreateSolidFill [GDIPLUS.@]
551 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
553 COLORREF col
= ARGB2COLORREF(color
);
555 TRACE("(%x, %p)\n", color
, sf
);
557 if(!sf
) return InvalidParameter
;
559 *sf
= GdipAlloc(sizeof(GpSolidFill
));
560 if (!*sf
) return OutOfMemory
;
562 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
563 (*sf
)->brush
.lb
.lbColor
= col
;
564 (*sf
)->brush
.lb
.lbHatch
= 0;
566 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
567 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
568 (*sf
)->color
= color
;
569 (*sf
)->bmp
= ARGB2BMP(color
);
574 /******************************************************************************
575 * GdipCreateTexture [GDIPLUS.@]
578 * image [I] image to use
579 * wrapmode [I] optional
580 * texture [O] pointer to the resulting texturebrush
584 * FAILURE: element of GpStatus
586 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
590 GpImageAttributes attributes
;
593 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
595 if (!(image
&& texture
))
596 return InvalidParameter
;
598 stat
= GdipGetImageWidth(image
, &width
);
599 if (stat
!= Ok
) return stat
;
600 stat
= GdipGetImageHeight(image
, &height
);
601 if (stat
!= Ok
) return stat
;
602 attributes
.wrap
= wrapmode
;
604 return GdipCreateTextureIA(image
, &attributes
, 0, 0, width
, height
,
608 /******************************************************************************
609 * GdipCreateTexture2 [GDIPLUS.@]
611 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
612 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
614 GpImageAttributes attributes
;
616 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
617 x
, y
, width
, height
, texture
);
619 attributes
.wrap
= wrapmode
;
620 return GdipCreateTextureIA(image
, &attributes
, x
, y
, width
, height
,
624 /******************************************************************************
625 * GdipCreateTextureIA [GDIPLUS.@]
627 * FIXME: imageattr ignored
629 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
630 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
631 REAL height
, GpTexture
**texture
)
634 HBITMAP hbm
, old
= NULL
;
636 BITMAPINFOHEADER
*bmih
;
637 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
639 BYTE
*dibits
, *buff
, *textbits
;
642 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
645 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
646 return InvalidParameter
;
648 if(image
->type
!= ImageTypeBitmap
){
649 FIXME("not implemented for image type %d\n", image
->type
);
650 return NotImplemented
;
655 n_width
= roundr(width
);
656 n_height
= roundr(height
);
658 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
659 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
660 return InvalidParameter
;
662 IPicture_get_Handle(image
->picture
, (OLE_HANDLE
*)&hbm
);
663 if(!hbm
) return GenericError
;
664 IPicture_get_CurDC(image
->picture
, &hdc
);
665 bm_is_selected
= (hdc
!= 0);
667 pbmi
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
670 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
671 pbmi
->bmiHeader
.biBitCount
= 0;
674 hdc
= CreateCompatibleDC(0);
675 old
= SelectObject(hdc
, hbm
);
679 GetDIBits(hdc
, hbm
, 0, 0, NULL
, pbmi
, DIB_RGB_COLORS
);
681 bytespp
= pbmi
->bmiHeader
.biBitCount
/ 8;
682 abs_height
= abs(pbmi
->bmiHeader
.biHeight
);
684 if(n_x
> pbmi
->bmiHeader
.biWidth
|| n_x
+ n_width
> pbmi
->bmiHeader
.biWidth
||
685 n_y
> abs_height
|| n_y
+ n_height
> abs_height
){
687 return InvalidParameter
;
690 dibits
= GdipAlloc(pbmi
->bmiHeader
.biSizeImage
);
692 if(dibits
) /* this is not a good place to error out */
693 GetDIBits(hdc
, hbm
, 0, abs_height
, dibits
, pbmi
, DIB_RGB_COLORS
);
696 SelectObject(hdc
, old
);
705 image_stride
= (pbmi
->bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
706 stride
= (n_width
* bytespp
+ 3) & ~3;
707 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
714 bmih
= (BITMAPINFOHEADER
*)buff
;
715 textbits
= (BYTE
*) (bmih
+ 1);
716 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
717 bmih
->biWidth
= n_width
;
718 bmih
->biHeight
= n_height
;
719 bmih
->biCompression
= BI_RGB
;
720 bmih
->biSizeImage
= stride
* n_height
;
721 bmih
->biBitCount
= pbmi
->bmiHeader
.biBitCount
;
725 /* image is flipped */
726 if(pbmi
->bmiHeader
.biHeight
> 0){
727 dibits
+= pbmi
->bmiHeader
.biSizeImage
;
729 textbits
+= stride
* (n_height
- 1);
735 for(i
= 0; i
< n_height
; i
++)
736 memcpy(&textbits
[i
* stride
],
737 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
740 *texture
= GdipAlloc(sizeof(GpTexture
));
747 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
754 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
755 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
756 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
758 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
759 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
760 (*texture
)->wrap
= imageattr
->wrap
;
768 /******************************************************************************
769 * GdipCreateTextureIAI [GDIPLUS.@]
771 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
772 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
774 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
777 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
780 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
781 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
783 GpImageAttributes imageattr
;
785 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
788 imageattr
.wrap
= wrapmode
;
790 return GdipCreateTextureIA(image
, &imageattr
, x
, y
, width
, height
, texture
);
793 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
795 TRACE("(%p, %p)\n", brush
, type
);
797 if(!brush
|| !type
) return InvalidParameter
;
804 GpStatus WINGDIPAPI
GdipGetHatchBackgroundColor(GpHatch
*brush
, ARGB
*backcol
)
806 TRACE("(%p, %p)\n", brush
, backcol
);
808 if(!brush
|| !backcol
) return InvalidParameter
;
810 *backcol
= brush
->backcol
;
815 GpStatus WINGDIPAPI
GdipGetHatchForegroundColor(GpHatch
*brush
, ARGB
*forecol
)
817 TRACE("(%p, %p)\n", brush
, forecol
);
819 if(!brush
|| !forecol
) return InvalidParameter
;
821 *forecol
= brush
->forecol
;
826 GpStatus WINGDIPAPI
GdipGetHatchStyle(GpHatch
*brush
, HatchStyle
*hatchstyle
)
828 TRACE("(%p, %p)\n", brush
, hatchstyle
);
830 if(!brush
|| !hatchstyle
) return InvalidParameter
;
832 *hatchstyle
= brush
->hatchstyle
;
837 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
839 TRACE("(%p)\n", brush
);
841 if(!brush
) return InvalidParameter
;
845 case BrushTypePathGradient
:
846 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
847 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
848 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
849 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
851 case BrushTypeSolidColor
:
852 if (((GpSolidFill
*)brush
)->bmp
)
853 DeleteObject(((GpSolidFill
*)brush
)->bmp
);
855 case BrushTypeLinearGradient
:
856 GdipFree(((GpLineGradient
*)brush
)->blendfac
);
857 GdipFree(((GpLineGradient
*)brush
)->blendpos
);
859 case BrushTypeTextureFill
:
860 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
866 DeleteObject(brush
->gdibrush
);
872 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
875 TRACE("(%p, %p)\n", line
, usinggamma
);
877 if(!line
|| !usinggamma
)
878 return InvalidParameter
;
880 *usinggamma
= line
->gamma
;
885 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
887 TRACE("(%p, %p)\n", brush
, wrapmode
);
889 if(!brush
|| !wrapmode
)
890 return InvalidParameter
;
892 *wrapmode
= brush
->wrap
;
897 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
898 REAL
*positions
, INT count
)
900 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
902 if(!brush
|| !blend
|| !positions
|| count
<= 0)
903 return InvalidParameter
;
905 if(count
< brush
->blendcount
)
906 return InsufficientBuffer
;
908 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
909 if(brush
->blendcount
> 1){
910 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
916 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
918 TRACE("(%p, %p)\n", brush
, count
);
921 return InvalidParameter
;
923 *count
= brush
->blendcount
;
928 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
931 TRACE("(%p, %p)\n", grad
, point
);
934 return InvalidParameter
;
936 point
->X
= grad
->center
.X
;
937 point
->Y
= grad
->center
.Y
;
942 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
948 TRACE("(%p, %p)\n", grad
, point
);
951 return InvalidParameter
;
953 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
956 point
->X
= roundr(ptf
.X
);
957 point
->Y
= roundr(ptf
.Y
);
963 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
966 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
968 if(!grad
|| !x
|| !y
)
969 return InvalidParameter
;
977 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
980 TRACE("(%p, %p)\n", grad
, gamma
);
983 return InvalidParameter
;
985 *gamma
= grad
->gamma
;
990 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
993 TRACE("(%p, %p)\n", grad
, count
);
996 return InvalidParameter
;
998 *count
= grad
->pathdata
.Count
;
1003 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
1009 TRACE("(%p, %p)\n", brush
, rect
);
1012 return InvalidParameter
;
1014 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
1015 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
1016 if(stat
!= Ok
) return stat
;
1018 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
1020 GdipDeletePath(path
);
1024 memcpy(rect
, &r
, sizeof(GpRectF
));
1026 GdipDeletePath(path
);
1031 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
1036 TRACE("(%p, %p)\n", brush
, rect
);
1039 return InvalidParameter
;
1041 stat
= GdipGetPathGradientRect(brush
, &rectf
);
1042 if(stat
!= Ok
) return stat
;
1044 rect
->X
= roundr(rectf
.X
);
1045 rect
->Y
= roundr(rectf
.Y
);
1046 rect
->Width
= roundr(rectf
.Width
);
1047 rect
->Height
= roundr(rectf
.Height
);
1052 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
1053 *grad
, ARGB
*argb
, INT
*count
)
1057 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
1058 return InvalidParameter
;
1061 FIXME("not implemented\n");
1063 return NotImplemented
;
1066 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
1067 GpWrapMode
*wrapmode
)
1069 TRACE("(%p, %p)\n", brush
, wrapmode
);
1071 if(!brush
|| !wrapmode
)
1072 return InvalidParameter
;
1074 *wrapmode
= brush
->wrap
;
1079 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
1081 TRACE("(%p, %p)\n", sf
, argb
);
1084 return InvalidParameter
;
1091 /******************************************************************************
1092 * GdipGetTextureTransform [GDIPLUS.@]
1094 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
1096 TRACE("(%p, %p)\n", brush
, matrix
);
1098 if(!brush
|| !matrix
)
1099 return InvalidParameter
;
1101 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
1106 /******************************************************************************
1107 * GdipGetTextureWrapMode [GDIPLUS.@]
1109 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
1111 TRACE("(%p, %p)\n", brush
, wrapmode
);
1113 if(!brush
|| !wrapmode
)
1114 return InvalidParameter
;
1116 *wrapmode
= brush
->wrap
;
1121 /******************************************************************************
1122 * GdipMultiplyTextureTransform [GDIPLUS.@]
1124 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
1125 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1127 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
1129 if(!brush
|| !matrix
)
1130 return InvalidParameter
;
1132 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
1135 /******************************************************************************
1136 * GdipResetTextureTransform [GDIPLUS.@]
1138 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
1140 TRACE("(%p)\n", brush
);
1143 return InvalidParameter
;
1145 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1148 /******************************************************************************
1149 * GdipScaleTextureTransform [GDIPLUS.@]
1151 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
1152 REAL sx
, REAL sy
, GpMatrixOrder order
)
1154 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
1157 return InvalidParameter
;
1159 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
1162 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
1163 GDIPCONST REAL
*factors
, GDIPCONST REAL
* positions
, INT count
)
1165 REAL
*new_blendfac
, *new_blendpos
;
1167 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1169 if(!brush
|| !factors
|| !positions
|| count
<= 0 ||
1170 (count
>= 2 && (positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)))
1171 return InvalidParameter
;
1173 new_blendfac
= GdipAlloc(count
* sizeof(REAL
));
1174 new_blendpos
= GdipAlloc(count
* sizeof(REAL
));
1176 if (!new_blendfac
|| !new_blendpos
)
1178 GdipFree(new_blendfac
);
1179 GdipFree(new_blendpos
);
1183 memcpy(new_blendfac
, factors
, count
* sizeof(REAL
));
1184 memcpy(new_blendpos
, positions
, count
* sizeof(REAL
));
1186 GdipFree(brush
->blendfac
);
1187 GdipFree(brush
->blendpos
);
1189 brush
->blendcount
= count
;
1190 brush
->blendfac
= new_blendfac
;
1191 brush
->blendpos
= new_blendpos
;
1196 GpStatus WINGDIPAPI
GdipGetLineBlend(GpLineGradient
*brush
, REAL
*factors
,
1197 REAL
*positions
, INT count
)
1199 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1201 if (!brush
|| !factors
|| !positions
|| count
<= 0)
1202 return InvalidParameter
;
1204 if (count
< brush
->blendcount
)
1205 return InsufficientBuffer
;
1207 memcpy(factors
, brush
->blendfac
, brush
->blendcount
* sizeof(REAL
));
1208 memcpy(positions
, brush
->blendpos
, brush
->blendcount
* sizeof(REAL
));
1213 GpStatus WINGDIPAPI
GdipGetLineBlendCount(GpLineGradient
*brush
, INT
*count
)
1215 TRACE("(%p, %p)\n", brush
, count
);
1217 if (!brush
|| !count
)
1218 return InvalidParameter
;
1220 *count
= brush
->blendcount
;
1225 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
1228 TRACE("(%p, %d)\n", line
, usegamma
);
1231 return InvalidParameter
;
1233 line
->gamma
= usegamma
;
1238 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1245 const int precision
= 16;
1246 REAL erf_range
; /* we use values erf(-erf_range) through erf(+erf_range) */
1250 TRACE("(%p, %0.2f, %0.2f)\n", line
, focus
, scale
);
1252 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1253 return InvalidParameter
;
1255 /* we want 2 standard deviations */
1256 erf_range
= 2.0 / sqrt(2);
1258 /* calculate the constants we need to normalize the error function to be
1259 between 0.0 and scale over the range we need */
1260 min_erf
= erf(-erf_range
);
1261 scale_erf
= scale
/ (-2.0 * min_erf
);
1267 for (i
=1; i
<precision
; i
++)
1269 positions
[i
] = focus
* i
/ precision
;
1270 factors
[i
] = scale_erf
* (erf(2 * erf_range
* i
/ precision
- erf_range
) - min_erf
);
1272 num_points
+= precision
;
1275 positions
[num_points
] = focus
;
1276 factors
[num_points
] = scale
;
1281 for (i
=1; i
<precision
; i
++)
1283 positions
[i
+num_points
-1] = (focus
+ ((1.0-focus
) * i
/ precision
));
1284 factors
[i
+num_points
-1] = scale_erf
* (erf(erf_range
- 2 * erf_range
* i
/ precision
) - min_erf
);
1286 num_points
+= precision
;
1287 positions
[num_points
-1] = 1.0;
1288 factors
[num_points
-1] = 0.0;
1291 return GdipSetLineBlend(line
, factors
, positions
, num_points
);
1294 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1297 TRACE("(%p, %d)\n", line
, wrap
);
1299 if(!line
|| wrap
== WrapModeClamp
)
1300 return InvalidParameter
;
1307 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1308 GDIPCONST REAL
*pos
, INT count
)
1313 FIXME("not implemented\n");
1315 return NotImplemented
;
1318 GpStatus WINGDIPAPI
GdipSetPathGradientPresetBlend(GpPathGradient
*brush
,
1319 GDIPCONST ARGB
*blend
, GDIPCONST REAL
*pos
, INT count
)
1321 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1322 return NotImplemented
;
1325 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1328 TRACE("(%p, %x)\n", grad
, argb
);
1331 return InvalidParameter
;
1333 grad
->centercolor
= argb
;
1334 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1336 DeleteObject(grad
->brush
.gdibrush
);
1337 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
1342 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1345 TRACE("(%p, %p)\n", grad
, point
);
1348 return InvalidParameter
;
1350 grad
->center
.X
= point
->X
;
1351 grad
->center
.Y
= point
->Y
;
1356 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1361 TRACE("(%p, %p)\n", grad
, point
);
1364 return InvalidParameter
;
1366 ptf
.X
= (REAL
)point
->X
;
1367 ptf
.Y
= (REAL
)point
->Y
;
1369 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1372 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1375 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1378 return InvalidParameter
;
1386 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1389 TRACE("(%p, %d)\n", grad
, gamma
);
1392 return InvalidParameter
;
1394 grad
->gamma
= gamma
;
1399 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1400 REAL focus
, REAL scale
)
1404 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1405 return InvalidParameter
;
1408 FIXME("not implemented\n");
1410 return NotImplemented
;
1413 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1414 *grad
, ARGB
*argb
, INT
*count
)
1418 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1419 (*count
> grad
->pathdata
.Count
))
1420 return InvalidParameter
;
1423 FIXME("not implemented\n");
1425 return NotImplemented
;
1428 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1431 TRACE("(%p, %d)\n", grad
, wrap
);
1434 return InvalidParameter
;
1441 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1443 TRACE("(%p, %x)\n", sf
, argb
);
1446 return InvalidParameter
;
1449 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1451 DeleteObject(sf
->brush
.gdibrush
);
1452 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
1457 /******************************************************************************
1458 * GdipSetTextureTransform [GDIPLUS.@]
1460 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1461 GDIPCONST GpMatrix
*matrix
)
1463 TRACE("(%p, %p)\n", texture
, matrix
);
1465 if(!texture
|| !matrix
)
1466 return InvalidParameter
;
1468 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1473 /******************************************************************************
1474 * GdipSetTextureWrapMode [GDIPLUS.@]
1476 * WrapMode not used, only stored
1478 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1480 TRACE("(%p, %d)\n", brush
, wrapmode
);
1483 return InvalidParameter
;
1485 brush
->wrap
= wrapmode
;
1490 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1493 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1496 return InvalidParameter
;
1498 brush
->startcolor
= color1
;
1499 brush
->endcolor
= color2
;
1504 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1506 TRACE("(%p, %p)\n", brush
, colors
);
1508 if(!brush
|| !colors
)
1509 return InvalidParameter
;
1511 colors
[0] = brush
->startcolor
;
1512 colors
[1] = brush
->endcolor
;
1517 /******************************************************************************
1518 * GdipRotateTextureTransform [GDIPLUS.@]
1520 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1521 GpMatrixOrder order
)
1523 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1526 return InvalidParameter
;
1528 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1531 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1537 FIXME("not implemented\n");
1539 return NotImplemented
;
1542 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1543 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1548 FIXME("not implemented\n");
1550 return NotImplemented
;
1553 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1554 GDIPCONST GpMatrix
*matrix
)
1559 FIXME("not implemented\n");
1561 return NotImplemented
;
1564 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1565 REAL dx
, REAL dy
, GpMatrixOrder order
)
1567 FIXME("stub: %p %f %f %d\n", brush
, dx
, dy
, order
);
1569 return NotImplemented
;
1572 /******************************************************************************
1573 * GdipTranslateTextureTransform [GDIPLUS.@]
1575 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1576 GpMatrixOrder order
)
1578 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1581 return InvalidParameter
;
1583 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1586 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1588 TRACE("(%p, %p)\n", brush
, rect
);
1591 return InvalidParameter
;
1593 *rect
= brush
->rect
;
1598 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1603 TRACE("(%p, %p)\n", brush
, rect
);
1606 return InvalidParameter
;
1608 ret
= GdipGetLineRect(brush
, &rectF
);
1611 rect
->X
= roundr(rectF
.X
);
1612 rect
->Y
= roundr(rectF
.Y
);
1613 rect
->Width
= roundr(rectF
.Width
);
1614 rect
->Height
= roundr(rectF
.Height
);
1620 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1621 REAL angle
, GpMatrixOrder order
)
1626 return InvalidParameter
;
1629 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1631 return NotImplemented
;