1/**************************************************************************\
2*
3* Copyright (c) 1998-2000, Microsoft Corp.  All Rights Reserved.
4*
5* Module Name:
6*
7*   GdiplusPen.h
8*
9* Abstract:
10*
11*   Pen API related declarations
12*
13\**************************************************************************/
14#ifndef _GDIPLUSPEN_H
15#define _GDIPLUSPEN_H
16
17//--------------------------------------------------------------------------
18// class for various pen types
19//--------------------------------------------------------------------------
20
21class Pen : public GdiplusBase
22{
23public:
24    friend class GraphicsPath;
25    friend class Graphics;
26
27    // abstract Clone() can't be implemented here because it can't
28    // new an object with pure virtual functions
29
30    // Constructors
31
32    Pen(IN const Color& color,
33        IN REAL width = 1.0f)
34    {
35        Unit unit = UnitWorld;
36        nativePen = NULL;
37        lastResult = DllExports::GdipCreatePen1(color.GetValue(),
38                                    width, unit, &nativePen);
39    }
40
41    Pen(IN const Brush* brush,
42        IN REAL width = 1.0f)
43    {
44        Unit unit = UnitWorld;
45        nativePen = NULL;
46        lastResult = DllExports::GdipCreatePen2(brush->nativeBrush,
47                                    width, unit, &nativePen);
48    }
49
50    ~Pen()
51    {
52        DllExports::GdipDeletePen(nativePen);
53    }
54
55    Pen* Clone() const
56    {
57        GpPen *clonePen = NULL;
58
59        lastResult = DllExports::GdipClonePen(nativePen, &clonePen);
60
61        return new Pen(clonePen, lastResult);
62    }
63
64    Status SetWidth(IN REAL width)
65    {
66        return SetStatus(DllExports::GdipSetPenWidth(nativePen, width));
67    }
68
69    REAL GetWidth() const
70    {
71        REAL width;
72
73        SetStatus(DllExports::GdipGetPenWidth(nativePen, &width));
74
75        return width;
76    }
77
78    // Set/get line caps: start, end, and dash
79
80    // Line cap and join APIs by using LineCap and LineJoin enums.
81
82    #ifdef DCR_USE_NEW_197819
83    Status SetLineCap(IN LineCap startCap,
84                      IN LineCap endCap,
85                      IN DashCap dashCap)
86    {
87        return SetStatus(DllExports::GdipSetPenLineCap197819(nativePen,
88                                   startCap, endCap, dashCap));
89    }
90    #else
91    Status SetLineCap(IN LineCap startCap,
92                      IN LineCap endCap,
93                      IN LineCap dashCap)
94    {
95        return SetStatus(DllExports::GdipSetPenLineCap(nativePen,
96                                   startCap, endCap, dashCap));
97    }
98    #endif // DCR_USE_NEW_197819
99
100    Status SetStartCap(IN LineCap startCap)
101    {
102        return SetStatus(DllExports::GdipSetPenStartCap(nativePen, startCap));
103    }
104
105    Status SetEndCap(IN LineCap endCap)
106    {
107        return SetStatus(DllExports::GdipSetPenEndCap(nativePen, endCap));
108    }
109
110    #ifdef DCR_USE_NEW_197819
111    Status SetDashCap(IN DashCap dashCap)
112    {
113        return SetStatus(DllExports::GdipSetPenDashCap197819(nativePen,
114                                   dashCap));
115    }
116    #else
117    Status SetDashCap(IN LineCap dashCap)
118    {
119        return SetStatus(DllExports::GdipSetPenDashCap(nativePen, dashCap));
120    }
121    #endif // DCR_USE_NEW_197819
122
123    LineCap GetStartCap() const
124    {
125        LineCap startCap;
126
127        SetStatus(DllExports::GdipGetPenStartCap(nativePen, &startCap));
128
129        return startCap;
130    }
131
132    LineCap GetEndCap() const
133    {
134        LineCap endCap;
135
136        SetStatus(DllExports::GdipGetPenEndCap(nativePen, &endCap));
137
138        return endCap;
139    }
140
141    #ifdef DCR_USE_NEW_197819
142    DashCap GetDashCap() const
143    {
144        DashCap dashCap;
145
146        SetStatus(DllExports::GdipGetPenDashCap197819(nativePen,
147                            &dashCap));
148
149        return dashCap;
150    }
151    #else
152    LineCap GetDashCap() const
153    {
154        LineCap dashCap;
155
156        SetStatus(DllExports::GdipGetPenDashCap(nativePen, &dashCap));
157
158        return dashCap;
159    }
160    #endif // DCR_USE_NEW_197819
161
162
163    // Set/get line join
164
165    Status SetLineJoin(IN LineJoin lineJoin)
166    {
167        return SetStatus(DllExports::GdipSetPenLineJoin(nativePen, lineJoin));
168    }
169
170    LineJoin GetLineJoin() const
171    {
172        LineJoin lineJoin;
173
174        SetStatus(DllExports::GdipGetPenLineJoin(nativePen, &lineJoin));
175
176        return lineJoin;
177    }
178
179    Status SetCustomStartCap(IN const CustomLineCap* customCap)
180    {
181        GpCustomLineCap* nativeCap = NULL;
182        if(customCap)
183            nativeCap = customCap->nativeCap;
184
185        return SetStatus(DllExports::GdipSetPenCustomStartCap(nativePen, nativeCap));
186    }
187
188    Status GetCustomStartCap(OUT CustomLineCap* customCap) const
189    {
190        if(!customCap)
191            return SetStatus(InvalidParameter);
192
193        return SetStatus(DllExports::GdipGetPenCustomStartCap(nativePen, &(customCap->nativeCap)));
194    }
195
196    Status SetCustomEndCap(IN const CustomLineCap* customCap)
197    {
198        GpCustomLineCap* nativeCap = NULL;
199        if(customCap)
200            nativeCap = customCap->nativeCap;
201
202        return SetStatus(DllExports::GdipSetPenCustomEndCap(nativePen, nativeCap));
203    }
204
205    Status GetCustomEndCap(OUT CustomLineCap* customCap) const
206    {
207        if(!customCap)
208            return SetStatus(InvalidParameter);
209
210        return SetStatus(DllExports::GdipGetPenCustomEndCap(nativePen, &(customCap->nativeCap)));
211    }
212
213    Status SetMiterLimit(IN REAL miterLimit)
214    {
215        return SetStatus(DllExports::GdipSetPenMiterLimit(nativePen, miterLimit));
216    }
217
218    REAL GetMiterLimit() const
219    {
220        REAL miterLimit;
221
222        SetStatus(DllExports::GdipGetPenMiterLimit(nativePen, &miterLimit));
223
224        return miterLimit;
225    }
226
227    // Set/get pen mode
228    Status SetAlignment(IN PenAlignment penAlignment)
229    {
230        return SetStatus(DllExports::GdipSetPenMode(nativePen, penAlignment));
231    }
232
233    PenAlignment GetAlignment() const
234    {
235        PenAlignment penAlignment;
236
237        SetStatus(DllExports::GdipGetPenMode(nativePen, &penAlignment));
238
239        return penAlignment;
240    }
241
242    // Set/get pen transform
243    Status SetTransform(IN const Matrix* matrix)
244    {
245        return SetStatus(DllExports::GdipSetPenTransform(nativePen,
246                                                         matrix->nativeMatrix));
247    }
248
249    Status GetTransform(OUT Matrix* matrix) const
250    {
251        return SetStatus(DllExports::GdipGetPenTransform(nativePen, matrix->nativeMatrix));
252    }
253
254    Status ResetTransform()
255    {
256        return SetStatus(DllExports::GdipResetPenTransform(nativePen));
257    }
258
259    Status MultiplyTransform(IN const Matrix* matrix,
260                             IN MatrixOrder order = MatrixOrderPrepend)
261    {
262        return SetStatus(DllExports::GdipMultiplyPenTransform(nativePen,
263                                                              matrix->nativeMatrix,
264                                                              order));
265    }
266
267    Status TranslateTransform(IN REAL dx,
268                              IN REAL dy,
269                              IN MatrixOrder order = MatrixOrderPrepend)
270    {
271        return SetStatus(DllExports::GdipTranslatePenTransform(nativePen,
272                                                               dx, dy, order));
273    }
274
275    Status ScaleTransform(IN REAL sx,
276                          IN REAL sy,
277                          IN MatrixOrder order = MatrixOrderPrepend)
278    {
279        return SetStatus(DllExports::GdipScalePenTransform(nativePen,
280                                                             sx, sy, order));
281    }
282
283    Status RotateTransform(IN REAL angle,
284                           IN MatrixOrder order = MatrixOrderPrepend)
285    {
286        return SetStatus(DllExports::GdipRotatePenTransform(nativePen,
287                                                              angle, order));
288    }
289
290    PenType GetPenType() const
291    {
292       PenType type;
293       SetStatus(DllExports::GdipGetPenFillType(nativePen, &type));
294
295       return type;
296    }
297
298    Status SetColor(IN const Color& color)
299    {
300        return SetStatus(DllExports::GdipSetPenColor(nativePen,
301                                                     color.GetValue()));
302    }
303
304    Status SetBrush(IN const Brush* brush)
305    {
306        return SetStatus(DllExports::GdipSetPenBrushFill(nativePen,
307                                       brush->nativeBrush));
308    }
309
310    Status GetColor(OUT Color* color) const
311    {
312        if (color == NULL)
313        {
314            return SetStatus(InvalidParameter);
315        }
316
317        PenType type = GetPenType();
318
319        if (type != PenTypeSolidColor)
320        {
321            return WrongState;
322        }
323
324        ARGB argb;
325
326        SetStatus(DllExports::GdipGetPenColor(nativePen,
327                                              &argb));
328        if (lastResult == Ok)
329        {
330            color->SetValue(argb);
331        }
332
333        return lastResult;
334    }
335
336    Brush* GetBrush() const
337    {
338       PenType type = GetPenType();
339
340       Brush* brush = NULL;
341
342       switch(type)
343       {
344       case PenTypeSolidColor:
345           brush = new SolidBrush();
346           break;
347
348       case PenTypeHatchFill:
349           brush = new HatchBrush();
350           break;
351
352       case PenTypeTextureFill:
353           brush = new TextureBrush();
354           break;
355
356       case PenTypePathGradient:
357           brush = new Brush();
358           break;
359
360       case PenTypeLinearGradient:
361           brush = new LinearGradientBrush();
362           break;
363
364       default:
365           break;
366       }
367
368       if(brush)
369       {
370           GpBrush* nativeBrush;
371
372           SetStatus(DllExports::GdipGetPenBrushFill(nativePen, &nativeBrush));
373           brush->SetNativeBrush(nativeBrush);
374       }
375
376       return brush;
377    }
378
379    DashStyle GetDashStyle() const
380    {
381        DashStyle dashStyle;
382
383        SetStatus(DllExports::GdipGetPenDashStyle(nativePen, &dashStyle));
384
385        return dashStyle;
386    }
387
388    Status SetDashStyle(IN DashStyle dashStyle)
389    {
390        return SetStatus(DllExports::GdipSetPenDashStyle(nativePen, dashStyle));
391    }
392
393    REAL GetDashOffset() const
394    {
395        REAL dashOffset;
396
397        SetStatus(DllExports::GdipGetPenDashOffset(nativePen, &dashOffset));
398
399        return dashOffset;
400    }
401
402    Status SetDashOffset(IN REAL dashOffset)
403    {
404        return SetStatus(DllExports::GdipSetPenDashOffset(nativePen, dashOffset));
405    }
406
407    Status SetDashPattern(IN const REAL* dashArray, IN INT count)
408    {
409        return SetStatus(DllExports::GdipSetPenDashArray(nativePen, dashArray,
410                                                    count));
411    }
412
413    INT GetDashPatternCount() const
414    {
415        INT count = 0;
416
417        SetStatus(DllExports::GdipGetPenDashCount(nativePen, &count));
418
419        return count;
420    }
421
422    Status GetDashPattern(OUT REAL* dashArray,
423                          IN INT count) const
424    {
425        if (dashArray == NULL || count <= 0)
426            return SetStatus(InvalidParameter);
427
428        return SetStatus(DllExports::GdipGetPenDashArray(nativePen,
429                                                         dashArray,
430                                                         count));
431    }
432
433    Status SetCompoundArray(IN const REAL* compoundArray,
434                            IN INT count)
435    {
436        return SetStatus(DllExports::GdipSetPenCompoundArray(nativePen, compoundArray,
437                                                    count));
438    }
439
440    INT GetCompoundArrayCount() const
441    {
442        INT count = 0;
443
444        SetStatus(DllExports::GdipGetPenCompoundCount(nativePen, &count));
445
446        return count;
447    }
448
449    Status GetCompoundArray(OUT REAL* compoundArray,
450                            IN INT count) const
451    {
452        if (compoundArray == NULL || count <= 0)
453            return SetStatus(InvalidParameter);
454
455        return SetStatus(DllExports::GdipGetPenCompoundArray(nativePen,
456                                                             compoundArray,
457                                                             count));
458    }
459
460    Status GetLastStatus() const
461    {
462        Status lastStatus = lastResult;
463        lastResult = Ok;
464
465        return lastStatus;
466    }
467
468protected:
469
470#ifdef DCR_USE_NEW_250932
471
472private:
473    Pen(const Pen &);
474    Pen& operator=(const Pen &);
475protected:
476
477#else
478
479    Pen(const Pen& pen)
480    {
481        pen;
482        SetStatus(NotImplemented);
483        SetNativePen(NULL);
484    }
485
486    Pen& operator=(const Pen& pen)
487    {
488        pen;
489        SetStatus(NotImplemented);
490        return *this;
491    }
492
493#endif
494
495    Pen(GpPen* nativePen, Status status)
496    {
497        lastResult = status;
498        SetNativePen(nativePen);
499    }
500
501    VOID SetNativePen(GpPen* nativePen)
502    {
503        this->nativePen = nativePen;
504    }
505
506    Status SetStatus(Status status) const
507    {
508        if (status != Ok)
509            return (lastResult = status);
510        else
511            return status;
512    }
513
514protected:
515    GpPen* nativePen;
516    mutable Status lastResult;
517};
518
519#endif
520