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

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

Version: ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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 "wingdi.h"
 24 
 25 #include "objbase.h"
 26 
 27 #include "gdiplus.h"
 28 #include "gdiplus_private.h"
 29 #include "wine/debug.h"
 30 
 31 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
 32 
 33 static DWORD gdip_to_gdi_dash(GpDashStyle dash)
 34 {
 35     switch(dash){
 36         case DashStyleSolid:
 37             return PS_SOLID;
 38         case DashStyleDash:
 39             return PS_DASH;
 40         case DashStyleDot:
 41             return PS_DOT;
 42         case DashStyleDashDot:
 43             return PS_DASHDOT;
 44         case DashStyleDashDotDot:
 45             return PS_DASHDOTDOT;
 46         case DashStyleCustom:
 47             return PS_USERSTYLE;
 48         default:
 49             ERR("Not a member of GpDashStyle enumeration\n");
 50             return 0;
 51     }
 52 }
 53 
 54 static DWORD gdip_to_gdi_join(GpLineJoin join)
 55 {
 56     switch(join){
 57         case LineJoinRound:
 58             return PS_JOIN_ROUND;
 59         case LineJoinBevel:
 60             return PS_JOIN_BEVEL;
 61         case LineJoinMiter:
 62         case LineJoinMiterClipped:
 63             return PS_JOIN_MITER;
 64         default:
 65             ERR("Not a member of GpLineJoin enumeration\n");
 66             return 0;
 67     }
 68 }
 69 
 70 GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen)
 71 {
 72     if(!pen || !clonepen)
 73         return InvalidParameter;
 74 
 75     *clonepen = GdipAlloc(sizeof(GpPen));
 76     if(!*clonepen)  return OutOfMemory;
 77 
 78     **clonepen = *pen;
 79 
 80     GdipCloneCustomLineCap(pen->customstart, &(*clonepen)->customstart);
 81     GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
 82     GdipCloneBrush(pen->brush, &(*clonepen)->brush);
 83 
 84     return Ok;
 85 }
 86 
 87 GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, REAL width, GpUnit unit,
 88     GpPen **pen)
 89 {
 90     GpBrush *brush;
 91     GpStatus status;
 92 
 93     GdipCreateSolidFill(color, (GpSolidFill **)(&brush));
 94     status = GdipCreatePen2(brush, width, unit, pen);
 95     GdipDeleteBrush(brush);
 96     return status;
 97 }
 98 
 99 GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit,
100     GpPen **pen)
101 {
102     GpPen *gp_pen;
103     GpBrush *clone_brush;
104 
105     if(!pen || !brush)
106         return InvalidParameter;
107 
108     gp_pen = GdipAlloc(sizeof(GpPen));
109     if(!gp_pen)    return OutOfMemory;
110 
111     gp_pen->style = GP_DEFAULT_PENSTYLE;
112     gp_pen->width = width;
113     gp_pen->unit = unit;
114     gp_pen->endcap = LineCapFlat;
115     gp_pen->join = LineJoinMiter;
116     gp_pen->miterlimit = 10.0;
117     gp_pen->dash = DashStyleSolid;
118     gp_pen->offset = 0.0;
119     gp_pen->customstart = NULL;
120     gp_pen->customend = NULL;
121 
122     if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) {
123         FIXME("UnitWorld, UnitPixel only supported units\n");
124         GdipFree(gp_pen);
125         return NotImplemented;
126     }
127 
128     GdipCloneBrush(brush, &clone_brush);
129     gp_pen->brush = clone_brush;
130 
131     *pen = gp_pen;
132 
133     return Ok;
134 }
135 
136 GpStatus WINGDIPAPI GdipDeletePen(GpPen *pen)
137 {
138     if(!pen)    return InvalidParameter;
139 
140     GdipDeleteBrush(pen->brush);
141     GdipDeleteCustomLineCap(pen->customstart);
142     GdipDeleteCustomLineCap(pen->customend);
143     GdipFree(pen->dashes);
144     GdipFree(pen);
145 
146     return Ok;
147 }
148 
149 GpStatus WINGDIPAPI GdipGetPenBrushFill(GpPen *pen, GpBrush **brush)
150 {
151     if(!pen || !brush)
152         return InvalidParameter;
153 
154     return GdipCloneBrush(pen->brush, brush);
155 }
156 
157 GpStatus WINGDIPAPI GdipGetPenColor(GpPen *pen, ARGB *argb)
158 {
159     if(!pen || !argb)
160         return InvalidParameter;
161 
162     if(pen->brush->bt != BrushTypeSolidColor)
163         return NotImplemented;
164 
165     return GdipGetSolidFillColor(((GpSolidFill*)pen->brush), argb);
166 }
167 
168 GpStatus WINGDIPAPI GdipGetPenCustomEndCap(GpPen *pen, GpCustomLineCap** customCap)
169 {
170     if(!pen || !customCap)
171         return InvalidParameter;
172 
173     if(!pen->customend){
174         *customCap = NULL;
175         return Ok;
176     }
177 
178     return GdipCloneCustomLineCap(pen->customend, customCap);
179 }
180 
181 GpStatus WINGDIPAPI GdipGetPenCustomStartCap(GpPen *pen, GpCustomLineCap** customCap)
182 {
183     if(!pen || !customCap)
184         return InvalidParameter;
185 
186     if(!pen->customstart){
187         *customCap = NULL;
188         return Ok;
189     }
190 
191     return GdipCloneCustomLineCap(pen->customstart, customCap);
192 }
193 
194 GpStatus WINGDIPAPI GdipGetPenDashArray(GpPen *pen, REAL *dash, INT count)
195 {
196     if(!pen || !dash || count > pen->numdashes)
197         return InvalidParameter;
198 
199     /* note: if you pass a negative value for count, it crashes native gdiplus. */
200     if(count < 0)
201         return GenericError;
202 
203     memcpy(dash, pen->dashes, count * sizeof(REAL));
204 
205     return Ok;
206 }
207 
208 GpStatus WINGDIPAPI GdipGetPenDashCap197819(GpPen *pen, GpDashCap *dashCap)
209 {
210     if(!pen || !dashCap)
211         return InvalidParameter;
212 
213     *dashCap = pen->dashcap;
214 
215     return Ok;
216 }
217 
218 GpStatus WINGDIPAPI GdipGetPenDashCount(GpPen *pen, INT *count)
219 {
220     if(!pen || !count)
221         return InvalidParameter;
222 
223     *count = pen->numdashes;
224 
225     return Ok;
226 }
227 
228 GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen *pen, REAL *offset)
229 {
230     if(!pen || !offset)
231         return InvalidParameter;
232 
233     *offset = pen->offset;
234 
235     return Ok;
236 }
237 
238 GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dash)
239 {
240     if(!pen || !dash)
241         return InvalidParameter;
242 
243     *dash = pen->dash;
244 
245     return Ok;
246 }
247 
248 GpStatus WINGDIPAPI GdipGetPenEndCap(GpPen *pen, GpLineCap *endCap)
249 {
250     if(!pen || !endCap)
251         return InvalidParameter;
252 
253     *endCap = pen->endcap;
254 
255     return Ok;
256 }
257 
258 GpStatus WINGDIPAPI GdipGetPenLineJoin(GpPen *pen, GpLineJoin *lineJoin)
259 {
260     if(!pen || !lineJoin)
261         return InvalidParameter;
262 
263     *lineJoin = pen->join;
264 
265     return Ok;
266 }
267 
268 GpStatus WINGDIPAPI GdipGetPenMode(GpPen *pen, GpPenAlignment *mode)
269 {
270     if(!pen || !mode)
271         return InvalidParameter;
272 
273     *mode = pen->align;
274 
275     return Ok;
276 }
277 
278 GpStatus WINGDIPAPI GdipGetPenMiterLimit(GpPen *pen, REAL *miterLimit)
279 {
280     if(!pen || !miterLimit)
281         return InvalidParameter;
282 
283     *miterLimit = pen->miterlimit;
284 
285     return Ok;
286 }
287 
288 GpStatus WINGDIPAPI GdipGetPenStartCap(GpPen *pen, GpLineCap *startCap)
289 {
290     if(!pen || !startCap)
291         return InvalidParameter;
292 
293     *startCap = pen->startcap;
294 
295     return Ok;
296 }
297 
298 GpStatus WINGDIPAPI GdipGetPenUnit(GpPen *pen, GpUnit *unit)
299 {
300     if(!pen || !unit)
301         return InvalidParameter;
302 
303     *unit = pen->unit;
304 
305     return Ok;
306 }
307 
308 GpStatus WINGDIPAPI GdipGetPenWidth(GpPen *pen, REAL *width)
309 {
310     if(!pen || !width)
311         return InvalidParameter;
312 
313     *width = pen->width;
314 
315     return Ok;
316 }
317 
318 GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush)
319 {
320     if(!pen || !brush)
321         return InvalidParameter;
322 
323     GdipDeleteBrush(pen->brush);
324     return GdipCloneBrush(brush, &pen->brush);
325 }
326 
327 GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb)
328 {
329     if(!pen)
330         return InvalidParameter;
331 
332     if(pen->brush->bt != BrushTypeSolidColor)
333         return NotImplemented;
334 
335     return GdipSetSolidFillColor(((GpSolidFill*)pen->brush), argb);
336 }
337 
338 GpStatus WINGDIPAPI GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap* customCap)
339 {
340     GpCustomLineCap * cap;
341     GpStatus ret;
342 
343     /* native crashes on pen == NULL, customCap != NULL */
344     if(!customCap) return InvalidParameter;
345 
346     if((ret = GdipCloneCustomLineCap(customCap, &cap)) == Ok){
347         GdipDeleteCustomLineCap(pen->customend);
348         pen->endcap = LineCapCustom;
349         pen->customend = cap;
350     }
351 
352     return ret;
353 }
354 
355 GpStatus WINGDIPAPI GdipSetPenCustomStartCap(GpPen *pen, GpCustomLineCap* customCap)
356 {
357     GpCustomLineCap * cap;
358     GpStatus ret;
359 
360     /* native crashes on pen == NULL, customCap != NULL */
361     if(!customCap) return InvalidParameter;
362 
363     if((ret = GdipCloneCustomLineCap(customCap, &cap)) == Ok){
364         GdipDeleteCustomLineCap(pen->customstart);
365         pen->startcap = LineCapCustom;
366         pen->customstart = cap;
367     }
368 
369     return ret;
370 }
371 
372 GpStatus WINGDIPAPI GdipSetPenDashArray(GpPen *pen, GDIPCONST REAL *dash,
373     INT count)
374 {
375     INT i;
376     REAL sum = 0;
377 
378     if(!pen || !dash)
379         return InvalidParameter;
380 
381     if(count <= 0)
382         return OutOfMemory;
383 
384     for(i = 0; i < count; i++){
385         sum += dash[i];
386         if(dash[i] < 0.0)
387             return InvalidParameter;
388     }
389 
390     if(sum == 0.0 && count)
391         return InvalidParameter;
392 
393     GdipFree(pen->dashes);
394     pen->dashes = NULL;
395 
396     if(count > 0)
397         pen->dashes = GdipAlloc(count * sizeof(REAL));
398     if(!pen->dashes){
399         pen->numdashes = 0;
400         return OutOfMemory;
401     }
402 
403     GdipSetPenDashStyle(pen, DashStyleCustom);
404     memcpy(pen->dashes, dash, count * sizeof(REAL));
405     pen->numdashes = count;
406 
407     return Ok;
408 }
409 
410 GpStatus WINGDIPAPI GdipSetPenDashCap197819(GpPen *pen, GpDashCap dashCap)
411 {
412     if(!pen)
413         return InvalidParameter;
414 
415     pen->dashcap = dashCap;
416 
417     return Ok;
418 }
419 
420 /* FIXME: dash offset not used */
421 GpStatus WINGDIPAPI GdipSetPenDashOffset(GpPen *pen, REAL offset)
422 {
423     if(!pen)
424         return InvalidParameter;
425 
426     pen->offset = offset;
427 
428     return Ok;
429 }
430 
431 GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen *pen, GpDashStyle dash)
432 {
433     if(!pen)
434         return InvalidParameter;
435 
436     if(dash != DashStyleCustom){
437         GdipFree(pen->dashes);
438         pen->dashes = NULL;
439         pen->numdashes = 0;
440     }
441 
442     pen->dash = dash;
443     pen->style &= ~(PS_ALTERNATE | PS_SOLID | PS_DASH | PS_DOT | PS_DASHDOT |
444                     PS_DASHDOTDOT | PS_NULL | PS_USERSTYLE | PS_INSIDEFRAME);
445     pen->style |= gdip_to_gdi_dash(dash);
446 
447     return Ok;
448 }
449 
450 GpStatus WINGDIPAPI GdipSetPenEndCap(GpPen *pen, GpLineCap cap)
451 {
452     if(!pen)    return InvalidParameter;
453 
454     /* The old custom cap gets deleted even if the new style is LineCapCustom. */
455     GdipDeleteCustomLineCap(pen->customend);
456     pen->customend = NULL;
457     pen->endcap = cap;
458 
459     return Ok;
460 }
461 
462 /* FIXME: startcap, dashcap not used. */
463 GpStatus WINGDIPAPI GdipSetPenLineCap197819(GpPen *pen, GpLineCap start,
464     GpLineCap end, GpDashCap dash)
465 {
466     if(!pen)
467         return InvalidParameter;
468 
469     GdipDeleteCustomLineCap(pen->customend);
470     GdipDeleteCustomLineCap(pen->customstart);
471     pen->customend = NULL;
472     pen->customstart = NULL;
473 
474     pen->startcap = start;
475     pen->endcap = end;
476     pen->dashcap = dash;
477 
478     return Ok;
479 }
480 
481 /* FIXME: Miter line joins behave a bit differently than they do in windows.
482  * Both kinds of miter joins clip if the angle is less than 11 degrees. */
483 GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen *pen, GpLineJoin join)
484 {
485     if(!pen)    return InvalidParameter;
486 
487     pen->join = join;
488     pen->style &= ~(PS_JOIN_ROUND | PS_JOIN_BEVEL | PS_JOIN_MITER);
489     pen->style |= gdip_to_gdi_join(join);
490 
491     return Ok;
492 }
493 
494 GpStatus WINGDIPAPI GdipSetPenMiterLimit(GpPen *pen, REAL limit)
495 {
496     if(!pen)
497         return InvalidParameter;
498 
499     pen->miterlimit = limit;
500 
501     return Ok;
502 }
503 
504 GpStatus WINGDIPAPI GdipSetPenStartCap(GpPen *pen, GpLineCap cap)
505 {
506     if(!pen)    return InvalidParameter;
507 
508     GdipDeleteCustomLineCap(pen->customstart);
509     pen->customstart = NULL;
510     pen->startcap = cap;
511 
512     return Ok;
513 }
514 
515 GpStatus WINGDIPAPI GdipSetPenWidth(GpPen *pen, REAL width)
516 {
517     if(!pen)    return InvalidParameter;
518 
519     pen->width = width;
520 
521     return Ok;
522 }
523 
524 GpStatus WINGDIPAPI GdipSetPenMode(GpPen *pen, GpPenAlignment mode)
525 {
526     if(!pen)    return InvalidParameter;
527 
528     pen->align = mode;
529 
530     return Ok;
531 }
532 

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