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
);
39 Code from http://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/
43 const float a1
= 0.254829592;
44 const float a2
= -0.284496736;
45 const float a3
= 1.421413741;
46 const float a4
= -1.453152027;
47 const float a5
= 1.061405429;
48 const float p
= 0.3275911;
51 /* Save the sign of x */
59 y
= 1.0 - (((((a5
*t
+ a4
)*t
) + a3
)*t
+ a2
)*t
+ a1
)*t
*exp(-x
*x
);
64 /******************************************************************************
65 * GdipCloneBrush [GDIPLUS.@]
67 GpStatus WINGDIPAPI
GdipCloneBrush(GpBrush
*brush
, GpBrush
**clone
)
69 TRACE("(%p, %p)\n", brush
, clone
);
72 return InvalidParameter
;
75 case BrushTypeSolidColor
:
76 *clone
= GdipAlloc(sizeof(GpSolidFill
));
77 if (!*clone
) return OutOfMemory
;
79 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
81 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
83 case BrushTypeHatchFill
:
84 *clone
= GdipAlloc(sizeof(GpHatch
));
85 if (!*clone
) return OutOfMemory
;
87 memcpy(*clone
, brush
, sizeof(GpHatch
));
89 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
91 case BrushTypePathGradient
:{
92 GpPathGradient
*src
, *dest
;
95 *clone
= GdipAlloc(sizeof(GpPathGradient
));
96 if (!*clone
) return OutOfMemory
;
98 src
= (GpPathGradient
*) brush
,
99 dest
= (GpPathGradient
*) *clone
;
100 count
= src
->pathdata
.Count
;
102 memcpy(dest
, src
, sizeof(GpPathGradient
));
104 dest
->pathdata
.Count
= count
;
105 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
106 dest
->pathdata
.Types
= GdipAlloc(count
);
108 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
109 GdipFree(dest
->pathdata
.Points
);
110 GdipFree(dest
->pathdata
.Types
);
115 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
116 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
119 count
= src
->blendcount
;
120 dest
->blendcount
= count
;
121 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
122 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
124 if(!dest
->blendfac
|| !dest
->blendpos
){
125 GdipFree(dest
->pathdata
.Points
);
126 GdipFree(dest
->pathdata
.Types
);
127 GdipFree(dest
->blendfac
);
128 GdipFree(dest
->blendpos
);
133 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
134 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
138 case BrushTypeLinearGradient
:{
139 GpLineGradient
*dest
, *src
;
142 dest
= GdipAlloc(sizeof(GpLineGradient
));
143 if(!dest
) return OutOfMemory
;
145 src
= (GpLineGradient
*)brush
;
147 memcpy(dest
, src
, sizeof(GpLineGradient
));
149 dest
->brush
.gdibrush
= CreateSolidBrush(dest
->brush
.lb
.lbColor
);
151 count
= dest
->blendcount
;
152 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
153 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
155 if (!dest
->blendfac
|| !dest
->blendpos
)
157 GdipFree(dest
->blendfac
);
158 GdipFree(dest
->blendpos
);
159 DeleteObject(dest
->brush
.gdibrush
);
164 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
165 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
167 *clone
= &dest
->brush
;
170 case BrushTypeTextureFill
:
171 *clone
= GdipAlloc(sizeof(GpTexture
));
172 if(!*clone
) return OutOfMemory
;
174 memcpy(*clone
, brush
, sizeof(GpTexture
));
176 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
179 ERR("not implemented for brush type %d\n", brush
->bt
);
180 return NotImplemented
;
186 static LONG
HatchStyleToHatch(HatchStyle hatchstyle
)
190 case HatchStyleHorizontal
: return HS_HORIZONTAL
;
191 case HatchStyleVertical
: return HS_VERTICAL
;
192 case HatchStyleForwardDiagonal
: return HS_FDIAGONAL
;
193 case HatchStyleBackwardDiagonal
: return HS_BDIAGONAL
;
194 case HatchStyleCross
: return HS_CROSS
;
195 case HatchStyleDiagonalCross
: return HS_DIAGCROSS
;
200 /******************************************************************************
201 * GdipCreateHatchBrush [GDIPLUS.@]
203 GpStatus WINGDIPAPI
GdipCreateHatchBrush(HatchStyle hatchstyle
, ARGB forecol
, ARGB backcol
, GpHatch
**brush
)
205 COLORREF fgcol
= ARGB2COLORREF(forecol
);
207 TRACE("(%d, %d, %d, %p)\n", hatchstyle
, forecol
, backcol
, brush
);
209 if(!brush
) return InvalidParameter
;
211 *brush
= GdipAlloc(sizeof(GpHatch
));
212 if (!*brush
) return OutOfMemory
;
216 case HatchStyleHorizontal
:
217 case HatchStyleVertical
:
218 case HatchStyleForwardDiagonal
:
219 case HatchStyleBackwardDiagonal
:
220 case HatchStyleCross
:
221 case HatchStyleDiagonalCross
:
222 /* Brushes that map to BS_HATCHED */
223 (*brush
)->brush
.lb
.lbStyle
= BS_HATCHED
;
224 (*brush
)->brush
.lb
.lbColor
= fgcol
;
225 (*brush
)->brush
.lb
.lbHatch
= HatchStyleToHatch(hatchstyle
);
229 FIXME("Unimplemented hatch style %d\n", hatchstyle
);
231 (*brush
)->brush
.lb
.lbStyle
= BS_SOLID
;
232 (*brush
)->brush
.lb
.lbColor
= fgcol
;
233 (*brush
)->brush
.lb
.lbHatch
= 0;
238 (*brush
)->brush
.gdibrush
= CreateBrushIndirect(&(*brush
)->brush
.lb
);
239 (*brush
)->brush
.bt
= BrushTypeHatchFill
;
240 (*brush
)->forecol
= forecol
;
241 (*brush
)->backcol
= backcol
;
242 (*brush
)->hatchstyle
= hatchstyle
;
247 /******************************************************************************
248 * GdipCreateLineBrush [GDIPLUS.@]
250 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
251 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
252 GpWrapMode wrap
, GpLineGradient
**line
)
254 COLORREF col
= ARGB2COLORREF(startcolor
);
256 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
257 startcolor
, endcolor
, wrap
, line
);
259 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
260 return InvalidParameter
;
262 *line
= GdipAlloc(sizeof(GpLineGradient
));
263 if(!*line
) return OutOfMemory
;
265 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
266 (*line
)->brush
.lb
.lbColor
= col
;
267 (*line
)->brush
.lb
.lbHatch
= 0;
268 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
269 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
271 (*line
)->startpoint
.X
= startpoint
->X
;
272 (*line
)->startpoint
.Y
= startpoint
->Y
;
273 (*line
)->endpoint
.X
= endpoint
->X
;
274 (*line
)->endpoint
.Y
= endpoint
->Y
;
275 (*line
)->startcolor
= startcolor
;
276 (*line
)->endcolor
= endcolor
;
277 (*line
)->wrap
= wrap
;
278 (*line
)->gamma
= FALSE
;
280 (*line
)->rect
.X
= (startpoint
->X
< endpoint
->X
? startpoint
->X
: endpoint
->X
);
281 (*line
)->rect
.Y
= (startpoint
->Y
< endpoint
->Y
? startpoint
->Y
: endpoint
->Y
);
282 (*line
)->rect
.Width
= fabs(startpoint
->X
- endpoint
->X
);
283 (*line
)->rect
.Height
= fabs(startpoint
->Y
- endpoint
->Y
);
285 (*line
)->blendcount
= 1;
286 (*line
)->blendfac
= GdipAlloc(sizeof(REAL
));
287 (*line
)->blendpos
= GdipAlloc(sizeof(REAL
));
289 if (!(*line
)->blendfac
|| !(*line
)->blendpos
)
291 GdipFree((*line
)->blendfac
);
292 GdipFree((*line
)->blendpos
);
293 DeleteObject((*line
)->brush
.gdibrush
);
299 (*line
)->blendfac
[0] = 1.0f
;
300 (*line
)->blendpos
[0] = 1.0f
;
305 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
306 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
307 GpWrapMode wrap
, GpLineGradient
**line
)
312 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
313 startcolor
, endcolor
, wrap
, line
);
315 if(!startpoint
|| !endpoint
)
316 return InvalidParameter
;
318 stF
.X
= (REAL
)startpoint
->X
;
319 stF
.Y
= (REAL
)startpoint
->Y
;
320 endF
.X
= (REAL
)endpoint
->X
;
321 endF
.X
= (REAL
)endpoint
->Y
;
323 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
326 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
327 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
328 GpLineGradient
**line
)
333 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
337 return InvalidParameter
;
341 case LinearGradientModeHorizontal
:
344 end
.X
= rect
->X
+ rect
->Width
;
347 case LinearGradientModeVertical
:
351 end
.Y
= rect
->Y
+ rect
->Height
;
353 case LinearGradientModeForwardDiagonal
:
356 end
.X
= rect
->X
+ rect
->Width
;
357 end
.Y
= rect
->Y
+ rect
->Height
;
359 case LinearGradientModeBackwardDiagonal
:
360 start
.X
= rect
->X
+ rect
->Width
;
363 end
.Y
= rect
->Y
+ rect
->Height
;
366 return InvalidParameter
;
369 stat
= GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
372 (*line
)->rect
= *rect
;
377 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
378 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
379 GpLineGradient
**line
)
383 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
386 rectF
.X
= (REAL
) rect
->X
;
387 rectF
.Y
= (REAL
) rect
->Y
;
388 rectF
.Width
= (REAL
) rect
->Width
;
389 rectF
.Height
= (REAL
) rect
->Height
;
391 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
394 /******************************************************************************
395 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
397 * FIXME: angle value completely ignored. Don't know how to use it since native
398 * always set Brush rectangle to rect (independetly of this angle).
399 * Maybe it's used only on drawing.
401 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
402 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
403 GpLineGradient
**line
)
405 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
408 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
412 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
413 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
414 GpLineGradient
**line
)
416 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
419 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
423 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
424 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
426 COLORREF col
= ARGB2COLORREF(0xffffffff);
428 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
431 return InvalidParameter
;
436 *grad
= GdipAlloc(sizeof(GpPathGradient
));
437 if (!*grad
) return OutOfMemory
;
439 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
440 if(!(*grad
)->blendfac
){
444 (*grad
)->blendfac
[0] = 1.0;
445 (*grad
)->blendpos
= NULL
;
446 (*grad
)->blendcount
= 1;
448 (*grad
)->pathdata
.Count
= count
;
449 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
450 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
452 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
453 GdipFree((*grad
)->pathdata
.Points
);
454 GdipFree((*grad
)->pathdata
.Types
);
459 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
460 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
462 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
463 (*grad
)->brush
.lb
.lbColor
= col
;
464 (*grad
)->brush
.lb
.lbHatch
= 0;
466 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
467 (*grad
)->brush
.bt
= BrushTypePathGradient
;
468 (*grad
)->centercolor
= 0xffffffff;
469 (*grad
)->wrap
= wrap
;
470 (*grad
)->gamma
= FALSE
;
471 (*grad
)->center
.X
= 0.0;
472 (*grad
)->center
.Y
= 0.0;
473 (*grad
)->focus
.X
= 0.0;
474 (*grad
)->focus
.Y
= 0.0;
479 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
480 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
486 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
489 return InvalidParameter
;
494 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
498 for(i
= 0; i
< count
; i
++){
499 pointsF
[i
].X
= (REAL
)points
[i
].X
;
500 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
503 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
509 /******************************************************************************
510 * GdipCreatePathGradientFromPath [GDIPLUS.@]
512 * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
514 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
515 GpPathGradient
**grad
)
517 COLORREF col
= ARGB2COLORREF(0xffffffff);
519 TRACE("(%p, %p)\n", path
, grad
);
522 return InvalidParameter
;
524 *grad
= GdipAlloc(sizeof(GpPathGradient
));
525 if (!*grad
) return OutOfMemory
;
527 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
528 if(!(*grad
)->blendfac
){
532 (*grad
)->blendfac
[0] = 1.0;
533 (*grad
)->blendpos
= NULL
;
534 (*grad
)->blendcount
= 1;
536 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
537 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
538 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
540 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
541 GdipFree((*grad
)->pathdata
.Points
);
542 GdipFree((*grad
)->pathdata
.Types
);
547 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
548 path
->pathdata
.Count
* sizeof(PointF
));
549 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
551 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
552 (*grad
)->brush
.lb
.lbColor
= col
;
553 (*grad
)->brush
.lb
.lbHatch
= 0;
555 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
556 (*grad
)->brush
.bt
= BrushTypePathGradient
;
557 (*grad
)->centercolor
= 0xffffffff;
558 (*grad
)->wrap
= WrapModeClamp
;
559 (*grad
)->gamma
= FALSE
;
560 /* FIXME: this should be set to the "centroid" of the path by default */
561 (*grad
)->center
.X
= 0.0;
562 (*grad
)->center
.Y
= 0.0;
563 (*grad
)->focus
.X
= 0.0;
564 (*grad
)->focus
.Y
= 0.0;
569 /******************************************************************************
570 * GdipCreateSolidFill [GDIPLUS.@]
572 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
574 COLORREF col
= ARGB2COLORREF(color
);
576 TRACE("(%x, %p)\n", color
, sf
);
578 if(!sf
) return InvalidParameter
;
580 *sf
= GdipAlloc(sizeof(GpSolidFill
));
581 if (!*sf
) return OutOfMemory
;
583 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
584 (*sf
)->brush
.lb
.lbColor
= col
;
585 (*sf
)->brush
.lb
.lbHatch
= 0;
587 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
588 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
589 (*sf
)->color
= color
;
594 /******************************************************************************
595 * GdipCreateTexture [GDIPLUS.@]
598 * image [I] image to use
599 * wrapmode [I] optional
600 * texture [O] pointer to the resulting texturebrush
604 * FAILURE: element of GpStatus
606 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
610 GpImageAttributes attributes
;
613 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
615 if (!(image
&& texture
))
616 return InvalidParameter
;
618 stat
= GdipGetImageWidth(image
, &width
);
619 if (stat
!= Ok
) return stat
;
620 stat
= GdipGetImageHeight(image
, &height
);
621 if (stat
!= Ok
) return stat
;
622 attributes
.wrap
= wrapmode
;
624 return GdipCreateTextureIA(image
, &attributes
, 0, 0, width
, height
,
628 /******************************************************************************
629 * GdipCreateTexture2 [GDIPLUS.@]
631 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
632 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
634 GpImageAttributes attributes
;
636 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
637 x
, y
, width
, height
, texture
);
639 attributes
.wrap
= wrapmode
;
640 return GdipCreateTextureIA(image
, &attributes
, x
, y
, width
, height
,
644 /******************************************************************************
645 * GdipCreateTextureIA [GDIPLUS.@]
647 * FIXME: imageattr ignored
649 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
650 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
651 REAL height
, GpTexture
**texture
)
654 HBITMAP hbm
, old
= NULL
;
656 BITMAPINFOHEADER
*bmih
;
657 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
659 BYTE
*dibits
, *buff
, *textbits
;
662 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
665 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
666 return InvalidParameter
;
668 if(image
->type
!= ImageTypeBitmap
){
669 FIXME("not implemented for image type %d\n", image
->type
);
670 return NotImplemented
;
675 n_width
= roundr(width
);
676 n_height
= roundr(height
);
678 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
679 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
680 return InvalidParameter
;
682 IPicture_get_Handle(image
->picture
, (OLE_HANDLE
*)&hbm
);
683 if(!hbm
) return GenericError
;
684 IPicture_get_CurDC(image
->picture
, &hdc
);
685 bm_is_selected
= (hdc
!= 0);
687 pbmi
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
690 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
691 pbmi
->bmiHeader
.biBitCount
= 0;
694 hdc
= CreateCompatibleDC(0);
695 old
= SelectObject(hdc
, hbm
);
699 GetDIBits(hdc
, hbm
, 0, 0, NULL
, pbmi
, DIB_RGB_COLORS
);
701 bytespp
= pbmi
->bmiHeader
.biBitCount
/ 8;
702 abs_height
= abs(pbmi
->bmiHeader
.biHeight
);
704 if(n_x
> pbmi
->bmiHeader
.biWidth
|| n_x
+ n_width
> pbmi
->bmiHeader
.biWidth
||
705 n_y
> abs_height
|| n_y
+ n_height
> abs_height
){
707 return InvalidParameter
;
710 dibits
= GdipAlloc(pbmi
->bmiHeader
.biSizeImage
);
712 if(dibits
) /* this is not a good place to error out */
713 GetDIBits(hdc
, hbm
, 0, abs_height
, dibits
, pbmi
, DIB_RGB_COLORS
);
716 SelectObject(hdc
, old
);
725 image_stride
= (pbmi
->bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
726 stride
= (n_width
* bytespp
+ 3) & ~3;
727 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
734 bmih
= (BITMAPINFOHEADER
*)buff
;
735 textbits
= (BYTE
*) (bmih
+ 1);
736 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
737 bmih
->biWidth
= n_width
;
738 bmih
->biHeight
= n_height
;
739 bmih
->biCompression
= BI_RGB
;
740 bmih
->biSizeImage
= stride
* n_height
;
741 bmih
->biBitCount
= pbmi
->bmiHeader
.biBitCount
;
745 /* image is flipped */
746 if(pbmi
->bmiHeader
.biHeight
> 0){
747 dibits
+= pbmi
->bmiHeader
.biSizeImage
;
749 textbits
+= stride
* (n_height
- 1);
755 for(i
= 0; i
< n_height
; i
++)
756 memcpy(&textbits
[i
* stride
],
757 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
760 *texture
= GdipAlloc(sizeof(GpTexture
));
767 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
774 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
775 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
776 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
778 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
779 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
780 (*texture
)->wrap
= imageattr
->wrap
;
788 /******************************************************************************
789 * GdipCreateTextureIAI [GDIPLUS.@]
791 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
792 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
794 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
797 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
800 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
801 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
803 GpImageAttributes imageattr
;
805 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
808 imageattr
.wrap
= wrapmode
;
810 return GdipCreateTextureIA(image
, &imageattr
, x
, y
, width
, height
, texture
);
813 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
815 TRACE("(%p, %p)\n", brush
, type
);
817 if(!brush
|| !type
) return InvalidParameter
;
824 GpStatus WINGDIPAPI
GdipGetHatchBackgroundColor(GpHatch
*brush
, ARGB
*backcol
)
826 TRACE("(%p, %p)\n", brush
, backcol
);
828 if(!brush
|| !backcol
) return InvalidParameter
;
830 *backcol
= brush
->backcol
;
835 GpStatus WINGDIPAPI
GdipGetHatchForegroundColor(GpHatch
*brush
, ARGB
*forecol
)
837 TRACE("(%p, %p)\n", brush
, forecol
);
839 if(!brush
|| !forecol
) return InvalidParameter
;
841 *forecol
= brush
->forecol
;
846 GpStatus WINGDIPAPI
GdipGetHatchStyle(GpHatch
*brush
, HatchStyle
*hatchstyle
)
848 TRACE("(%p, %p)\n", brush
, hatchstyle
);
850 if(!brush
|| !hatchstyle
) return InvalidParameter
;
852 *hatchstyle
= brush
->hatchstyle
;
857 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
859 TRACE("(%p)\n", brush
);
861 if(!brush
) return InvalidParameter
;
865 case BrushTypePathGradient
:
866 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
867 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
868 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
869 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
871 case BrushTypeSolidColor
:
873 case BrushTypeLinearGradient
:
874 GdipFree(((GpLineGradient
*)brush
)->blendfac
);
875 GdipFree(((GpLineGradient
*)brush
)->blendpos
);
877 case BrushTypeTextureFill
:
878 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
884 DeleteObject(brush
->gdibrush
);
890 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
893 TRACE("(%p, %p)\n", line
, usinggamma
);
895 if(!line
|| !usinggamma
)
896 return InvalidParameter
;
898 *usinggamma
= line
->gamma
;
903 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
905 TRACE("(%p, %p)\n", brush
, wrapmode
);
907 if(!brush
|| !wrapmode
)
908 return InvalidParameter
;
910 *wrapmode
= brush
->wrap
;
915 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
916 REAL
*positions
, INT count
)
918 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
920 if(!brush
|| !blend
|| !positions
|| count
<= 0)
921 return InvalidParameter
;
923 if(count
< brush
->blendcount
)
924 return InsufficientBuffer
;
926 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
927 if(brush
->blendcount
> 1){
928 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
934 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
936 TRACE("(%p, %p)\n", brush
, count
);
939 return InvalidParameter
;
941 *count
= brush
->blendcount
;
946 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
949 TRACE("(%p, %p)\n", grad
, point
);
952 return InvalidParameter
;
954 point
->X
= grad
->center
.X
;
955 point
->Y
= grad
->center
.Y
;
960 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
966 TRACE("(%p, %p)\n", grad
, point
);
969 return InvalidParameter
;
971 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
974 point
->X
= roundr(ptf
.X
);
975 point
->Y
= roundr(ptf
.Y
);
981 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
984 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
986 if(!grad
|| !x
|| !y
)
987 return InvalidParameter
;
995 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
998 TRACE("(%p, %p)\n", grad
, gamma
);
1001 return InvalidParameter
;
1003 *gamma
= grad
->gamma
;
1008 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
1011 TRACE("(%p, %p)\n", grad
, count
);
1014 return InvalidParameter
;
1016 *count
= grad
->pathdata
.Count
;
1021 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
1027 TRACE("(%p, %p)\n", brush
, rect
);
1030 return InvalidParameter
;
1032 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
1033 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
1034 if(stat
!= Ok
) return stat
;
1036 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
1038 GdipDeletePath(path
);
1042 memcpy(rect
, &r
, sizeof(GpRectF
));
1044 GdipDeletePath(path
);
1049 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
1054 TRACE("(%p, %p)\n", brush
, rect
);
1057 return InvalidParameter
;
1059 stat
= GdipGetPathGradientRect(brush
, &rectf
);
1060 if(stat
!= Ok
) return stat
;
1062 rect
->X
= roundr(rectf
.X
);
1063 rect
->Y
= roundr(rectf
.Y
);
1064 rect
->Width
= roundr(rectf
.Width
);
1065 rect
->Height
= roundr(rectf
.Height
);
1070 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
1071 *grad
, ARGB
*argb
, INT
*count
)
1075 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
1076 return InvalidParameter
;
1079 FIXME("not implemented\n");
1081 return NotImplemented
;
1084 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
1085 GpWrapMode
*wrapmode
)
1087 TRACE("(%p, %p)\n", brush
, wrapmode
);
1089 if(!brush
|| !wrapmode
)
1090 return InvalidParameter
;
1092 *wrapmode
= brush
->wrap
;
1097 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
1099 TRACE("(%p, %p)\n", sf
, argb
);
1102 return InvalidParameter
;
1109 /******************************************************************************
1110 * GdipGetTextureTransform [GDIPLUS.@]
1112 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
1114 TRACE("(%p, %p)\n", brush
, matrix
);
1116 if(!brush
|| !matrix
)
1117 return InvalidParameter
;
1119 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
1124 /******************************************************************************
1125 * GdipGetTextureWrapMode [GDIPLUS.@]
1127 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
1129 TRACE("(%p, %p)\n", brush
, wrapmode
);
1131 if(!brush
|| !wrapmode
)
1132 return InvalidParameter
;
1134 *wrapmode
= brush
->wrap
;
1139 /******************************************************************************
1140 * GdipMultiplyTextureTransform [GDIPLUS.@]
1142 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
1143 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1145 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
1147 if(!brush
|| !matrix
)
1148 return InvalidParameter
;
1150 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
1153 /******************************************************************************
1154 * GdipResetTextureTransform [GDIPLUS.@]
1156 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
1158 TRACE("(%p)\n", brush
);
1161 return InvalidParameter
;
1163 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1166 /******************************************************************************
1167 * GdipScaleTextureTransform [GDIPLUS.@]
1169 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
1170 REAL sx
, REAL sy
, GpMatrixOrder order
)
1172 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
1175 return InvalidParameter
;
1177 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
1180 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
1181 GDIPCONST REAL
*factors
, GDIPCONST REAL
* positions
, INT count
)
1183 REAL
*new_blendfac
, *new_blendpos
;
1185 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1187 if(!brush
|| !factors
|| !positions
|| count
<= 0 ||
1188 (count
>= 2 && (positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)))
1189 return InvalidParameter
;
1191 new_blendfac
= GdipAlloc(count
* sizeof(REAL
));
1192 new_blendpos
= GdipAlloc(count
* sizeof(REAL
));
1194 if (!new_blendfac
|| !new_blendpos
)
1196 GdipFree(new_blendfac
);
1197 GdipFree(new_blendpos
);
1201 memcpy(new_blendfac
, factors
, count
* sizeof(REAL
));
1202 memcpy(new_blendpos
, positions
, count
* sizeof(REAL
));
1204 GdipFree(brush
->blendfac
);
1205 GdipFree(brush
->blendpos
);
1207 brush
->blendcount
= count
;
1208 brush
->blendfac
= new_blendfac
;
1209 brush
->blendpos
= new_blendpos
;
1214 GpStatus WINGDIPAPI
GdipGetLineBlend(GpLineGradient
*brush
, REAL
*factors
,
1215 REAL
*positions
, INT count
)
1217 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1219 if (!brush
|| !factors
|| !positions
|| count
<= 0)
1220 return InvalidParameter
;
1222 if (count
< brush
->blendcount
)
1223 return InsufficientBuffer
;
1225 memcpy(factors
, brush
->blendfac
, brush
->blendcount
* sizeof(REAL
));
1226 memcpy(positions
, brush
->blendpos
, brush
->blendcount
* sizeof(REAL
));
1231 GpStatus WINGDIPAPI
GdipGetLineBlendCount(GpLineGradient
*brush
, INT
*count
)
1233 TRACE("(%p, %p)\n", brush
, count
);
1235 if (!brush
|| !count
)
1236 return InvalidParameter
;
1238 *count
= brush
->blendcount
;
1243 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
1246 TRACE("(%p, %d)\n", line
, usegamma
);
1249 return InvalidParameter
;
1251 line
->gamma
= usegamma
;
1256 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1263 const int precision
= 16;
1264 REAL erf_range
; /* we use values erf(-erf_range) through erf(+erf_range) */
1268 TRACE("(%p, %0.2f, %0.2f)\n", line
, focus
, scale
);
1270 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1271 return InvalidParameter
;
1273 /* we want 2 standard deviations */
1274 erf_range
= 2.0 / sqrt(2);
1276 /* calculate the constants we need to normalize the error function to be
1277 between 0.0 and scale over the range we need */
1278 min_erf
= erf(-erf_range
);
1279 scale_erf
= scale
/ (-2.0 * min_erf
);
1285 for (i
=1; i
<precision
; i
++)
1287 positions
[i
] = focus
* i
/ precision
;
1288 factors
[i
] = scale_erf
* (erf(2 * erf_range
* i
/ precision
- erf_range
) - min_erf
);
1290 num_points
+= precision
;
1293 positions
[num_points
] = focus
;
1294 factors
[num_points
] = scale
;
1299 for (i
=1; i
<precision
; i
++)
1301 positions
[i
+num_points
-1] = (focus
+ ((1.0-focus
) * i
/ precision
));
1302 factors
[i
+num_points
-1] = scale_erf
* (erf(erf_range
- 2 * erf_range
* i
/ precision
) - min_erf
);
1304 num_points
+= precision
;
1305 positions
[num_points
-1] = 1.0;
1306 factors
[num_points
-1] = 0.0;
1309 return GdipSetLineBlend(line
, factors
, positions
, num_points
);
1312 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1315 TRACE("(%p, %d)\n", line
, wrap
);
1317 if(!line
|| wrap
== WrapModeClamp
)
1318 return InvalidParameter
;
1325 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1326 GDIPCONST REAL
*pos
, INT count
)
1331 FIXME("not implemented\n");
1333 return NotImplemented
;
1336 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1339 TRACE("(%p, %x)\n", grad
, argb
);
1342 return InvalidParameter
;
1344 grad
->centercolor
= argb
;
1345 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1347 DeleteObject(grad
->brush
.gdibrush
);
1348 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
1353 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1356 TRACE("(%p, %p)\n", grad
, point
);
1359 return InvalidParameter
;
1361 grad
->center
.X
= point
->X
;
1362 grad
->center
.Y
= point
->Y
;
1367 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1372 TRACE("(%p, %p)\n", grad
, point
);
1375 return InvalidParameter
;
1377 ptf
.X
= (REAL
)point
->X
;
1378 ptf
.Y
= (REAL
)point
->Y
;
1380 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1383 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1386 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1389 return InvalidParameter
;
1397 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1400 TRACE("(%p, %d)\n", grad
, gamma
);
1403 return InvalidParameter
;
1405 grad
->gamma
= gamma
;
1410 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1411 REAL focus
, REAL scale
)
1415 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1416 return InvalidParameter
;
1419 FIXME("not implemented\n");
1421 return NotImplemented
;
1424 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1425 *grad
, ARGB
*argb
, INT
*count
)
1429 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1430 (*count
> grad
->pathdata
.Count
))
1431 return InvalidParameter
;
1434 FIXME("not implemented\n");
1436 return NotImplemented
;
1439 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1442 TRACE("(%p, %d)\n", grad
, wrap
);
1445 return InvalidParameter
;
1452 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1454 TRACE("(%p, %x)\n", sf
, argb
);
1457 return InvalidParameter
;
1460 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1462 DeleteObject(sf
->brush
.gdibrush
);
1463 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
1468 /******************************************************************************
1469 * GdipSetTextureTransform [GDIPLUS.@]
1471 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1472 GDIPCONST GpMatrix
*matrix
)
1474 TRACE("(%p, %p)\n", texture
, matrix
);
1476 if(!texture
|| !matrix
)
1477 return InvalidParameter
;
1479 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1484 /******************************************************************************
1485 * GdipSetTextureWrapMode [GDIPLUS.@]
1487 * WrapMode not used, only stored
1489 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1491 TRACE("(%p, %d)\n", brush
, wrapmode
);
1494 return InvalidParameter
;
1496 brush
->wrap
= wrapmode
;
1501 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1504 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1507 return InvalidParameter
;
1509 brush
->startcolor
= color1
;
1510 brush
->endcolor
= color2
;
1515 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1517 TRACE("(%p, %p)\n", brush
, colors
);
1519 if(!brush
|| !colors
)
1520 return InvalidParameter
;
1522 colors
[0] = brush
->startcolor
;
1523 colors
[1] = brush
->endcolor
;
1528 /******************************************************************************
1529 * GdipRotateTextureTransform [GDIPLUS.@]
1531 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1532 GpMatrixOrder order
)
1534 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1537 return InvalidParameter
;
1539 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1542 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1548 FIXME("not implemented\n");
1550 return NotImplemented
;
1553 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1554 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1559 FIXME("not implemented\n");
1561 return NotImplemented
;
1564 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1565 GDIPCONST GpMatrix
*matrix
)
1570 FIXME("not implemented\n");
1572 return NotImplemented
;
1575 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1576 REAL dx
, REAL dy
, GpMatrixOrder order
)
1578 FIXME("stub: %p %f %f %d\n", brush
, dx
, dy
, order
);
1580 return NotImplemented
;
1583 /******************************************************************************
1584 * GdipTranslateTextureTransform [GDIPLUS.@]
1586 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1587 GpMatrixOrder order
)
1589 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1592 return InvalidParameter
;
1594 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1597 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1599 TRACE("(%p, %p)\n", brush
, rect
);
1602 return InvalidParameter
;
1604 *rect
= brush
->rect
;
1609 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1614 TRACE("(%p, %p)\n", brush
, rect
);
1617 return InvalidParameter
;
1619 ret
= GdipGetLineRect(brush
, &rectF
);
1622 rect
->X
= roundr(rectF
.X
);
1623 rect
->Y
= roundr(rectF
.Y
);
1624 rect
->Width
= roundr(rectF
.Width
);
1625 rect
->Height
= roundr(rectF
.Height
);
1631 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1632 REAL angle
, GpMatrixOrder order
)
1637 return InvalidParameter
;
1640 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1642 return NotImplemented
;