/** * @file gdiplusbrush.h * Copyright 2012, 2013 MinGW.org project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* Created by Markus Koenig */ #ifndef __GDIPLUS_BRUSH_H #define __GDIPLUS_BRUSH_H #pragma GCC system_header #include <_mingw.h> /* * GDI+ brush classes */ #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 */