~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/gdiplus/brush.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright (C) 2007 Google (Evan Stade)
  3  *
  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.
  8  *
  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.
 13  *
 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
 17  */
 18 
 19 #include <stdarg.h>
 20 
 21 #include "windef.h"
 22 #include "winbase.h"
 23 #include "winuser.h"
 24 #include "wingdi.h"
 25 
 26 #define COBJMACROS
 27 #include "objbase.h"
 28 #include "olectl.h"
 29 #include "ole2.h"
 30 
 31 #include "gdiplus.h"
 32 #include "gdiplus_private.h"
 33 #include "wine/debug.h"
 34 
 35 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
 36 
 37 /******************************************************************************
 38  * GdipCloneBrush [GDIPLUS.@]
 39  */
 40 GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
 41 {
 42     TRACE("(%p, %p)\n", brush, clone);
 43 
 44     if(!brush || !clone)
 45         return InvalidParameter;
 46 
 47     switch(brush->bt){
 48         case BrushTypeSolidColor:
 49             *clone = GdipAlloc(sizeof(GpSolidFill));
 50             if (!*clone) return OutOfMemory;
 51 
 52             memcpy(*clone, brush, sizeof(GpSolidFill));
 53 
 54             (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
 55             break;
 56         case BrushTypeHatchFill:
 57             *clone = GdipAlloc(sizeof(GpHatch));
 58             if (!*clone) return OutOfMemory;
 59 
 60             memcpy(*clone, brush, sizeof(GpHatch));
 61 
 62             (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
 63             break;
 64         case BrushTypePathGradient:{
 65             GpPathGradient *src, *dest;
 66             INT count;
 67 
 68             *clone = GdipAlloc(sizeof(GpPathGradient));
 69             if (!*clone) return OutOfMemory;
 70 
 71             src = (GpPathGradient*) brush,
 72             dest = (GpPathGradient*) *clone;
 73             count = src->pathdata.Count;
 74 
 75             memcpy(dest, src, sizeof(GpPathGradient));
 76 
 77             dest->pathdata.Count = count;
 78             dest->pathdata.Points = GdipAlloc(count * sizeof(PointF));
 79             dest->pathdata.Types = GdipAlloc(count);
 80 
 81             if(!dest->pathdata.Points || !dest->pathdata.Types){
 82                 GdipFree(dest->pathdata.Points);
 83                 GdipFree(dest->pathdata.Types);
 84                 GdipFree(dest);
 85                 return OutOfMemory;
 86             }
 87 
 88             memcpy(dest->pathdata.Points, src->pathdata.Points, count * sizeof(PointF));
 89             memcpy(dest->pathdata.Types, src->pathdata.Types, count);
 90 
 91             /* blending */
 92             count = src->blendcount;
 93             dest->blendcount = count;
 94             dest->blendfac = GdipAlloc(count * sizeof(REAL));
 95             dest->blendpos = GdipAlloc(count * sizeof(REAL));
 96 
 97             if(!dest->blendfac || !dest->blendpos){
 98                 GdipFree(dest->pathdata.Points);
 99                 GdipFree(dest->pathdata.Types);
100                 GdipFree(dest->blendfac);
101                 GdipFree(dest->blendpos);
102                 GdipFree(dest);
103                 return OutOfMemory;
104             }
105 
106             memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
107             memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
108 
109             break;
110         }
111         case BrushTypeLinearGradient:
112             *clone = GdipAlloc(sizeof(GpLineGradient));
113             if(!*clone)    return OutOfMemory;
114 
115             memcpy(*clone, brush, sizeof(GpLineGradient));
116 
117             (*clone)->gdibrush = CreateSolidBrush((*clone)->lb.lbColor);
118             break;
119         case BrushTypeTextureFill:
120             *clone = GdipAlloc(sizeof(GpTexture));
121             if(!*clone)    return OutOfMemory;
122 
123             memcpy(*clone, brush, sizeof(GpTexture));
124 
125             (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
126             break;
127         default:
128             ERR("not implemented for brush type %d\n", brush->bt);
129             return NotImplemented;
130     }
131 
132     return Ok;
133 }
134 
135 static LONG HatchStyleToHatch(HatchStyle hatchstyle)
136 {
137     switch (hatchstyle)
138     {
139         case HatchStyleHorizontal:        return HS_HORIZONTAL;
140         case HatchStyleVertical:          return HS_VERTICAL;
141         case HatchStyleForwardDiagonal:   return HS_FDIAGONAL;
142         case HatchStyleBackwardDiagonal:  return HS_BDIAGONAL;
143         case HatchStyleCross:             return HS_CROSS;
144         case HatchStyleDiagonalCross:     return HS_DIAGCROSS;
145         default:                          return 0;
146     }
147 }
148 
149 /******************************************************************************
150  * GdipCreateHatchBrush [GDIPLUS.@]
151  */
152 GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
153 {
154     COLORREF fgcol = ARGB2COLORREF(forecol);
155 
156     TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
157 
158     if(!brush)  return InvalidParameter;
159 
160     *brush = GdipAlloc(sizeof(GpHatch));
161     if (!*brush) return OutOfMemory;
162 
163     switch (hatchstyle)
164     {
165         case HatchStyleHorizontal:
166         case HatchStyleVertical:
167         case HatchStyleForwardDiagonal:
168         case HatchStyleBackwardDiagonal:
169         case HatchStyleCross:
170         case HatchStyleDiagonalCross:
171             /* Brushes that map to BS_HATCHED */
172             (*brush)->brush.lb.lbStyle = BS_HATCHED;
173             (*brush)->brush.lb.lbColor = fgcol;
174             (*brush)->brush.lb.lbHatch = HatchStyleToHatch(hatchstyle);
175             break;
176 
177         default:
178             FIXME("Unimplemented hatch style %d\n", hatchstyle);
179 
180             (*brush)->brush.lb.lbStyle = BS_SOLID;
181             (*brush)->brush.lb.lbColor = fgcol;
182             (*brush)->brush.lb.lbHatch = 0;
183             break;
184     }
185 
186 
187     (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
188     (*brush)->brush.bt = BrushTypeHatchFill;
189     (*brush)->forecol = forecol;
190     (*brush)->backcol = backcol;
191     (*brush)->hatchstyle = hatchstyle;
192 
193     return Ok;
194 }
195 
196 /******************************************************************************
197  * GdipCreateLineBrush [GDIPLUS.@]
198  */
199 GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
200     GDIPCONST GpPointF* endpoint, ARGB startcolor, ARGB endcolor,
201     GpWrapMode wrap, GpLineGradient **line)
202 {
203     COLORREF col = ARGB2COLORREF(startcolor);
204 
205     TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
206           startcolor, endcolor, wrap, line);
207 
208     if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
209         return InvalidParameter;
210 
211     *line = GdipAlloc(sizeof(GpLineGradient));
212     if(!*line)  return OutOfMemory;
213 
214     (*line)->brush.lb.lbStyle = BS_SOLID;
215     (*line)->brush.lb.lbColor = col;
216     (*line)->brush.lb.lbHatch = 0;
217     (*line)->brush.gdibrush = CreateSolidBrush(col);
218     (*line)->brush.bt = BrushTypeLinearGradient;
219 
220     (*line)->startpoint.X = startpoint->X;
221     (*line)->startpoint.Y = startpoint->Y;
222     (*line)->endpoint.X = endpoint->X;
223     (*line)->endpoint.Y = endpoint->Y;
224     (*line)->startcolor = startcolor;
225     (*line)->endcolor = endcolor;
226     (*line)->wrap = wrap;
227     (*line)->gamma = FALSE;
228 
229     return Ok;
230 }
231 
232 GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint,
233     GDIPCONST GpPoint* endpoint, ARGB startcolor, ARGB endcolor,
234     GpWrapMode wrap, GpLineGradient **line)
235 {
236     GpPointF stF;
237     GpPointF endF;
238 
239     TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
240           startcolor, endcolor, wrap, line);
241 
242     if(!startpoint || !endpoint)
243         return InvalidParameter;
244 
245     stF.X  = (REAL)startpoint->X;
246     stF.Y  = (REAL)startpoint->Y;
247     endF.X = (REAL)endpoint->X;
248     endF.X = (REAL)endpoint->Y;
249 
250     return GdipCreateLineBrush(&stF, &endF, startcolor, endcolor, wrap, line);
251 }
252 
253 GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
254     ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
255     GpLineGradient **line)
256 {
257     GpPointF start, end;
258 
259     TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
260           wrap, line);
261 
262     if(!line || !rect)
263         return InvalidParameter;
264 
265     start.X = rect->X;
266     start.Y = rect->Y;
267     end.X = rect->X + rect->Width;
268     end.Y = rect->Y + rect->Height;
269 
270     return GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line);
271 }
272 
273 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
274     ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
275     GpLineGradient **line)
276 {
277     GpRectF rectF;
278 
279     TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
280           wrap, line);
281 
282     rectF.X      = (REAL) rect->X;
283     rectF.Y      = (REAL) rect->Y;
284     rectF.Width  = (REAL) rect->Width;
285     rectF.Height = (REAL) rect->Height;
286 
287     return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line);
288 }
289 
290 /******************************************************************************
291  * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
292  *
293  * FIXME: angle value completely ignored. Don't know how to use it since native
294  *        always set Brush rectangle to rect (independetly of this angle).
295  *        Maybe it's used only on drawing.
296  */
297 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
298     ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
299     GpLineGradient **line)
300 {
301     TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
302           wrap, line);
303 
304     return GdipCreateLineBrushFromRect(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
305                                        wrap, line);
306 }
307 
308 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect,
309     ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
310     GpLineGradient **line)
311 {
312     TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
313           wrap, line);
314 
315     return GdipCreateLineBrushFromRectI(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
316                                         wrap, line);
317 }
318 
319 GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
320     INT count, GpWrapMode wrap, GpPathGradient **grad)
321 {
322     COLORREF col = ARGB2COLORREF(0xffffffff);
323 
324     TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
325 
326     if(!points || !grad)
327         return InvalidParameter;
328 
329     if(count <= 0)
330         return OutOfMemory;
331 
332     *grad = GdipAlloc(sizeof(GpPathGradient));
333     if (!*grad) return OutOfMemory;
334 
335     (*grad)->blendfac = GdipAlloc(sizeof(REAL));
336     if(!(*grad)->blendfac){
337         GdipFree(*grad);
338         return OutOfMemory;
339     }
340     (*grad)->blendfac[0] = 1.0;
341     (*grad)->blendpos    = NULL;
342     (*grad)->blendcount  = 1;
343 
344     (*grad)->pathdata.Count = count;
345     (*grad)->pathdata.Points = GdipAlloc(count * sizeof(PointF));
346     (*grad)->pathdata.Types = GdipAlloc(count);
347 
348     if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){
349         GdipFree((*grad)->pathdata.Points);
350         GdipFree((*grad)->pathdata.Types);
351         GdipFree(*grad);
352         return OutOfMemory;
353     }
354 
355     memcpy((*grad)->pathdata.Points, points, count * sizeof(PointF));
356     memset((*grad)->pathdata.Types, PathPointTypeLine, count);
357 
358     (*grad)->brush.lb.lbStyle = BS_SOLID;
359     (*grad)->brush.lb.lbColor = col;
360     (*grad)->brush.lb.lbHatch = 0;
361 
362     (*grad)->brush.gdibrush = CreateSolidBrush(col);
363     (*grad)->brush.bt = BrushTypePathGradient;
364     (*grad)->centercolor = 0xffffffff;
365     (*grad)->wrap = wrap;
366     (*grad)->gamma = FALSE;
367     (*grad)->center.X = 0.0;
368     (*grad)->center.Y = 0.0;
369     (*grad)->focus.X = 0.0;
370     (*grad)->focus.Y = 0.0;
371 
372     return Ok;
373 }
374 
375 GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
376     INT count, GpWrapMode wrap, GpPathGradient **grad)
377 {
378     GpPointF *pointsF;
379     GpStatus ret;
380     INT i;
381 
382     TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
383 
384     if(!points || !grad)
385         return InvalidParameter;
386 
387     if(count <= 0)
388         return OutOfMemory;
389 
390     pointsF = GdipAlloc(sizeof(GpPointF) * count);
391     if(!pointsF)
392         return OutOfMemory;
393 
394     for(i = 0; i < count; i++){
395         pointsF[i].X = (REAL)points[i].X;
396         pointsF[i].Y = (REAL)points[i].Y;
397     }
398 
399     ret = GdipCreatePathGradient(pointsF, count, wrap, grad);
400     GdipFree(pointsF);
401 
402     return ret;
403 }
404 
405 /******************************************************************************
406  * GdipCreatePathGradientFromPath [GDIPLUS.@]
407  *
408  * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
409  */
410 GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
411     GpPathGradient **grad)
412 {
413     COLORREF col = ARGB2COLORREF(0xffffffff);
414 
415     TRACE("(%p, %p)\n", path, grad);
416 
417     if(!path || !grad)
418         return InvalidParameter;
419 
420     *grad = GdipAlloc(sizeof(GpPathGradient));
421     if (!*grad) return OutOfMemory;
422 
423     (*grad)->blendfac = GdipAlloc(sizeof(REAL));
424     if(!(*grad)->blendfac){
425         GdipFree(*grad);
426         return OutOfMemory;
427     }
428     (*grad)->blendfac[0] = 1.0;
429     (*grad)->blendpos    = NULL;
430     (*grad)->blendcount  = 1;
431 
432     (*grad)->pathdata.Count = path->pathdata.Count;
433     (*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF));
434     (*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count);
435 
436     if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){
437         GdipFree((*grad)->pathdata.Points);
438         GdipFree((*grad)->pathdata.Types);
439         GdipFree(*grad);
440         return OutOfMemory;
441     }
442 
443     memcpy((*grad)->pathdata.Points, path->pathdata.Points,
444            path->pathdata.Count * sizeof(PointF));
445     memcpy((*grad)->pathdata.Types, path->pathdata.Types, path->pathdata.Count);
446 
447     (*grad)->brush.lb.lbStyle = BS_SOLID;
448     (*grad)->brush.lb.lbColor = col;
449     (*grad)->brush.lb.lbHatch = 0;
450 
451     (*grad)->brush.gdibrush = CreateSolidBrush(col);
452     (*grad)->brush.bt = BrushTypePathGradient;
453     (*grad)->centercolor = 0xffffffff;
454     (*grad)->wrap = WrapModeClamp;
455     (*grad)->gamma = FALSE;
456     /* FIXME: this should be set to the "centroid" of the path by default */
457     (*grad)->center.X = 0.0;
458     (*grad)->center.Y = 0.0;
459     (*grad)->focus.X = 0.0;
460     (*grad)->focus.Y = 0.0;
461 
462     return Ok;
463 }
464 
465 /******************************************************************************
466  * GdipCreateSolidFill [GDIPLUS.@]
467  */
468 GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
469 {
470     COLORREF col = ARGB2COLORREF(color);
471 
472     TRACE("(%x, %p)\n", color, sf);
473 
474     if(!sf)  return InvalidParameter;
475 
476     *sf = GdipAlloc(sizeof(GpSolidFill));
477     if (!*sf) return OutOfMemory;
478 
479     (*sf)->brush.lb.lbStyle = BS_SOLID;
480     (*sf)->brush.lb.lbColor = col;
481     (*sf)->brush.lb.lbHatch = 0;
482 
483     (*sf)->brush.gdibrush = CreateSolidBrush(col);
484     (*sf)->brush.bt = BrushTypeSolidColor;
485     (*sf)->color = color;
486 
487     return Ok;
488 }
489 
490 /******************************************************************************
491  * GdipCreateTexture [GDIPLUS.@]
492  *
493  * PARAMS
494  *  image       [I] image to use
495  *  wrapmode    [I] optional
496  *  texture     [O] pointer to the resulting texturebrush
497  *
498  * RETURNS
499  *  SUCCESS: Ok
500  *  FAILURE: element of GpStatus
501  */
502 GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
503         GpTexture **texture)
504 {
505     UINT width, height;
506     GpImageAttributes attributes;
507     GpStatus stat;
508 
509     TRACE("%p, %d %p\n", image, wrapmode, texture);
510 
511     if (!(image && texture))
512         return InvalidParameter;
513 
514     stat = GdipGetImageWidth(image, &width);
515     if (stat != Ok) return stat;
516     stat = GdipGetImageHeight(image, &height);
517     if (stat != Ok) return stat;
518     attributes.wrap = wrapmode;
519 
520     return GdipCreateTextureIA(image, &attributes, 0, 0, width, height,
521             texture);
522 }
523 
524 /******************************************************************************
525  * GdipCreateTexture2 [GDIPLUS.@]
526  */
527 GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode,
528         REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
529 {
530     GpImageAttributes attributes;
531 
532     TRACE("%p %d %f %f %f %f %p\n", image, wrapmode,
533             x, y, width, height, texture);
534 
535     attributes.wrap = wrapmode;
536     return GdipCreateTextureIA(image, &attributes, x, y, width, height,
537             texture);
538 }
539 
540 /******************************************************************************
541  * GdipCreateTextureIA [GDIPLUS.@]
542  *
543  * FIXME: imageattr ignored
544  */
545 GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
546     GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
547     REAL height, GpTexture **texture)
548 {
549     HDC hdc;
550     HBITMAP hbm, old = NULL;
551     BITMAPINFO *pbmi;
552     BITMAPINFOHEADER *bmih;
553     INT n_x, n_y, n_width, n_height, abs_height, stride, image_stride, i, bytespp;
554     BOOL bm_is_selected;
555     BYTE *dibits, *buff, *textbits;
556     GpStatus status;
557 
558     TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height,
559            texture);
560 
561     if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
562         return InvalidParameter;
563 
564     if(image->type != ImageTypeBitmap){
565         FIXME("not implemented for image type %d\n", image->type);
566         return NotImplemented;
567     }
568 
569     n_x = roundr(x);
570     n_y = roundr(y);
571     n_width = roundr(width);
572     n_height = roundr(height);
573 
574     if(n_x + n_width > ((GpBitmap*)image)->width ||
575        n_y + n_height > ((GpBitmap*)image)->height)
576         return InvalidParameter;
577 
578     IPicture_get_Handle(image->picture, (OLE_HANDLE*)&hbm);
579     if(!hbm)   return GenericError;
580     IPicture_get_CurDC(image->picture, &hdc);
581     bm_is_selected = (hdc != 0);
582 
583     pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
584     if (!pbmi)
585         return OutOfMemory;
586     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
587     pbmi->bmiHeader.biBitCount = 0;
588 
589     if(!bm_is_selected){
590         hdc = CreateCompatibleDC(0);
591         old = SelectObject(hdc, hbm);
592     }
593 
594     /* fill out bmi */
595     GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
596 
597     bytespp = pbmi->bmiHeader.biBitCount / 8;
598     abs_height = abs(pbmi->bmiHeader.biHeight);
599 
600     if(n_x > pbmi->bmiHeader.biWidth || n_x + n_width > pbmi->bmiHeader.biWidth ||
601        n_y > abs_height || n_y + n_height > abs_height){
602         GdipFree(pbmi);
603         return InvalidParameter;
604     }
605 
606     dibits = GdipAlloc(pbmi->bmiHeader.biSizeImage);
607 
608     if(dibits)  /* this is not a good place to error out */
609         GetDIBits(hdc, hbm, 0, abs_height, dibits, pbmi, DIB_RGB_COLORS);
610 
611     if(!bm_is_selected){
612         SelectObject(hdc, old);
613         DeleteDC(hdc);
614     }
615 
616     if(!dibits){
617         GdipFree(pbmi);
618         return OutOfMemory;
619     }
620 
621     image_stride = (pbmi->bmiHeader.biWidth * bytespp + 3) & ~3;
622     stride = (n_width * bytespp + 3) & ~3;
623     buff = GdipAlloc(sizeof(BITMAPINFOHEADER) + stride * n_height);
624     if(!buff){
625         GdipFree(pbmi);
626         GdipFree(dibits);
627         return OutOfMemory;
628     }
629 
630     bmih = (BITMAPINFOHEADER*)buff;
631     textbits = (BYTE*) (bmih + 1);
632     bmih->biSize = sizeof(BITMAPINFOHEADER);
633     bmih->biWidth = n_width;
634     bmih->biHeight = n_height;
635     bmih->biCompression = BI_RGB;
636     bmih->biSizeImage = stride * n_height;
637     bmih->biBitCount = pbmi->bmiHeader.biBitCount;
638     bmih->biClrUsed = 0;
639     bmih->biPlanes = 1;
640 
641     /* image is flipped */
642     if(pbmi->bmiHeader.biHeight > 0){
643         dibits += pbmi->bmiHeader.biSizeImage;
644         image_stride *= -1;
645         textbits += stride * (n_height - 1);
646         stride *= -1;
647     }
648 
649     GdipFree(pbmi);
650 
651     for(i = 0; i < n_height; i++)
652         memcpy(&textbits[i * stride],
653                &dibits[n_x * bytespp + (n_y + i) * image_stride],
654                abs(stride));
655 
656     *texture = GdipAlloc(sizeof(GpTexture));
657     if (!*texture){
658         GdipFree(dibits);
659         GdipFree(buff);
660         return OutOfMemory;
661     }
662 
663     if((status = GdipCreateMatrix(&(*texture)->transform)) != Ok){
664         GdipFree(*texture);
665         GdipFree(dibits);
666         GdipFree(buff);
667         return status;
668     }
669 
670     (*texture)->brush.lb.lbStyle = BS_DIBPATTERNPT;
671     (*texture)->brush.lb.lbColor = DIB_RGB_COLORS;
672     (*texture)->brush.lb.lbHatch = (ULONG_PTR)buff;
673 
674     (*texture)->brush.gdibrush = CreateBrushIndirect(&(*texture)->brush.lb);
675     (*texture)->brush.bt = BrushTypeTextureFill;
676     (*texture)->wrap = imageattr->wrap;
677 
678     GdipFree(dibits);
679     GdipFree(buff);
680 
681     return Ok;
682 }
683 
684 /******************************************************************************
685  * GdipCreateTextureIAI [GDIPLUS.@]
686  */
687 GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageattr,
688     INT x, INT y, INT width, INT height, GpTexture **texture)
689 {
690     TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image, imageattr, x, y, width, height,
691            texture);
692 
693     return GdipCreateTextureIA(image,imageattr,(REAL)x,(REAL)y,(REAL)width,(REAL)height,texture);
694 }
695 
696 GpStatus WINGDIPAPI GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode,
697         INT x, INT y, INT width, INT height, GpTexture **texture)
698 {
699     GpImageAttributes imageattr;
700 
701     TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height,
702             texture);
703 
704     imageattr.wrap = wrapmode;
705 
706     return GdipCreateTextureIA(image, &imageattr, x, y, width, height, texture);
707 }
708 
709 GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
710 {
711     TRACE("(%p, %p)\n", brush, type);
712 
713     if(!brush || !type)  return InvalidParameter;
714 
715     *type = brush->bt;
716 
717     return Ok;
718 }
719 
720 GpStatus WINGDIPAPI GdipGetHatchBackgroundColor(GpHatch *brush, ARGB *backcol)
721 {
722     TRACE("(%p, %p)\n", brush, backcol);
723 
724     if(!brush || !backcol)  return InvalidParameter;
725 
726     *backcol = brush->backcol;
727 
728     return Ok;
729 }
730 
731 GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol)
732 {
733     TRACE("(%p, %p)\n", brush, forecol);
734 
735     if(!brush || !forecol)  return InvalidParameter;
736 
737     *forecol = brush->forecol;
738 
739     return Ok;
740 }
741 
742 GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, HatchStyle *hatchstyle)
743 {
744     TRACE("(%p, %p)\n", brush, hatchstyle);
745 
746     if(!brush || !hatchstyle)  return InvalidParameter;
747 
748     *hatchstyle = brush->hatchstyle;
749 
750     return Ok;
751 }
752 
753 GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
754 {
755     TRACE("(%p)\n", brush);
756 
757     if(!brush)  return InvalidParameter;
758 
759     switch(brush->bt)
760     {
761         case BrushTypePathGradient:
762             GdipFree(((GpPathGradient*) brush)->pathdata.Points);
763             GdipFree(((GpPathGradient*) brush)->pathdata.Types);
764             GdipFree(((GpPathGradient*) brush)->blendfac);
765             GdipFree(((GpPathGradient*) brush)->blendpos);
766             break;
767         case BrushTypeSolidColor:
768         case BrushTypeLinearGradient:
769             break;
770         case BrushTypeTextureFill:
771             GdipDeleteMatrix(((GpTexture*)brush)->transform);
772             break;
773         default:
774             break;
775     }
776 
777     DeleteObject(brush->gdibrush);
778     GdipFree(brush);
779 
780     return Ok;
781 }
782 
783 GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line,
784     BOOL *usinggamma)
785 {
786     TRACE("(%p, %p)\n", line, usinggamma);
787 
788     if(!line || !usinggamma)
789         return InvalidParameter;
790 
791     *usinggamma = line->gamma;
792 
793     return Ok;
794 }
795 
796 GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode)
797 {
798     TRACE("(%p, %p)\n", brush, wrapmode);
799 
800     if(!brush || !wrapmode)
801         return InvalidParameter;
802 
803     *wrapmode = brush->wrap;
804 
805     return Ok;
806 }
807 
808 GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend,
809     REAL *positions, INT count)
810 {
811     TRACE("(%p, %p, %p, %d)\n", brush, blend, positions, count);
812 
813     if(!brush || !blend || !positions || count <= 0)
814         return InvalidParameter;
815 
816     if(count < brush->blendcount)
817         return InsufficientBuffer;
818 
819     memcpy(blend, brush->blendfac, count*sizeof(REAL));
820     if(brush->blendcount > 1){
821         memcpy(positions, brush->blendpos, count*sizeof(REAL));
822     }
823 
824     return Ok;
825 }
826 
827 GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count)
828 {
829     TRACE("(%p, %p)\n", brush, count);
830 
831     if(!brush || !count)
832         return InvalidParameter;
833 
834     *count = brush->blendcount;
835 
836     return Ok;
837 }
838 
839 GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad,
840     GpPointF *point)
841 {
842     TRACE("(%p, %p)\n", grad, point);
843 
844     if(!grad || !point)
845         return InvalidParameter;
846 
847     point->X = grad->center.X;
848     point->Y = grad->center.Y;
849 
850     return Ok;
851 }
852 
853 GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad,
854     GpPoint *point)
855 {
856     GpStatus ret;
857     GpPointF ptf;
858 
859     TRACE("(%p, %p)\n", grad, point);
860 
861     if(!point)
862         return InvalidParameter;
863 
864     ret = GdipGetPathGradientCenterPoint(grad,&ptf);
865 
866     if(ret == Ok){
867         point->X = roundr(ptf.X);
868         point->Y = roundr(ptf.Y);
869     }
870 
871     return ret;
872 }
873 
874 GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad,
875     REAL *x, REAL *y)
876 {
877     TRACE("(%p, %p, %p)\n", grad, x, y);
878 
879     if(!grad || !x || !y)
880         return InvalidParameter;
881 
882     *x = grad->focus.X;
883     *y = grad->focus.Y;
884 
885     return Ok;
886 }
887 
888 GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad,
889     BOOL *gamma)
890 {
891     TRACE("(%p, %p)\n", grad, gamma);
892 
893     if(!grad || !gamma)
894         return InvalidParameter;
895 
896     *gamma = grad->gamma;
897 
898     return Ok;
899 }
900 
901 GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
902     INT *count)
903 {
904     TRACE("(%p, %p)\n", grad, count);
905 
906     if(!grad || !count)
907         return InvalidParameter;
908 
909     *count = grad->pathdata.Count;
910 
911     return Ok;
912 }
913 
914 GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
915 {
916     GpRectF r;
917     GpPath* path;
918     GpStatus stat;
919 
920     TRACE("(%p, %p)\n", brush, rect);
921 
922     if(!brush || !rect)
923         return InvalidParameter;
924 
925     stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types,
926                            brush->pathdata.Count, FillModeAlternate, &path);
927     if(stat != Ok)  return stat;
928 
929     stat = GdipGetPathWorldBounds(path, &r, NULL, NULL);
930     if(stat != Ok){
931         GdipDeletePath(path);
932         return stat;
933     }
934 
935     memcpy(rect, &r, sizeof(GpRectF));
936 
937     GdipDeletePath(path);
938 
939     return Ok;
940 }
941 
942 GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
943 {
944     GpRectF rectf;
945     GpStatus stat;
946 
947     TRACE("(%p, %p)\n", brush, rect);
948 
949     if(!brush || !rect)
950         return InvalidParameter;
951 
952     stat = GdipGetPathGradientRect(brush, &rectf);
953     if(stat != Ok)  return stat;
954 
955     rect->X = roundr(rectf.X);
956     rect->Y = roundr(rectf.Y);
957     rect->Width  = roundr(rectf.Width);
958     rect->Height = roundr(rectf.Height);
959 
960     return Ok;
961 }
962 
963 GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
964     *grad, ARGB *argb, INT *count)
965 {
966     static int calls;
967 
968     if(!grad || !argb || !count || (*count < grad->pathdata.Count))
969         return InvalidParameter;
970 
971     if(!(calls++))
972         FIXME("not implemented\n");
973 
974     return NotImplemented;
975 }
976 
977 GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush,
978     GpWrapMode *wrapmode)
979 {
980     TRACE("(%p, %p)\n", brush, wrapmode);
981 
982     if(!brush || !wrapmode)
983         return InvalidParameter;
984 
985     *wrapmode = brush->wrap;
986 
987     return Ok;
988 }
989 
990 GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb)
991 {
992     TRACE("(%p, %p)\n", sf, argb);
993 
994     if(!sf || !argb)
995         return InvalidParameter;
996 
997     *argb = sf->color;
998 
999     return Ok;
1000 }
1001 
1002 /******************************************************************************
1003  * GdipGetTextureTransform [GDIPLUS.@]
1004  */
1005 GpStatus WINGDIPAPI GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix)
1006 {
1007     TRACE("(%p, %p)\n", brush, matrix);
1008 
1009     if(!brush || !matrix)
1010         return InvalidParameter;
1011 
1012     memcpy(matrix, brush->transform, sizeof(GpMatrix));
1013 
1014     return Ok;
1015 }
1016 
1017 /******************************************************************************
1018  * GdipGetTextureWrapMode [GDIPLUS.@]
1019  */
1020 GpStatus WINGDIPAPI GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmode)
1021 {
1022     TRACE("(%p, %p)\n", brush, wrapmode);
1023 
1024     if(!brush || !wrapmode)
1025         return InvalidParameter;
1026 
1027     *wrapmode = brush->wrap;
1028 
1029     return Ok;
1030 }
1031 
1032 /******************************************************************************
1033  * GdipMultiplyTextureTransform [GDIPLUS.@]
1034  */
1035 GpStatus WINGDIPAPI GdipMultiplyTextureTransform(GpTexture* brush,
1036     GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
1037 {
1038     TRACE("(%p, %p, %d)\n", brush, matrix, order);
1039 
1040     if(!brush || !matrix)
1041         return InvalidParameter;
1042 
1043     return GdipMultiplyMatrix(brush->transform, matrix, order);
1044 }
1045 
1046 /******************************************************************************
1047  * GdipResetTextureTransform [GDIPLUS.@]
1048  */
1049 GpStatus WINGDIPAPI GdipResetTextureTransform(GpTexture* brush)
1050 {
1051     TRACE("(%p)\n", brush);
1052 
1053     if(!brush)
1054         return InvalidParameter;
1055 
1056     return GdipSetMatrixElements(brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
1057 }
1058 
1059 /******************************************************************************
1060  * GdipScaleTextureTransform [GDIPLUS.@]
1061  */
1062 GpStatus WINGDIPAPI GdipScaleTextureTransform(GpTexture* brush,
1063     REAL sx, REAL sy, GpMatrixOrder order)
1064 {
1065     TRACE("(%p, %.2f, %.2f, %d)\n", brush, sx, sy, order);
1066 
1067     if(!brush)
1068         return InvalidParameter;
1069 
1070     return GdipScaleMatrix(brush->transform, sx, sy, order);
1071 }
1072 
1073 GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush,
1074     GDIPCONST REAL *blend, GDIPCONST REAL* positions, INT count)
1075 {
1076     static int calls;
1077 
1078     if(!brush || !blend || !positions || count <= 0)
1079         return InvalidParameter;
1080 
1081     if(!(calls++))
1082         FIXME("not implemented\n");
1083 
1084     return Ok;
1085 }
1086 
1087 GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line,
1088     BOOL usegamma)
1089 {
1090     TRACE("(%p, %d)\n", line, usegamma);
1091 
1092     if(!line)
1093         return InvalidParameter;
1094 
1095     line->gamma = usegamma;
1096 
1097     return Ok;
1098 }
1099 
1100 GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus,
1101     REAL scale)
1102 {
1103     static int calls;
1104 
1105     if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
1106         return InvalidParameter;
1107 
1108     if(!(calls++))
1109         FIXME("not implemented\n");
1110 
1111     return NotImplemented;
1112 }
1113 
1114 GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line,
1115     GpWrapMode wrap)
1116 {
1117     TRACE("(%p, %d)\n", line, wrap);
1118 
1119     if(!line || wrap == WrapModeClamp)
1120         return InvalidParameter;
1121 
1122     line->wrap = wrap;
1123 
1124     return Ok;
1125 }
1126 
1127 GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST REAL *blend,
1128     GDIPCONST REAL *pos, INT count)
1129 {
1130     static int calls;
1131 
1132     if(!(calls++))
1133         FIXME("not implemented\n");
1134 
1135     return NotImplemented;
1136 }
1137 
1138 GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
1139     ARGB argb)
1140 {
1141     TRACE("(%p, %x)\n", grad, argb);
1142 
1143     if(!grad)
1144         return InvalidParameter;
1145 
1146     grad->centercolor = argb;
1147     grad->brush.lb.lbColor = ARGB2COLORREF(argb);
1148 
1149     DeleteObject(grad->brush.gdibrush);
1150     grad->brush.gdibrush = CreateSolidBrush(grad->brush.lb.lbColor);
1151 
1152     return Ok;
1153 }
1154 
1155 GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad,
1156     GpPointF *point)
1157 {
1158     TRACE("(%p, %p)\n", grad, point);
1159 
1160     if(!grad || !point)
1161         return InvalidParameter;
1162 
1163     grad->center.X = point->X;
1164     grad->center.Y = point->Y;
1165 
1166     return Ok;
1167 }
1168 
1169 GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad,
1170     GpPoint *point)
1171 {
1172     GpPointF ptf;
1173 
1174     TRACE("(%p, %p)\n", grad, point);
1175 
1176     if(!point)
1177         return InvalidParameter;
1178 
1179     ptf.X = (REAL)point->X;
1180     ptf.Y = (REAL)point->Y;
1181 
1182     return GdipSetPathGradientCenterPoint(grad,&ptf);
1183 }
1184 
1185 GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad,
1186     REAL x, REAL y)
1187 {
1188     TRACE("(%p, %.2f, %.2f)\n", grad, x, y);
1189 
1190     if(!grad)
1191         return InvalidParameter;
1192 
1193     grad->focus.X = x;
1194     grad->focus.Y = y;
1195 
1196     return Ok;
1197 }
1198 
1199 GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
1200     BOOL gamma)
1201 {
1202     TRACE("(%p, %d)\n", grad, gamma);
1203 
1204     if(!grad)
1205         return InvalidParameter;
1206 
1207     grad->gamma = gamma;
1208 
1209     return Ok;
1210 }
1211 
1212 GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
1213     REAL focus, REAL scale)
1214 {
1215     static int calls;
1216 
1217     if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
1218         return InvalidParameter;
1219 
1220     if(!(calls++))
1221         FIXME("not implemented\n");
1222 
1223     return NotImplemented;
1224 }
1225 
1226 GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1227     *grad, ARGB *argb, INT *count)
1228 {
1229     static int calls;
1230 
1231     if(!grad || !argb || !count || (*count <= 0) ||
1232         (*count > grad->pathdata.Count))
1233         return InvalidParameter;
1234 
1235     if(!(calls++))
1236         FIXME("not implemented\n");
1237 
1238     return NotImplemented;
1239 }
1240 
1241 GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad,
1242     GpWrapMode wrap)
1243 {
1244     TRACE("(%p, %d)\n", grad, wrap);
1245 
1246     if(!grad)
1247         return InvalidParameter;
1248 
1249     grad->wrap = wrap;
1250 
1251     return Ok;
1252 }
1253 
1254 GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
1255 {
1256     TRACE("(%p, %x)\n", sf, argb);
1257 
1258     if(!sf)
1259         return InvalidParameter;
1260 
1261     sf->color = argb;
1262     sf->brush.lb.lbColor = ARGB2COLORREF(argb);
1263 
1264     DeleteObject(sf->brush.gdibrush);
1265     sf->brush.gdibrush = CreateSolidBrush(sf->brush.lb.lbColor);
1266 
1267     return Ok;
1268 }
1269 
1270 /******************************************************************************
1271  * GdipSetTextureTransform [GDIPLUS.@]
1272  */
1273 GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture,
1274     GDIPCONST GpMatrix *matrix)
1275 {
1276     TRACE("(%p, %p)\n", texture, matrix);
1277 
1278     if(!texture || !matrix)
1279         return InvalidParameter;
1280 
1281     memcpy(texture->transform, matrix, sizeof(GpMatrix));
1282 
1283     return Ok;
1284 }
1285 
1286 /******************************************************************************
1287  * GdipSetTextureWrapMode [GDIPLUS.@]
1288  *
1289  * WrapMode not used, only stored
1290  */
1291 GpStatus WINGDIPAPI GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode)
1292 {
1293     TRACE("(%p, %d)\n", brush, wrapmode);
1294 
1295     if(!brush)
1296         return InvalidParameter;
1297 
1298     brush->wrap = wrapmode;
1299 
1300     return Ok;
1301 }
1302 
1303 GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1,
1304     ARGB color2)
1305 {
1306     TRACE("(%p, %x, %x)\n", brush, color1, color2);
1307 
1308     if(!brush)
1309         return InvalidParameter;
1310 
1311     brush->startcolor = color1;
1312     brush->endcolor   = color2;
1313 
1314     return Ok;
1315 }
1316 
1317 GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors)
1318 {
1319     TRACE("(%p, %p)\n", brush, colors);
1320 
1321     if(!brush || !colors)
1322         return InvalidParameter;
1323 
1324     colors[0] = brush->startcolor;
1325     colors[1] = brush->endcolor;
1326 
1327     return Ok;
1328 }
1329 
1330 /******************************************************************************
1331  * GdipRotateTextureTransform [GDIPLUS.@]
1332  */
1333 GpStatus WINGDIPAPI GdipRotateTextureTransform(GpTexture* brush, REAL angle,
1334     GpMatrixOrder order)
1335 {
1336     TRACE("(%p, %.2f, %d)\n", brush, angle, order);
1337 
1338     if(!brush)
1339         return InvalidParameter;
1340 
1341     return GdipRotateMatrix(brush->transform, angle, order);
1342 }
1343 
1344 GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
1345     REAL scale)
1346 {
1347     static int calls;
1348 
1349     if(!(calls++))
1350         FIXME("not implemented\n");
1351 
1352     return NotImplemented;
1353 }
1354 
1355 GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,
1356     GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
1357 {
1358     static int calls;
1359 
1360     if(!(calls++))
1361         FIXME("not implemented\n");
1362 
1363     return NotImplemented;
1364 }
1365 
1366 GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
1367     GDIPCONST GpMatrix *matrix)
1368 {
1369     static int calls;
1370 
1371     if(!(calls++))
1372         FIXME("not implemented\n");
1373 
1374     return NotImplemented;
1375 }
1376 
1377 GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush,
1378         REAL dx, REAL dy, GpMatrixOrder order)
1379 {
1380     FIXME("stub: %p %f %f %d\n", brush, dx, dy, order);
1381 
1382     return NotImplemented;
1383 }
1384 
1385 /******************************************************************************
1386  * GdipTranslateTextureTransform [GDIPLUS.@]
1387  */
1388 GpStatus WINGDIPAPI GdipTranslateTextureTransform(GpTexture* brush, REAL dx, REAL dy,
1389     GpMatrixOrder order)
1390 {
1391     TRACE("(%p, %.2f, %.2f, %d)\n", brush, dx, dy, order);
1392 
1393     if(!brush)
1394         return InvalidParameter;
1395 
1396     return GdipTranslateMatrix(brush->transform, dx, dy, order);
1397 }
1398 
1399 GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect)
1400 {
1401     TRACE("(%p, %p)\n", brush, rect);
1402 
1403     if(!brush || !rect)
1404         return InvalidParameter;
1405 
1406     rect->X = (brush->startpoint.X < brush->endpoint.X ? brush->startpoint.X: brush->endpoint.X);
1407     rect->Y = (brush->startpoint.Y < brush->endpoint.Y ? brush->startpoint.Y: brush->endpoint.Y);
1408 
1409     rect->Width  = fabs(brush->startpoint.X - brush->endpoint.X);
1410     rect->Height = fabs(brush->startpoint.Y - brush->endpoint.Y);
1411 
1412     return Ok;
1413 }
1414 
1415 GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect)
1416 {
1417     GpRectF  rectF;
1418     GpStatus ret;
1419 
1420     TRACE("(%p, %p)\n", brush, rect);
1421 
1422     if(!rect)
1423         return InvalidParameter;
1424 
1425     ret = GdipGetLineRect(brush, &rectF);
1426 
1427     if(ret == Ok){
1428         rect->X      = roundr(rectF.X);
1429         rect->Y      = roundr(rectF.Y);
1430         rect->Width  = roundr(rectF.Width);
1431         rect->Height = roundr(rectF.Height);
1432     }
1433 
1434     return ret;
1435 }
1436 
1437 GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient* brush,
1438     REAL angle, GpMatrixOrder order)
1439 {
1440     static int calls;
1441 
1442     if(!brush)
1443         return InvalidParameter;
1444 
1445     if(!(calls++))
1446         FIXME("(%p, %.2f, %d) stub\n", brush, angle, order);
1447 
1448     return NotImplemented;
1449 }
1450 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.