| /* | |
| * gdiplusbrush.h | |
| * | |
| * GDI+ brush classes | |
| * | |
| * This file is part of the w32api package. | |
| * | |
| * Contributors: | |
| * Created by Markus Koenig <markus@stber-koenig.de> | |
| * | |
| * THIS SOFTWARE IS NOT COPYRIGHTED | |
| * | |
| * This source code is offered for use in the public domain. You may | |
| * use, modify or distribute it freely. | |
| * | |
| * This code is distributed in the hope that it will be useful but | |
| * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY | |
| * DISCLAIMED. This includes but is not limited to warranties of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| * | |
| */ | |
| #ifndef __GDIPLUS_BRUSH_H | |
| #define __GDIPLUS_BRUSH_H | |
| #if __GNUC__ >=3 | |
| #pragma GCC system_header | |
| #endif | |
| #ifndef __cplusplus | |
| #error "A C++ compiler is required to include gdiplusbrush.h." | |
| #endif | |
| class Brush: public GdiplusBase | |
| { | |
| friend class HatchBrush; | |
| friend class LinearGradientBrush; | |
| friend class PathGradientBrush; | |
| friend class SolidBrush; | |
| friend class TextureBrush; | |
| friend class Graphics; | |
| friend class Pen; | |
| public: | |
| virtual ~Brush() | |
| { | |
| DllExports::GdipDeleteBrush(nativeBrush); | |
| } | |
| virtual Brush* Clone() const // each subclass must implement this | |
| { | |
| lastStatus = NotImplemented; | |
| return NULL; | |
| } | |
| Status GetLastStatus() const | |
| { | |
| Status result = lastStatus; | |
| lastStatus = Ok; | |
| return result; | |
| } | |
| BrushType GetType() const | |
| { | |
| BrushType result = BrushTypeSolidColor; | |
| updateStatus(DllExports::GdipGetBrushType(nativeBrush, &result)); | |
| return result; | |
| } | |
| private: | |
| Brush(): nativeBrush(NULL), lastStatus(Ok) {} | |
| Brush(GpBrush *brush, Status status): | |
| nativeBrush(brush), lastStatus(status) {} | |
| Brush(const Brush& brush); | |
| Brush& operator=(const Brush&); | |
| Status updateStatus(Status newStatus) const | |
| { | |
| if (newStatus != Ok) lastStatus = newStatus; | |
| return newStatus; | |
| } | |
| GpBrush *nativeBrush; | |
| mutable Status lastStatus; | |
| }; | |
| class HatchBrush: public Brush | |
| { | |
| public: | |
| HatchBrush(HatchStyle hatchStyle, | |
| const Color& foreColor, | |
| const Color& backColor = Color()) | |
| { | |
| GpHatch *nativeHatch = NULL; | |
| lastStatus = DllExports::GdipCreateHatchBrush(hatchStyle, | |
| foreColor.GetValue(), backColor.GetValue(), | |
| &nativeHatch); | |
| nativeBrush = nativeHatch; | |
| } | |
| virtual HatchBrush* Clone() const | |
| { | |
| GpBrush *cloneBrush = NULL; | |
| Status status = updateStatus(DllExports::GdipCloneBrush( | |
| nativeBrush, &cloneBrush)); | |
| if (status == Ok) { | |
| HatchBrush *result = | |
| new HatchBrush(cloneBrush, lastStatus); | |
| if (!result) { | |
| DllExports::GdipDeleteBrush(cloneBrush); | |
| updateStatus(OutOfMemory); | |
| } | |
| return result; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| Status GetBackgroundColor(Color *color) const | |
| { | |
| return updateStatus(DllExports::GdipGetHatchBackgroundColor( | |
| (GpHatch*) nativeBrush, | |
| color ? &color->Value : NULL)); | |
| } | |
| Status GetForegroundColor(Color *color) const | |
| { | |
| return updateStatus(DllExports::GdipGetHatchForegroundColor( | |
| (GpHatch*) nativeBrush, | |
| color ? &color->Value : NULL)); | |
| } | |
| HatchStyle GetHatchStyle() const | |
| { | |
| HatchStyle result; | |
| updateStatus(DllExports::GdipGetHatchStyle( | |
| (GpHatch*) nativeBrush, &result)); | |
| return result; | |
| } | |
| private: | |
| HatchBrush(GpBrush *brush, Status status): Brush(brush, status) {} | |
| HatchBrush(const HatchBrush& brush); | |
| HatchBrush& operator=(const HatchBrush&); | |
| }; | |
| class LinearGradientBrush: public Brush | |
| { | |
| public: | |
| LinearGradientBrush(const PointF& point1, const PointF& point2, | |
| const Color& color1, const Color& color2) | |
| { | |
| GpLineGradient *nativeLineGradient = NULL; | |
| lastStatus = DllExports::GdipCreateLineBrush( | |
| &point1, &point2, | |
| color1.GetValue(), color2.GetValue(), | |
| WrapModeTile, &nativeLineGradient); | |
| nativeBrush = nativeLineGradient; | |
| } | |
| LinearGradientBrush(const Point& point1, const Point& point2, | |
| const Color& color1, const Color& color2) | |
| { | |
| GpLineGradient *nativeLineGradient = NULL; | |
| lastStatus = DllExports::GdipCreateLineBrushI( | |
| &point1, &point2, | |
| color1.GetValue(), color2.GetValue(), | |
| WrapModeTile, &nativeLineGradient); | |
| nativeBrush = nativeLineGradient; | |
| } | |
| LinearGradientBrush(const RectF& rect, const Color& color1, | |
| const Color& color2, LinearGradientMode mode) | |
| { | |
| GpLineGradient *nativeLineGradient = NULL; | |
| lastStatus = DllExports::GdipCreateLineBrushFromRect( | |
| &rect, color1.GetValue(), color2.GetValue(), | |
| mode, WrapModeTile, &nativeLineGradient); | |
| nativeBrush = nativeLineGradient; | |
| } | |
| LinearGradientBrush(const Rect& rect, const Color& color1, | |
| const Color& color2, LinearGradientMode mode) | |
| { | |
| GpLineGradient *nativeLineGradient = NULL; | |
| lastStatus = DllExports::GdipCreateLineBrushFromRectI( | |
| &rect, color1.GetValue(), color2.GetValue(), | |
| mode, WrapModeTile, &nativeLineGradient); | |
| nativeBrush = nativeLineGradient; | |
| } | |
| LinearGradientBrush(const RectF& rect, const Color& color1, | |
| const Color& color2, REAL angle, | |
| BOOL isAngleScalable = FALSE) | |
| { | |
| GpLineGradient *nativeLineGradient = NULL; | |
| lastStatus = DllExports::GdipCreateLineBrushFromRectWithAngle( | |
| &rect, color1.GetValue(), color2.GetValue(), | |
| angle, isAngleScalable, WrapModeTile, | |
| &nativeLineGradient); | |
| nativeBrush = nativeLineGradient; | |
| } | |
| LinearGradientBrush(const Rect& rect, const Color& color1, | |
| const Color& color2, REAL angle, | |
| BOOL isAngleScalable = FALSE) | |
| { | |
| GpLineGradient *nativeLineGradient = NULL; | |
| lastStatus = DllExports::GdipCreateLineBrushFromRectWithAngleI( | |
| &rect, color1.GetValue(), color2.GetValue(), | |
| angle, isAngleScalable, WrapModeTile, | |
| &nativeLineGradient); | |
| nativeBrush = nativeLineGradient; | |
| } | |
| virtual LinearGradientBrush* Clone() const | |
| { | |
| GpBrush *cloneBrush = NULL; | |
| Status status = updateStatus(DllExports::GdipCloneBrush( | |
| nativeBrush, &cloneBrush)); | |
| if (status == Ok) { | |
| LinearGradientBrush *result = | |
| new LinearGradientBrush(cloneBrush, lastStatus); | |
| if (!result) { | |
| DllExports::GdipDeleteBrush(cloneBrush); | |
| updateStatus(OutOfMemory); | |
| } | |
| return result; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| Status GetBlend(REAL *blendFactors, REAL *blendPositions, | |
| INT count) const | |
| { | |
| return updateStatus(DllExports::GdipGetLineBlend( | |
| (GpLineGradient*) nativeBrush, | |
| blendFactors, blendPositions, count)); | |
| } | |
| INT GetBlendCount() const | |
| { | |
| INT result = 0; | |
| updateStatus(DllExports::GdipGetLineBlendCount( | |
| (GpLineGradient*) nativeBrush, &result)); | |
| return result; | |
| } | |
| BOOL GetGammaCorrection() const | |
| { | |
| BOOL result = FALSE; | |
| updateStatus(DllExports::GdipGetLineGammaCorrection( | |
| (GpLineGradient*) nativeBrush, &result)); | |
| return result; | |
| } | |
| INT GetInterpolationColorCount() const | |
| { | |
| INT result = 0; | |
| updateStatus(DllExports::GdipGetLinePresetBlendCount( | |
| (GpLineGradient*) nativeBrush, &result)); | |
| return result; | |
| } | |
| Status GetInterpolationColors(Color *presetColors, | |
| REAL *blendPositions, INT count) const | |
| { | |
| if (!presetColors || count <= 0) | |
| return lastStatus = InvalidParameter; | |
| ARGB *presetArgb = | |
| (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB)); | |
| if (!presetArgb) | |
| return lastStatus = OutOfMemory; | |
| Status status = updateStatus(DllExports::GdipGetLinePresetBlend( | |
| (GpLineGradient*) nativeBrush, presetArgb, | |
| blendPositions, count)); | |
| for (INT i = 0; i < count; ++i) { | |
| presetColors[i].SetValue(presetArgb[i]); | |
| } | |
| DllExports::GdipFree((void*) presetArgb); | |
| return status; | |
| } | |
| Status GetLinearColors(Color *colors) const | |
| { | |
| if (!colors) return lastStatus = InvalidParameter; | |
| ARGB colorsArgb[2]; | |
| Status status = updateStatus(DllExports::GdipGetLineColors( | |
| (GpLineGradient*) nativeBrush, colorsArgb)); | |
| colors[0].SetValue(colorsArgb[0]); | |
| colors[1].SetValue(colorsArgb[1]); | |
| return status; | |
| } | |
| Status GetRectangle(RectF *rect) const | |
| { | |
| return updateStatus(DllExports::GdipGetLineRect( | |
| (GpLineGradient*) nativeBrush, rect)); | |
| } | |
| Status GetRectangle(Rect *rect) const | |
| { | |
| return updateStatus(DllExports::GdipGetLineRectI( | |
| (GpLineGradient*) nativeBrush, rect)); | |
| } | |
| Status GetTransform(Matrix *matrix) const | |
| { | |
| return updateStatus(DllExports::GdipGetLineTransform( | |
| (GpLineGradient*) nativeBrush, | |
| matrix ? matrix->nativeMatrix : NULL)); | |
| } | |
| WrapMode GetWrapMode() const | |
| { | |
| WrapMode wrapMode = WrapModeTile; | |
| updateStatus(DllExports::GdipGetLineWrapMode( | |
| (GpLineGradient*) nativeBrush, &wrapMode)); | |
| return wrapMode; | |
| } | |
| Status MultiplyTransform(const Matrix *matrix, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipMultiplyLineTransform( | |
| (GpLineGradient*) nativeBrush, | |
| matrix ? matrix->nativeMatrix : NULL, order)); | |
| } | |
| Status ResetTransform() | |
| { | |
| return updateStatus(DllExports::GdipResetLineTransform( | |
| (GpLineGradient*) nativeBrush)); | |
| } | |
| Status RotateTranform(REAL angle, MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipRotateLineTransform( | |
| (GpLineGradient*) nativeBrush, angle, order)); | |
| } | |
| Status ScaleTransform(REAL sx, REAL sy, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipScaleLineTransform( | |
| (GpLineGradient*) nativeBrush, sx, sy, order)); | |
| } | |
| Status SetBlend(const REAL *blendFactors, | |
| const REAL *blendPositions, INT count) | |
| { | |
| return updateStatus(DllExports::GdipSetLineBlend( | |
| (GpLineGradient*) nativeBrush, | |
| blendFactors, blendPositions, count)); | |
| } | |
| Status SetBlendBellShape(REAL focus, REAL scale = 1.0f) | |
| { | |
| return updateStatus(DllExports::GdipSetLineSigmaBlend( | |
| (GpLineGradient*) nativeBrush, | |
| focus, scale)); | |
| } | |
| Status SetBlendTriangularShape(REAL focus, REAL scale = 1.0f) | |
| { | |
| return updateStatus(DllExports::GdipSetLineLinearBlend( | |
| (GpLineGradient*) nativeBrush, | |
| focus, scale)); | |
| } | |
| Status SetGammaCorrection(BOOL useGammaCorrection) | |
| { | |
| return updateStatus(DllExports::GdipSetLineGammaCorrection( | |
| (GpLineGradient*) nativeBrush, | |
| useGammaCorrection)); | |
| } | |
| Status SetInterpolationColors(const Color *presetColors, | |
| const REAL *blendPositions, INT count) | |
| { | |
| if (!presetColors || count < 0) | |
| return lastStatus = InvalidParameter; | |
| ARGB *presetArgb = | |
| (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB)); | |
| if (!presetArgb) | |
| return lastStatus = OutOfMemory; | |
| for (INT i = 0; i < count; ++i) { | |
| presetArgb[i] = presetColors[i].GetValue(); | |
| } | |
| Status status = updateStatus(DllExports::GdipSetLinePresetBlend( | |
| (GpLineGradient*) nativeBrush, | |
| presetArgb, blendPositions, count)); | |
| DllExports::GdipFree((void*) presetArgb); | |
| return status; | |
| } | |
| Status SetLinearColors(const Color& color1, const Color& color2) | |
| { | |
| return updateStatus(DllExports::GdipSetLineColors( | |
| (GpLineGradient*) nativeBrush, | |
| color1.GetValue(), color2.GetValue())); | |
| } | |
| Status SetTransform(const Matrix *matrix) | |
| { | |
| return updateStatus(DllExports::GdipSetLineTransform( | |
| (GpLineGradient*) nativeBrush, | |
| matrix ? matrix->nativeMatrix : NULL)); | |
| } | |
| Status SetWrapMode(WrapMode wrapMode) | |
| { | |
| return updateStatus(DllExports::GdipSetLineWrapMode( | |
| (GpLineGradient*) nativeBrush, wrapMode)); | |
| } | |
| Status TranslateTransform(REAL dx, REAL dy, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipTranslateLineTransform( | |
| (GpLineGradient*) nativeBrush, dx, dy, order)); | |
| } | |
| private: | |
| LinearGradientBrush(GpBrush *brush, Status status): Brush(brush, status) {} | |
| LinearGradientBrush(const LinearGradientBrush& brush); | |
| LinearGradientBrush& operator=(const LinearGradientBrush&); | |
| }; | |
| class SolidBrush: public Brush | |
| { | |
| public: | |
| SolidBrush(const Color& color) | |
| { | |
| GpSolidFill *nativeSolidFill = NULL; | |
| lastStatus = DllExports::GdipCreateSolidFill( | |
| color.GetValue(), &nativeSolidFill); | |
| nativeBrush = nativeSolidFill; | |
| } | |
| virtual SolidBrush* Clone() const | |
| { | |
| GpBrush *cloneBrush = NULL; | |
| Status status = updateStatus(DllExports::GdipCloneBrush( | |
| nativeBrush, &cloneBrush)); | |
| if (status == Ok) { | |
| SolidBrush *result = | |
| new SolidBrush(cloneBrush, lastStatus); | |
| if (!result) { | |
| DllExports::GdipDeleteBrush(cloneBrush); | |
| updateStatus(OutOfMemory); | |
| } | |
| return result; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| Status GetColor(Color *color) const | |
| { | |
| return updateStatus(DllExports::GdipGetSolidFillColor( | |
| (GpSolidFill*) nativeBrush, | |
| color ? &color->Value : NULL)); | |
| } | |
| Status SetColor(const Color& color) | |
| { | |
| return updateStatus(DllExports::GdipSetSolidFillColor( | |
| (GpSolidFill*) nativeBrush, color.GetValue())); | |
| } | |
| private: | |
| SolidBrush(GpBrush *brush, Status status): Brush(brush, status) {} | |
| SolidBrush(const SolidBrush&); | |
| SolidBrush& operator=(const SolidBrush&); | |
| }; | |
| class TextureBrush: public Brush | |
| { | |
| public: | |
| TextureBrush(Image *image, WrapMode wrapMode = WrapModeTile) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTexture( | |
| image ? image->nativeImage : NULL, | |
| wrapMode, &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| TextureBrush(Image *image, WrapMode wrapMode, | |
| REAL dstX, REAL dstY, REAL dstWidth, REAL dstHeight) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTexture2( | |
| image ? image->nativeImage : NULL, | |
| wrapMode, dstX, dstY, dstWidth, dstHeight, | |
| &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| TextureBrush(Image *image, WrapMode wrapMode, | |
| INT dstX, INT dstY, INT dstWidth, INT dstHeight) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTexture2I( | |
| image ? image->nativeImage : NULL, | |
| wrapMode, dstX, dstY, dstWidth, dstHeight, | |
| &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| TextureBrush(Image *image, WrapMode wrapMode, const RectF& dstRect) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTexture2( | |
| image ? image->nativeImage : NULL, wrapMode, | |
| dstRect.X, dstRect.Y, | |
| dstRect.Width, dstRect.Height, &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| TextureBrush(Image *image, WrapMode wrapMode, const Rect& dstRect) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTexture2I( | |
| image ? image->nativeImage : NULL, wrapMode, | |
| dstRect.X, dstRect.Y, | |
| dstRect.Width, dstRect.Height, &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| TextureBrush(Image *image, const RectF& dstRect, | |
| ImageAttributes *imageAttributes = NULL) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTextureIA( | |
| image ? image->nativeImage : NULL, | |
| imageAttributes ? imageAttributes->nativeImageAttributes : NULL, | |
| dstRect.X, dstRect.Y, | |
| dstRect.Width, dstRect.Height, &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| TextureBrush(Image *image, const Rect& dstRect, | |
| ImageAttributes *imageAttributes = NULL) | |
| { | |
| GpTexture *nativeTexture = NULL; | |
| lastStatus = DllExports::GdipCreateTextureIAI( | |
| image ? image->nativeImage : NULL, | |
| imageAttributes ? imageAttributes->nativeImageAttributes : NULL, | |
| dstRect.X, dstRect.Y, | |
| dstRect.Width, dstRect.Height, &nativeTexture); | |
| nativeBrush = nativeTexture; | |
| } | |
| virtual TextureBrush* Clone() const | |
| { | |
| GpBrush *cloneBrush = NULL; | |
| Status status = updateStatus(DllExports::GdipCloneBrush( | |
| nativeBrush, &cloneBrush)); | |
| if (status == Ok) { | |
| TextureBrush *result = | |
| new TextureBrush(cloneBrush, lastStatus); | |
| if (!result) { | |
| DllExports::GdipDeleteBrush(cloneBrush); | |
| updateStatus(OutOfMemory); | |
| } | |
| return result; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| //TODO: implement TextureBrush::GetImage() | |
| //Image *GetImage() const | |
| //{ | |
| // // where is the Image allocated (static,member,new,other)? | |
| // // GdipGetTextureImage just returns a GpImage* | |
| // updateStatus(NotImplemented); | |
| // return NULL; | |
| //} | |
| Status GetTransfrom(Matrix *matrix) const | |
| { | |
| return updateStatus(DllExports::GdipGetTextureTransform( | |
| (GpTexture*) nativeBrush, | |
| matrix ? matrix->nativeMatrix : NULL)); | |
| } | |
| WrapMode GetWrapMode() const | |
| { | |
| WrapMode result = WrapModeTile; | |
| updateStatus(DllExports::GdipGetTextureWrapMode( | |
| (GpTexture*) nativeBrush, &result)); | |
| return result; | |
| } | |
| Status MultiplyTransform(const Matrix *matrix, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipMultiplyTextureTransform( | |
| (GpTexture*) nativeBrush, | |
| matrix ? matrix->nativeMatrix : NULL, order)); | |
| } | |
| Status ResetTransform() | |
| { | |
| return updateStatus(DllExports::GdipResetTextureTransform( | |
| (GpTexture*) nativeBrush)); | |
| } | |
| Status RotateTransform(REAL angle, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipRotateTextureTransform( | |
| (GpTexture*) nativeBrush, angle, order)); | |
| } | |
| Status ScaleTransform(REAL sx, REAL sy, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipScaleTextureTransform( | |
| (GpTexture*) nativeBrush, sx, sy, order)); | |
| } | |
| Status SetTransform(const Matrix *matrix) | |
| { | |
| return updateStatus(DllExports::GdipSetTextureTransform( | |
| (GpTexture*) nativeBrush, | |
| matrix ? matrix->nativeMatrix : NULL)); | |
| } | |
| Status SetWrapMode(WrapMode wrapMode) | |
| { | |
| return updateStatus(DllExports::GdipSetTextureWrapMode( | |
| (GpTexture*) nativeBrush, wrapMode)); | |
| } | |
| Status TranslateTransform(REAL dx, REAL dy, | |
| MatrixOrder order = MatrixOrderPrepend) | |
| { | |
| return updateStatus(DllExports::GdipTranslateTextureTransform( | |
| (GpTexture*) nativeBrush, dx, dy, order)); | |
| } | |
| private: | |
| TextureBrush(GpBrush *brush, Status status): Brush(brush, status) {} | |
| TextureBrush(const TextureBrush&); | |
| TextureBrush& operator=(const TextureBrush&); | |
| }; | |
| #endif /* __GDIPLUS_BRUSH_H */ |