1 /* 2 * gdipluspath.h 3 * 4 * GDI+ GraphicsPath 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_PATH_H 24 #define __GDIPLUS_PATH_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 gdipluspath.h." 31 #endif 32 33 // Note that some methods of GraphicsPath are implemented in gdiplusimpl.h. 34 // This avoids a cyclic dependency on Graphics and Pen. 35 36 class GraphicsPath: public GdiplusBase 37 { 38 friend class CustomLineCap; 39 friend class Graphics; 40 friend class GraphicsPathIterator; 41 friend class PathGradientBrush; 42 friend class Region; 43 44 public: 45 GraphicsPath(FillMode fillMode = FillModeAlternate): 46 nativePath(NULL), lastStatus(Ok) 47 { 48 lastStatus = DllExports::GdipCreatePath(fillMode, &nativePath); 49 } 50 GraphicsPath(const PointF *points, const BYTE *types, INT count, 51 FillMode fillMode = FillModeAlternate): 52 nativePath(NULL), lastStatus(Ok) 53 { 54 lastStatus = DllExports::GdipCreatePath2( 55 points, types, count, fillMode, &nativePath); 56 } 57 GraphicsPath(const Point *points, const BYTE *types, INT count, 58 FillMode fillMode = FillModeAlternate): 59 nativePath(NULL), lastStatus(Ok) 60 { 61 lastStatus = DllExports::GdipCreatePath2I( 62 points, types, count, fillMode, &nativePath); 63 } 64 ~GraphicsPath() 65 { 66 DllExports::GdipDeletePath(nativePath); 67 } 68 GraphicsPath* Clone() const 69 { 70 GpPath *clonePath = NULL; 71 Status status = updateStatus(DllExports::GdipClonePath( 72 nativePath, &clonePath)); 73 if (status == Ok) { 74 GraphicsPath *result = new GraphicsPath(clonePath, lastStatus); 75 if (!result) { 76 DllExports::GdipDeletePath(clonePath); 77 lastStatus = OutOfMemory; 78 } 79 return result; 80 } else { 81 return NULL; 82 } 83 } 84 85 Status AddArc(REAL x, REAL y, REAL width, REAL height, 86 REAL startAngle, REAL sweepAngle) 87 { 88 return updateStatus(DllExports::GdipAddPathArc(nativePath, 89 x, y, width, height, startAngle, sweepAngle)); 90 } 91 Status AddArc(INT x, INT y, INT width, INT height, 92 REAL startAngle, REAL sweepAngle) 93 { 94 return updateStatus(DllExports::GdipAddPathArcI(nativePath, 95 x, y, width, height, startAngle, sweepAngle)); 96 } 97 Status AddArc(const RectF& rect, REAL startAngle, REAL sweepAngle) 98 { 99 return updateStatus(DllExports::GdipAddPathArc(nativePath, 100 rect.X, rect.Y, rect.Width, rect.Height, 101 startAngle, sweepAngle)); 102 } 103 Status AddArc(const Rect& rect, REAL startAngle, REAL sweepAngle) 104 { 105 return updateStatus(DllExports::GdipAddPathArcI(nativePath, 106 rect.X, rect.Y, rect.Width, rect.Height, 107 startAngle, sweepAngle)); 108 } 109 Status AddBezier(REAL x1, REAL y1, REAL x2, REAL y2, 110 REAL x3, REAL y3, REAL x4, REAL y4) 111 { 112 return updateStatus(DllExports::GdipAddPathBezier(nativePath, 113 x1, y1, x2, y2, x3, y3, x4, y4)); 114 } 115 Status AddBezier(INT x1, INT y1, INT x2, INT y2, 116 INT x3, INT y3, INT x4, INT y4) 117 { 118 return updateStatus(DllExports::GdipAddPathBezierI(nativePath, 119 x1, y1, x2, y2, x3, y3, x4, y4)); 120 } 121 Status AddBezier(const PointF& pt1, const PointF& pt2, 122 const PointF& pt3, const PointF& pt4) 123 { 124 return updateStatus(DllExports::GdipAddPathBezier(nativePath, 125 pt1.X, pt1.Y, pt2.X, pt2.Y, 126 pt3.X, pt3.Y, pt4.X, pt4.Y)); 127 } 128 Status AddBezier(const Point& pt1, const Point& pt2, 129 const Point& pt3, const Point& pt4) 130 { 131 return updateStatus(DllExports::GdipAddPathBezierI(nativePath, 132 pt1.X, pt1.Y, pt2.X, pt2.Y, 133 pt3.X, pt3.Y, pt4.X, pt4.Y)); 134 } 135 Status AddBeziers(const PointF *points, INT count) 136 { 137 return updateStatus(DllExports::GdipAddPathBeziers( 138 nativePath, points, count)); 139 } 140 Status AddBeziers(const Point *points, INT count) 141 { 142 return updateStatus(DllExports::GdipAddPathBeziersI( 143 nativePath, points, count)); 144 } 145 Status AddClosedCurve(const PointF *points, INT count) 146 { 147 return updateStatus(DllExports::GdipAddPathClosedCurve( 148 nativePath, points, count)); 149 } 150 Status AddClosedCurve(const Point *points, INT count) 151 { 152 return updateStatus(DllExports::GdipAddPathClosedCurveI( 153 nativePath, points, count)); 154 } 155 Status AddClosedCurve(const PointF *points, INT count, REAL tension) 156 { 157 return updateStatus(DllExports::GdipAddPathClosedCurve2( 158 nativePath, points, count, tension)); 159 } 160 Status AddClosedCurve(const Point *points, INT count, REAL tension) 161 { 162 return updateStatus(DllExports::GdipAddPathClosedCurve2I( 163 nativePath, points, count, tension)); 164 } 165 Status AddCurve(const PointF *points, INT count) 166 { 167 return updateStatus(DllExports::GdipAddPathCurve( 168 nativePath, points, count)); 169 } 170 Status AddCurve(const Point *points, INT count) 171 { 172 return updateStatus(DllExports::GdipAddPathCurveI( 173 nativePath, points, count)); 174 } 175 Status AddCurve(const PointF *points, INT count, REAL tension) 176 { 177 return updateStatus(DllExports::GdipAddPathCurve2( 178 nativePath, points, count, tension)); 179 } 180 Status AddCurve(const Point *points, INT count, REAL tension) 181 { 182 return updateStatus(DllExports::GdipAddPathCurve2I( 183 nativePath, points, count, tension)); 184 } 185 Status AddCurve(const PointF *points, INT count, INT offset, 186 INT numberOfSegments, REAL tension) 187 { 188 return updateStatus(DllExports::GdipAddPathCurve3( 189 nativePath, points, count, 190 offset, numberOfSegments, tension)); 191 } 192 Status AddCurve(const Point *points, INT count, INT offset, 193 INT numberOfSegments, REAL tension) 194 { 195 return updateStatus(DllExports::GdipAddPathCurve3I( 196 nativePath, points, count, 197 offset, numberOfSegments, tension)); 198 } 199 Status AddEllipse(REAL x, REAL y, REAL width, REAL height) 200 { 201 return updateStatus(DllExports::GdipAddPathEllipse(nativePath, 202 x, y, width, height)); 203 } 204 Status AddEllipse(INT x, INT y, INT width, INT height) 205 { 206 return updateStatus(DllExports::GdipAddPathEllipseI(nativePath, 207 x, y, width, height)); 208 } 209 Status AddEllipse(const RectF& rect) 210 { 211 return updateStatus(DllExports::GdipAddPathEllipse(nativePath, 212 rect.X, rect.Y, rect.Width, rect.Height)); 213 } 214 Status AddEllipse(const Rect& rect) 215 { 216 return updateStatus(DllExports::GdipAddPathEllipseI(nativePath, 217 rect.X, rect.Y, rect.Width, rect.Height)); 218 } 219 Status AddLine(REAL x1, REAL y1, REAL x2, REAL y2) 220 { 221 return updateStatus(DllExports::GdipAddPathLine(nativePath, 222 x1, y1, x2, y2)); 223 } 224 Status AddLine(INT x1, INT y1, INT x2, INT y2) 225 { 226 return updateStatus(DllExports::GdipAddPathLineI(nativePath, 227 x1, y1, x2, y2)); 228 } 229 Status AddLine(const PointF& pt1, const PointF& pt2) 230 { 231 return updateStatus(DllExports::GdipAddPathLine(nativePath, 232 pt1.X, pt1.Y, pt2.X, pt2.Y)); 233 } 234 Status AddLine(const Point& pt1, const Point& pt2) 235 { 236 return updateStatus(DllExports::GdipAddPathLineI(nativePath, 237 pt1.X, pt1.Y, pt2.X, pt2.Y)); 238 } 239 Status AddLines(const PointF *points, INT count) 240 { 241 return updateStatus(DllExports::GdipAddPathLine2(nativePath, 242 points, count)); 243 } 244 Status AddLines(const Point *points, INT count) 245 { 246 return updateStatus(DllExports::GdipAddPathLine2I(nativePath, 247 points, count)); 248 } 249 Status AddPath(const GraphicsPath *addingPath, BOOL connect) 250 { 251 return updateStatus(DllExports::GdipAddPathPath(nativePath, 252 addingPath ? addingPath->nativePath : NULL, 253 connect)); 254 } 255 Status AddPie(REAL x, REAL y, REAL width, REAL height, 256 REAL startAngle, REAL sweepAngle) 257 { 258 return updateStatus(DllExports::GdipAddPathPie(nativePath, 259 x, y, width, height, startAngle, sweepAngle)); 260 } 261 Status AddPie(INT x, INT y, INT width, INT height, 262 REAL startAngle, REAL sweepAngle) 263 { 264 return updateStatus(DllExports::GdipAddPathPieI(nativePath, 265 x, y, width, height, startAngle, sweepAngle)); 266 } 267 Status AddPie(const RectF& rect, REAL startAngle, REAL sweepAngle) 268 { 269 return updateStatus(DllExports::GdipAddPathPie(nativePath, 270 rect.X, rect.Y, rect.Width, rect.Height, 271 startAngle, sweepAngle)); 272 } 273 Status AddPie(const Rect& rect, REAL startAngle, REAL sweepAngle) 274 { 275 return updateStatus(DllExports::GdipAddPathPieI(nativePath, 276 rect.X, rect.Y, rect.Width, rect.Height, 277 startAngle, sweepAngle)); 278 } 279 Status AddPolygon(const PointF *points, INT count) 280 { 281 return updateStatus(DllExports::GdipAddPathPolygon(nativePath, 282 points, count)); 283 } 284 Status AddPolygon(const Point *points, INT count) 285 { 286 return updateStatus(DllExports::GdipAddPathPolygonI(nativePath, 287 points, count)); 288 } 289 Status AddRectangle(const RectF& rect) 290 { 291 return updateStatus(DllExports::GdipAddPathRectangle(nativePath, 292 rect.X, rect.Y, rect.Width, rect.Height)); 293 } 294 Status AddRectangle(const Rect& rect) 295 { 296 return updateStatus(DllExports::GdipAddPathRectangleI( 297 nativePath, 298 rect.X, rect.Y, rect.Width, rect.Height)); 299 } 300 Status AddRectangles(const RectF *rects, INT count) 301 { 302 return updateStatus(DllExports::GdipAddPathRectangles( 303 nativePath, rects, count)); 304 } 305 Status AddRectangles(const Rect *rects, INT count) 306 { 307 return updateStatus(DllExports::GdipAddPathRectanglesI( 308 nativePath, rects, count)); 309 } 310 Status AddString(const WCHAR *string, INT length, 311 const FontFamily *family, INT style, REAL emSize, 312 const PointF& origin, const StringFormat *format) 313 { 314 RectF layoutRect(origin, SizeF(0.0f, 0.0f)); 315 return updateStatus(DllExports::GdipAddPathString(nativePath, 316 string, length, 317 family ? family->nativeFontFamily : NULL, 318 style, emSize, &layoutRect, 319 format ? format->nativeStringFormat : NULL)); 320 } 321 Status AddString(const WCHAR *string, INT length, 322 const FontFamily *family, INT style, REAL emSize, 323 const Point& origin, const StringFormat *format) 324 { 325 Rect layoutRect(origin, Size(0, 0)); 326 return updateStatus(DllExports::GdipAddPathStringI(nativePath, 327 string, length, 328 family ? family->nativeFontFamily : NULL, 329 style, emSize, &layoutRect, 330 format ? format->nativeStringFormat : NULL)); 331 } 332 Status AddString(const WCHAR *string, INT length, 333 const FontFamily *family, INT style, REAL emSize, 334 const RectF& layoutRect, const StringFormat *format) 335 { 336 return updateStatus(DllExports::GdipAddPathString(nativePath, 337 string, length, 338 family ? family->nativeFontFamily : NULL, 339 style, emSize, &layoutRect, 340 format ? format->nativeStringFormat : NULL)); 341 } 342 Status AddString(const WCHAR *string, INT length, 343 const FontFamily *family, INT style, REAL emSize, 344 const Rect& layoutRect, const StringFormat *format) 345 { 346 return updateStatus(DllExports::GdipAddPathStringI(nativePath, 347 string, length, 348 family ? family->nativeFontFamily : NULL, 349 style, emSize, &layoutRect, 350 format ? format->nativeStringFormat : NULL)); 351 } 352 Status ClearMarkers() 353 { 354 return updateStatus(DllExports::GdipClearPathMarkers( 355 nativePath)); 356 } 357 Status CloseAllFigures() 358 { 359 return updateStatus(DllExports::GdipClosePathFigures( 360 nativePath)); 361 } 362 Status CloseFigure() 363 { 364 return updateStatus(DllExports::GdipClosePathFigure( 365 nativePath)); 366 } 367 Status Flatten(const Matrix *matrix = NULL, 368 REAL flatness = FlatnessDefault) 369 { 370 return updateStatus(DllExports::GdipFlattenPath(nativePath, 371 matrix ? matrix->nativeMatrix : NULL, 372 flatness)); 373 } 374 Status GetBounds(RectF *bounds, const Matrix *matrix = NULL, 375 const Pen *pen = NULL) const 376 { 377 return updateStatus(DllExports::GdipGetPathWorldBounds( 378 nativePath, bounds, 379 matrix ? matrix->nativeMatrix : NULL, 380 pen ? pen->nativePen : NULL)); 381 } 382 Status GetBounds(Rect *bounds, const Matrix *matrix = NULL, 383 const Pen *pen = NULL) const 384 { 385 return updateStatus(DllExports::GdipGetPathWorldBoundsI( 386 nativePath, bounds, 387 matrix ? matrix->nativeMatrix : NULL, 388 pen ? pen->nativePen : NULL)); 389 } 390 FillMode GetFillMode() const 391 { 392 FillMode result = FillModeAlternate; 393 updateStatus(DllExports::GdipGetPathFillMode(nativePath, 394 &result)); 395 return result; 396 } 397 Status GetLastPoint(PointF *lastPoint) const 398 { 399 return updateStatus(DllExports::GdipGetPathLastPoint( 400 nativePath, lastPoint)); 401 } 402 Status GetLastStatus() const 403 { 404 Status result = lastStatus; 405 lastStatus = Ok; 406 return result; 407 } 408 Status GetPathData(PathData *pathData) const 409 { 410 if (!pathData) return lastStatus = InvalidParameter; 411 412 Status status; 413 INT count; 414 415 status = updateStatus(DllExports::GdipGetPointCount( 416 nativePath, &count)); 417 if (status != Ok) return status; 418 419 status = updateStatus(pathData->AllocateArrays(count)); 420 if (status != Ok) return status; 421 422 return updateStatus(DllExports::GdipGetPathData( 423 nativePath, (GpPathData*) pathData)); 424 } 425 Status GetPathPoints(PointF *points, INT count) const 426 { 427 return updateStatus(DllExports::GdipGetPathPoints(nativePath, 428 points, count)); 429 } 430 Status GetPathPoints(Point *points, INT count) const 431 { 432 return updateStatus(DllExports::GdipGetPathPointsI(nativePath, 433 points, count)); 434 } 435 Status GetPathTypes(BYTE *types, INT count) const 436 { 437 return updateStatus(DllExports::GdipGetPathTypes(nativePath, 438 types, count)); 439 } 440 INT GetPointCount() const 441 { 442 INT result = 0; 443 updateStatus(DllExports::GdipGetPointCount(nativePath, 444 &result)); 445 return result; 446 } 447 BOOL IsOutlineVisible(REAL x, REAL y, const Pen *pen, 448 const Graphics *g = NULL) const; 449 BOOL IsOutlineVisible(INT x, INT y, const Pen *pen, 450 const Graphics *g = NULL) const; 451 BOOL IsOutlineVisible(const PointF& point, const Pen *pen, 452 const Graphics *g = NULL) const; 453 BOOL IsOutlineVisible(const Point& point, const Pen *pen, 454 const Graphics *g = NULL) const; 455 BOOL IsVisible(REAL x, REAL y, const Graphics *g = NULL) const; 456 BOOL IsVisible(INT x, INT y, const Graphics *g = NULL) const; 457 BOOL IsVisible(const PointF& point, const Graphics *g = NULL) const; 458 BOOL IsVisible(const Point& point, const Graphics *g = NULL) const; 459 Status Outline(const Matrix *matrix = NULL, 460 REAL flatness = FlatnessDefault) 461 { 462 return updateStatus(DllExports::GdipWindingModeOutline( 463 nativePath, 464 matrix ? matrix->nativeMatrix : NULL, 465 flatness)); 466 } 467 Status Reset() 468 { 469 return updateStatus(DllExports::GdipResetPath(nativePath)); 470 } 471 Status Reverse() 472 { 473 return updateStatus(DllExports::GdipReversePath(nativePath)); 474 } 475 Status SetFillMode(FillMode fillMode) 476 { 477 return updateStatus(DllExports::GdipSetPathFillMode( 478 nativePath, fillMode)); 479 } 480 Status SetMarker() 481 { 482 return updateStatus(DllExports::GdipSetPathMarker(nativePath)); 483 } 484 Status StartFigure() 485 { 486 return updateStatus(DllExports::GdipStartPathFigure( 487 nativePath)); 488 } 489 Status Transform(const Matrix *matrix) 490 { 491 return updateStatus(DllExports::GdipTransformPath( 492 nativePath, 493 matrix ? matrix->nativeMatrix : NULL)); 494 } 495 Status Warp(const PointF *destPoints, INT count, const RectF& srcRect, 496 const Matrix *matrix = NULL, 497 WarpMode warpMode = WarpModePerspective, 498 REAL flatness = FlatnessDefault) 499 { 500 return updateStatus(DllExports::GdipWarpPath(nativePath, 501 matrix ? matrix->nativeMatrix : NULL, 502 destPoints, count, 503 srcRect.X, srcRect.Y, 504 srcRect.Width, srcRect.Height, 505 warpMode, flatness)); 506 } 507 Status Widen(const Pen *pen, const Matrix *matrix = NULL, 508 REAL flatness = FlatnessDefault) 509 { 510 return updateStatus(DllExports::GdipWidenPath(nativePath, 511 pen ? pen->nativePen : NULL, 512 matrix ? matrix->nativeMatrix : NULL, 513 flatness)); 514 } 515 516 private: 517 GraphicsPath(GpPath *path, Status status): 518 nativePath(path), lastStatus(status) {} 519 GraphicsPath(const GraphicsPath&); 520 GraphicsPath& operator=(const GraphicsPath&); 521 522 Status updateStatus(Status newStatus) const 523 { 524 if (newStatus != Ok) lastStatus = newStatus; 525 return newStatus; 526 } 527 528 GpPath *nativePath; 529 mutable Status lastStatus; 530 }; 531 532 class GraphicsPathIterator: public GdiplusBase 533 { 534 public: 535 GraphicsPathIterator(GraphicsPath *path): 536 nativePathIterator(NULL), lastStatus(Ok) 537 { 538 lastStatus = DllExports::GdipCreatePathIter( 539 &nativePathIterator, 540 path ? path->nativePath : NULL); 541 } 542 ~GraphicsPathIterator() 543 { 544 DllExports::GdipDeletePathIter(nativePathIterator); 545 } 546 547 INT CopyData(PointF *points, BYTE *types, INT startIndex, INT endIndex) 548 { 549 INT result = 0; 550 updateStatus(DllExports::GdipPathIterCopyData( 551 nativePathIterator, &result, 552 points, types, startIndex, endIndex)); 553 return result; 554 } 555 INT Enumerate(PointF *points, BYTE *types, INT count) 556 { 557 INT result = 0; 558 updateStatus(DllExports::GdipPathIterEnumerate( 559 nativePathIterator, &result, 560 points, types, count)); 561 return result; 562 } 563 INT GetCount() const 564 { 565 INT result = 0; 566 updateStatus(DllExports::GdipPathIterGetCount( 567 nativePathIterator, &result)); 568 return result; 569 } 570 Status GetLastStatus() const 571 { 572 Status result = lastStatus; 573 lastStatus = Ok; 574 return result; 575 } 576 INT GetSubpathCount() const 577 { 578 INT result = 0; 579 updateStatus(DllExports::GdipPathIterGetSubpathCount( 580 nativePathIterator, &result)); 581 return result; 582 } 583 BOOL HasCurve() const 584 { 585 BOOL result = FALSE; 586 updateStatus(DllExports::GdipPathIterHasCurve( 587 nativePathIterator, &result)); 588 return result; 589 } 590 INT NextMarker(INT *startIndex, INT *endIndex) 591 { 592 INT result = 0; 593 updateStatus(DllExports::GdipPathIterNextMarker( 594 nativePathIterator, &result, 595 startIndex, endIndex)); 596 return result; 597 } 598 INT NextMarker(GraphicsPath *path) 599 { 600 INT result = 0; 601 updateStatus(DllExports::GdipPathIterNextMarkerPath( 602 nativePathIterator, &result, 603 path ? path->nativePath : NULL)); 604 return result; 605 } 606 INT NextPathType(BYTE *pathType, INT *startIndex, INT *endIndex) 607 { 608 INT result = 0; 609 updateStatus(DllExports::GdipPathIterNextPathType( 610 nativePathIterator, &result, 611 pathType, startIndex, endIndex)); 612 return result; 613 } 614 INT NextSubpath(INT *startIndex, INT *endIndex, BOOL *isClosed) 615 { 616 INT result = 0; 617 updateStatus(DllExports::GdipPathIterNextSubpath( 618 nativePathIterator, &result, 619 startIndex, endIndex, isClosed)); 620 return result; 621 } 622 INT NextSubpath(GraphicsPath *path, BOOL *isClosed) 623 { 624 INT result = 0; 625 updateStatus(DllExports::GdipPathIterNextSubpathPath( 626 nativePathIterator, &result, 627 path ? path->nativePath : NULL, isClosed)); 628 return result; 629 } 630 VOID Rewind() 631 { 632 updateStatus(DllExports::GdipPathIterRewind( 633 nativePathIterator)); 634 } 635 636 private: 637 GraphicsPathIterator(GpPathIterator *pathIterator, Status status): 638 nativePathIterator(pathIterator), lastStatus(status) {} 639 GraphicsPathIterator(const GraphicsPathIterator&); 640 GraphicsPathIterator& operator=(const GraphicsPathIterator&); 641 642 Status updateStatus(Status newStatus) const 643 { 644 if (newStatus != Ok) lastStatus = newStatus; 645 return newStatus; 646 } 647 648 GpPathIterator *nativePathIterator; 649 mutable Status lastStatus; 650 }; 651 652 class PathGradientBrush: public Brush 653 { 654 public: 655 PathGradientBrush(const PointF *points, INT count, 656 WrapMode wrapMode = WrapModeClamp) 657 { 658 GpPathGradient *nativePathGradient = NULL; 659 lastStatus = DllExports::GdipCreatePathGradient( 660 points, count, wrapMode, &nativePathGradient); 661 nativeBrush = nativePathGradient; 662 } 663 PathGradientBrush(const Point *points, INT count, 664 WrapMode wrapMode = WrapModeClamp) 665 { 666 GpPathGradient *nativePathGradient = NULL; 667 lastStatus = DllExports::GdipCreatePathGradientI( 668 points, count, wrapMode, &nativePathGradient); 669 nativeBrush = nativePathGradient; 670 } 671 PathGradientBrush(const GraphicsPath *path) 672 { 673 GpPathGradient *nativePathGradient = NULL; 674 lastStatus = DllExports::GdipCreatePathGradientFromPath( 675 path ? path->nativePath : NULL, 676 &nativePathGradient); 677 nativeBrush = nativePathGradient; 678 } 679 virtual PathGradientBrush *Clone() const 680 { 681 GpBrush *cloneBrush = NULL; 682 Status status = updateStatus(DllExports::GdipCloneBrush( 683 nativeBrush, &cloneBrush)); 684 if (status == Ok) { 685 PathGradientBrush *result = 686 new PathGradientBrush(cloneBrush, lastStatus); 687 if (!result) { 688 DllExports::GdipDeleteBrush(cloneBrush); 689 updateStatus(OutOfMemory); 690 } 691 return result; 692 } else { 693 return NULL; 694 } 695 } 696 697 Status GetBlend(REAL *blendFactors, REAL *blendPositions, 698 INT count) const 699 { 700 return updateStatus(DllExports::GdipGetPathGradientBlend( 701 (GpPathGradient*) nativeBrush, 702 blendFactors, blendPositions, count)); 703 } 704 INT GetBlendCount() const 705 { 706 INT result = 0; 707 updateStatus(DllExports::GdipGetPathGradientBlendCount( 708 (GpPathGradient*) nativeBrush, &result)); 709 return result; 710 } 711 Status GetCenterColor(Color *color) const 712 { 713 return updateStatus(DllExports::GdipGetPathGradientCenterColor( 714 (GpPathGradient*) nativeBrush, 715 color ? &color->Value : NULL)); 716 } 717 Status GetCenterPoint(PointF *point) const 718 { 719 return updateStatus(DllExports::GdipGetPathGradientCenterPoint( 720 (GpPathGradient*) nativeBrush, point)); 721 } 722 Status GetCenterPoint(Point *point) const 723 { 724 return updateStatus(DllExports::GdipGetPathGradientCenterPointI( 725 (GpPathGradient*) nativeBrush, point)); 726 } 727 Status GetFocusScales(REAL *xScale, REAL *yScale) const 728 { 729 return updateStatus(DllExports::GdipGetPathGradientFocusScales( 730 (GpPathGradient*) nativeBrush, xScale, yScale)); 731 } 732 BOOL GetGammaCorrection() const 733 { 734 BOOL result = FALSE; 735 updateStatus(DllExports::GdipGetPathGradientGammaCorrection( 736 (GpPathGradient*) nativeBrush, &result)); 737 return result; 738 } 739 //Status GetGraphicsPath(GraphicsPath *path) const 740 //{ 741 // // TODO: implement PathGradientBrush::GetGraphicsPath 742 // return updateStatus(NotImplemented); 743 //} 744 INT GetInterpolationColorCount() const 745 { 746 INT result = 0; 747 updateStatus(DllExports::GdipGetPathGradientPresetBlendCount( 748 (GpPathGradient*) nativeBrush, &result)); 749 return result; 750 } 751 Status GetInterpolationColors(Color *presetColors, 752 REAL *blendPositions, INT count) const 753 { 754 if (!presetColors || count <= 0) 755 return lastStatus = InvalidParameter; 756 757 ARGB *presetArgb = 758 (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB)); 759 if (!presetArgb) 760 return lastStatus = OutOfMemory; 761 762 Status status = updateStatus(DllExports::GdipGetPathGradientPresetBlend( 763 (GpPathGradient*) nativeBrush, 764 presetArgb, blendPositions, count)); 765 for (INT i = 0; i < count; ++i) { 766 presetColors[i].SetValue(presetArgb[i]); 767 } 768 DllExports::GdipFree((void*) presetArgb); 769 return status; 770 } 771 INT GetPointCount() const 772 { 773 INT result = 0; 774 updateStatus(DllExports::GdipGetPathGradientPointCount( 775 (GpPathGradient*) nativeBrush, &result)); 776 return result; 777 } 778 Status GetRectangle(RectF *rect) const 779 { 780 return updateStatus(DllExports::GdipGetPathGradientRect( 781 (GpPathGradient*) nativeBrush, rect)); 782 } 783 Status GetRectangle(Rect *rect) const 784 { 785 return updateStatus(DllExports::GdipGetPathGradientRectI( 786 (GpPathGradient*) nativeBrush, rect)); 787 } 788 INT GetSurroundColorCount() const 789 { 790 INT result = 0; 791 updateStatus(DllExports::GdipGetPathGradientSurroundColorCount( 792 (GpPathGradient*) nativeBrush, &result)); 793 return result; 794 } 795 Status GetSurroundColors(Color *colors, INT *count) 796 { 797 if (!colors || !count || *count <= 0) 798 return lastStatus = InvalidParameter; 799 800 ARGB *colorsArgb = 801 (ARGB*) DllExports::GdipAlloc(*count * sizeof(ARGB)); 802 if (!colorsArgb) 803 return lastStatus = OutOfMemory; 804 805 Status status = updateStatus(DllExports::GdipGetPathGradientSurroundColorsWithCount( 806 (GpPathGradient*) nativeBrush, 807 colorsArgb, count)); 808 for (INT i = 0; i < *count; ++i) { 809 colors[i].SetValue(colorsArgb[i]); 810 } 811 DllExports::GdipFree((void*) colorsArgb); 812 return status; 813 } 814 Status GetTransform(Matrix *matrix) const 815 { 816 return updateStatus(DllExports::GdipGetPathGradientTransform( 817 (GpPathGradient*) nativeBrush, 818 matrix ? matrix->nativeMatrix : NULL)); 819 } 820 WrapMode GetWrapMode() const 821 { 822 WrapMode result = WrapModeTile; 823 updateStatus(DllExports::GdipGetPathGradientWrapMode( 824 (GpPathGradient*) nativeBrush, &result)); 825 return result; 826 } 827 Status MultiplyTransform(const Matrix *matrix, 828 MatrixOrder order = MatrixOrderPrepend) 829 { 830 return updateStatus(DllExports::GdipMultiplyPathGradientTransform( 831 (GpPathGradient*) nativeBrush, 832 matrix ? matrix->nativeMatrix : NULL, order)); 833 } 834 Status ResetTransform() 835 { 836 return updateStatus(DllExports::GdipResetPathGradientTransform( 837 (GpPathGradient*) nativeBrush)); 838 } 839 Status RotateTransform(REAL angle, 840 MatrixOrder order = MatrixOrderPrepend) 841 { 842 return updateStatus(DllExports::GdipRotatePathGradientTransform( 843 (GpPathGradient*) nativeBrush, angle, order)); 844 } 845 Status ScaleTransform(REAL sx, REAL sy, 846 MatrixOrder order = MatrixOrderPrepend) 847 { 848 return updateStatus(DllExports::GdipScalePathGradientTransform( 849 (GpPathGradient*) nativeBrush, sx, sy, order)); 850 } 851 Status SetBlend(REAL *blendFactors, REAL *blendPositions, INT count) 852 { 853 return updateStatus(DllExports::GdipSetPathGradientBlend( 854 (GpPathGradient*) nativeBrush, 855 blendFactors, blendPositions, count)); 856 } 857 Status SetBlendBellShape(REAL focus, REAL scale = 1.0f) 858 { 859 return updateStatus(DllExports::GdipSetPathGradientSigmaBlend( 860 (GpPathGradient*) nativeBrush, focus, scale)); 861 } 862 Status SetBlendTriangularShape(REAL focus, REAL scale = 1.0f) 863 { 864 return updateStatus(DllExports::GdipSetPathGradientLinearBlend( 865 (GpPathGradient*) nativeBrush, focus, scale)); 866 } 867 Status SetCenterColor(const Color& color) 868 { 869 return updateStatus(DllExports::GdipSetPathGradientCenterColor( 870 (GpPathGradient*) nativeBrush, 871 color.GetValue())); 872 } 873 Status SetCenterPoint(const PointF& point) 874 { 875 return updateStatus(DllExports::GdipSetPathGradientCenterPoint( 876 (GpPathGradient*) nativeBrush, &point)); 877 } 878 Status SetCenterPoint(const Point& point) 879 { 880 return updateStatus(DllExports::GdipSetPathGradientCenterPointI( 881 (GpPathGradient*) nativeBrush, &point)); 882 } 883 Status SetFocusScales(REAL xScale, REAL yScale) 884 { 885 return updateStatus(DllExports::GdipSetPathGradientFocusScales( 886 (GpPathGradient*) nativeBrush, xScale, yScale)); 887 } 888 Status SetGammaCorrection(BOOL useGammaCorrection) 889 { 890 return updateStatus(DllExports::GdipSetPathGradientGammaCorrection( 891 (GpPathGradient*) nativeBrush, 892 useGammaCorrection)); 893 } 894 //Status SetGraphicsPath(const GraphicsPath *path) 895 //{ 896 // // TODO: implement PathGradientBrush::SetGraphicsPath 897 // return updateStatus(NotImplemented); 898 //} 899 Status SetInterpolationColors(const Color *presetColors, 900 REAL *blendPositions, INT count) 901 { 902 if (!presetColors || count <= 0) 903 return lastStatus = InvalidParameter; 904 905 ARGB *presetArgb = 906 (ARGB*) DllExports::GdipAlloc(count * sizeof(ARGB)); 907 if (!presetArgb) 908 return lastStatus = OutOfMemory; 909 for (INT i = 0; i < count; ++i) { 910 presetArgb[i] = presetColors[i].GetValue(); 911 } 912 913 Status status = updateStatus(DllExports::GdipSetPathGradientPresetBlend( 914 (GpPathGradient*) nativeBrush, 915 presetArgb, blendPositions, count)); 916 DllExports::GdipFree((void*) presetArgb); 917 return status; 918 } 919 Status SetSurroundColors(const Color *colors, INT *count) 920 { 921 if (!colors || !count || *count <= 0) 922 return lastStatus = InvalidParameter; 923 924 ARGB *colorsArgb = 925 (ARGB*) DllExports::GdipAlloc(*count * sizeof(ARGB)); 926 if (!colorsArgb) 927 return lastStatus = OutOfMemory; 928 for (INT i = 0; i < *count; ++i) { 929 colorsArgb[i] = colors[i].GetValue(); 930 } 931 932 Status status = updateStatus(DllExports::GdipSetPathGradientSurroundColorsWithCount( 933 (GpPathGradient*) nativeBrush, 934 colorsArgb, count)); 935 DllExports::GdipFree((void*) colorsArgb); 936 return status; 937 } 938 Status SetTransform(const Matrix *matrix) 939 { 940 return updateStatus(DllExports::GdipSetPathGradientTransform( 941 (GpPathGradient*) nativeBrush, 942 matrix ? matrix->nativeMatrix : NULL)); 943 } 944 Status SetWrapMode(WrapMode wrapMode) 945 { 946 return updateStatus(DllExports::GdipSetPathGradientWrapMode( 947 (GpPathGradient*) nativeBrush, wrapMode)); 948 } 949 Status TranslateTransform(REAL dx, REAL dy, 950 MatrixOrder order = MatrixOrderPrepend) 951 { 952 return updateStatus(DllExports::GdipTranslatePathGradientTransform( 953 (GpPathGradient*) nativeBrush, dx, dy, order)); 954 } 955 956 private: 957 PathGradientBrush(GpBrush *brush, Status status): Brush(brush, status) {} 958 PathGradientBrush(const PathGradientBrush&); 959 PathGradientBrush& operator=(const PathGradientBrush&); 960 }; 961 962 963 964 #endif /* __GDIPLUS_PATH_H */ 965