Home | History | Annotate | Download | only in gdiplus
      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 (at) 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 
     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):
     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 
    323 private:
    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 */
    339