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
:
78 *clone
= GdipAlloc(sizeof(GpSolidFill
));
79 if (!*clone
) return OutOfMemory
;
81 fill
= (GpSolidFill
*)*clone
;
83 memcpy(*clone
, brush
, sizeof(GpSolidFill
));
85 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
86 fill
->bmp
= ARGB2BMP(fill
->color
);
89 case BrushTypeHatchFill
:
90 *clone
= GdipAlloc(sizeof(GpHatch
));
91 if (!*clone
) return OutOfMemory
;
93 memcpy(*clone
, brush
, sizeof(GpHatch
));
95 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
97 case BrushTypePathGradient
:{
98 GpPathGradient
*src
, *dest
;
101 *clone
= GdipAlloc(sizeof(GpPathGradient
));
102 if (!*clone
) return OutOfMemory
;
104 src
= (GpPathGradient
*) brush
,
105 dest
= (GpPathGradient
*) *clone
;
106 count
= src
->pathdata
.Count
;
108 memcpy(dest
, src
, sizeof(GpPathGradient
));
110 dest
->pathdata
.Count
= count
;
111 dest
->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
112 dest
->pathdata
.Types
= GdipAlloc(count
);
114 if(!dest
->pathdata
.Points
|| !dest
->pathdata
.Types
){
115 GdipFree(dest
->pathdata
.Points
);
116 GdipFree(dest
->pathdata
.Types
);
121 memcpy(dest
->pathdata
.Points
, src
->pathdata
.Points
, count
* sizeof(PointF
));
122 memcpy(dest
->pathdata
.Types
, src
->pathdata
.Types
, count
);
125 count
= src
->blendcount
;
126 dest
->blendcount
= count
;
127 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
128 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
130 if(!dest
->blendfac
|| !dest
->blendpos
){
131 GdipFree(dest
->pathdata
.Points
);
132 GdipFree(dest
->pathdata
.Types
);
133 GdipFree(dest
->blendfac
);
134 GdipFree(dest
->blendpos
);
139 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
140 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
144 case BrushTypeLinearGradient
:{
145 GpLineGradient
*dest
, *src
;
148 dest
= GdipAlloc(sizeof(GpLineGradient
));
149 if(!dest
) return OutOfMemory
;
151 src
= (GpLineGradient
*)brush
;
153 memcpy(dest
, src
, sizeof(GpLineGradient
));
155 dest
->brush
.gdibrush
= CreateSolidBrush(dest
->brush
.lb
.lbColor
);
157 count
= dest
->blendcount
;
158 dest
->blendfac
= GdipAlloc(count
* sizeof(REAL
));
159 dest
->blendpos
= GdipAlloc(count
* sizeof(REAL
));
161 if (!dest
->blendfac
|| !dest
->blendpos
)
163 GdipFree(dest
->blendfac
);
164 GdipFree(dest
->blendpos
);
165 DeleteObject(dest
->brush
.gdibrush
);
170 memcpy(dest
->blendfac
, src
->blendfac
, count
* sizeof(REAL
));
171 memcpy(dest
->blendpos
, src
->blendpos
, count
* sizeof(REAL
));
173 *clone
= &dest
->brush
;
176 case BrushTypeTextureFill
:
177 *clone
= GdipAlloc(sizeof(GpTexture
));
178 if(!*clone
) return OutOfMemory
;
180 memcpy(*clone
, brush
, sizeof(GpTexture
));
182 (*clone
)->gdibrush
= CreateBrushIndirect(&(*clone
)->lb
);
185 ERR("not implemented for brush type %d\n", brush
->bt
);
186 return NotImplemented
;
192 static LONG
HatchStyleToHatch(HatchStyle hatchstyle
)
196 case HatchStyleHorizontal
: return HS_HORIZONTAL
;
197 case HatchStyleVertical
: return HS_VERTICAL
;
198 case HatchStyleForwardDiagonal
: return HS_FDIAGONAL
;
199 case HatchStyleBackwardDiagonal
: return HS_BDIAGONAL
;
200 case HatchStyleCross
: return HS_CROSS
;
201 case HatchStyleDiagonalCross
: return HS_DIAGCROSS
;
206 /******************************************************************************
207 * GdipCreateHatchBrush [GDIPLUS.@]
209 GpStatus WINGDIPAPI
GdipCreateHatchBrush(HatchStyle hatchstyle
, ARGB forecol
, ARGB backcol
, GpHatch
**brush
)
211 COLORREF fgcol
= ARGB2COLORREF(forecol
);
213 TRACE("(%d, %d, %d, %p)\n", hatchstyle
, forecol
, backcol
, brush
);
215 if(!brush
) return InvalidParameter
;
217 *brush
= GdipAlloc(sizeof(GpHatch
));
218 if (!*brush
) return OutOfMemory
;
222 case HatchStyleHorizontal
:
223 case HatchStyleVertical
:
224 case HatchStyleForwardDiagonal
:
225 case HatchStyleBackwardDiagonal
:
226 case HatchStyleCross
:
227 case HatchStyleDiagonalCross
:
228 /* Brushes that map to BS_HATCHED */
229 (*brush
)->brush
.lb
.lbStyle
= BS_HATCHED
;
230 (*brush
)->brush
.lb
.lbColor
= fgcol
;
231 (*brush
)->brush
.lb
.lbHatch
= HatchStyleToHatch(hatchstyle
);
235 FIXME("Unimplemented hatch style %d\n", hatchstyle
);
237 (*brush
)->brush
.lb
.lbStyle
= BS_SOLID
;
238 (*brush
)->brush
.lb
.lbColor
= fgcol
;
239 (*brush
)->brush
.lb
.lbHatch
= 0;
244 (*brush
)->brush
.gdibrush
= CreateBrushIndirect(&(*brush
)->brush
.lb
);
245 (*brush
)->brush
.bt
= BrushTypeHatchFill
;
246 (*brush
)->forecol
= forecol
;
247 (*brush
)->backcol
= backcol
;
248 (*brush
)->hatchstyle
= hatchstyle
;
253 /******************************************************************************
254 * GdipCreateLineBrush [GDIPLUS.@]
256 GpStatus WINGDIPAPI
GdipCreateLineBrush(GDIPCONST GpPointF
* startpoint
,
257 GDIPCONST GpPointF
* endpoint
, ARGB startcolor
, ARGB endcolor
,
258 GpWrapMode wrap
, GpLineGradient
**line
)
260 COLORREF col
= ARGB2COLORREF(startcolor
);
262 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
263 startcolor
, endcolor
, wrap
, line
);
265 if(!line
|| !startpoint
|| !endpoint
|| wrap
== WrapModeClamp
)
266 return InvalidParameter
;
268 *line
= GdipAlloc(sizeof(GpLineGradient
));
269 if(!*line
) return OutOfMemory
;
271 (*line
)->brush
.lb
.lbStyle
= BS_SOLID
;
272 (*line
)->brush
.lb
.lbColor
= col
;
273 (*line
)->brush
.lb
.lbHatch
= 0;
274 (*line
)->brush
.gdibrush
= CreateSolidBrush(col
);
275 (*line
)->brush
.bt
= BrushTypeLinearGradient
;
277 (*line
)->startpoint
.X
= startpoint
->X
;
278 (*line
)->startpoint
.Y
= startpoint
->Y
;
279 (*line
)->endpoint
.X
= endpoint
->X
;
280 (*line
)->endpoint
.Y
= endpoint
->Y
;
281 (*line
)->startcolor
= startcolor
;
282 (*line
)->endcolor
= endcolor
;
283 (*line
)->wrap
= wrap
;
284 (*line
)->gamma
= FALSE
;
286 (*line
)->rect
.X
= (startpoint
->X
< endpoint
->X
? startpoint
->X
: endpoint
->X
);
287 (*line
)->rect
.Y
= (startpoint
->Y
< endpoint
->Y
? startpoint
->Y
: endpoint
->Y
);
288 (*line
)->rect
.Width
= fabs(startpoint
->X
- endpoint
->X
);
289 (*line
)->rect
.Height
= fabs(startpoint
->Y
- endpoint
->Y
);
291 if ((*line
)->rect
.Width
== 0)
293 (*line
)->rect
.X
-= (*line
)->rect
.Height
/ 2.0f
;
294 (*line
)->rect
.Width
= (*line
)->rect
.Height
;
296 else if ((*line
)->rect
.Height
== 0)
298 (*line
)->rect
.Y
-= (*line
)->rect
.Width
/ 2.0f
;
299 (*line
)->rect
.Height
= (*line
)->rect
.Width
;
302 (*line
)->blendcount
= 1;
303 (*line
)->blendfac
= GdipAlloc(sizeof(REAL
));
304 (*line
)->blendpos
= GdipAlloc(sizeof(REAL
));
306 if (!(*line
)->blendfac
|| !(*line
)->blendpos
)
308 GdipFree((*line
)->blendfac
);
309 GdipFree((*line
)->blendpos
);
310 DeleteObject((*line
)->brush
.gdibrush
);
316 (*line
)->blendfac
[0] = 1.0f
;
317 (*line
)->blendpos
[0] = 1.0f
;
322 GpStatus WINGDIPAPI
GdipCreateLineBrushI(GDIPCONST GpPoint
* startpoint
,
323 GDIPCONST GpPoint
* endpoint
, ARGB startcolor
, ARGB endcolor
,
324 GpWrapMode wrap
, GpLineGradient
**line
)
329 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint
, endpoint
,
330 startcolor
, endcolor
, wrap
, line
);
332 if(!startpoint
|| !endpoint
)
333 return InvalidParameter
;
335 stF
.X
= (REAL
)startpoint
->X
;
336 stF
.Y
= (REAL
)startpoint
->Y
;
337 endF
.X
= (REAL
)endpoint
->X
;
338 endF
.X
= (REAL
)endpoint
->Y
;
340 return GdipCreateLineBrush(&stF
, &endF
, startcolor
, endcolor
, wrap
, line
);
343 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRect(GDIPCONST GpRectF
* rect
,
344 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
345 GpLineGradient
**line
)
350 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
354 return InvalidParameter
;
358 case LinearGradientModeHorizontal
:
361 end
.X
= rect
->X
+ rect
->Width
;
364 case LinearGradientModeVertical
:
368 end
.Y
= rect
->Y
+ rect
->Height
;
370 case LinearGradientModeForwardDiagonal
:
373 end
.X
= rect
->X
+ rect
->Width
;
374 end
.Y
= rect
->Y
+ rect
->Height
;
376 case LinearGradientModeBackwardDiagonal
:
377 start
.X
= rect
->X
+ rect
->Width
;
380 end
.Y
= rect
->Y
+ rect
->Height
;
383 return InvalidParameter
;
386 stat
= GdipCreateLineBrush(&start
, &end
, startcolor
, endcolor
, wrap
, line
);
389 (*line
)->rect
= *rect
;
394 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectI(GDIPCONST GpRect
* rect
,
395 ARGB startcolor
, ARGB endcolor
, LinearGradientMode mode
, GpWrapMode wrap
,
396 GpLineGradient
**line
)
400 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect
, startcolor
, endcolor
, mode
,
403 rectF
.X
= (REAL
) rect
->X
;
404 rectF
.Y
= (REAL
) rect
->Y
;
405 rectF
.Width
= (REAL
) rect
->Width
;
406 rectF
.Height
= (REAL
) rect
->Height
;
408 return GdipCreateLineBrushFromRect(&rectF
, startcolor
, endcolor
, mode
, wrap
, line
);
411 /******************************************************************************
412 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
414 * FIXME: angle value completely ignored. Don't know how to use it since native
415 * always set Brush rectangle to rect (independetly of this angle).
416 * Maybe it's used only on drawing.
418 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF
* rect
,
419 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
420 GpLineGradient
**line
)
422 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
425 return GdipCreateLineBrushFromRect(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
429 GpStatus WINGDIPAPI
GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect
* rect
,
430 ARGB startcolor
, ARGB endcolor
, REAL angle
, BOOL isAngleScalable
, GpWrapMode wrap
,
431 GpLineGradient
**line
)
433 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect
, startcolor
, endcolor
, angle
, isAngleScalable
,
436 return GdipCreateLineBrushFromRectI(rect
, startcolor
, endcolor
, LinearGradientModeForwardDiagonal
,
440 GpStatus WINGDIPAPI
GdipCreatePathGradient(GDIPCONST GpPointF
* points
,
441 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
443 COLORREF col
= ARGB2COLORREF(0xffffffff);
445 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
448 return InvalidParameter
;
453 *grad
= GdipAlloc(sizeof(GpPathGradient
));
454 if (!*grad
) return OutOfMemory
;
456 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
457 if(!(*grad
)->blendfac
){
461 (*grad
)->blendfac
[0] = 1.0;
462 (*grad
)->blendpos
= NULL
;
463 (*grad
)->blendcount
= 1;
465 (*grad
)->pathdata
.Count
= count
;
466 (*grad
)->pathdata
.Points
= GdipAlloc(count
* sizeof(PointF
));
467 (*grad
)->pathdata
.Types
= GdipAlloc(count
);
469 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
470 GdipFree((*grad
)->pathdata
.Points
);
471 GdipFree((*grad
)->pathdata
.Types
);
476 memcpy((*grad
)->pathdata
.Points
, points
, count
* sizeof(PointF
));
477 memset((*grad
)->pathdata
.Types
, PathPointTypeLine
, count
);
479 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
480 (*grad
)->brush
.lb
.lbColor
= col
;
481 (*grad
)->brush
.lb
.lbHatch
= 0;
483 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
484 (*grad
)->brush
.bt
= BrushTypePathGradient
;
485 (*grad
)->centercolor
= 0xffffffff;
486 (*grad
)->wrap
= wrap
;
487 (*grad
)->gamma
= FALSE
;
488 (*grad
)->center
.X
= 0.0;
489 (*grad
)->center
.Y
= 0.0;
490 (*grad
)->focus
.X
= 0.0;
491 (*grad
)->focus
.Y
= 0.0;
496 GpStatus WINGDIPAPI
GdipCreatePathGradientI(GDIPCONST GpPoint
* points
,
497 INT count
, GpWrapMode wrap
, GpPathGradient
**grad
)
503 TRACE("(%p, %d, %d, %p)\n", points
, count
, wrap
, grad
);
506 return InvalidParameter
;
511 pointsF
= GdipAlloc(sizeof(GpPointF
) * count
);
515 for(i
= 0; i
< count
; i
++){
516 pointsF
[i
].X
= (REAL
)points
[i
].X
;
517 pointsF
[i
].Y
= (REAL
)points
[i
].Y
;
520 ret
= GdipCreatePathGradient(pointsF
, count
, wrap
, grad
);
526 /******************************************************************************
527 * GdipCreatePathGradientFromPath [GDIPLUS.@]
529 * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
531 GpStatus WINGDIPAPI
GdipCreatePathGradientFromPath(GDIPCONST GpPath
* path
,
532 GpPathGradient
**grad
)
534 COLORREF col
= ARGB2COLORREF(0xffffffff);
536 TRACE("(%p, %p)\n", path
, grad
);
539 return InvalidParameter
;
541 *grad
= GdipAlloc(sizeof(GpPathGradient
));
542 if (!*grad
) return OutOfMemory
;
544 (*grad
)->blendfac
= GdipAlloc(sizeof(REAL
));
545 if(!(*grad
)->blendfac
){
549 (*grad
)->blendfac
[0] = 1.0;
550 (*grad
)->blendpos
= NULL
;
551 (*grad
)->blendcount
= 1;
553 (*grad
)->pathdata
.Count
= path
->pathdata
.Count
;
554 (*grad
)->pathdata
.Points
= GdipAlloc(path
->pathdata
.Count
* sizeof(PointF
));
555 (*grad
)->pathdata
.Types
= GdipAlloc(path
->pathdata
.Count
);
557 if(!(*grad
)->pathdata
.Points
|| !(*grad
)->pathdata
.Types
){
558 GdipFree((*grad
)->pathdata
.Points
);
559 GdipFree((*grad
)->pathdata
.Types
);
564 memcpy((*grad
)->pathdata
.Points
, path
->pathdata
.Points
,
565 path
->pathdata
.Count
* sizeof(PointF
));
566 memcpy((*grad
)->pathdata
.Types
, path
->pathdata
.Types
, path
->pathdata
.Count
);
568 (*grad
)->brush
.lb
.lbStyle
= BS_SOLID
;
569 (*grad
)->brush
.lb
.lbColor
= col
;
570 (*grad
)->brush
.lb
.lbHatch
= 0;
572 (*grad
)->brush
.gdibrush
= CreateSolidBrush(col
);
573 (*grad
)->brush
.bt
= BrushTypePathGradient
;
574 (*grad
)->centercolor
= 0xffffffff;
575 (*grad
)->wrap
= WrapModeClamp
;
576 (*grad
)->gamma
= FALSE
;
577 /* FIXME: this should be set to the "centroid" of the path by default */
578 (*grad
)->center
.X
= 0.0;
579 (*grad
)->center
.Y
= 0.0;
580 (*grad
)->focus
.X
= 0.0;
581 (*grad
)->focus
.Y
= 0.0;
586 /******************************************************************************
587 * GdipCreateSolidFill [GDIPLUS.@]
589 GpStatus WINGDIPAPI
GdipCreateSolidFill(ARGB color
, GpSolidFill
**sf
)
591 COLORREF col
= ARGB2COLORREF(color
);
593 TRACE("(%x, %p)\n", color
, sf
);
595 if(!sf
) return InvalidParameter
;
597 *sf
= GdipAlloc(sizeof(GpSolidFill
));
598 if (!*sf
) return OutOfMemory
;
600 (*sf
)->brush
.lb
.lbStyle
= BS_SOLID
;
601 (*sf
)->brush
.lb
.lbColor
= col
;
602 (*sf
)->brush
.lb
.lbHatch
= 0;
604 (*sf
)->brush
.gdibrush
= CreateSolidBrush(col
);
605 (*sf
)->brush
.bt
= BrushTypeSolidColor
;
606 (*sf
)->color
= color
;
607 (*sf
)->bmp
= ARGB2BMP(color
);
612 /******************************************************************************
613 * GdipCreateTexture [GDIPLUS.@]
616 * image [I] image to use
617 * wrapmode [I] optional
618 * texture [O] pointer to the resulting texturebrush
622 * FAILURE: element of GpStatus
624 GpStatus WINGDIPAPI
GdipCreateTexture(GpImage
*image
, GpWrapMode wrapmode
,
628 GpImageAttributes attributes
;
631 TRACE("%p, %d %p\n", image
, wrapmode
, texture
);
633 if (!(image
&& texture
))
634 return InvalidParameter
;
636 stat
= GdipGetImageWidth(image
, &width
);
637 if (stat
!= Ok
) return stat
;
638 stat
= GdipGetImageHeight(image
, &height
);
639 if (stat
!= Ok
) return stat
;
640 attributes
.wrap
= wrapmode
;
642 return GdipCreateTextureIA(image
, &attributes
, 0, 0, width
, height
,
646 /******************************************************************************
647 * GdipCreateTexture2 [GDIPLUS.@]
649 GpStatus WINGDIPAPI
GdipCreateTexture2(GpImage
*image
, GpWrapMode wrapmode
,
650 REAL x
, REAL y
, REAL width
, REAL height
, GpTexture
**texture
)
652 GpImageAttributes attributes
;
654 TRACE("%p %d %f %f %f %f %p\n", image
, wrapmode
,
655 x
, y
, width
, height
, texture
);
657 attributes
.wrap
= wrapmode
;
658 return GdipCreateTextureIA(image
, &attributes
, x
, y
, width
, height
,
662 /******************************************************************************
663 * GdipCreateTextureIA [GDIPLUS.@]
665 * FIXME: imageattr ignored
667 GpStatus WINGDIPAPI
GdipCreateTextureIA(GpImage
*image
,
668 GDIPCONST GpImageAttributes
*imageattr
, REAL x
, REAL y
, REAL width
,
669 REAL height
, GpTexture
**texture
)
672 HBITMAP hbm
, old
= NULL
;
674 BITMAPINFOHEADER
*bmih
;
675 INT n_x
, n_y
, n_width
, n_height
, abs_height
, stride
, image_stride
, i
, bytespp
;
677 BYTE
*dibits
, *buff
, *textbits
;
680 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image
, imageattr
, x
, y
, width
, height
,
683 if(!image
|| !texture
|| x
< 0.0 || y
< 0.0 || width
< 0.0 || height
< 0.0)
684 return InvalidParameter
;
686 if(image
->type
!= ImageTypeBitmap
){
687 FIXME("not implemented for image type %d\n", image
->type
);
688 return NotImplemented
;
693 n_width
= roundr(width
);
694 n_height
= roundr(height
);
696 if(n_x
+ n_width
> ((GpBitmap
*)image
)->width
||
697 n_y
+ n_height
> ((GpBitmap
*)image
)->height
)
698 return InvalidParameter
;
700 hbm
= ((GpBitmap
*)image
)->hbitmap
;
701 if(!hbm
) return GenericError
;
702 hdc
= ((GpBitmap
*)image
)->hdc
;
703 bm_is_selected
= (hdc
!= 0);
705 pbmi
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
708 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
709 pbmi
->bmiHeader
.biBitCount
= 0;
712 hdc
= CreateCompatibleDC(0);
713 old
= SelectObject(hdc
, hbm
);
717 GetDIBits(hdc
, hbm
, 0, 0, NULL
, pbmi
, DIB_RGB_COLORS
);
719 bytespp
= pbmi
->bmiHeader
.biBitCount
/ 8;
720 abs_height
= abs(pbmi
->bmiHeader
.biHeight
);
722 if(n_x
> pbmi
->bmiHeader
.biWidth
|| n_x
+ n_width
> pbmi
->bmiHeader
.biWidth
||
723 n_y
> abs_height
|| n_y
+ n_height
> abs_height
){
725 return InvalidParameter
;
728 dibits
= GdipAlloc(pbmi
->bmiHeader
.biSizeImage
);
730 if(dibits
) /* this is not a good place to error out */
731 GetDIBits(hdc
, hbm
, 0, abs_height
, dibits
, pbmi
, DIB_RGB_COLORS
);
734 SelectObject(hdc
, old
);
743 image_stride
= (pbmi
->bmiHeader
.biWidth
* bytespp
+ 3) & ~3;
744 stride
= (n_width
* bytespp
+ 3) & ~3;
745 buff
= GdipAlloc(sizeof(BITMAPINFOHEADER
) + stride
* n_height
);
752 bmih
= (BITMAPINFOHEADER
*)buff
;
753 textbits
= (BYTE
*) (bmih
+ 1);
754 bmih
->biSize
= sizeof(BITMAPINFOHEADER
);
755 bmih
->biWidth
= n_width
;
756 bmih
->biHeight
= n_height
;
757 bmih
->biCompression
= BI_RGB
;
758 bmih
->biSizeImage
= stride
* n_height
;
759 bmih
->biBitCount
= pbmi
->bmiHeader
.biBitCount
;
763 /* image is flipped */
764 if(pbmi
->bmiHeader
.biHeight
> 0){
765 dibits
+= pbmi
->bmiHeader
.biSizeImage
;
767 textbits
+= stride
* (n_height
- 1);
773 for(i
= 0; i
< n_height
; i
++)
774 memcpy(&textbits
[i
* stride
],
775 &dibits
[n_x
* bytespp
+ (n_y
+ i
) * image_stride
],
778 *texture
= GdipAlloc(sizeof(GpTexture
));
785 if((status
= GdipCreateMatrix(&(*texture
)->transform
)) != Ok
){
792 (*texture
)->brush
.lb
.lbStyle
= BS_DIBPATTERNPT
;
793 (*texture
)->brush
.lb
.lbColor
= DIB_RGB_COLORS
;
794 (*texture
)->brush
.lb
.lbHatch
= (ULONG_PTR
)buff
;
796 (*texture
)->brush
.gdibrush
= CreateBrushIndirect(&(*texture
)->brush
.lb
);
797 (*texture
)->brush
.bt
= BrushTypeTextureFill
;
798 (*texture
)->wrap
= imageattr
->wrap
;
806 /******************************************************************************
807 * GdipCreateTextureIAI [GDIPLUS.@]
809 GpStatus WINGDIPAPI
GdipCreateTextureIAI(GpImage
*image
, GDIPCONST GpImageAttributes
*imageattr
,
810 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
812 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image
, imageattr
, x
, y
, width
, height
,
815 return GdipCreateTextureIA(image
,imageattr
,(REAL
)x
,(REAL
)y
,(REAL
)width
,(REAL
)height
,texture
);
818 GpStatus WINGDIPAPI
GdipCreateTexture2I(GpImage
*image
, GpWrapMode wrapmode
,
819 INT x
, INT y
, INT width
, INT height
, GpTexture
**texture
)
821 GpImageAttributes imageattr
;
823 TRACE("%p %d %d %d %d %d %p\n", image
, wrapmode
, x
, y
, width
, height
,
826 imageattr
.wrap
= wrapmode
;
828 return GdipCreateTextureIA(image
, &imageattr
, x
, y
, width
, height
, texture
);
831 GpStatus WINGDIPAPI
GdipGetBrushType(GpBrush
*brush
, GpBrushType
*type
)
833 TRACE("(%p, %p)\n", brush
, type
);
835 if(!brush
|| !type
) return InvalidParameter
;
842 GpStatus WINGDIPAPI
GdipGetHatchBackgroundColor(GpHatch
*brush
, ARGB
*backcol
)
844 TRACE("(%p, %p)\n", brush
, backcol
);
846 if(!brush
|| !backcol
) return InvalidParameter
;
848 *backcol
= brush
->backcol
;
853 GpStatus WINGDIPAPI
GdipGetHatchForegroundColor(GpHatch
*brush
, ARGB
*forecol
)
855 TRACE("(%p, %p)\n", brush
, forecol
);
857 if(!brush
|| !forecol
) return InvalidParameter
;
859 *forecol
= brush
->forecol
;
864 GpStatus WINGDIPAPI
GdipGetHatchStyle(GpHatch
*brush
, HatchStyle
*hatchstyle
)
866 TRACE("(%p, %p)\n", brush
, hatchstyle
);
868 if(!brush
|| !hatchstyle
) return InvalidParameter
;
870 *hatchstyle
= brush
->hatchstyle
;
875 GpStatus WINGDIPAPI
GdipDeleteBrush(GpBrush
*brush
)
877 TRACE("(%p)\n", brush
);
879 if(!brush
) return InvalidParameter
;
883 case BrushTypePathGradient
:
884 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Points
);
885 GdipFree(((GpPathGradient
*) brush
)->pathdata
.Types
);
886 GdipFree(((GpPathGradient
*) brush
)->blendfac
);
887 GdipFree(((GpPathGradient
*) brush
)->blendpos
);
889 case BrushTypeSolidColor
:
890 if (((GpSolidFill
*)brush
)->bmp
)
891 DeleteObject(((GpSolidFill
*)brush
)->bmp
);
893 case BrushTypeLinearGradient
:
894 GdipFree(((GpLineGradient
*)brush
)->blendfac
);
895 GdipFree(((GpLineGradient
*)brush
)->blendpos
);
897 case BrushTypeTextureFill
:
898 GdipDeleteMatrix(((GpTexture
*)brush
)->transform
);
904 DeleteObject(brush
->gdibrush
);
910 GpStatus WINGDIPAPI
GdipGetLineGammaCorrection(GpLineGradient
*line
,
913 TRACE("(%p, %p)\n", line
, usinggamma
);
915 if(!line
|| !usinggamma
)
916 return InvalidParameter
;
918 *usinggamma
= line
->gamma
;
923 GpStatus WINGDIPAPI
GdipGetLineWrapMode(GpLineGradient
*brush
, GpWrapMode
*wrapmode
)
925 TRACE("(%p, %p)\n", brush
, wrapmode
);
927 if(!brush
|| !wrapmode
)
928 return InvalidParameter
;
930 *wrapmode
= brush
->wrap
;
935 GpStatus WINGDIPAPI
GdipGetPathGradientBlend(GpPathGradient
*brush
, REAL
*blend
,
936 REAL
*positions
, INT count
)
938 TRACE("(%p, %p, %p, %d)\n", brush
, blend
, positions
, count
);
940 if(!brush
|| !blend
|| !positions
|| count
<= 0)
941 return InvalidParameter
;
943 if(count
< brush
->blendcount
)
944 return InsufficientBuffer
;
946 memcpy(blend
, brush
->blendfac
, count
*sizeof(REAL
));
947 if(brush
->blendcount
> 1){
948 memcpy(positions
, brush
->blendpos
, count
*sizeof(REAL
));
954 GpStatus WINGDIPAPI
GdipGetPathGradientBlendCount(GpPathGradient
*brush
, INT
*count
)
956 TRACE("(%p, %p)\n", brush
, count
);
959 return InvalidParameter
;
961 *count
= brush
->blendcount
;
966 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPoint(GpPathGradient
*grad
,
969 TRACE("(%p, %p)\n", grad
, point
);
972 return InvalidParameter
;
974 point
->X
= grad
->center
.X
;
975 point
->Y
= grad
->center
.Y
;
980 GpStatus WINGDIPAPI
GdipGetPathGradientCenterPointI(GpPathGradient
*grad
,
986 TRACE("(%p, %p)\n", grad
, point
);
989 return InvalidParameter
;
991 ret
= GdipGetPathGradientCenterPoint(grad
,&ptf
);
994 point
->X
= roundr(ptf
.X
);
995 point
->Y
= roundr(ptf
.Y
);
1001 GpStatus WINGDIPAPI
GdipGetPathGradientFocusScales(GpPathGradient
*grad
,
1004 TRACE("(%p, %p, %p)\n", grad
, x
, y
);
1006 if(!grad
|| !x
|| !y
)
1007 return InvalidParameter
;
1015 GpStatus WINGDIPAPI
GdipGetPathGradientGammaCorrection(GpPathGradient
*grad
,
1018 TRACE("(%p, %p)\n", grad
, gamma
);
1021 return InvalidParameter
;
1023 *gamma
= grad
->gamma
;
1028 GpStatus WINGDIPAPI
GdipGetPathGradientPointCount(GpPathGradient
*grad
,
1031 TRACE("(%p, %p)\n", grad
, count
);
1034 return InvalidParameter
;
1036 *count
= grad
->pathdata
.Count
;
1041 GpStatus WINGDIPAPI
GdipGetPathGradientRect(GpPathGradient
*brush
, GpRectF
*rect
)
1047 TRACE("(%p, %p)\n", brush
, rect
);
1050 return InvalidParameter
;
1052 stat
= GdipCreatePath2(brush
->pathdata
.Points
, brush
->pathdata
.Types
,
1053 brush
->pathdata
.Count
, FillModeAlternate
, &path
);
1054 if(stat
!= Ok
) return stat
;
1056 stat
= GdipGetPathWorldBounds(path
, &r
, NULL
, NULL
);
1058 GdipDeletePath(path
);
1062 memcpy(rect
, &r
, sizeof(GpRectF
));
1064 GdipDeletePath(path
);
1069 GpStatus WINGDIPAPI
GdipGetPathGradientRectI(GpPathGradient
*brush
, GpRect
*rect
)
1074 TRACE("(%p, %p)\n", brush
, rect
);
1077 return InvalidParameter
;
1079 stat
= GdipGetPathGradientRect(brush
, &rectf
);
1080 if(stat
!= Ok
) return stat
;
1082 rect
->X
= roundr(rectf
.X
);
1083 rect
->Y
= roundr(rectf
.Y
);
1084 rect
->Width
= roundr(rectf
.Width
);
1085 rect
->Height
= roundr(rectf
.Height
);
1090 GpStatus WINGDIPAPI
GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
1091 *grad
, ARGB
*argb
, INT
*count
)
1095 if(!grad
|| !argb
|| !count
|| (*count
< grad
->pathdata
.Count
))
1096 return InvalidParameter
;
1099 FIXME("not implemented\n");
1101 return NotImplemented
;
1104 GpStatus WINGDIPAPI
GdipGetPathGradientWrapMode(GpPathGradient
*brush
,
1105 GpWrapMode
*wrapmode
)
1107 TRACE("(%p, %p)\n", brush
, wrapmode
);
1109 if(!brush
|| !wrapmode
)
1110 return InvalidParameter
;
1112 *wrapmode
= brush
->wrap
;
1117 GpStatus WINGDIPAPI
GdipGetSolidFillColor(GpSolidFill
*sf
, ARGB
*argb
)
1119 TRACE("(%p, %p)\n", sf
, argb
);
1122 return InvalidParameter
;
1129 /******************************************************************************
1130 * GdipGetTextureTransform [GDIPLUS.@]
1132 GpStatus WINGDIPAPI
GdipGetTextureTransform(GpTexture
*brush
, GpMatrix
*matrix
)
1134 TRACE("(%p, %p)\n", brush
, matrix
);
1136 if(!brush
|| !matrix
)
1137 return InvalidParameter
;
1139 memcpy(matrix
, brush
->transform
, sizeof(GpMatrix
));
1144 /******************************************************************************
1145 * GdipGetTextureWrapMode [GDIPLUS.@]
1147 GpStatus WINGDIPAPI
GdipGetTextureWrapMode(GpTexture
*brush
, GpWrapMode
*wrapmode
)
1149 TRACE("(%p, %p)\n", brush
, wrapmode
);
1151 if(!brush
|| !wrapmode
)
1152 return InvalidParameter
;
1154 *wrapmode
= brush
->wrap
;
1159 /******************************************************************************
1160 * GdipMultiplyTextureTransform [GDIPLUS.@]
1162 GpStatus WINGDIPAPI
GdipMultiplyTextureTransform(GpTexture
* brush
,
1163 GDIPCONST GpMatrix
*matrix
, GpMatrixOrder order
)
1165 TRACE("(%p, %p, %d)\n", brush
, matrix
, order
);
1167 if(!brush
|| !matrix
)
1168 return InvalidParameter
;
1170 return GdipMultiplyMatrix(brush
->transform
, matrix
, order
);
1173 /******************************************************************************
1174 * GdipResetTextureTransform [GDIPLUS.@]
1176 GpStatus WINGDIPAPI
GdipResetTextureTransform(GpTexture
* brush
)
1178 TRACE("(%p)\n", brush
);
1181 return InvalidParameter
;
1183 return GdipSetMatrixElements(brush
->transform
, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1186 /******************************************************************************
1187 * GdipScaleTextureTransform [GDIPLUS.@]
1189 GpStatus WINGDIPAPI
GdipScaleTextureTransform(GpTexture
* brush
,
1190 REAL sx
, REAL sy
, GpMatrixOrder order
)
1192 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, sx
, sy
, order
);
1195 return InvalidParameter
;
1197 return GdipScaleMatrix(brush
->transform
, sx
, sy
, order
);
1200 GpStatus WINGDIPAPI
GdipSetLineBlend(GpLineGradient
*brush
,
1201 GDIPCONST REAL
*factors
, GDIPCONST REAL
* positions
, INT count
)
1203 REAL
*new_blendfac
, *new_blendpos
;
1205 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1207 if(!brush
|| !factors
|| !positions
|| count
<= 0 ||
1208 (count
>= 2 && (positions
[0] != 0.0f
|| positions
[count
-1] != 1.0f
)))
1209 return InvalidParameter
;
1211 new_blendfac
= GdipAlloc(count
* sizeof(REAL
));
1212 new_blendpos
= GdipAlloc(count
* sizeof(REAL
));
1214 if (!new_blendfac
|| !new_blendpos
)
1216 GdipFree(new_blendfac
);
1217 GdipFree(new_blendpos
);
1221 memcpy(new_blendfac
, factors
, count
* sizeof(REAL
));
1222 memcpy(new_blendpos
, positions
, count
* sizeof(REAL
));
1224 GdipFree(brush
->blendfac
);
1225 GdipFree(brush
->blendpos
);
1227 brush
->blendcount
= count
;
1228 brush
->blendfac
= new_blendfac
;
1229 brush
->blendpos
= new_blendpos
;
1234 GpStatus WINGDIPAPI
GdipGetLineBlend(GpLineGradient
*brush
, REAL
*factors
,
1235 REAL
*positions
, INT count
)
1237 TRACE("(%p, %p, %p, %i)\n", brush
, factors
, positions
, count
);
1239 if (!brush
|| !factors
|| !positions
|| count
<= 0)
1240 return InvalidParameter
;
1242 if (count
< brush
->blendcount
)
1243 return InsufficientBuffer
;
1245 memcpy(factors
, brush
->blendfac
, brush
->blendcount
* sizeof(REAL
));
1246 memcpy(positions
, brush
->blendpos
, brush
->blendcount
* sizeof(REAL
));
1251 GpStatus WINGDIPAPI
GdipGetLineBlendCount(GpLineGradient
*brush
, INT
*count
)
1253 TRACE("(%p, %p)\n", brush
, count
);
1255 if (!brush
|| !count
)
1256 return InvalidParameter
;
1258 *count
= brush
->blendcount
;
1263 GpStatus WINGDIPAPI
GdipSetLineGammaCorrection(GpLineGradient
*line
,
1266 TRACE("(%p, %d)\n", line
, usegamma
);
1269 return InvalidParameter
;
1271 line
->gamma
= usegamma
;
1276 GpStatus WINGDIPAPI
GdipSetLineSigmaBlend(GpLineGradient
*line
, REAL focus
,
1283 const int precision
= 16;
1284 REAL erf_range
; /* we use values erf(-erf_range) through erf(+erf_range) */
1288 TRACE("(%p, %0.2f, %0.2f)\n", line
, focus
, scale
);
1290 if(!line
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1291 return InvalidParameter
;
1293 /* we want 2 standard deviations */
1294 erf_range
= 2.0 / sqrt(2);
1296 /* calculate the constants we need to normalize the error function to be
1297 between 0.0 and scale over the range we need */
1298 min_erf
= erf(-erf_range
);
1299 scale_erf
= scale
/ (-2.0 * min_erf
);
1305 for (i
=1; i
<precision
; i
++)
1307 positions
[i
] = focus
* i
/ precision
;
1308 factors
[i
] = scale_erf
* (erf(2 * erf_range
* i
/ precision
- erf_range
) - min_erf
);
1310 num_points
+= precision
;
1313 positions
[num_points
] = focus
;
1314 factors
[num_points
] = scale
;
1319 for (i
=1; i
<precision
; i
++)
1321 positions
[i
+num_points
-1] = (focus
+ ((1.0-focus
) * i
/ precision
));
1322 factors
[i
+num_points
-1] = scale_erf
* (erf(erf_range
- 2 * erf_range
* i
/ precision
) - min_erf
);
1324 num_points
+= precision
;
1325 positions
[num_points
-1] = 1.0;
1326 factors
[num_points
-1] = 0.0;
1329 return GdipSetLineBlend(line
, factors
, positions
, num_points
);
1332 GpStatus WINGDIPAPI
GdipSetLineWrapMode(GpLineGradient
*line
,
1335 TRACE("(%p, %d)\n", line
, wrap
);
1337 if(!line
|| wrap
== WrapModeClamp
)
1338 return InvalidParameter
;
1345 GpStatus WINGDIPAPI
GdipSetPathGradientBlend(GpPathGradient
*brush
, GDIPCONST REAL
*blend
,
1346 GDIPCONST REAL
*pos
, INT count
)
1351 FIXME("not implemented\n");
1353 return NotImplemented
;
1356 GpStatus WINGDIPAPI
GdipSetPathGradientPresetBlend(GpPathGradient
*brush
,
1357 GDIPCONST ARGB
*blend
, GDIPCONST REAL
*pos
, INT count
)
1359 FIXME("(%p,%p,%p,%i): stub\n", brush
, blend
, pos
, count
);
1360 return NotImplemented
;
1363 GpStatus WINGDIPAPI
GdipSetPathGradientCenterColor(GpPathGradient
*grad
,
1366 TRACE("(%p, %x)\n", grad
, argb
);
1369 return InvalidParameter
;
1371 grad
->centercolor
= argb
;
1372 grad
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1374 DeleteObject(grad
->brush
.gdibrush
);
1375 grad
->brush
.gdibrush
= CreateSolidBrush(grad
->brush
.lb
.lbColor
);
1380 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPoint(GpPathGradient
*grad
,
1383 TRACE("(%p, %p)\n", grad
, point
);
1386 return InvalidParameter
;
1388 grad
->center
.X
= point
->X
;
1389 grad
->center
.Y
= point
->Y
;
1394 GpStatus WINGDIPAPI
GdipSetPathGradientCenterPointI(GpPathGradient
*grad
,
1399 TRACE("(%p, %p)\n", grad
, point
);
1402 return InvalidParameter
;
1404 ptf
.X
= (REAL
)point
->X
;
1405 ptf
.Y
= (REAL
)point
->Y
;
1407 return GdipSetPathGradientCenterPoint(grad
,&ptf
);
1410 GpStatus WINGDIPAPI
GdipSetPathGradientFocusScales(GpPathGradient
*grad
,
1413 TRACE("(%p, %.2f, %.2f)\n", grad
, x
, y
);
1416 return InvalidParameter
;
1424 GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient
*grad
,
1427 TRACE("(%p, %d)\n", grad
, gamma
);
1430 return InvalidParameter
;
1432 grad
->gamma
= gamma
;
1437 GpStatus WINGDIPAPI
GdipSetPathGradientSigmaBlend(GpPathGradient
*grad
,
1438 REAL focus
, REAL scale
)
1442 if(!grad
|| focus
< 0.0 || focus
> 1.0 || scale
< 0.0 || scale
> 1.0)
1443 return InvalidParameter
;
1446 FIXME("not implemented\n");
1448 return NotImplemented
;
1451 GpStatus WINGDIPAPI
GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1452 *grad
, ARGB
*argb
, INT
*count
)
1456 if(!grad
|| !argb
|| !count
|| (*count
<= 0) ||
1457 (*count
> grad
->pathdata
.Count
))
1458 return InvalidParameter
;
1461 FIXME("not implemented\n");
1463 return NotImplemented
;
1466 GpStatus WINGDIPAPI
GdipSetPathGradientWrapMode(GpPathGradient
*grad
,
1469 TRACE("(%p, %d)\n", grad
, wrap
);
1472 return InvalidParameter
;
1479 GpStatus WINGDIPAPI
GdipSetSolidFillColor(GpSolidFill
*sf
, ARGB argb
)
1481 TRACE("(%p, %x)\n", sf
, argb
);
1484 return InvalidParameter
;
1487 sf
->brush
.lb
.lbColor
= ARGB2COLORREF(argb
);
1489 DeleteObject(sf
->brush
.gdibrush
);
1490 sf
->brush
.gdibrush
= CreateSolidBrush(sf
->brush
.lb
.lbColor
);
1495 /******************************************************************************
1496 * GdipSetTextureTransform [GDIPLUS.@]
1498 GpStatus WINGDIPAPI
GdipSetTextureTransform(GpTexture
*texture
,
1499 GDIPCONST GpMatrix
*matrix
)
1501 TRACE("(%p, %p)\n", texture
, matrix
);
1503 if(!texture
|| !matrix
)
1504 return InvalidParameter
;
1506 memcpy(texture
->transform
, matrix
, sizeof(GpMatrix
));
1511 /******************************************************************************
1512 * GdipSetTextureWrapMode [GDIPLUS.@]
1514 * WrapMode not used, only stored
1516 GpStatus WINGDIPAPI
GdipSetTextureWrapMode(GpTexture
*brush
, GpWrapMode wrapmode
)
1518 TRACE("(%p, %d)\n", brush
, wrapmode
);
1521 return InvalidParameter
;
1523 brush
->wrap
= wrapmode
;
1528 GpStatus WINGDIPAPI
GdipSetLineColors(GpLineGradient
*brush
, ARGB color1
,
1531 TRACE("(%p, %x, %x)\n", brush
, color1
, color2
);
1534 return InvalidParameter
;
1536 brush
->startcolor
= color1
;
1537 brush
->endcolor
= color2
;
1542 GpStatus WINGDIPAPI
GdipGetLineColors(GpLineGradient
*brush
, ARGB
*colors
)
1544 TRACE("(%p, %p)\n", brush
, colors
);
1546 if(!brush
|| !colors
)
1547 return InvalidParameter
;
1549 colors
[0] = brush
->startcolor
;
1550 colors
[1] = brush
->endcolor
;
1555 /******************************************************************************
1556 * GdipRotateTextureTransform [GDIPLUS.@]
1558 GpStatus WINGDIPAPI
GdipRotateTextureTransform(GpTexture
* brush
, REAL angle
,
1559 GpMatrixOrder order
)
1561 TRACE("(%p, %.2f, %d)\n", brush
, angle
, order
);
1564 return InvalidParameter
;
1566 return GdipRotateMatrix(brush
->transform
, angle
, order
);
1569 GpStatus WINGDIPAPI
GdipSetLineLinearBlend(GpLineGradient
*brush
, REAL focus
,
1576 TRACE("(%p,%.2f,%.2f)\n", brush
, focus
, scale
);
1578 if (!brush
) return InvalidParameter
;
1582 factors
[num_points
] = 0.0;
1583 positions
[num_points
] = 0.0;
1587 factors
[num_points
] = scale
;
1588 positions
[num_points
] = focus
;
1593 factors
[num_points
] = 0.0;
1594 positions
[num_points
] = 1.0;
1598 return GdipSetLineBlend(brush
, factors
, positions
, num_points
);
1601 GpStatus WINGDIPAPI
GdipSetLinePresetBlend(GpLineGradient
*brush
,
1602 GDIPCONST ARGB
*blend
, GDIPCONST REAL
* positions
, INT count
)
1607 FIXME("not implemented\n");
1609 return NotImplemented
;
1612 GpStatus WINGDIPAPI
GdipSetLineTransform(GpLineGradient
*brush
,
1613 GDIPCONST GpMatrix
*matrix
)
1618 FIXME("not implemented\n");
1620 return NotImplemented
;
1623 GpStatus WINGDIPAPI
GdipTranslateLineTransform(GpLineGradient
* brush
,
1624 REAL dx
, REAL dy
, GpMatrixOrder order
)
1626 FIXME("stub: %p %f %f %d\n", brush
, dx
, dy
, order
);
1628 return NotImplemented
;
1631 /******************************************************************************
1632 * GdipTranslateTextureTransform [GDIPLUS.@]
1634 GpStatus WINGDIPAPI
GdipTranslateTextureTransform(GpTexture
* brush
, REAL dx
, REAL dy
,
1635 GpMatrixOrder order
)
1637 TRACE("(%p, %.2f, %.2f, %d)\n", brush
, dx
, dy
, order
);
1640 return InvalidParameter
;
1642 return GdipTranslateMatrix(brush
->transform
, dx
, dy
, order
);
1645 GpStatus WINGDIPAPI
GdipGetLineRect(GpLineGradient
*brush
, GpRectF
*rect
)
1647 TRACE("(%p, %p)\n", brush
, rect
);
1650 return InvalidParameter
;
1652 *rect
= brush
->rect
;
1657 GpStatus WINGDIPAPI
GdipGetLineRectI(GpLineGradient
*brush
, GpRect
*rect
)
1662 TRACE("(%p, %p)\n", brush
, rect
);
1665 return InvalidParameter
;
1667 ret
= GdipGetLineRect(brush
, &rectF
);
1670 rect
->X
= roundr(rectF
.X
);
1671 rect
->Y
= roundr(rectF
.Y
);
1672 rect
->Width
= roundr(rectF
.Width
);
1673 rect
->Height
= roundr(rectF
.Height
);
1679 GpStatus WINGDIPAPI
GdipRotateLineTransform(GpLineGradient
* brush
,
1680 REAL angle
, GpMatrixOrder order
)
1685 return InvalidParameter
;
1688 FIXME("(%p, %.2f, %d) stub\n", brush
, angle
, order
);
1690 return NotImplemented
;