~ [ 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 BrushTypePathGradient:{
 57             GpPathGradient *src, *dest;
 58             INT count;
 59 
 60             *clone = GdipAlloc(sizeof(GpPathGradient));
 61             if (!*clone) return OutOfMemory;
 62 
 63             src = (GpPathGradient*) brush,
 64             dest = (GpPathGradient*) *clone;
 65             count = src->pathdata.Count;
 66 
 67             memcpy(dest, src, sizeof(GpPathGradient));
 68 
 69             dest->pathdata.Count = count;
 70             dest->pathdata.Points = GdipAlloc(count * sizeof(PointF));
 71             dest->pathdata.Types = GdipAlloc(count);
 72 
 73             if(!dest->pathdata.Points || !dest->pathdata.Types){
 74                 GdipFree(dest->pathdata.Points);
 75                 GdipFree(dest->pathdata.Types);
 76                 GdipFree(dest);
 77                 return OutOfMemory;
 78             }
 79 
 80             memcpy(dest->pathdata.Points, src->pathdata.Points, count * sizeof(PointF));
 81             memcpy(dest->pathdata.Types, src->pathdata.Types, count);
 82 
 83             /* blending */
 84             count = src->blendcount;
 85             dest->blendcount = count;
 86             dest->blendfac = GdipAlloc(count * sizeof(REAL));
 87             dest->blendpos = GdipAlloc(count * sizeof(REAL));
 88 
 89             if(!dest->blendfac || !dest->blendpos){
 90                 GdipFree(dest->pathdata.Points);
 91                 GdipFree(dest->pathdata.Types);
 92                 GdipFree(dest->blendfac);
 93                 GdipFree(dest->blendpos);
 94                 GdipFree(dest);
 95                 return OutOfMemory;
 96             }
 97 
 98             memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
 99             memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
100 
101             break;
102         }
103         case BrushTypeLinearGradient:
104             *clone = GdipAlloc(sizeof(GpLineGradient));
105             if(!*clone)    return OutOfMemory;
106 
107             memcpy(*clone, brush, sizeof(GpLineGradient));
108 
109             (*clone)->gdibrush = CreateSolidBrush((*clone)->lb.lbColor);
110             break;
111         case BrushTypeTextureFill:
112             *clone = GdipAlloc(sizeof(GpTexture));
113             if(!*clone)    return OutOfMemory;
114 
115             memcpy(*clone, brush, sizeof(GpTexture));
116 
117             (*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
118             break;
119         default:
120             ERR("not implemented for brush type %d\n", brush->bt);
121             return NotImplemented;
122     }
123 
124     return Ok;
125 }
126 
127 /******************************************************************************
128  * GdipCreateLineBrush [GDIPLUS.@]
129  */
130 GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
131     GDIPCONST GpPointF* endpoint, ARGB startcolor, ARGB endcolor,
132     GpWrapMode wrap, GpLineGradient **line)
133 {
134     COLORREF col = ARGB2COLORREF(startcolor);
135 
136     TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
137           startcolor, endcolor, wrap, line);
138 
139     if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
140         return InvalidParameter;
141 
142     *line = GdipAlloc(sizeof(GpLineGradient));
143     if(!*line)  return OutOfMemory;
144 
145     (*line)->brush.lb.lbStyle = BS_SOLID;
146     (*line)->brush.lb.lbColor = col;
147     (*line)->brush.lb.lbHatch = 0;
148     (*line)->brush.gdibrush = CreateSolidBrush(col);
149     (*line)->brush.bt = BrushTypeLinearGradient;
150 
151     (*line)->startpoint.X = startpoint->X;
152     (*line)->startpoint.Y = startpoint->Y;
153     (*line)->endpoint.X = endpoint->X;
154     (*line)->endpoint.Y = endpoint->Y;
155     (*line)->startcolor = startcolor;
156     (*line)->endcolor = endcolor;
157     (*line)->wrap = wrap;
158     (*line)->gamma = FALSE;
159 
160     return Ok;
161 }
162 
163 GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint,
164     GDIPCONST GpPoint* endpoint, ARGB startcolor, ARGB endcolor,
165     GpWrapMode wrap, GpLineGradient **line)
166 {
167     GpPointF stF;
168     GpPointF endF;
169 
170     TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
171           startcolor, endcolor, wrap, line);
172 
173     if(!startpoint || !endpoint)
174         return InvalidParameter;
175 
176     stF.X  = (REAL)startpoint->X;
177     stF.Y  = (REAL)startpoint->Y;
178     endF.X = (REAL)endpoint->X;
179     endF.X = (REAL)endpoint->Y;
180 
181     return GdipCreateLineBrush(&stF, &endF, startcolor, endcolor, wrap, line);
182 }
183 
184 GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
185     ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
186     GpLineGradient **line)
187 {
188     GpPointF start, end;
189 
190     TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
191           wrap, line);
192 
193     if(!line || !rect)
194         return InvalidParameter;
195 
196     start.X = rect->X;
197     start.Y = rect->Y;
198     end.X = rect->X + rect->Width;
199     end.Y = rect->Y + rect->Height;
200 
201     return GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line);
202 }
203 
204 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
205     ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
206     GpLineGradient **line)
207 {
208     GpRectF rectF;
209 
210     TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
211           wrap, line);
212 
213     rectF.X      = (REAL) rect->X;
214     rectF.Y      = (REAL) rect->Y;
215     rectF.Width  = (REAL) rect->Width;
216     rectF.Height = (REAL) rect->Height;
217 
218     return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line);
219 }
220 
221 /******************************************************************************
222  * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@]
223  *
224  * FIXME: angle value completely ignored. Don't know how to use it since native
225  *        always set Brush rectangle to rect (independetly of this angle).
226  *        Maybe it's used only on drawing.
227  */
228 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
229     ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
230     GpLineGradient **line)
231 {
232     TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
233           wrap, line);
234 
235     return GdipCreateLineBrushFromRect(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
236                                        wrap, line);
237 }
238 
239 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect,
240     ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
241     GpLineGradient **line)
242 {
243     TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
244           wrap, line);
245 
246     return GdipCreateLineBrushFromRectI(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
247                                         wrap, line);
248 }
249 
250 GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
251     INT count, GpWrapMode wrap, GpPathGradient **grad)
252 {
253     COLORREF col = ARGB2COLORREF(0xffffffff);
254 
255     TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
256 
257     if(!points || !grad)
258         return InvalidParameter;
259 
260     if(count <= 0)
261         return OutOfMemory;
262 
263     *grad = GdipAlloc(sizeof(GpPathGradient));
264     if (!*grad) return OutOfMemory;
265 
266     (*grad)->blendfac = GdipAlloc(sizeof(REAL));
267     if(!(*grad)->blendfac){
268         GdipFree(*grad);
269         return OutOfMemory;
270     }
271     (*grad)->blendfac[0] = 1.0;
272     (*grad)->blendpos    = NULL;
273     (*grad)->blendcount  = 1;
274 
275     (*grad)->pathdata.Count = count;
276     (*grad)->pathdata.Points = GdipAlloc(count * sizeof(PointF));
277     (*grad)->pathdata.Types = GdipAlloc(count);
278 
279     if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){
280         GdipFree((*grad)->pathdata.Points);
281         GdipFree((*grad)->pathdata.Types);
282         GdipFree(*grad);
283         return OutOfMemory;
284     }
285 
286     memcpy((*grad)->pathdata.Points, points, count * sizeof(PointF));
287     memset((*grad)->pathdata.Types, PathPointTypeLine, count);
288 
289     (*grad)->brush.lb.lbStyle = BS_SOLID;
290     (*grad)->brush.lb.lbColor = col;
291     (*grad)->brush.lb.lbHatch = 0;
292 
293     (*grad)->brush.gdibrush = CreateSolidBrush(col);
294     (*grad)->brush.bt = BrushTypePathGradient;
295     (*grad)->centercolor = 0xffffffff;
296     (*grad)->wrap = wrap;
297     (*grad)->gamma = FALSE;
298     (*grad)->center.X = 0.0;
299     (*grad)->center.Y = 0.0;
300     (*grad)->focus.X = 0.0;
301     (*grad)->focus.Y = 0.0;
302 
303     return Ok;
304 }
305 
306 GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points,
307     INT count, GpWrapMode wrap, GpPathGradient **grad)
308 {
309     GpPointF *pointsF;
310     GpStatus ret;
311     INT i;
312 
313     TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad);
314 
315     if(!points || !grad)
316         return InvalidParameter;
317 
318     if(count <= 0)
319         return OutOfMemory;
320 
321     pointsF = GdipAlloc(sizeof(GpPointF) * count);
322     if(!pointsF)
323         return OutOfMemory;
324 
325     for(i = 0; i < count; i++){
326         pointsF[i].X = (REAL)points[i].X;
327         pointsF[i].Y = (REAL)points[i].Y;
328     }
329 
330     ret = GdipCreatePathGradient(pointsF, count, wrap, grad);
331     GdipFree(pointsF);
332 
333     return ret;
334 }
335 
336 /******************************************************************************
337  * GdipCreatePathGradientFromPath [GDIPLUS.@]
338  *
339  * FIXME: path gradient brushes not truly supported (drawn as solid brushes)
340  */
341 GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
342     GpPathGradient **grad)
343 {
344     COLORREF col = ARGB2COLORREF(0xffffffff);
345 
346     TRACE("(%p, %p)\n", path, grad);
347 
348     if(!path || !grad)
349         return InvalidParameter;
350 
351     *grad = GdipAlloc(sizeof(GpPathGradient));
352     if (!*grad) return OutOfMemory;
353 
354     (*grad)->blendfac = GdipAlloc(sizeof(REAL));
355     if(!(*grad)->blendfac){
356         GdipFree(*grad);
357         return OutOfMemory;
358     }
359     (*grad)->blendfac[0] = 1.0;
360     (*grad)->blendpos    = NULL;
361     (*grad)->blendcount  = 1;
362 
363     (*grad)->pathdata.Count = path->pathdata.Count;
364     (*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF));
365     (*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count);
366 
367     if(!(*grad)->pathdata.Points || !(*grad)->pathdata.Types){
368         GdipFree((*grad)->pathdata.Points);
369         GdipFree((*grad)->pathdata.Types);
370         GdipFree(*grad);
371         return OutOfMemory;
372     }
373 
374     memcpy((*grad)->pathdata.Points, path->pathdata.Points,
375            path->pathdata.Count * sizeof(PointF));
376     memcpy((*grad)->pathdata.Types, path->pathdata.Types, path->pathdata.Count);
377 
378     (*grad)->brush.lb.lbStyle = BS_SOLID;
379     (*grad)->brush.lb.lbColor = col;
380     (*grad)->brush.lb.lbHatch = 0;
381 
382     (*grad)->brush.gdibrush = CreateSolidBrush(col);
383     (*grad)->brush.bt = BrushTypePathGradient;
384     (*grad)->centercolor = 0xffffffff;
385     (*grad)->wrap = WrapModeClamp;
386     (*grad)->gamma = FALSE;
387     /* FIXME: this should be set to the "centroid" of the path by default */
388     (*grad)->center.X = 0.0;
389     (*grad)->center.Y = 0.0;
390     (*grad)->focus.X = 0.0;
391     (*grad)->focus.Y = 0.0;
392 
393     return Ok;
394 }
395 
396 /******************************************************************************
397  * GdipCreateSolidFill [GDIPLUS.@]
398  */
399 GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
400 {
401     COLORREF col = ARGB2COLORREF(color);
402 
403     TRACE("(%x, %p)\n", color, sf);
404 
405     if(!sf)  return InvalidParameter;
406 
407     *sf = GdipAlloc(sizeof(GpSolidFill));
408     if (!*sf) return OutOfMemory;
409 
410     (*sf)->brush.lb.lbStyle = BS_SOLID;
411     (*sf)->brush.lb.lbColor = col;
412     (*sf)->brush.lb.lbHatch = 0;
413 
414     (*sf)->brush.gdibrush = CreateSolidBrush(col);
415     (*sf)->brush.bt = BrushTypeSolidColor;
416     (*sf)->color = color;
417 
418     return Ok;
419 }
420 
421 /******************************************************************************
422  * GdipCreateTexture [GDIPLUS.@]
423  *
424  * PARAMS
425  *  image       [I] image to use
426  *  wrapmode    [I] optional
427  *  texture     [O] pointer to the resulting texturebrush
428  *
429  * RETURNS
430  *  SUCCESS: Ok
431  *  FAILURE: element of GpStatus
432  */
433 GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
434         GpTexture **texture)
435 {
436     UINT width, height;
437     GpImageAttributes attributes;
438     GpStatus stat;
439 
440     TRACE("%p, %d %p\n", image, wrapmode, texture);
441 
442     if (!(image && texture))
443         return InvalidParameter;
444 
445     stat = GdipGetImageWidth(image, &width);
446     if (stat != Ok) return stat;
447     stat = GdipGetImageHeight(image, &height);
448     if (stat != Ok) return stat;
449     attributes.wrap = wrapmode;
450 
451     return GdipCreateTextureIA(image, &attributes, 0, 0, width, height,
452             texture);
453 }
454 
455 /******************************************************************************
456  * GdipCreateTexture2 [GDIPLUS.@]
457  */
458 GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode,
459         REAL x, REAL y, REAL width, REAL height, GpTexture **texture)
460 {
461     GpImageAttributes attributes;
462 
463     TRACE("%p %d %f %f %f %f %p\n", image, wrapmode,
464             x, y, width, height, texture);
465 
466     attributes.wrap = wrapmode;
467     return GdipCreateTextureIA(image, &attributes, x, y, width, height,
468             texture);
469 }
470 
471 /******************************************************************************
472  * GdipCreateTextureIA [GDIPLUS.@]
473  *
474  * FIXME: imageattr ignored
475  */
476 GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
477     GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
478     REAL height, GpTexture **texture)
479 {
480     HDC hdc;
481     OLE_HANDLE hbm;
482     HBITMAP old = NULL;
483     BITMAPINFO bmi;
484     BITMAPINFOHEADER *bmih;
485     INT n_x, n_y, n_width, n_height, abs_height, stride, image_stride, i, bytespp;
486     BOOL bm_is_selected;
487     BYTE *dibits, *buff, *textbits;
488 
489     TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height,
490            texture);
491 
492     if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
493         return InvalidParameter;
494 
495     if(image->type != ImageTypeBitmap){
496         FIXME("not implemented for image type %d\n", image->type);
497         return NotImplemented;
498     }
499 
500     n_x = roundr(x);
501     n_y = roundr(y);
502     n_width = roundr(width);
503     n_height = roundr(height);
504 
505     if(n_x + n_width > ((GpBitmap*)image)->width ||
506        n_y + n_height > ((GpBitmap*)image)->height)
507         return InvalidParameter;
508 
509     IPicture_get_Handle(image->picture, &hbm);
510     if(!hbm)   return GenericError;
511     IPicture_get_CurDC(image->picture, &hdc);
512     bm_is_selected = (hdc != 0);
513 
514     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
515     bmi.bmiHeader.biBitCount = 0;
516 
517     if(!bm_is_selected){
518         hdc = CreateCompatibleDC(0);
519         old = SelectObject(hdc, (HBITMAP)hbm);
520     }
521 
522     /* fill out bmi */
523     GetDIBits(hdc, (HBITMAP)hbm, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
524 
525     bytespp = bmi.bmiHeader.biBitCount / 8;
526     abs_height = abs(bmi.bmiHeader.biHeight);
527 
528     if(n_x > bmi.bmiHeader.biWidth || n_x + n_width > bmi.bmiHeader.biWidth ||
529        n_y > abs_height || n_y + n_height > abs_height)
530         return InvalidParameter;
531 
532     dibits = GdipAlloc(bmi.bmiHeader.biSizeImage);
533 
534     if(dibits)  /* this is not a good place to error out */
535         GetDIBits(hdc, (HBITMAP)hbm, 0, abs_height, dibits, &bmi, DIB_RGB_COLORS);
536 
537     if(!bm_is_selected){
538         SelectObject(hdc, old);
539         DeleteDC(hdc);
540     }
541 
542     if(!dibits)
543         return OutOfMemory;
544 
545     image_stride = (bmi.bmiHeader.biWidth * bytespp + 3) & ~3;
546     stride = (n_width * bytespp + 3) & ~3;
547     buff = GdipAlloc(sizeof(BITMAPINFOHEADER) + stride * n_height);
548     if(!buff){
549         GdipFree(dibits);
550         return OutOfMemory;
551     }
552 
553     bmih = (BITMAPINFOHEADER*)buff;
554     textbits = (BYTE*) (bmih + 1);
555     bmih->biSize = sizeof(BITMAPINFOHEADER);
556     bmih->biWidth = n_width;
557     bmih->biHeight = n_height;
558     bmih->biCompression = BI_RGB;
559     bmih->biSizeImage = stride * n_height;
560     bmih->biBitCount = bmi.bmiHeader.biBitCount;
561     bmih->biClrUsed = 0;
562     bmih->biPlanes = 1;
563 
564     /* image is flipped */
565     if(bmi.bmiHeader.biHeight > 0){
566         dibits += bmi.bmiHeader.biSizeImage;
567         image_stride *= -1;
568         textbits += stride * (n_height - 1);
569         stride *= -1;
570     }
571 
572     for(i = 0; i < n_height; i++)
573         memcpy(&textbits[i * stride],
574                &dibits[n_x * bytespp + (n_y + i) * image_stride],
575                abs(stride));
576 
577     *texture = GdipAlloc(sizeof(GpTexture));
578     if (!*texture) return OutOfMemory;
579 
580     (*texture)->brush.lb.lbStyle = BS_DIBPATTERNPT;
581     (*texture)->brush.lb.lbColor = DIB_RGB_COLORS;
582     (*texture)->brush.lb.lbHatch = (ULONG_PTR)buff;
583 
584     (*texture)->brush.gdibrush = CreateBrushIndirect(&(*texture)->brush.lb);
585     (*texture)->brush.bt = BrushTypeTextureFill;
586 
587     GdipFree(dibits);
588     GdipFree(buff);
589 
590     return Ok;
591 }
592 
593 /******************************************************************************
594  * GdipCreateTextureIAI [GDIPLUS.@]
595  */
596 GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageattr,
597     INT x, INT y, INT width, INT height, GpTexture **texture)
598 {
599     TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image, imageattr, x, y, width, height,
600            texture);
601 
602     return GdipCreateTextureIA(image,imageattr,(REAL)x,(REAL)y,(REAL)width,(REAL)height,texture);
603 }
604 
605 GpStatus WINGDIPAPI GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode,
606         INT x, INT y, INT width, INT height, GpTexture **texture)
607 {
608     GpImageAttributes imageattr;
609 
610     TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height,
611             texture);
612 
613     imageattr.wrap = wrapmode;
614 
615     return GdipCreateTextureIA(image, &imageattr, x, y, width, height, texture);
616 }
617 
618 GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
619 {
620     TRACE("(%p, %p)\n", brush, type);
621 
622     if(!brush || !type)  return InvalidParameter;
623 
624     *type = brush->bt;
625 
626     return Ok;
627 }
628 
629 GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
630 {
631     TRACE("(%p)\n", brush);
632 
633     if(!brush)  return InvalidParameter;
634 
635     switch(brush->bt)
636     {
637         case BrushTypePathGradient:
638             GdipFree(((GpPathGradient*) brush)->pathdata.Points);
639             GdipFree(((GpPathGradient*) brush)->pathdata.Types);
640             GdipFree(((GpPathGradient*) brush)->blendfac);
641             GdipFree(((GpPathGradient*) brush)->blendpos);
642             break;
643         case BrushTypeSolidColor:
644         case BrushTypeLinearGradient:
645         case BrushTypeTextureFill:
646         default:
647             break;
648     }
649 
650     DeleteObject(brush->gdibrush);
651     GdipFree(brush);
652 
653     return Ok;
654 }
655 
656 GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line,
657     BOOL *usinggamma)
658 {
659     TRACE("(%p, %p)\n", line, usinggamma);
660 
661     if(!line || !usinggamma)
662         return InvalidParameter;
663 
664     *usinggamma = line->gamma;
665 
666     return Ok;
667 }
668 
669 GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode)
670 {
671     TRACE("(%p, %p)\n", brush, wrapmode);
672 
673     if(!brush || !wrapmode)
674         return InvalidParameter;
675 
676     *wrapmode = brush->wrap;
677 
678     return Ok;
679 }
680 
681 GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend,
682     REAL *positions, INT count)
683 {
684     TRACE("(%p, %p, %p, %d)\n", brush, blend, positions, count);
685 
686     if(!brush || !blend || !positions || count <= 0)
687         return InvalidParameter;
688 
689     if(count < brush->blendcount)
690         return InsufficientBuffer;
691 
692     memcpy(blend, brush->blendfac, count*sizeof(REAL));
693     if(brush->blendcount > 1){
694         memcpy(positions, brush->blendpos, count*sizeof(REAL));
695     }
696 
697     return Ok;
698 }
699 
700 GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count)
701 {
702     TRACE("(%p, %p)\n", brush, count);
703 
704     if(!brush || !count)
705         return InvalidParameter;
706 
707     *count = brush->blendcount;
708 
709     return Ok;
710 }
711 
712 GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad,
713     GpPointF *point)
714 {
715     TRACE("(%p, %p)\n", grad, point);
716 
717     if(!grad || !point)
718         return InvalidParameter;
719 
720     point->X = grad->center.X;
721     point->Y = grad->center.Y;
722 
723     return Ok;
724 }
725 
726 GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad,
727     GpPoint *point)
728 {
729     GpStatus ret;
730     GpPointF ptf;
731 
732     TRACE("(%p, %p)\n", grad, point);
733 
734     if(!point)
735         return InvalidParameter;
736 
737     ret = GdipGetPathGradientCenterPoint(grad,&ptf);
738 
739     if(ret == Ok){
740         point->X = roundr(ptf.X);
741         point->Y = roundr(ptf.Y);
742     }
743 
744     return ret;
745 }
746 
747 GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad,
748     REAL *x, REAL *y)
749 {
750     TRACE("(%p, %p, %p)\n", grad, x, y);
751 
752     if(!grad || !x || !y)
753         return InvalidParameter;
754 
755     *x = grad->focus.X;
756     *y = grad->focus.Y;
757 
758     return Ok;
759 }
760 
761 GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad,
762     BOOL *gamma)
763 {
764     TRACE("(%p, %p)\n", grad, gamma);
765 
766     if(!grad || !gamma)
767         return InvalidParameter;
768 
769     *gamma = grad->gamma;
770 
771     return Ok;
772 }
773 
774 GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
775     INT *count)
776 {
777     TRACE("(%p, %p)\n", grad, count);
778 
779     if(!grad || !count)
780         return InvalidParameter;
781 
782     *count = grad->pathdata.Count;
783 
784     return Ok;
785 }
786 
787 GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
788 {
789     GpRectF r;
790     GpPath* path;
791     GpStatus stat;
792 
793     TRACE("(%p, %p)\n", brush, rect);
794 
795     if(!brush || !rect)
796         return InvalidParameter;
797 
798     stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types,
799                            brush->pathdata.Count, FillModeAlternate, &path);
800     if(stat != Ok)  return stat;
801 
802     stat = GdipGetPathWorldBounds(path, &r, NULL, NULL);
803     if(stat != Ok){
804         GdipDeletePath(path);
805         return stat;
806     }
807 
808     memcpy(rect, &r, sizeof(GpRectF));
809 
810     GdipDeletePath(path);
811 
812     return Ok;
813 }
814 
815 GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
816 {
817     GpRectF rectf;
818     GpStatus stat;
819 
820     TRACE("(%p, %p)\n", brush, rect);
821 
822     if(!brush || !rect)
823         return InvalidParameter;
824 
825     stat = GdipGetPathGradientRect(brush, &rectf);
826     if(stat != Ok)  return stat;
827 
828     rect->X = roundr(rectf.X);
829     rect->Y = roundr(rectf.Y);
830     rect->Width  = roundr(rectf.Width);
831     rect->Height = roundr(rectf.Height);
832 
833     return Ok;
834 }
835 
836 GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
837     *grad, ARGB *argb, INT *count)
838 {
839     static int calls;
840 
841     if(!grad || !argb || !count || (*count < grad->pathdata.Count))
842         return InvalidParameter;
843 
844     if(!(calls++))
845         FIXME("not implemented\n");
846 
847     return NotImplemented;
848 }
849 
850 GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush,
851     GpWrapMode *wrapmode)
852 {
853     TRACE("(%p, %p)\n", brush, wrapmode);
854 
855     if(!brush || !wrapmode)
856         return InvalidParameter;
857 
858     *wrapmode = brush->wrap;
859 
860     return Ok;
861 }
862 
863 GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb)
864 {
865     TRACE("(%p, %p)\n", sf, argb);
866 
867     if(!sf || !argb)
868         return InvalidParameter;
869 
870     *argb = sf->color;
871 
872     return Ok;
873 }
874 
875 GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush,
876     GDIPCONST REAL *blend, GDIPCONST REAL* positions, INT count)
877 {
878     static int calls;
879 
880     if(!brush || !blend || !positions || count <= 0)
881         return InvalidParameter;
882 
883     if(!(calls++))
884         FIXME("not implemented\n");
885 
886     return Ok;
887 }
888 
889 GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line,
890     BOOL usegamma)
891 {
892     TRACE("(%p, %d)\n", line, usegamma);
893 
894     if(!line)
895         return InvalidParameter;
896 
897     line->gamma = usegamma;
898 
899     return Ok;
900 }
901 
902 GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus,
903     REAL scale)
904 {
905     static int calls;
906 
907     if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
908         return InvalidParameter;
909 
910     if(!(calls++))
911         FIXME("not implemented\n");
912 
913     return NotImplemented;
914 }
915 
916 GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line,
917     GpWrapMode wrap)
918 {
919     TRACE("(%p, %d)\n", line, wrap);
920 
921     if(!line || wrap == WrapModeClamp)
922         return InvalidParameter;
923 
924     line->wrap = wrap;
925 
926     return Ok;
927 }
928 
929 GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
930     ARGB argb)
931 {
932     TRACE("(%p, %x)\n", grad, argb);
933 
934     if(!grad)
935         return InvalidParameter;
936 
937     grad->centercolor = argb;
938     grad->brush.lb.lbColor = ARGB2COLORREF(argb);
939 
940     DeleteObject(grad->brush.gdibrush);
941     grad->brush.gdibrush = CreateSolidBrush(grad->brush.lb.lbColor);
942 
943     return Ok;
944 }
945 
946 GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad,
947     GpPointF *point)
948 {
949     TRACE("(%p, %p)\n", grad, point);
950 
951     if(!grad || !point)
952         return InvalidParameter;
953 
954     grad->center.X = point->X;
955     grad->center.Y = point->Y;
956 
957     return Ok;
958 }
959 
960 GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad,
961     GpPoint *point)
962 {
963     GpPointF ptf;
964 
965     TRACE("(%p, %p)\n", grad, point);
966 
967     if(!point)
968         return InvalidParameter;
969 
970     ptf.X = (REAL)point->X;
971     ptf.Y = (REAL)point->Y;
972 
973     return GdipSetPathGradientCenterPoint(grad,&ptf);
974 }
975 
976 GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad,
977     REAL x, REAL y)
978 {
979     TRACE("(%p, %.2f, %.2f)\n", grad, x, y);
980 
981     if(!grad)
982         return InvalidParameter;
983 
984     grad->focus.X = x;
985     grad->focus.Y = y;
986 
987     return Ok;
988 }
989 
990 GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
991     BOOL gamma)
992 {
993     TRACE("(%p, %d)\n", grad, gamma);
994 
995     if(!grad)
996         return InvalidParameter;
997 
998     grad->gamma = gamma;
999 
1000     return Ok;
1001 }
1002 
1003 GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
1004     REAL focus, REAL scale)
1005 {
1006     static int calls;
1007 
1008     if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0)
1009         return InvalidParameter;
1010 
1011     if(!(calls++))
1012         FIXME("not implemented\n");
1013 
1014     return NotImplemented;
1015 }
1016 
1017 GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient
1018     *grad, ARGB *argb, INT *count)
1019 {
1020     static int calls;
1021 
1022     if(!grad || !argb || !count || (*count <= 0) ||
1023         (*count > grad->pathdata.Count))
1024         return InvalidParameter;
1025 
1026     if(!(calls++))
1027         FIXME("not implemented\n");
1028 
1029     return NotImplemented;
1030 }
1031 
1032 GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad,
1033     GpWrapMode wrap)
1034 {
1035     TRACE("(%p, %d)\n", grad, wrap);
1036 
1037     if(!grad)
1038         return InvalidParameter;
1039 
1040     grad->wrap = wrap;
1041 
1042     return Ok;
1043 }
1044 
1045 GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
1046 {
1047     TRACE("(%p, %x)\n", sf, argb);
1048 
1049     if(!sf)
1050         return InvalidParameter;
1051 
1052     sf->color = argb;
1053     sf->brush.lb.lbColor = ARGB2COLORREF(argb);
1054 
1055     DeleteObject(sf->brush.gdibrush);
1056     sf->brush.gdibrush = CreateSolidBrush(sf->brush.lb.lbColor);
1057 
1058     return Ok;
1059 }
1060 
1061 GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture,
1062     GDIPCONST GpMatrix *matrix)
1063 {
1064     static int calls;
1065 
1066     if(!texture || !matrix)
1067         return InvalidParameter;
1068 
1069     if(!(calls++))
1070         FIXME("not implemented\n");
1071 
1072     return Ok;
1073 }
1074 
1075 GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1,
1076     ARGB color2)
1077 {
1078     TRACE("(%p, %x, %x)\n", brush, color1, color2);
1079 
1080     if(!brush)
1081         return InvalidParameter;
1082 
1083     brush->startcolor = color1;
1084     brush->endcolor   = color2;
1085 
1086     return Ok;
1087 }
1088 
1089 GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors)
1090 {
1091     TRACE("(%p, %p)\n", brush, colors);
1092 
1093     if(!brush || !colors)
1094         return InvalidParameter;
1095 
1096     colors[0] = brush->startcolor;
1097     colors[1] = brush->endcolor;
1098 
1099     return Ok;
1100 }
1101 
1102 GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
1103     REAL scale)
1104 {
1105     static int calls;
1106 
1107     if(!(calls++))
1108         FIXME("not implemented\n");
1109 
1110     return NotImplemented;
1111 }
1112 
1113 GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,
1114     GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
1115 {
1116     static int calls;
1117 
1118     if(!(calls++))
1119         FIXME("not implemented\n");
1120 
1121     return NotImplemented;
1122 }
1123 
1124 GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
1125     GDIPCONST GpMatrix *matrix)
1126 {
1127     static int calls;
1128 
1129     if(!(calls++))
1130         FIXME("not implemented\n");
1131 
1132     return NotImplemented;
1133 }
1134 
1135 GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush,
1136         REAL dx, REAL dy, GpMatrixOrder order)
1137 {
1138     FIXME("stub: %p %f %f %d\n", brush, dx, dy, order);
1139 
1140     return NotImplemented;
1141 }
1142 
1143 GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect)
1144 {
1145     TRACE("(%p, %p)\n", brush, rect);
1146 
1147     if(!brush || !rect)
1148         return InvalidParameter;
1149 
1150     rect->X = (brush->startpoint.X < brush->endpoint.X ? brush->startpoint.X: brush->endpoint.X);
1151     rect->Y = (brush->startpoint.Y < brush->endpoint.Y ? brush->startpoint.Y: brush->endpoint.Y);
1152 
1153     rect->Width  = fabs(brush->startpoint.X - brush->endpoint.X);
1154     rect->Height = fabs(brush->startpoint.Y - brush->endpoint.Y);
1155 
1156     return Ok;
1157 }
1158 
1159 GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect)
1160 {
1161     GpRectF  rectF;
1162     GpStatus ret;
1163 
1164     TRACE("(%p, %p)\n", brush, rect);
1165 
1166     if(!rect)
1167         return InvalidParameter;
1168 
1169     ret = GdipGetLineRect(brush, &rectF);
1170 
1171     if(ret == Ok){
1172         rect->X      = roundr(rectF.X);
1173         rect->Y      = roundr(rectF.Y);
1174         rect->Width  = roundr(rectF.Width);
1175         rect->Height = roundr(rectF.Height);
1176     }
1177 
1178     return ret;
1179 }
1180 

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