1 module directx.d2d1helper; 2 /*=========================================================================*\ 3 4 Copyright (c) Microsoft Corporation. All rights reserved. 5 6 File: D2D1helper.h 7 8 Module Name: D2D 9 10 Description: Helper files over the D2D interfaces and APIs. 11 12 \*=========================================================================*/ 13 14 version(Windows): 15 16 public import directx.d2d1; 17 18 struct D2D1 19 { 20 // 21 // The default trait type for objects in D2D is float. 22 // 23 template TypeTraits(T) 24 { 25 alias Point = D2D1_POINT_2F; 26 alias Size = D2D1_SIZE_F; 27 alias Rect = D2D1_RECT_F; 28 } 29 30 template TypeTraits(T : UINT32) 31 { 32 alias Point = D2D1_POINT_2U; 33 alias Size = D2D1_SIZE_U; 34 alias Rect = D2D1_RECT_U; 35 } 36 37 static nothrow 38 FLOAT FloatMax() 39 { 40 static if ( __traits(compiles, FLT_MAX.stringof) ) 41 return FLT_MAX; 42 else 43 return 3.402823466e+38F; 44 } 45 46 // 47 // Construction helpers 48 // 49 50 template Point2(Type) 51 { 52 struct Point2_(Type) 53 { 54 Type x; 55 Type y; 56 } 57 58 static Point2_!Type Point2(Type x, Type y) 59 { 60 61 return Point2_(x,y); 62 } 63 } 64 65 66 static D2D1_POINT_2F 67 Point2F( 68 FLOAT x = 0.0f, 69 FLOAT y = 0.0f 70 ) 71 { 72 return D2D1_POINT_2F(x, y); 73 } 74 75 static D2D1_POINT_2U 76 Point2U( 77 UINT32 x = 0, 78 UINT32 y = 0 79 ) 80 { 81 return D2D1_POINT_2U(x, y); 82 } 83 84 template Size(Type) 85 { 86 static TypeTraits!Type.Size Size( Type width, Type height ) 87 { 88 TypeTraits!Type.Size size = { width, height }; 89 return size; 90 } 91 } 92 93 static D2D1_SIZE_F SizeF( FLOAT width = 0.0f, FLOAT height = 0.0f ) 94 { 95 return Size!FLOAT(width, height); 96 } 97 98 static D2D1_SIZE_U SizeU( UINT32 width = 0, UINT32 height = 0 ) 99 { 100 return Size!UINT32(width, height); 101 } 102 103 104 template Rect(Type) 105 { 106 static TypeTraits!Type.Rect Rect( 107 Type left, 108 Type top, 109 Type right, 110 Type bottom 111 ) 112 { 113 TypeTraits!Type.Rect rect = { left, top, right, bottom }; 114 return rect; 115 } 116 } 117 118 static D2D1_RECT_F RectF( 119 FLOAT left = 0.0f, 120 FLOAT top = 0.0f, 121 FLOAT right = 0.0f, 122 FLOAT bottom = 0.0f 123 ) 124 { 125 return Rect!FLOAT(left, top, right, bottom); 126 } 127 128 static D2D1_RECT_U RectU( 129 UINT32 left = 0, 130 UINT32 top = 0, 131 UINT32 right = 0, 132 UINT32 bottom = 0 133 ) 134 { 135 return Rect!UINT32(left, top, right, bottom); 136 } 137 138 static D2D1_RECT_F 139 InfiniteRect() 140 { 141 D2D1_RECT_F rect = { -FloatMax(), -FloatMax(), FloatMax(), FloatMax() }; 142 return rect; 143 } 144 145 static D2D1_ARC_SEGMENT 146 ArcSegment( 147 const(D2D1_POINT_2F) point, 148 const(D2D1_SIZE_F) size, 149 FLOAT rotationAngle, 150 const(D2D1_SWEEP_DIRECTION) sweepDirection, 151 const(D2D1_ARC_SIZE) arcSize 152 ) 153 { 154 D2D1_ARC_SEGMENT arcSegment = { point, size, rotationAngle, sweepDirection, arcSize }; 155 156 return arcSegment; 157 } 158 159 160 static D2D1_BEZIER_SEGMENT 161 BezierSegment( 162 const(D2D1_POINT_2F) point1, 163 const(D2D1_POINT_2F) point2, 164 const(D2D1_POINT_2F) point3 165 ) 166 { 167 D2D1_BEZIER_SEGMENT bezierSegment = { point1, point2, point3 }; 168 169 return bezierSegment; 170 } 171 172 static D2D1_ELLIPSE 173 Ellipse( 174 in D2D1_POINT_2F center, 175 FLOAT radiusX, 176 FLOAT radiusY 177 ) 178 { 179 D2D1_ELLIPSE ellipse; 180 181 ellipse.point = center; 182 ellipse.radiusX = radiusX; 183 ellipse.radiusY = radiusY; 184 185 return ellipse; 186 } 187 188 static D2D1_ROUNDED_RECT 189 RoundedRect( 190 in D2D1_RECT_F rect, 191 FLOAT radiusX, 192 FLOAT radiusY 193 ) 194 { 195 D2D1_ROUNDED_RECT roundedRect; 196 197 roundedRect.rect = rect; 198 roundedRect.radiusX = radiusX; 199 roundedRect.radiusY = radiusY; 200 201 return roundedRect; 202 } 203 204 static D2D1_BRUSH_PROPERTIES 205 BrushProperties( 206 FLOAT opacity = 1.0, 207 in D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix() 208 ) 209 { 210 D2D1_BRUSH_PROPERTIES brushProperties; 211 212 brushProperties.opacity = opacity; 213 brushProperties.transform = transform; 214 215 return brushProperties; 216 } 217 218 static D2D1_GRADIENT_STOP 219 GradientStop( 220 FLOAT position, 221 in D2D1_COLOR_F color 222 ) 223 { 224 D2D1_GRADIENT_STOP gradientStop = { position, color }; 225 226 return gradientStop; 227 } 228 229 static D2D1_QUADRATIC_BEZIER_SEGMENT 230 QuadraticBezierSegment( 231 in D2D1_POINT_2F point1, 232 in D2D1_POINT_2F point2 233 ) 234 { 235 D2D1_QUADRATIC_BEZIER_SEGMENT quadraticBezier = { point1, point2 }; 236 237 return quadraticBezier; 238 } 239 240 static D2D1_STROKE_STYLE_PROPERTIES 241 StrokeStyleProperties( 242 D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT, 243 D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT, 244 D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT, 245 D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER, 246 FLOAT miterLimit = 10.0f, 247 D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID, 248 FLOAT dashOffset = 0.0f 249 ) 250 { 251 D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties; 252 253 strokeStyleProperties.startCap = startCap; 254 strokeStyleProperties.endCap = endCap; 255 strokeStyleProperties.dashCap = dashCap; 256 strokeStyleProperties.lineJoin = lineJoin; 257 strokeStyleProperties.miterLimit = miterLimit; 258 strokeStyleProperties.dashStyle = dashStyle; 259 strokeStyleProperties.dashOffset = dashOffset; 260 261 return strokeStyleProperties; 262 } 263 264 static D2D1_BITMAP_BRUSH_PROPERTIES 265 BitmapBrushProperties( 266 D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, 267 D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, 268 D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR 269 ) 270 { 271 D2D1_BITMAP_BRUSH_PROPERTIES bitmapBrushProperties; 272 273 bitmapBrushProperties.extendModeX = extendModeX; 274 bitmapBrushProperties.extendModeY = extendModeY; 275 bitmapBrushProperties.interpolationMode = interpolationMode; 276 277 return bitmapBrushProperties; 278 } 279 280 static D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES 281 LinearGradientBrushProperties( 282 in D2D1_POINT_2F startPoint, 283 in D2D1_POINT_2F endPoint 284 ) 285 { 286 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties; 287 288 linearGradientBrushProperties.startPoint = startPoint; 289 linearGradientBrushProperties.endPoint = endPoint; 290 291 return linearGradientBrushProperties; 292 } 293 294 static D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES 295 RadialGradientBrushProperties( 296 in D2D1_POINT_2F center, 297 in D2D1_POINT_2F gradientOriginOffset, 298 FLOAT radiusX, 299 FLOAT radiusY 300 ) 301 { 302 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties; 303 304 radialGradientBrushProperties.center = center; 305 radialGradientBrushProperties.gradientOriginOffset = gradientOriginOffset; 306 radialGradientBrushProperties.radiusX = radiusX; 307 radialGradientBrushProperties.radiusY = radiusY; 308 309 return radialGradientBrushProperties; 310 } 311 312 // 313 // PixelFormat 314 // 315 static D2D1_PIXEL_FORMAT 316 PixelFormat( 317 in DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN, 318 in D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_UNKNOWN 319 ) 320 { 321 D2D1_PIXEL_FORMAT pixelFormat; 322 323 pixelFormat.format = dxgiFormat; 324 pixelFormat.alphaMode = alphaMode; 325 326 return pixelFormat; 327 } 328 329 // 330 // Bitmaps 331 // 332 static D2D1_BITMAP_PROPERTIES 333 BitmapProperties( 334 in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 335 FLOAT dpiX = 96.0f, 336 FLOAT dpiY = 96.0f 337 ) 338 { 339 D2D1_BITMAP_PROPERTIES bitmapProperties; 340 341 bitmapProperties.pixelFormat = pixelFormat; 342 bitmapProperties.dpiX = dpiX; 343 bitmapProperties.dpiY = dpiY; 344 345 return bitmapProperties; 346 } 347 348 349 // 350 // Render Targets 351 // 352 static D2D1_RENDER_TARGET_PROPERTIES 353 RenderTargetProperties( 354 D2D1_RENDER_TARGET_TYPE type = D2D1_RENDER_TARGET_TYPE_DEFAULT, 355 in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 356 FLOAT dpiX = 0.0, 357 FLOAT dpiY = 0.0, 358 D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE, 359 D2D1_FEATURE_LEVEL minLevel = D2D1_FEATURE_LEVEL_DEFAULT 360 ) 361 { 362 D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties; 363 364 renderTargetProperties.type = type; 365 renderTargetProperties.pixelFormat = pixelFormat; 366 renderTargetProperties.dpiX = dpiX; 367 renderTargetProperties.dpiY = dpiY; 368 renderTargetProperties.usage = usage; 369 renderTargetProperties.minLevel = minLevel; 370 371 return renderTargetProperties; 372 } 373 374 static D2D1_RENDER_TARGET_PROPERTIES* 375 RenderTargetPropertiesPtr( 376 D2D1_RENDER_TARGET_TYPE type = D2D1_RENDER_TARGET_TYPE_DEFAULT, 377 in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 378 FLOAT dpiX = 0.0, 379 FLOAT dpiY = 0.0, 380 D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE, 381 D2D1_FEATURE_LEVEL minLevel = D2D1_FEATURE_LEVEL_DEFAULT 382 ) 383 { 384 D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties = new D2D1_RENDER_TARGET_PROPERTIES(); 385 386 renderTargetProperties.type = type; 387 renderTargetProperties.pixelFormat = pixelFormat; 388 renderTargetProperties.dpiX = dpiX; 389 renderTargetProperties.dpiY = dpiY; 390 renderTargetProperties.usage = usage; 391 renderTargetProperties.minLevel = minLevel; 392 393 return renderTargetProperties; 394 } 395 396 static D2D1_HWND_RENDER_TARGET_PROPERTIES 397 HwndRenderTargetProperties( 398 HWND hwnd, 399 in D2D1_SIZE_U pixelSize = D2D1.Size(cast(UINT32)0, cast(UINT32)0), 400 in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE 401 ) 402 { 403 D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderTargetProperties; 404 405 hwndRenderTargetProperties.hwnd = hwnd; 406 hwndRenderTargetProperties.pixelSize = pixelSize; 407 hwndRenderTargetProperties.presentOptions = presentOptions; 408 409 return hwndRenderTargetProperties; 410 } 411 412 static D2D1_HWND_RENDER_TARGET_PROPERTIES* 413 HwndRenderTargetPropertiesPtr( 414 HWND hwnd, 415 in D2D1_SIZE_U pixelSize = D2D1.Size(cast(UINT32)0, cast(UINT32)0), 416 in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE 417 ) 418 { 419 D2D1_HWND_RENDER_TARGET_PROPERTIES* hwndRenderTargetProperties = new D2D1_HWND_RENDER_TARGET_PROPERTIES(); 420 421 hwndRenderTargetProperties.hwnd = hwnd; 422 hwndRenderTargetProperties.pixelSize = pixelSize; 423 hwndRenderTargetProperties.presentOptions = presentOptions; 424 425 return hwndRenderTargetProperties; 426 } 427 428 static D2D1_LAYER_PARAMETERS 429 LayerParameters( 430 in D2D1_RECT_F contentBounds = D2D1.InfiniteRect(), 431 ID2D1Geometry geometricMask = null, 432 D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 433 D2D1_MATRIX_3X2_F maskTransform = D2D1.IdentityMatrix(), 434 FLOAT opacity = 1.0, 435 ID2D1Brush opacityBrush = null, 436 D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE 437 ) 438 { 439 D2D1_LAYER_PARAMETERS layerParameters; 440 441 layerParameters.contentBounds = contentBounds; 442 layerParameters.geometricMask = geometricMask; 443 layerParameters.maskAntialiasMode = maskAntialiasMode; 444 layerParameters.maskTransform = maskTransform; 445 layerParameters.opacity = opacity; 446 layerParameters.opacityBrush = opacityBrush; 447 layerParameters.layerOptions = layerOptions; 448 449 return layerParameters; 450 } 451 452 static D2D1_DRAWING_STATE_DESCRIPTION 453 DrawingStateDescription( 454 D2D1_ANTIALIAS_MODE antialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 455 D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, 456 D2D1_TAG tag1 = 0, 457 D2D1_TAG tag2 = 0, 458 in D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix() 459 ) 460 { 461 D2D1_DRAWING_STATE_DESCRIPTION drawingStateDescription; 462 463 drawingStateDescription.antialiasMode = antialiasMode; 464 drawingStateDescription.textAntialiasMode = textAntialiasMode; 465 drawingStateDescription.tag1 = tag1; 466 drawingStateDescription.tag2 = tag2; 467 drawingStateDescription.transform = transform; 468 469 return drawingStateDescription; 470 } 471 472 // 473 // Colors, this enum defines a set of predefined colors. 474 // 475 struct ColorF 476 { 477 public: 478 D2D1_COLOR_F color; 479 alias color this; 480 481 alias Enum = uint; 482 enum : Enum 483 { 484 AliceBlue = 0xF0F8FF, 485 AntiqueWhite = 0xFAEBD7, 486 Aqua = 0x00FFFF, 487 Aquamarine = 0x7FFFD4, 488 Azure = 0xF0FFFF, 489 Beige = 0xF5F5DC, 490 Bisque = 0xFFE4C4, 491 Black = 0x000000, 492 BlanchedAlmond = 0xFFEBCD, 493 Blue = 0x0000FF, 494 BlueViolet = 0x8A2BE2, 495 Brown = 0xA52A2A, 496 BurlyWood = 0xDEB887, 497 CadetBlue = 0x5F9EA0, 498 Chartreuse = 0x7FFF00, 499 Chocolate = 0xD2691E, 500 Coral = 0xFF7F50, 501 CornflowerBlue = 0x6495ED, 502 Cornsilk = 0xFFF8DC, 503 Crimson = 0xDC143C, 504 Cyan = 0x00FFFF, 505 DarkBlue = 0x00008B, 506 DarkCyan = 0x008B8B, 507 DarkGoldenrod = 0xB8860B, 508 DarkGray = 0xA9A9A9, 509 DarkGreen = 0x006400, 510 DarkKhaki = 0xBDB76B, 511 DarkMagenta = 0x8B008B, 512 DarkOliveGreen = 0x556B2F, 513 DarkOrange = 0xFF8C00, 514 DarkOrchid = 0x9932CC, 515 DarkRed = 0x8B0000, 516 DarkSalmon = 0xE9967A, 517 DarkSeaGreen = 0x8FBC8F, 518 DarkSlateBlue = 0x483D8B, 519 DarkSlateGray = 0x2F4F4F, 520 DarkTurquoise = 0x00CED1, 521 DarkViolet = 0x9400D3, 522 DeepPink = 0xFF1493, 523 DeepSkyBlue = 0x00BFFF, 524 DimGray = 0x696969, 525 DodgerBlue = 0x1E90FF, 526 Firebrick = 0xB22222, 527 FloralWhite = 0xFFFAF0, 528 ForestGreen = 0x228B22, 529 Fuchsia = 0xFF00FF, 530 Gainsboro = 0xDCDCDC, 531 GhostWhite = 0xF8F8FF, 532 Gold = 0xFFD700, 533 Goldenrod = 0xDAA520, 534 Gray = 0x808080, 535 Green = 0x008000, 536 GreenYellow = 0xADFF2F, 537 Honeydew = 0xF0FFF0, 538 HotPink = 0xFF69B4, 539 IndianRed = 0xCD5C5C, 540 Indigo = 0x4B0082, 541 Ivory = 0xFFFFF0, 542 Khaki = 0xF0E68C, 543 Lavender = 0xE6E6FA, 544 LavenderBlush = 0xFFF0F5, 545 LawnGreen = 0x7CFC00, 546 LemonChiffon = 0xFFFACD, 547 LightBlue = 0xADD8E6, 548 LightCoral = 0xF08080, 549 LightCyan = 0xE0FFFF, 550 LightGoldenrodYellow = 0xFAFAD2, 551 LightGreen = 0x90EE90, 552 LightGray = 0xD3D3D3, 553 LightPink = 0xFFB6C1, 554 LightSalmon = 0xFFA07A, 555 LightSeaGreen = 0x20B2AA, 556 LightSkyBlue = 0x87CEFA, 557 LightSlateGray = 0x778899, 558 LightSteelBlue = 0xB0C4DE, 559 LightYellow = 0xFFFFE0, 560 Lime = 0x00FF00, 561 LimeGreen = 0x32CD32, 562 Linen = 0xFAF0E6, 563 Magenta = 0xFF00FF, 564 Maroon = 0x800000, 565 MediumAquamarine = 0x66CDAA, 566 MediumBlue = 0x0000CD, 567 MediumOrchid = 0xBA55D3, 568 MediumPurple = 0x9370DB, 569 MediumSeaGreen = 0x3CB371, 570 MediumSlateBlue = 0x7B68EE, 571 MediumSpringGreen = 0x00FA9A, 572 MediumTurquoise = 0x48D1CC, 573 MediumVioletRed = 0xC71585, 574 MidnightBlue = 0x191970, 575 MintCream = 0xF5FFFA, 576 MistyRose = 0xFFE4E1, 577 Moccasin = 0xFFE4B5, 578 NavajoWhite = 0xFFDEAD, 579 Navy = 0x000080, 580 OldLace = 0xFDF5E6, 581 Olive = 0x808000, 582 OliveDrab = 0x6B8E23, 583 Orange = 0xFFA500, 584 OrangeRed = 0xFF4500, 585 Orchid = 0xDA70D6, 586 PaleGoldenrod = 0xEEE8AA, 587 PaleGreen = 0x98FB98, 588 PaleTurquoise = 0xAFEEEE, 589 PaleVioletRed = 0xDB7093, 590 PapayaWhip = 0xFFEFD5, 591 PeachPuff = 0xFFDAB9, 592 Peru = 0xCD853F, 593 Pink = 0xFFC0CB, 594 Plum = 0xDDA0DD, 595 PowderBlue = 0xB0E0E6, 596 Purple = 0x800080, 597 Red = 0xFF0000, 598 RosyBrown = 0xBC8F8F, 599 RoyalBlue = 0x4169E1, 600 SaddleBrown = 0x8B4513, 601 Salmon = 0xFA8072, 602 SandyBrown = 0xF4A460, 603 SeaGreen = 0x2E8B57, 604 SeaShell = 0xFFF5EE, 605 Sienna = 0xA0522D, 606 Silver = 0xC0C0C0, 607 SkyBlue = 0x87CEEB, 608 SlateBlue = 0x6A5ACD, 609 SlateGray = 0x708090, 610 Snow = 0xFFFAFA, 611 SpringGreen = 0x00FF7F, 612 SteelBlue = 0x4682B4, 613 Tan = 0xD2B48C, 614 Teal = 0x008080, 615 Thistle = 0xD8BFD8, 616 Tomato = 0xFF6347, 617 Turquoise = 0x40E0D0, 618 Violet = 0xEE82EE, 619 Wheat = 0xF5DEB3, 620 White = 0xFFFFFF, 621 WhiteSmoke = 0xF5F5F5, 622 Yellow = 0xFFFF00, 623 YellowGreen = 0x9ACD32, 624 } 625 626 627 // 628 // Construct a color, note that the alpha value from the "rgb" component 629 // is never used. 630 // 631 this( 632 UINT32 rgb, 633 FLOAT a = 1.0 634 ) 635 { 636 Init(rgb, a); 637 } 638 /* 639 this( 640 Enum knownColor, 641 FLOAT a = 1.0 642 ) 643 { 644 Init(knownColor, a); 645 } 646 */ 647 648 this( 649 FLOAT r, 650 FLOAT g, 651 FLOAT b, 652 FLOAT a = 1.0 653 ) 654 { 655 this.r = r; 656 this.g = g; 657 this.b = b; 658 this.a = a; 659 } 660 661 private: 662 663 void 664 Init( 665 UINT32 rgb, 666 FLOAT a 667 ) 668 { 669 this.r = cast(FLOAT)((rgb & sc_redMask) >> sc_redShift) / 255.0f; 670 this.g = cast(FLOAT)((rgb & sc_greenMask) >> sc_greenShift) / 255.0f; 671 this.b = cast(FLOAT)((rgb & sc_blueMask) >> sc_blueShift) / 255.0f; 672 this.a = a; 673 } 674 675 static const UINT32 sc_redShift = 16; 676 static const UINT32 sc_greenShift = 8; 677 static const UINT32 sc_blueShift = 0; 678 679 static const UINT32 sc_redMask = 0xff << sc_redShift; 680 static const UINT32 sc_greenMask = 0xff << sc_greenShift; 681 static const UINT32 sc_blueMask = 0xff << sc_blueShift; 682 } 683 684 685 struct Matrix3x2F //: public D2D1_MATRIX_3X2_F 686 { 687 public: 688 D2D1_MATRIX_3X2_F matrix; 689 alias matrix this; 690 691 this(D2D1_MATRIX_3X2_F m) 692 { 693 matrix = m; 694 } 695 696 this( 697 FLOAT _11, 698 FLOAT _12, 699 FLOAT _21, 700 FLOAT _22, 701 FLOAT _31, 702 FLOAT _32 703 ) 704 { 705 this._11 = _11; 706 this._12 = _12; 707 this._21 = _21; 708 this._22 = _22; 709 this._31 = _31; 710 this._32 = _32; 711 } 712 713 // 714 // Named quasi-constructors 715 // 716 static @property 717 Matrix3x2F 718 Identity() 719 { 720 Matrix3x2F identity; 721 722 identity._11 = 1.0f; 723 identity._12 = 0.0f; 724 identity._21 = 0.0f; 725 identity._22 = 1.0f; 726 identity._31 = 0.0f; 727 identity._32 = 0.0f; 728 729 return identity; 730 } 731 732 static 733 Matrix3x2F 734 Translation( 735 D2D1_SIZE_F size 736 ) 737 { 738 Matrix3x2F translation; 739 740 translation._11 = 1.0; translation._12 = 0.0; 741 translation._21 = 0.0; translation._22 = 1.0; 742 translation._31 = size.width; translation._32 = size.height; 743 744 return translation; 745 } 746 747 static 748 Matrix3x2F 749 Translation( 750 FLOAT x, 751 FLOAT y 752 ) 753 { 754 return Translation(SizeF(x, y)); 755 } 756 757 758 static 759 Matrix3x2F 760 Scale( 761 D2D1_SIZE_F size, 762 D2D1_POINT_2F center = D2D1.Point2F() 763 ) 764 { 765 Matrix3x2F scale; 766 767 scale._11 = size.width; scale._12 = 0.0; 768 scale._21 = 0.0; scale._22 = size.height; 769 scale._31 = center.x - size.width * center.x; 770 scale._32 = center.y - size.height * center.y; 771 772 return scale; 773 } 774 775 static 776 Matrix3x2F 777 Scale( 778 FLOAT x, 779 FLOAT y, 780 D2D1_POINT_2F center = D2D1.Point2F() 781 ) 782 { 783 return Scale(SizeF(x, y), center); 784 } 785 786 static 787 Matrix3x2F 788 Rotation( 789 FLOAT angle, 790 D2D1_POINT_2F center = D2D1.Point2F() 791 ) 792 { 793 Matrix3x2F rotation; 794 795 D2D1MakeRotateMatrix(angle, center, &rotation.matrix); 796 797 return rotation; 798 } 799 800 static 801 Matrix3x2F 802 Skew( 803 FLOAT angleX, 804 FLOAT angleY, 805 D2D1_POINT_2F center = D2D1.Point2F() 806 ) 807 { 808 Matrix3x2F skew; 809 810 D2D1MakeSkewMatrix(angleX, angleY, center, &skew.matrix); 811 812 return skew; 813 } 814 815 //TODO: find a way to do such manipulation 816 /* 817 // 818 // Functions for convertion from the base D2D1_MATRIX_3X2_F to this type 819 // without making a copy 820 // 821 static 822 const(Matrix3x2F)* 823 ReinterpretBaseType(const(D2D1_MATRIX_3X2_F)* pMatrix) 824 { 825 return cast(const(Matrix3x2F)*)pMatrix; 826 } 827 828 static 829 COM_DECLSPEC_NOTHROW 830 inline 831 Matrix3x2F* 832 ReinterpretBaseType(D2D1_MATRIX_3X2_F *pMatrix) 833 { 834 return static_cast<Matrix3x2F *>(pMatrix); 835 } 836 */ 837 838 FLOAT 839 Determinant() const 840 { 841 return (_11 * _22) - (_12 * _21); 842 } 843 844 bool 845 IsInvertible() const 846 { 847 return !!D2D1IsMatrixInvertible(&this.matrix); 848 } 849 850 bool 851 Invert() 852 { 853 return !!D2D1InvertMatrix(&this.matrix); 854 } 855 856 bool 857 IsIdentity() const 858 { 859 return _11 == 1.0f && _12 == 0.0f 860 && _21 == 0.0f && _22 == 1.0f 861 && _31 == 0.0f && _32 == 0.0f; 862 } 863 864 void SetProduct( 865 in Matrix3x2F a, 866 in Matrix3x2F b 867 ) 868 { 869 _11 = a._11 * b._11 + a._12 * b._21; 870 _12 = a._11 * b._12 + a._12 * b._22; 871 _21 = a._21 * b._11 + a._22 * b._21; 872 _22 = a._21 * b._12 + a._22 * b._22; 873 _31 = a._31 * b._11 + a._32 * b._21 + b._31; 874 _32 = a._31 * b._12 + a._32 * b._22 + b._32; 875 } 876 877 Matrix3x2F opBinary(string op)(Matrix3x2F rhs) const 878 { 879 Matrix3x2F result; 880 881 static if (op == "*") 882 result.SetProduct(this,rhs); 883 else 884 static assert(0, "Operator "~op~" not implemented"); 885 886 return result; 887 } 888 889 D2D1_POINT_2F 890 TransformPoint( 891 D2D1_POINT_2F point 892 ) const 893 { 894 D2D1_POINT_2F result = 895 { 896 point.x * _11 + point.y * _21 + _31, 897 point.x * _12 + point.y * _22 + _32 898 }; 899 900 return result; 901 } 902 /* TODO 903 static Matrix3x2F MakeFromBaseType(in D2D1_MATRIX_3X2_F mat) 904 { 905 Matrix3x2F matrix = new Matrix3x2F(mat); 906 return matrix; 907 } 908 */ 909 } 910 911 static IdentityMatrix() 912 { 913 return Matrix3x2F.Identity(); 914 } 915 916 } // namespace D2D1 917 918 D2D1_POINT_2F opBinary(string op)(in D2D1_POINT_2F point, in D2D1_MATRIX_3X2_F matrix) 919 { 920 return D2D1.Matrix3x2F.ReinterpretBaseType(&matrix).TransformPoint(point); 921 } 922 923 /* 924 COM_DECLSPEC_NOTHROW 925 D2D1FORCEINLINE 926 D2D1_MATRIX_3X2_F 927 operator*( 928 const D2D1_MATRIX_3X2_F &matrix1, 929 const D2D1_MATRIX_3X2_F &matrix2 930 ) 931 { 932 return 933 (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix1)) * 934 (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix2)); 935 } 936 937 COM_DECLSPEC_NOTHROW 938 inline 939 bool 940 operator==(const D2D1_SIZE_U &size1, const D2D1_SIZE_U &size2) 941 { 942 return (size1.width == size2.width) && (size1.height == size2.height); 943 } 944 945 COM_DECLSPEC_NOTHROW 946 inline 947 bool 948 operator==(const D2D1_RECT_U &rect1, const D2D1_RECT_U &rect2) 949 { 950 return (rect1.left == rect2.left) && (rect1.top == rect2.top) && 951 (rect1.right == rect2.right) && (rect1.bottom == rect2.bottom); 952 } 953 954 #endif // #ifndef D2D_USE_C_DEFINITIONS 955 956 #endif // #ifndef _D2D1_HELPER_H_ 957 958 */