master
  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 <markus@stber-koenig.de>
 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
 33class Pen: public GdiplusBase
 34{
 35	friend class Graphics;
 36	friend class GraphicsPath;
 37
 38public:
 39	Pen(const Color& color, REAL width = 1.0f):
 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):
 47		nativePen(NULL), lastStatus(Ok)
 48	{
 49		lastStatus = DllExports::GdipCreatePen2(
 50				brush ? brush->nativeBrush : NULL,
 51				width, UnitWorld, &nativePen);
 52	}
 53	~Pen()
 54	{
 55		DllExports::GdipDeletePen(nativePen);
 56	}
 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
 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	//}
 88	Status GetColor(Color *color) const
 89	{
 90		return updateStatus(DllExports::GdipGetPenColor(
 91				nativePen, color ? &color->Value : NULL));
 92	}
 93	Status GetCompoundArray(REAL *compoundArray, INT count) const
 94	{
 95		return updateStatus(DllExports::GdipGetPenCompoundArray(
 96				nativePen, compoundArray, count));
 97	}
 98	INT GetCompoundArrayCount() const
 99	{
100		INT result = 0;
101		updateStatus(DllExports::GdipGetPenCompoundCount(
102				nativePen, &result));
103		return result;
104	}
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	}
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	}
119	DashCap GetDashCap() const
120	{
121		DashCap result = DashCapFlat;
122		updateStatus(DllExports::GdipGetPenDashCap197819(
123				nativePen, &result));
124		return result;
125	}
126	REAL GetDashOffset() const
127	{
128		REAL result = 0.0f;
129		updateStatus(DllExports::GdipGetPenDashOffset(
130				nativePen, &result));
131		return result;
132	}
133	Status GetDashPattern(REAL *dashArray, INT count) const
134	{
135		return updateStatus(DllExports::GdipGetPenDashArray(
136				nativePen, dashArray, count));
137	}
138	INT GetDashPatternCount() const
139	{
140		INT result = 0;
141		updateStatus(DllExports::GdipGetPenDashCount(
142				nativePen, &result));
143		return result;
144	}
145	DashStyle GetDashStyle() const
146	{
147		DashStyle result = DashStyleSolid;
148		updateStatus(DllExports::GdipGetPenDashStyle(
149				nativePen, &result));
150		return result;
151	}
152	LineCap GetEndCap() const
153	{
154		LineCap result = LineCapFlat;
155		updateStatus(DllExports::GdipGetPenEndCap(nativePen, &result));
156		return result;
157	}
158	Status GetLastStatus() const
159	{
160		Status result = lastStatus;
161		lastStatus = Ok;
162		return result;
163	}
164	LineJoin GetLineJoin() const
165	{
166		LineJoin result = LineJoinMiter;
167		updateStatus(DllExports::GdipGetPenLineJoin(
168				nativePen, &result));
169		return result;
170	}
171	REAL GetMiterLimit() const
172	{
173		REAL result = 10.0f;
174		updateStatus(DllExports::GdipGetPenMiterLimit(
175				nativePen, &result));
176		return result;
177	}
178	PenType GetPenType() const
179	{
180		PenType result = PenTypeUnknown;
181		updateStatus(DllExports::GdipGetPenFillType(
182				nativePen, &result));
183		return result;
184	}
185	LineCap GetStartCap() const
186	{
187		LineCap result = LineCapFlat;
188		updateStatus(DllExports::GdipGetPenStartCap(
189				nativePen, &result));
190		return result;
191	}
192	Status GetTransform(Matrix *matrix) const
193	{
194		return updateStatus(DllExports::GdipGetPenTransform(
195				nativePen,
196				matrix ? matrix->nativeMatrix : NULL));
197	}
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	}
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	}
228	Status SetAlignment(PenAlignment penAlignment)
229	{
230		return updateStatus(DllExports::GdipSetPenMode(
231				nativePen, penAlignment));
232	}
233	Status SetBrush(const Brush *brush)
234	{
235		return updateStatus(DllExports::GdipSetPenBrushFill(
236				nativePen, brush ? brush->nativeBrush : NULL));
237	}
238	Status SetColor(const Color& color)
239	{
240		return updateStatus(DllExports::GdipSetPenColor(
241				nativePen, color.GetValue()));
242	}
243	Status SetCompoundArray(const REAL *compoundArray, INT count)
244	{
245		return updateStatus(DllExports::GdipSetPenCompoundArray(
246				nativePen, compoundArray, count));
247	}
248	Status SetCustomEndCap(const CustomLineCap *customCap)
249	{
250		return updateStatus(DllExports::GdipSetPenCustomEndCap(
251				nativePen,
252				customCap ? customCap->nativeCustomLineCap : NULL));
253	}
254	Status SetCustomStartCap(const CustomLineCap *customCap)
255	{
256		return updateStatus(DllExports::GdipSetPenCustomStartCap(
257				nativePen,
258				customCap ? customCap->nativeCustomLineCap : NULL));
259	}
260	Status SetDashCap(DashCap dashCap)
261	{
262		return updateStatus(DllExports::GdipSetPenDashCap197819(
263				nativePen, dashCap));
264	}
265	Status SetDashOffset(REAL dashOffset)
266	{
267		return updateStatus(DllExports::GdipSetPenDashOffset(
268				nativePen, dashOffset));
269	}
270	Status SetDashPattern(const REAL *dashArray, INT count)
271	{
272		return updateStatus(DllExports::GdipSetPenDashArray(
273				nativePen, dashArray, count));
274	}
275	Status SetDashStyle(DashStyle dashStyle)
276	{
277		return updateStatus(DllExports::GdipSetPenDashStyle(
278				nativePen, dashStyle));
279	}
280	Status SetEndCap(LineCap endCap)
281	{
282		return updateStatus(DllExports::GdipSetPenEndCap(
283				nativePen, endCap));
284	}
285	Status SetLineCap(LineCap startCap, LineCap endCap, DashCap dashCap)
286	{
287		return updateStatus(DllExports::GdipSetPenLineCap197819(
288				nativePen, startCap, endCap, dashCap));
289	}
290	Status SetLineJoin(LineJoin lineJoin)
291	{
292		return updateStatus(DllExports::GdipSetPenLineJoin(
293				nativePen, lineJoin));
294	}
295	Status SetMiterLimit(REAL miterLimit)
296	{
297		return updateStatus(DllExports::GdipSetPenMiterLimit(
298				nativePen, miterLimit));
299	}
300	Status SetStartCap(LineCap startCap)
301	{
302		return updateStatus(DllExports::GdipSetPenStartCap(
303				nativePen, startCap));
304	}
305	Status SetTransform(const Matrix *matrix)
306	{
307		return updateStatus(DllExports::GdipSetPenTransform(
308				nativePen,
309				matrix ? matrix->nativeMatrix : NULL));
310	}
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
323private:
324	Pen(GpPen *pen, Status status): nativePen(pen), lastStatus(status) {}
325	Pen(const Pen& pen);
326	Pen& operator=(const Pen&);
327
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 */