1 /* 2 * gdiplusbrush.h 3 * 4 * GDI+ brush classes 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_BRUSH_H 24 #define __GDIPLUS_BRUSH_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 gdiplusbrush.h." 31 #endif 32 33 class Brush: public GdiplusBase 34 { 35 friend class HatchBrush; 36 friend class LinearGradientBrush; 37 friend class PathGradientBrush; 38 friend class SolidBrush; 39 friend class TextureBrush; 40 friend class Graphics; 41 friend class Pen; 42 43 public: 44 virtual ~Brush() 45 { 46 DllExports::GdipDeleteBrush(nativeBrush); 47 } 48 virtual Brush* Clone() const // each subclass must implement this 49 { 50 lastStatus = NotImplemented; 51 return NULL; 52 } 53 54 Status GetLastStatus() const 55 { 56 Status result = lastStatus; 57 lastStatus = Ok; 58 return result; 59 } 60 BrushType GetType() const 61 { 62 BrushType result = BrushTypeSolidColor; 63 updateStatus(DllExports::GdipGetBrushType(nativeBrush, &result)); 64 return result; 65 } 66 67 private: 68 Brush(): nativeBrush(NULL), lastStatus(Ok) {} 69 Brush(GpBrush *brush, Status status): 70 nativeBrush(brush), lastStatus(status) {} 71 Brush(const Brush& brush); 72 Brush& operator=(const Brush&); 73 74 Status updateStatus(Status newStatus) const 75 { 76 if (newStatus != Ok) lastStatus = newStatus; 77 return newStatus; 78 } 79 80 GpBrush *nativeBrush; 81 mutable Status lastStatus; 82 }; 83 84 class HatchBrush: public Brush 85 { 86 public: 87 HatchBrush(HatchStyle hatchStyle, 88 const Color& foreColor, 89 const Color& backColor = Color()) 90 { 91 GpHatch *nativeHatch = NULL; 92 lastStatus = DllExports::GdipCreateHatchBrush(hatchStyle, 93 foreColor.GetValue(), backColor.GetValue(), 94 &nativeHatch); 95 nativeBrush = nativeHatch; 96 } 97 virtual HatchBrush* Clone() const 98 { 99 GpBrush *cloneBrush = NULL; 100 Status status = updateStatus(DllExports::GdipCloneBrush( 101 nativeBrush, &cloneBrush)); 102 if (status == Ok) { 103 HatchBrush *result = 104 new HatchBrush(cloneBrush, lastStatus); 105 if (!result) { 106 DllExports::GdipDeleteBrush(cloneBrush); 107 updateStatus(OutOfMemory); 108 } 109 return result; 110 } else { 111 return NULL; 112 } 113 } 114 115 Status GetBackgroundColor(Color *color) const 116 { 117 return updateStatus(DllExports::GdipGetHatchBackgroundColor( 118 (GpHatch*) nativeBrush, 119 color ? &color->Value : NULL)); 120 } 121 Status GetForegroundColor(Color *color) const 122 { 123 return updateStatus(DllExports::GdipGetHatchForegroundColor( 124 (GpHatch*) nativeBrush, 125 color ? &color->Value : NULL)); 126 } 127 HatchStyle GetHatchStyle() const 128 { 129 HatchStyle result; 130 updateStatus(DllExports::GdipGetHatchStyle( 131 (GpHatch*) nativeBrush, &result)); 132 return result; 133 } 134 135 private: 136 HatchBrush(GpBrush *brush, Status status): Brush(brush, status) {} 137 HatchBrush(const HatchBrush& brush); 138 HatchBrush& operator=(const HatchBrush&); 139 }; 140 141 class LinearGradientBrush: public Brush 142 { 143 public: 144 LinearGradientBrush(const PointF& point1, const PointF& point2, 145 const Color& color1, const Color& color2) 146 { 147 GpLineGradient *nativeLineGradient = NULL; 148 lastStatus = DllExports::GdipCreateLineBrush( 149 &point1, &point2, 150 color1.GetValue(), color2.GetValue(), 151 WrapModeTile, &nativeLineGradient); 152 nativeBrush = nativeLineGradient; 153 } 154 LinearGradientBrush(const Point& point1, const Point& point2, 155 const Color& color1, const Color& color2) 156 { 157 GpLineGradient *nativeLineGradient = NULL; 158 lastStatus = DllExports::GdipCreateLineBrushI( 159 &point1, &point2, 160 color1.GetValue(), color2.GetValue(), 161 WrapModeTile, &nativeLineGradient); 162 nativeBrush = nativeLineGradient; 163 } 164 LinearGradientBrush(const RectF& rect, const Color& color1, 165 const Color& color2, LinearGradientMode mode) 166 { 167 GpLineGradient *nativeLineGradient = NULL; 168 lastStatus = DllExports::GdipCreateLineBrushFromRect( 169 &rect, color1.GetValue(), color2.GetValue(), 170 mode, WrapModeTile, &nativeLineGradient); 171 nativeBrush = nativeLineGradient; 172 } 173 LinearGradientBrush(const Rect& rect, const Color& color1, 174 const Color& color2, LinearGradientMode mode) 175 { 176 GpLineGradient *nativeLineGradient = NULL; 177 lastStatus = DllExports::GdipCreateLineBrushFromRectI( 178 &rect, color1.GetValue(), color2.GetValue(), 179 mode, WrapModeTile, &nativeLineGradient); 180 nativeBrush = nativeLineGradient; 181 } 182 LinearGradientBrush(const RectF& rect, const Color& color1, 183 const Color& color2, REAL angle, 184 BOOL isAngleScalable = FALSE) 185 { 186 GpLineGradient *nativeLineGradient = NULL; 187 lastStatus = DllExports::GdipCreateLineBrushFromRectWithAngle( 188 &rect, color1.GetValue(), color2.GetValue(), 189 angle, isAngleScalable, WrapModeTile, 190 &nativeLineGradient); 191 nativeBrush = nativeLineGradient; 192 } 193 LinearGradientBrush(const Rect& rect, const Color& color1, 194 const Color& color2, REAL angle, 195 BOOL isAngleScalable = FALSE) 196 { 197 GpLineGradient *nativeLineGradient = NULL; 198 lastStatus = DllExports::GdipCreateLineBrushFromRectWithAngleI( 199 &rect, color1.GetValue(), color2.GetValue(), 200 angle, isAngleScalable, WrapModeTile, 201 &nativeLineGradient); 202 nativeBrush = nativeLineGradient; 203 } 204 virtual LinearGradientBrush* Clone() const 205 { 206 GpBrush *cloneBrush = NULL; 207 Status status = updateStatus(DllExports::GdipCloneBrush( 208 nativeBrush, &cloneBrush)); 209 if (status == Ok) { 210 LinearGradientBrush *result = 211 new LinearGradientBrush(cloneBrush, lastStatus); 212 if (!result) { 213 DllExports::GdipDeleteBrush(cloneBrush); 214 updateStatus(OutOfMemory); 215 } 216 return result; 217 } else { 218 return NULL; 219 } 220 } 221 222 Status GetBlend(REAL *blendFactors, REAL *blendPositions, 223 INT count) const 224 { 225 return updateStatus(DllExports::GdipGetLineBlend( 226 (GpLineGradient*) nativeBrush, 227 blendFactors, blendPositions, count)); 228 } 229 INT GetBlendCount() const 230 { 231 INT result = 0; 232 updateStatus(DllExports::GdipGetLineBlendCount( 233 (GpLineGradient*) nativeBrush, &result)); 234 return result; 235 } 236 BOOL GetGammaCorrection() const 237 { 238 BOOL result = FALSE; 239 updateStatus(DllExports::GdipGetLineGammaCorrection( 240 (GpLineGradient*) nativeBrush, &result)); 241 return result; 242 } 243 INT GetInterpolationColorCount() const 244 { 245 INT result = 0; 246 updateStatus(DllExports::GdipGetLinePresetBlendCount( 247 (GpLineGradient*) nativeBrush, &result)); 248 return result; 249 } 250 Status GetInterpolationColors(Color *presetColors, 251 REAL *blendPositions, INT count) const 252 { 253 if (!presetColors || count <= 0) 254 return lastStatus = InvalidParameter; 255 256 ARGB *presetArgb = 257 (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB)); 258 if (!presetArgb) 259 return lastStatus = OutOfMemory; 260 261 Status status = updateStatus(DllExports::GdipGetLinePresetBlend( 262 (GpLineGradient*) nativeBrush, presetArgb, 263 blendPositions, count)); 264 for (INT i = 0; i < count; ++i) { 265 presetColors[i].SetValue(presetArgb[i]); 266 } 267 DllExports::GdipFree((void*) presetArgb); 268 return status; 269 } 270 Status GetLinearColors(Color *colors) const 271 { 272 if (!colors) return lastStatus = InvalidParameter; 273 274 ARGB colorsArgb[2]; 275 Status status = updateStatus(DllExports::GdipGetLineColors( 276 (GpLineGradient*) nativeBrush, colorsArgb)); 277 colors[0].SetValue(colorsArgb[0]); 278 colors[1].SetValue(colorsArgb[1]); 279 return status; 280 } 281 Status GetRectangle(RectF *rect) const 282 { 283 return updateStatus(DllExports::GdipGetLineRect( 284 (GpLineGradient*) nativeBrush, rect)); 285 } 286 Status GetRectangle(Rect *rect) const 287 { 288 return updateStatus(DllExports::GdipGetLineRectI( 289 (GpLineGradient*) nativeBrush, rect)); 290 } 291 Status GetTransform(Matrix *matrix) const 292 { 293 return updateStatus(DllExports::GdipGetLineTransform( 294 (GpLineGradient*) nativeBrush, 295 matrix ? matrix->nativeMatrix : NULL)); 296 } 297 WrapMode GetWrapMode() const 298 { 299 WrapMode wrapMode = WrapModeTile; 300 updateStatus(DllExports::GdipGetLineWrapMode( 301 (GpLineGradient*) nativeBrush, &wrapMode)); 302 return wrapMode; 303 } 304 Status MultiplyTransform(const Matrix *matrix, 305 MatrixOrder order = MatrixOrderPrepend) 306 { 307 return updateStatus(DllExports::GdipMultiplyLineTransform( 308 (GpLineGradient*) nativeBrush, 309 matrix ? matrix->nativeMatrix : NULL, order)); 310 } 311 Status ResetTransform() 312 { 313 return updateStatus(DllExports::GdipResetLineTransform( 314 (GpLineGradient*) nativeBrush)); 315 } 316 Status RotateTranform(REAL angle, MatrixOrder order = MatrixOrderPrepend) 317 { 318 return updateStatus(DllExports::GdipRotateLineTransform( 319 (GpLineGradient*) nativeBrush, angle, order)); 320 } 321 Status ScaleTransform(REAL sx, REAL sy, 322 MatrixOrder order = MatrixOrderPrepend) 323 { 324 return updateStatus(DllExports::GdipScaleLineTransform( 325 (GpLineGradient*) nativeBrush, sx, sy, order)); 326 } 327 Status SetBlend(const REAL *blendFactors, 328 const REAL *blendPositions, INT count) 329 { 330 return updateStatus(DllExports::GdipSetLineBlend( 331 (GpLineGradient*) nativeBrush, 332 blendFactors, blendPositions, count)); 333 } 334 Status SetBlendBellShape(REAL focus, REAL scale = 1.0f) 335 { 336 return updateStatus(DllExports::GdipSetLineSigmaBlend( 337 (GpLineGradient*) nativeBrush, 338 focus, scale)); 339 } 340 Status SetBlendTriangularShape(REAL focus, REAL scale = 1.0f) 341 { 342 return updateStatus(DllExports::GdipSetLineLinearBlend( 343 (GpLineGradient*) nativeBrush, 344 focus, scale)); 345 } 346 Status SetGammaCorrection(BOOL useGammaCorrection) 347 { 348 return updateStatus(DllExports::GdipSetLineGammaCorrection( 349 (GpLineGradient*) nativeBrush, 350 useGammaCorrection)); 351 } 352 Status SetInterpolationColors(const Color *presetColors, 353 const REAL *blendPositions, INT count) 354 { 355 if (!presetColors || count < 0) 356 return lastStatus = InvalidParameter; 357 358 ARGB *presetArgb = 359 (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB)); 360 if (!presetArgb) 361 return lastStatus = OutOfMemory; 362 for (INT i = 0; i < count; ++i) { 363 presetArgb[i] = presetColors[i].GetValue(); 364 } 365 366 Status status = updateStatus(DllExports::GdipSetLinePresetBlend( 367 (GpLineGradient*) nativeBrush, 368 presetArgb, blendPositions, count)); 369 DllExports::GdipFree((void*) presetArgb); 370 return status; 371 } 372 Status SetLinearColors(const Color& color1, const Color& color2) 373 { 374 return updateStatus(DllExports::GdipSetLineColors( 375 (GpLineGradient*) nativeBrush, 376 color1.GetValue(), color2.GetValue())); 377 } 378 Status SetTransform(const Matrix *matrix) 379 { 380 return updateStatus(DllExports::GdipSetLineTransform( 381 (GpLineGradient*) nativeBrush, 382 matrix ? matrix->nativeMatrix : NULL)); 383 } 384 Status SetWrapMode(WrapMode wrapMode) 385 { 386 return updateStatus(DllExports::GdipSetLineWrapMode( 387 (GpLineGradient*) nativeBrush, wrapMode)); 388 } 389 Status TranslateTransform(REAL dx, REAL dy, 390 MatrixOrder order = MatrixOrderPrepend) 391 { 392 return updateStatus(DllExports::GdipTranslateLineTransform( 393 (GpLineGradient*) nativeBrush, dx, dy, order)); 394 } 395 396 private: 397 LinearGradientBrush(GpBrush *brush, Status status): Brush(brush, status) {} 398 LinearGradientBrush(const LinearGradientBrush& brush); 399 LinearGradientBrush& operator=(const LinearGradientBrush&); 400 }; 401 402 class SolidBrush: public Brush 403 { 404 public: 405 SolidBrush(const Color& color) 406 { 407 GpSolidFill *nativeSolidFill = NULL; 408 lastStatus = DllExports::GdipCreateSolidFill( 409 color.GetValue(), &nativeSolidFill); 410 nativeBrush = nativeSolidFill; 411 } 412 virtual SolidBrush* Clone() const 413 { 414 GpBrush *cloneBrush = NULL; 415 Status status = updateStatus(DllExports::GdipCloneBrush( 416 nativeBrush, &cloneBrush)); 417 if (status == Ok) { 418 SolidBrush *result = 419 new SolidBrush(cloneBrush, lastStatus); 420 if (!result) { 421 DllExports::GdipDeleteBrush(cloneBrush); 422 updateStatus(OutOfMemory); 423 } 424 return result; 425 } else { 426 return NULL; 427 } 428 } 429 430 Status GetColor(Color *color) const 431 { 432 return updateStatus(DllExports::GdipGetSolidFillColor( 433 (GpSolidFill*) nativeBrush, 434 color ? &color->Value : NULL)); 435 } 436 Status SetColor(const Color& color) 437 { 438 return updateStatus(DllExports::GdipSetSolidFillColor( 439 (GpSolidFill*) nativeBrush, color.GetValue())); 440 } 441 442 private: 443 SolidBrush(GpBrush *brush, Status status): Brush(brush, status) {} 444 SolidBrush(const SolidBrush&); 445 SolidBrush& operator=(const SolidBrush&); 446 }; 447 448 class TextureBrush: public Brush 449 { 450 public: 451 TextureBrush(Image *image, WrapMode wrapMode = WrapModeTile) 452 { 453 GpTexture *nativeTexture = NULL; 454 lastStatus = DllExports::GdipCreateTexture( 455 image ? image->nativeImage : NULL, 456 wrapMode, &nativeTexture); 457 nativeBrush = nativeTexture; 458 } 459 TextureBrush(Image *image, WrapMode wrapMode, 460 REAL dstX, REAL dstY, REAL dstWidth, REAL dstHeight) 461 { 462 GpTexture *nativeTexture = NULL; 463 lastStatus = DllExports::GdipCreateTexture2( 464 image ? image->nativeImage : NULL, 465 wrapMode, dstX, dstY, dstWidth, dstHeight, 466 &nativeTexture); 467 nativeBrush = nativeTexture; 468 } 469 TextureBrush(Image *image, WrapMode wrapMode, 470 INT dstX, INT dstY, INT dstWidth, INT dstHeight) 471 { 472 GpTexture *nativeTexture = NULL; 473 lastStatus = DllExports::GdipCreateTexture2I( 474 image ? image->nativeImage : NULL, 475 wrapMode, dstX, dstY, dstWidth, dstHeight, 476 &nativeTexture); 477 nativeBrush = nativeTexture; 478 } 479 TextureBrush(Image *image, WrapMode wrapMode, const RectF& dstRect) 480 { 481 GpTexture *nativeTexture = NULL; 482 lastStatus = DllExports::GdipCreateTexture2( 483 image ? image->nativeImage : NULL, wrapMode, 484 dstRect.X, dstRect.Y, 485 dstRect.Width, dstRect.Height, &nativeTexture); 486 nativeBrush = nativeTexture; 487 } 488 TextureBrush(Image *image, WrapMode wrapMode, const Rect& dstRect) 489 { 490 GpTexture *nativeTexture = NULL; 491 lastStatus = DllExports::GdipCreateTexture2I( 492 image ? image->nativeImage : NULL, wrapMode, 493 dstRect.X, dstRect.Y, 494 dstRect.Width, dstRect.Height, &nativeTexture); 495 nativeBrush = nativeTexture; 496 } 497 TextureBrush(Image *image, const RectF& dstRect, 498 ImageAttributes *imageAttributes = NULL) 499 { 500 GpTexture *nativeTexture = NULL; 501 lastStatus = DllExports::GdipCreateTextureIA( 502 image ? image->nativeImage : NULL, 503 imageAttributes ? imageAttributes->nativeImageAttributes : NULL, 504 dstRect.X, dstRect.Y, 505 dstRect.Width, dstRect.Height, &nativeTexture); 506 nativeBrush = nativeTexture; 507 } 508 TextureBrush(Image *image, const Rect& dstRect, 509 ImageAttributes *imageAttributes = NULL) 510 { 511 GpTexture *nativeTexture = NULL; 512 lastStatus = DllExports::GdipCreateTextureIAI( 513 image ? image->nativeImage : NULL, 514 imageAttributes ? imageAttributes->nativeImageAttributes : NULL, 515 dstRect.X, dstRect.Y, 516 dstRect.Width, dstRect.Height, &nativeTexture); 517 nativeBrush = nativeTexture; 518 } 519 virtual TextureBrush* Clone() const 520 { 521 GpBrush *cloneBrush = NULL; 522 Status status = updateStatus(DllExports::GdipCloneBrush( 523 nativeBrush, &cloneBrush)); 524 if (status == Ok) { 525 TextureBrush *result = 526 new TextureBrush(cloneBrush, lastStatus); 527 if (!result) { 528 DllExports::GdipDeleteBrush(cloneBrush); 529 updateStatus(OutOfMemory); 530 } 531 return result; 532 } else { 533 return NULL; 534 } 535 } 536 537 //TODO: implement TextureBrush::GetImage() 538 //Image *GetImage() const 539 //{ 540 // // where is the Image allocated (static,member,new,other)? 541 // // GdipGetTextureImage just returns a GpImage* 542 // updateStatus(NotImplemented); 543 // return NULL; 544 //} 545 Status GetTransfrom(Matrix *matrix) const 546 { 547 return updateStatus(DllExports::GdipGetTextureTransform( 548 (GpTexture*) nativeBrush, 549 matrix ? matrix->nativeMatrix : NULL)); 550 } 551 WrapMode GetWrapMode() const 552 { 553 WrapMode result = WrapModeTile; 554 updateStatus(DllExports::GdipGetTextureWrapMode( 555 (GpTexture*) nativeBrush, &result)); 556 return result; 557 } 558 Status MultiplyTransform(const Matrix *matrix, 559 MatrixOrder order = MatrixOrderPrepend) 560 { 561 return updateStatus(DllExports::GdipMultiplyTextureTransform( 562 (GpTexture*) nativeBrush, 563 matrix ? matrix->nativeMatrix : NULL, order)); 564 } 565 Status ResetTransform() 566 { 567 return updateStatus(DllExports::GdipResetTextureTransform( 568 (GpTexture*) nativeBrush)); 569 } 570 Status RotateTransform(REAL angle, 571 MatrixOrder order = MatrixOrderPrepend) 572 { 573 return updateStatus(DllExports::GdipRotateTextureTransform( 574 (GpTexture*) nativeBrush, angle, order)); 575 } 576 Status ScaleTransform(REAL sx, REAL sy, 577 MatrixOrder order = MatrixOrderPrepend) 578 { 579 return updateStatus(DllExports::GdipScaleTextureTransform( 580 (GpTexture*) nativeBrush, sx, sy, order)); 581 } 582 Status SetTransform(const Matrix *matrix) 583 { 584 return updateStatus(DllExports::GdipSetTextureTransform( 585 (GpTexture*) nativeBrush, 586 matrix ? matrix->nativeMatrix : NULL)); 587 } 588 Status SetWrapMode(WrapMode wrapMode) 589 { 590 return updateStatus(DllExports::GdipSetTextureWrapMode( 591 (GpTexture*) nativeBrush, wrapMode)); 592 } 593 Status TranslateTransform(REAL dx, REAL dy, 594 MatrixOrder order = MatrixOrderPrepend) 595 { 596 return updateStatus(DllExports::GdipTranslateTextureTransform( 597 (GpTexture*) nativeBrush, dx, dy, order)); 598 } 599 600 private: 601 TextureBrush(GpBrush *brush, Status status): Brush(brush, status) {} 602 TextureBrush(const TextureBrush&); 603 TextureBrush& operator=(const TextureBrush&); 604 }; 605 606 #endif /* __GDIPLUS_BRUSH_H */ 607