| /* |
| * 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 */ |