1 /*
2  * gdipluspen.h
3  *
4  * GDI+ Pen class
5  *
6  * This file is part of the w32api package.
7  *
8  * Contributors:
9  *   Created by Markus Koenig <[email protected]>
10  *
11  * THIS SOFTWARE IS NOT COPYRIGHTED
12  *
13  * This source code is offered for use in the public domain. You may
14  * use, modify or distribute it freely.
15  *
16  * This code is distributed in the hope that it will be useful but
17  * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
18  * DISCLAIMED. This includes but is not limited to warranties of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  */
22 
23 #ifndef __GDIPLUS_PEN_H
24 #define __GDIPLUS_PEN_H
25 #if __GNUC__ >=3
26 #pragma GCC system_header
27 #endif
28 
29 #ifndef __cplusplus
30 #error "A C++ compiler is required to include gdipluspen.h."
31 #endif
32 
33 class Pen: public GdiplusBase
34 {
35 	friend class Graphics;
36 	friend class GraphicsPath;
37 
38 public:
39 	Pen(const Color& color, REAL width = 1.0f):
nativePen(NULL)40 		nativePen(NULL), lastStatus(Ok)
41 	{
42 		lastStatus = DllExports::GdipCreatePen1(
43 				color.GetValue(), width, UnitWorld,
44 				&nativePen);
45 	}
46 	Pen(const Brush *brush, REAL width = 1.0f):
nativePen(NULL)47 		nativePen(NULL), lastStatus(Ok)
48 	{
49 		lastStatus = DllExports::GdipCreatePen2(
50 				brush ? brush->nativeBrush : NULL,
51 				width, UnitWorld, &nativePen);
52 	}
~Pen()53 	~Pen()
54 	{
55 		DllExports::GdipDeletePen(nativePen);
56 	}
Clone()57 	Pen* Clone() const
58 	{
59 		GpPen *clonePen = NULL;
60 		Status status = updateStatus(DllExports::GdipClonePen(
61 				nativePen, &clonePen));
62 		if (status == Ok) {
63 			Pen *result = new Pen(clonePen, lastStatus);
64 			if (!result) {
65 				DllExports::GdipDeletePen(clonePen);
66 				lastStatus = OutOfMemory;
67 			}
68 			return result;
69 		} else {
70 			return NULL;
71 		}
72 	}
73 
GetAlignment()74 	PenAlignment GetAlignment() const
75 	{
76 		PenAlignment result = PenAlignmentCenter;
77 		updateStatus(DllExports::GdipGetPenMode(nativePen, &result));
78 		return result;
79 	}
80 	// TODO: implement Pen::GetBrush()
81 	//Brush *GetBrush() const
82 	//{
83 	//	// where is the pen brush allocated (static,member,new,other)?
84 	//	// GdipGetPenBrushFill just returns a GpBrush*
85 	//	updateStatus(NotImplemented);
86 	//	return NULL;
87 	//}
GetColor(Color * color)88 	Status GetColor(Color *color) const
89 	{
90 		return updateStatus(DllExports::GdipGetPenColor(
91 				nativePen, color ? &color->Value : NULL));
92 	}
GetCompoundArray(REAL * compoundArray,INT count)93 	Status GetCompoundArray(REAL *compoundArray, INT count) const
94 	{
95 		return updateStatus(DllExports::GdipGetPenCompoundArray(
96 				nativePen, compoundArray, count));
97 	}
GetCompoundArrayCount()98 	INT GetCompoundArrayCount() const
99 	{
100 		INT result = 0;
101 		updateStatus(DllExports::GdipGetPenCompoundCount(
102 				nativePen, &result));
103 		return result;
104 	}
GetCustomEndCap(CustomLineCap * customCap)105 	Status GetCustomEndCap(CustomLineCap *customCap) const
106 	{
107 		if (!customCap) return lastStatus = InvalidParameter;
108 		// FIXME: do we need to call GdipDeleteCustomLineCap first?
109 		return updateStatus(DllExports::GdipGetPenCustomEndCap(
110 				nativePen, &customCap->nativeCustomLineCap));
111 	}
GetCustomStartCap(CustomLineCap * customCap)112 	Status GetCustomStartCap(CustomLineCap *customCap) const
113 	{
114 		if (!customCap) return lastStatus = InvalidParameter;
115 		// FIXME: do we need to call GdipDeleteCustomLineCap first?
116 		return updateStatus(DllExports::GdipGetPenCustomStartCap(
117 				nativePen, &customCap->nativeCustomLineCap));
118 	}
GetDashCap()119 	DashCap GetDashCap() const
120 	{
121 		DashCap result = DashCapFlat;
122 		updateStatus(DllExports::GdipGetPenDashCap197819(
123 				nativePen, &result));
124 		return result;
125 	}
GetDashOffset()126 	REAL GetDashOffset() const
127 	{
128 		REAL result = 0.0f;
129 		updateStatus(DllExports::GdipGetPenDashOffset(
130 				nativePen, &result));
131 		return result;
132 	}
GetDashPattern(REAL * dashArray,INT count)133 	Status GetDashPattern(REAL *dashArray, INT count) const
134 	{
135 		return updateStatus(DllExports::GdipGetPenDashArray(
136 				nativePen, dashArray, count));
137 	}
GetDashPatternCount()138 	INT GetDashPatternCount() const
139 	{
140 		INT result = 0;
141 		updateStatus(DllExports::GdipGetPenDashCount(
142 				nativePen, &result));
143 		return result;
144 	}
GetDashStyle()145 	DashStyle GetDashStyle() const
146 	{
147 		DashStyle result = DashStyleSolid;
148 		updateStatus(DllExports::GdipGetPenDashStyle(
149 				nativePen, &result));
150 		return result;
151 	}
GetEndCap()152 	LineCap GetEndCap() const
153 	{
154 		LineCap result = LineCapFlat;
155 		updateStatus(DllExports::GdipGetPenEndCap(nativePen, &result));
156 		return result;
157 	}
GetLastStatus()158 	Status GetLastStatus() const
159 	{
160 		Status result = lastStatus;
161 		lastStatus = Ok;
162 		return result;
163 	}
GetLineJoin()164 	LineJoin GetLineJoin() const
165 	{
166 		LineJoin result = LineJoinMiter;
167 		updateStatus(DllExports::GdipGetPenLineJoin(
168 				nativePen, &result));
169 		return result;
170 	}
GetMiterLimit()171 	REAL GetMiterLimit() const
172 	{
173 		REAL result = 10.0f;
174 		updateStatus(DllExports::GdipGetPenMiterLimit(
175 				nativePen, &result));
176 		return result;
177 	}
GetPenType()178 	PenType GetPenType() const
179 	{
180 		PenType result = PenTypeUnknown;
181 		updateStatus(DllExports::GdipGetPenFillType(
182 				nativePen, &result));
183 		return result;
184 	}
GetStartCap()185 	LineCap GetStartCap() const
186 	{
187 		LineCap result = LineCapFlat;
188 		updateStatus(DllExports::GdipGetPenStartCap(
189 				nativePen, &result));
190 		return result;
191 	}
GetTransform(Matrix * matrix)192 	Status GetTransform(Matrix *matrix) const
193 	{
194 		return updateStatus(DllExports::GdipGetPenTransform(
195 				nativePen,
196 				matrix ? matrix->nativeMatrix : NULL));
197 	}
GetWidth()198 	REAL GetWidth() const
199 	{
200 		REAL result = 1.0f;
201 		updateStatus(DllExports::GdipGetPenWidth(nativePen, &result));
202 		return result;
203 	}
204 	Status MultiplyTransform(const Matrix *matrix,
205 			MatrixOrder order = MatrixOrderPrepend)
206 	{
207 		return updateStatus(DllExports::GdipMultiplyPenTransform(
208 				nativePen,
209 				matrix ? matrix->nativeMatrix : NULL, order));
210 	}
ResetTransform()211 	Status ResetTransform()
212 	{
213 		return updateStatus(DllExports::GdipResetPenTransform(
214 				nativePen));
215 	}
216 	Status RotateTransform(REAL angle,
217 			MatrixOrder order = MatrixOrderPrepend)
218 	{
219 		return updateStatus(DllExports::GdipRotatePenTransform(
220 				nativePen, angle, order));
221 	}
222 	Status ScaleTransform(REAL sx, REAL sy,
223 			MatrixOrder order = MatrixOrderPrepend)
224 	{
225 		return updateStatus(DllExports::GdipScalePenTransform(
226 				nativePen, sx, sy, order));
227 	}
SetAlignment(PenAlignment penAlignment)228 	Status SetAlignment(PenAlignment penAlignment)
229 	{
230 		return updateStatus(DllExports::GdipSetPenMode(
231 				nativePen, penAlignment));
232 	}
SetBrush(const Brush * brush)233 	Status SetBrush(const Brush *brush)
234 	{
235 		return updateStatus(DllExports::GdipSetPenBrushFill(
236 				nativePen, brush ? brush->nativeBrush : NULL));
237 	}
SetColor(const Color & color)238 	Status SetColor(const Color& color)
239 	{
240 		return updateStatus(DllExports::GdipSetPenColor(
241 				nativePen, color.GetValue()));
242 	}
SetCompoundArray(const REAL * compoundArray,INT count)243 	Status SetCompoundArray(const REAL *compoundArray, INT count)
244 	{
245 		return updateStatus(DllExports::GdipSetPenCompoundArray(
246 				nativePen, compoundArray, count));
247 	}
SetCustomEndCap(const CustomLineCap * customCap)248 	Status SetCustomEndCap(const CustomLineCap *customCap)
249 	{
250 		return updateStatus(DllExports::GdipSetPenCustomEndCap(
251 				nativePen,
252 				customCap ? customCap->nativeCustomLineCap : NULL));
253 	}
SetCustomStartCap(const CustomLineCap * customCap)254 	Status SetCustomStartCap(const CustomLineCap *customCap)
255 	{
256 		return updateStatus(DllExports::GdipSetPenCustomStartCap(
257 				nativePen,
258 				customCap ? customCap->nativeCustomLineCap : NULL));
259 	}
SetDashCap(DashCap dashCap)260 	Status SetDashCap(DashCap dashCap)
261 	{
262 		return updateStatus(DllExports::GdipSetPenDashCap197819(
263 				nativePen, dashCap));
264 	}
SetDashOffset(REAL dashOffset)265 	Status SetDashOffset(REAL dashOffset)
266 	{
267 		return updateStatus(DllExports::GdipSetPenDashOffset(
268 				nativePen, dashOffset));
269 	}
SetDashPattern(const REAL * dashArray,INT count)270 	Status SetDashPattern(const REAL *dashArray, INT count)
271 	{
272 		return updateStatus(DllExports::GdipSetPenDashArray(
273 				nativePen, dashArray, count));
274 	}
SetDashStyle(DashStyle dashStyle)275 	Status SetDashStyle(DashStyle dashStyle)
276 	{
277 		return updateStatus(DllExports::GdipSetPenDashStyle(
278 				nativePen, dashStyle));
279 	}
SetEndCap(LineCap endCap)280 	Status SetEndCap(LineCap endCap)
281 	{
282 		return updateStatus(DllExports::GdipSetPenEndCap(
283 				nativePen, endCap));
284 	}
SetLineCap(LineCap startCap,LineCap endCap,DashCap dashCap)285 	Status SetLineCap(LineCap startCap, LineCap endCap, DashCap dashCap)
286 	{
287 		return updateStatus(DllExports::GdipSetPenLineCap197819(
288 				nativePen, startCap, endCap, dashCap));
289 	}
SetLineJoin(LineJoin lineJoin)290 	Status SetLineJoin(LineJoin lineJoin)
291 	{
292 		return updateStatus(DllExports::GdipSetPenLineJoin(
293 				nativePen, lineJoin));
294 	}
SetMiterLimit(REAL miterLimit)295 	Status SetMiterLimit(REAL miterLimit)
296 	{
297 		return updateStatus(DllExports::GdipSetPenMiterLimit(
298 				nativePen, miterLimit));
299 	}
SetStartCap(LineCap startCap)300 	Status SetStartCap(LineCap startCap)
301 	{
302 		return updateStatus(DllExports::GdipSetPenStartCap(
303 				nativePen, startCap));
304 	}
SetTransform(const Matrix * matrix)305 	Status SetTransform(const Matrix *matrix)
306 	{
307 		return updateStatus(DllExports::GdipSetPenTransform(
308 				nativePen,
309 				matrix ? matrix->nativeMatrix : NULL));
310 	}
SetWidth(REAL width)311 	Status SetWidth(REAL width)
312 	{
313 		return updateStatus(DllExports::GdipSetPenWidth(
314 				nativePen, width));
315 	}
316 	Status TranslateTransform(REAL dx, REAL dy,
317 			MatrixOrder order = MatrixOrderPrepend)
318 	{
319 		return updateStatus(DllExports::GdipTranslatePenTransform(
320 				nativePen, dx, dy, order));
321 	}
322 
323 private:
Pen(GpPen * pen,Status status)324 	Pen(GpPen *pen, Status status): nativePen(pen), lastStatus(status) {}
325 	Pen(const Pen& pen);
326 	Pen& operator=(const Pen&);
327 
updateStatus(Status newStatus)328 	Status updateStatus(Status newStatus) const
329 	{
330 		if (newStatus != Ok) lastStatus = newStatus;
331 		return newStatus;
332 	}
333 
334 	GpPen *nativePen;
335 	mutable Status lastStatus;
336 };
337 
338 #endif /* __GDIPLUS_PEN_H */
339