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