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

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

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

~ [ 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.