1 module directx.d2d1_1helper; 2 /*=========================================================================*\ 3 4 Copyright (c) Microsoft Corporation. All rights reserved. 5 6 File: D2D1_1Helper.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_1; 17 import directx.d2d1helper; 18 19 template TypeTraits(T : INT32) 20 { 21 alias Point = D2D1_POINT_2L; 22 alias Rect = D2D1_RECT_L; 23 } 24 25 template TypeTraits(T : LONG) 26 { 27 alias Point = D2D1_POINT_2L; 28 alias Rect = D2D1_RECT_L; 29 } 30 31 struct Matrix4x3F // : D2D1_MATRIX_4X3_F 32 { 33 D2D1_MATRIX_4X3_F matrix; 34 alias matrix this; 35 36 nothrow this(D2D1_MATRIX_4X3_F m) { matrix = m; } 37 nothrow this( 38 FLOAT m11, FLOAT m12, FLOAT m13, 39 FLOAT m21, FLOAT m22, FLOAT m23, 40 FLOAT m31, FLOAT m32, FLOAT m33, 41 FLOAT m41, FLOAT m42, FLOAT m43 42 ) 43 { 44 _11 = m11; 45 _12 = m12; 46 _13 = m13; 47 48 _21 = m21; 49 _22 = m22; 50 _23 = m23; 51 52 _31 = m31; 53 _32 = m32; 54 _33 = m33; 55 56 _41 = m41; 57 _42 = m42; 58 _43 = m43; 59 } 60 61 // this() 62 /// Use this instead of default constructor 63 static @property nothrow Identity() 64 { 65 return Matrix4x3F( 66 1, 0, 0, 67 0, 1, 0, 68 0, 0, 1, 69 0, 0, 0 70 ); 71 } 72 } 73 74 struct Matrix4x4F // : public D2D1_MATRIX_4X4_F 75 { 76 D2D1_MATRIX_4X4_F matrix; 77 alias matrix this; 78 79 nothrow this(D2D1_MATRIX_4X4_F m) { matrix = m; } 80 nothrow this( 81 FLOAT m11, FLOAT m12, FLOAT m13, FLOAT m14, 82 FLOAT m21, FLOAT m22, FLOAT m23, FLOAT m24, 83 FLOAT m31, FLOAT m32, FLOAT m33, FLOAT m34, 84 FLOAT m41, FLOAT m42, FLOAT m43, FLOAT m44 85 ) 86 { 87 _11 = m11; 88 _12 = m12; 89 _13 = m13; 90 _14 = m14; 91 92 _21 = m21; 93 _22 = m22; 94 _23 = m23; 95 _24 = m24; 96 97 _31 = m31; 98 _32 = m32; 99 _33 = m33; 100 _34 = m34; 101 102 _41 = m41; 103 _42 = m42; 104 _43 = m43; 105 _44 = m44; 106 } 107 108 // this() 109 /// Use this instead of default constructor 110 static nothrow @property Identity() 111 { 112 return Matrix4x4F( 113 1, 0, 0, 0, 114 0, 1, 0, 0, 115 0, 0, 1, 0, 116 0, 0, 0, 1 117 ); 118 } 119 120 bool opEquals( 121 const Matrix4x4F r 122 ) const 123 { 124 return _11 == r._11 && _12 == r._12 && _13 == r._13 && _14 == r._14 && 125 _21 == r._21 && _22 == r._22 && _23 == r._23 && _24 == r._24 && 126 _31 == r._31 && _32 == r._32 && _33 == r._33 && _34 == r._34 && 127 _41 == r._41 && _42 == r._42 && _43 == r._43 && _44 == r._44; 128 } 129 130 static 131 Matrix4x4F 132 Translation(FLOAT x, FLOAT y, FLOAT z) 133 { 134 Matrix4x4F translation; 135 136 translation._11 = 1.0; translation._12 = 0.0; translation._13 = 0.0; translation._14 = 0.0; 137 translation._21 = 0.0; translation._22 = 1.0; translation._23 = 0.0; translation._24 = 0.0; 138 translation._31 = 0.0; translation._32 = 0.0; translation._33 = 1.0; translation._34 = 0.0; 139 translation._41 = x; translation._42 = y; translation._43 = z; translation._44 = 1.0; 140 141 return translation; 142 } 143 144 static 145 Matrix4x4F 146 Scale(FLOAT x, FLOAT y, FLOAT z) 147 { 148 Matrix4x4F scale; 149 150 scale._11 = x; scale._12 = 0.0; scale._13 = 0.0; scale._14 = 0.0; 151 scale._21 = 0.0; scale._22 = y; scale._23 = 0.0; scale._24 = 0.0; 152 scale._31 = 0.0; scale._32 = 0.0; scale._33 = z; scale._34 = 0.0; 153 scale._41 = 0.0; scale._42 = 0.0; scale._43 = 0.0; scale._44 = 1.0; 154 155 return scale; 156 } 157 158 static 159 Matrix4x4F 160 RotationX(FLOAT degreeX) 161 { 162 FLOAT angleInRadian = degreeX * (3.141592654f / 180.0f); 163 164 FLOAT sinAngle = 0.0; 165 FLOAT cosAngle = 0.0; 166 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 167 168 return Matrix4x4F( 169 1, 0, 0, 0, 170 0, cosAngle, sinAngle, 0, 171 0, -sinAngle, cosAngle, 0, 172 0, 0, 0, 1 173 ); 174 } 175 176 static 177 Matrix4x4F 178 RotationY(FLOAT degreeY) 179 { 180 FLOAT angleInRadian = degreeY * (3.141592654f / 180.0f); 181 182 FLOAT sinAngle = 0.0; 183 FLOAT cosAngle = 0.0; 184 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 185 186 return Matrix4x4F( 187 cosAngle, 0, -sinAngle, 0, 188 0, 1, 0, 0, 189 sinAngle, 0, cosAngle, 0, 190 0, 0, 0, 1 191 ); 192 } 193 194 static 195 Matrix4x4F 196 RotationZ(FLOAT degreeZ) 197 { 198 FLOAT angleInRadian = degreeZ * (3.141592654f / 180.0f); 199 200 FLOAT sinAngle = 0.0; 201 FLOAT cosAngle = 0.0; 202 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 203 204 return Matrix4x4F( 205 cosAngle, sinAngle, 0, 0, 206 -sinAngle, cosAngle, 0, 0, 207 0, 0, 1, 0, 208 0, 0, 0, 1 209 ); 210 } 211 212 // 213 // 3D Rotation matrix for an arbitrary axis specified by x, y and z 214 // 215 static 216 Matrix4x4F 217 RotationArbitraryAxis(FLOAT x, FLOAT y, FLOAT z, FLOAT degree) 218 { 219 // Normalize the vector represented by x, y, and z 220 FLOAT magnitude = D2D1Vec3Length(x, y, z); 221 x /= magnitude; 222 y /= magnitude; 223 z /= magnitude; 224 225 FLOAT angleInRadian = degree * (3.141592654f / 180.0f); 226 227 FLOAT sinAngle = 0.0; 228 FLOAT cosAngle = 0.0; 229 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 230 231 FLOAT oneMinusCosAngle = 1 - cosAngle; 232 233 return Matrix4x4F( 234 1 + oneMinusCosAngle * (x * x - 1), 235 z * sinAngle + oneMinusCosAngle * x * y, 236 -y * sinAngle + oneMinusCosAngle * x * z, 237 0, 238 239 -z * sinAngle + oneMinusCosAngle * y * x, 240 1 + oneMinusCosAngle * (y * y - 1), 241 x * sinAngle + oneMinusCosAngle * y * z, 242 0, 243 244 y * sinAngle + oneMinusCosAngle * z * x, 245 -x * sinAngle + oneMinusCosAngle * z * y, 246 1 + oneMinusCosAngle * (z * z - 1) , 247 0, 248 249 0, 0, 0, 1 250 ); 251 } 252 253 static 254 Matrix4x4F 255 SkewX(FLOAT degreeX) 256 { 257 FLOAT angleInRadian = degreeX * (3.141592654f / 180.0f); 258 259 FLOAT tanAngle = D2D1Tan(angleInRadian); 260 261 return Matrix4x4F( 262 1, 0, 0, 0, 263 tanAngle, 1, 0, 0, 264 0, 0, 1, 0, 265 0, 0, 0, 1 266 ); 267 } 268 269 static 270 Matrix4x4F 271 SkewY(FLOAT degreeY) 272 { 273 FLOAT angleInRadian = degreeY * (3.141592654f / 180.0f); 274 275 FLOAT tanAngle = D2D1Tan(angleInRadian); 276 277 return Matrix4x4F( 278 1, tanAngle, 0, 0, 279 0, 1, 0, 0, 280 0, 0, 1, 0, 281 0, 0, 0, 1 282 ); 283 } 284 285 286 static 287 Matrix4x4F 288 PerspectiveProjection(FLOAT depth) 289 { 290 float proj = 0; 291 292 if (depth > 0) 293 { 294 proj = -1/depth; 295 } 296 297 return Matrix4x4F( 298 1, 0, 0, 0, 299 0, 1, 0, 0, 300 0, 0, 1, proj, 301 0, 0, 0, 1 302 ); 303 } 304 305 // 306 // Functions for convertion from the base D2D1_MATRIX_4X4_f to 307 // this type without making a copy 308 // 309 static 310 const(Matrix4x4F)* 311 ReinterpretBaseType(const(D2D1_MATRIX_4X4_F)* pMatrix) 312 { 313 return cast(const(Matrix4x4F)*)pMatrix; 314 } 315 316 static 317 nothrow 318 Matrix4x4F* 319 ReinterpretBaseType(D2D1_MATRIX_4X4_F *pMatrix) 320 { 321 return cast(Matrix4x4F*)(pMatrix); 322 } 323 324 nothrow 325 FLOAT 326 Determinant() const 327 { 328 FLOAT minor1 = _41 * (_12 * (_23 * _34 - _33 * _24) - _13 * (_22 * _34 - _24 * _32) + _14 * (_22 * _33 - _23 * _32)); 329 FLOAT minor2 = _42 * (_11 * (_21 * _34 - _31 * _24) - _13 * (_21 * _34 - _24 * _31) + _14 * (_21 * _33 - _23 * _31)); 330 FLOAT minor3 = _43 * (_11 * (_22 * _34 - _32 * _24) - _12 * (_21 * _34 - _24 * _31) + _14 * (_21 * _32 - _22 * _31)); 331 FLOAT minor4 = _44 * (_11 * (_22 * _33 - _32 * _23) - _12 * (_21 * _33 - _23 * _31) + _13 * (_21 * _32 - _22 * _31)); 332 333 return minor1 - minor2 + minor3 - minor4; 334 } 335 336 nothrow 337 bool 338 IsIdentity() const 339 { 340 return _11 == 1.0f && _12 == 0.0f && _13 == 0.0f && _14 == 0.0f 341 && _21 == 0.0f && _22 == 1.0f && _23 == 0.0f && _24 == 0.0f 342 && _31 == 0.0f && _32 == 0.0f && _33 == 1.0f && _34 == 0.0f 343 && _41 == 0.0f && _42 == 0.0f && _43 == 0.0f && _44 == 1.0f; 344 } 345 346 nothrow 347 void 348 SetProduct(const Matrix4x4F a, const Matrix4x4F b) 349 { 350 _11 = a._11 * b._11 + a._12 * b._21 + a._13 * b._31 + a._14 * b._41; 351 _12 = a._11 * b._12 + a._12 * b._22 + a._13 * b._32 + a._14 * b._42; 352 _13 = a._11 * b._13 + a._12 * b._23 + a._13 * b._33 + a._14 * b._43; 353 _14 = a._11 * b._14 + a._12 * b._24 + a._13 * b._34 + a._14 * b._44; 354 355 _21 = a._21 * b._11 + a._22 * b._21 + a._23 * b._31 + a._24 * b._41; 356 _22 = a._21 * b._12 + a._22 * b._22 + a._23 * b._32 + a._24 * b._42; 357 _23 = a._21 * b._13 + a._22 * b._23 + a._23 * b._33 + a._24 * b._43; 358 _24 = a._21 * b._14 + a._22 * b._24 + a._23 * b._34 + a._24 * b._44; 359 360 _31 = a._31 * b._11 + a._32 * b._21 + a._33 * b._31 + a._34 * b._41; 361 _32 = a._31 * b._12 + a._32 * b._22 + a._33 * b._32 + a._34 * b._42; 362 _33 = a._31 * b._13 + a._32 * b._23 + a._33 * b._33 + a._34 * b._43; 363 _34 = a._31 * b._14 + a._32 * b._24 + a._33 * b._34 + a._34 * b._44; 364 365 _41 = a._41 * b._11 + a._42 * b._21 + a._43 * b._31 + a._44 * b._41; 366 _42 = a._41 * b._12 + a._42 * b._22 + a._43 * b._32 + a._44 * b._42; 367 _43 = a._41 * b._13 + a._42 * b._23 + a._43 * b._33 + a._44 * b._43; 368 _44 = a._41 * b._14 + a._42 * b._24 + a._43 * b._34 + a._44 * b._44; 369 } 370 371 nothrow 372 Matrix4x4F 373 opBinary(string op)(const Matrix4x4F matrix) const if(op == "*") 374 { 375 Matrix4x4F result; 376 377 result.SetProduct(*this, matrix); 378 379 return result; 380 } 381 } 382 383 384 struct Matrix5x4F // : D2D1_MATRIX_5X4_F 385 { 386 D2D1_MATRIX_5X4_F matrix; 387 alias matrix this; 388 389 nothrow this(D2D1_MATRIX_5X4_F m) { matrix = m; } 390 nothrow this( 391 FLOAT m11, FLOAT m12, FLOAT m13, FLOAT m14, 392 FLOAT m21, FLOAT m22, FLOAT m23, FLOAT m24, 393 FLOAT m31, FLOAT m32, FLOAT m33, FLOAT m34, 394 FLOAT m41, FLOAT m42, FLOAT m43, FLOAT m44, 395 FLOAT m51, FLOAT m52, FLOAT m53, FLOAT m54 396 ) 397 { 398 _11 = m11; 399 _12 = m12; 400 _13 = m13; 401 _14 = m14; 402 403 _21 = m21; 404 _22 = m22; 405 _23 = m23; 406 _24 = m24; 407 408 _31 = m31; 409 _32 = m32; 410 _33 = m33; 411 _34 = m34; 412 413 _41 = m41; 414 _42 = m42; 415 _43 = m43; 416 _44 = m44; 417 418 _51 = m51; 419 _52 = m52; 420 _53 = m53; 421 _54 = m54; 422 } 423 424 // this() 425 /// Use this instead of default constructor 426 static nothrow @property Identity() 427 { 428 return Matrix5x4F( 429 1, 0, 0, 0, 430 0, 1, 0, 0, 431 0, 0, 1, 0, 432 0, 0, 0, 1, 433 0, 0, 0, 0 434 ); 435 } 436 } 437 438 D2D1_COLOR_F 439 ConvertColorSpace( 440 D2D1_COLOR_SPACE sourceColorSpace, 441 D2D1_COLOR_SPACE destinationColorSpace, 442 const D2D1_COLOR_F color 443 ) 444 { 445 return D2D1ConvertColorSpace( 446 sourceColorSpace, 447 destinationColorSpace, 448 &color 449 ); 450 } 451 452 D2D1_DRAWING_STATE_DESCRIPTION1 453 DrawingStateDescription1( 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 const D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix(), 459 D2D1_PRIMITIVE_BLEND primitiveBlend = D2D1_PRIMITIVE_BLEND_SOURCE_OVER, 460 D2D1_UNIT_MODE unitMode = D2D1_UNIT_MODE_DIPS 461 ) 462 { 463 D2D1_DRAWING_STATE_DESCRIPTION1 drawingStateDescription1; 464 465 drawingStateDescription1.antialiasMode = antialiasMode; 466 drawingStateDescription1.textAntialiasMode = textAntialiasMode; 467 drawingStateDescription1.tag1 = tag1; 468 drawingStateDescription1.tag2 = tag2; 469 drawingStateDescription1.transform = transform; 470 drawingStateDescription1.primitiveBlend = primitiveBlend; 471 drawingStateDescription1.unitMode = unitMode; 472 473 return drawingStateDescription1; 474 } 475 476 D2D1_DRAWING_STATE_DESCRIPTION1 477 DrawingStateDescription1( 478 const D2D1_DRAWING_STATE_DESCRIPTION desc, 479 D2D1_PRIMITIVE_BLEND primitiveBlend = D2D1_PRIMITIVE_BLEND_SOURCE_OVER, 480 D2D1_UNIT_MODE unitMode = D2D1_UNIT_MODE_DIPS 481 ) 482 { 483 D2D1_DRAWING_STATE_DESCRIPTION1 drawingStateDescription1; 484 485 drawingStateDescription1.antialiasMode = desc.antialiasMode; 486 drawingStateDescription1.textAntialiasMode = desc.textAntialiasMode; 487 drawingStateDescription1.tag1 = desc.tag1; 488 drawingStateDescription1.tag2 = desc.tag2; 489 drawingStateDescription1.transform = desc.transform; 490 drawingStateDescription1.primitiveBlend = primitiveBlend; 491 drawingStateDescription1.unitMode = unitMode; 492 493 return drawingStateDescription1; 494 } 495 496 D2D1_BITMAP_PROPERTIES1 497 BitmapProperties1( 498 D2D1_BITMAP_OPTIONS bitmapOptions = D2D1_BITMAP_OPTIONS_NONE, 499 const D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 500 FLOAT dpiX = 96.0f, 501 FLOAT dpiY = 96.0f, 502 ID2D1ColorContext colorContext = null 503 ) 504 { 505 D2D1_BITMAP_PROPERTIES1 bitmapProperties = 506 { 507 pixelFormat, 508 dpiX, dpiY, 509 bitmapOptions, 510 colorContext 511 }; 512 513 return bitmapProperties; 514 } 515 516 D2D1_LAYER_PARAMETERS1 517 LayerParameters1( 518 const D2D1_RECT_F contentBounds = D2D1.InfiniteRect(), 519 ID2D1Geometry geometricMask = NULL, 520 D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 521 D2D1_MATRIX_3X2_F maskTransform = D2D1.IdentityMatrix(), 522 FLOAT opacity = 1.0, 523 ID2D1Brush opacityBrush = NULL, 524 D2D1_LAYER_OPTIONS1 layerOptions = D2D1_LAYER_OPTIONS1_NONE 525 ) 526 { 527 D2D1_LAYER_PARAMETERS1 layerParameters; 528 529 layerParameters.contentBounds = contentBounds; 530 layerParameters.geometricMask = geometricMask; 531 layerParameters.maskAntialiasMode = maskAntialiasMode; 532 layerParameters.maskTransform = maskTransform; 533 layerParameters.opacity = opacity; 534 layerParameters.opacityBrush = opacityBrush; 535 layerParameters.layerOptions = layerOptions; 536 537 return layerParameters; 538 } 539 540 D2D1_STROKE_STYLE_PROPERTIES1 541 StrokeStyleProperties1( 542 D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT, 543 D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT, 544 D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT, 545 D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER, 546 FLOAT miterLimit = 10.0f, 547 D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID, 548 FLOAT dashOffset = 0.0f, 549 D2D1_STROKE_TRANSFORM_TYPE transformType = D2D1_STROKE_TRANSFORM_TYPE_NORMAL 550 ) 551 { 552 D2D1_STROKE_STYLE_PROPERTIES1 strokeStyleProperties; 553 554 strokeStyleProperties.startCap = startCap; 555 strokeStyleProperties.endCap = endCap; 556 strokeStyleProperties.dashCap = dashCap; 557 strokeStyleProperties.lineJoin = lineJoin; 558 strokeStyleProperties.miterLimit = miterLimit; 559 strokeStyleProperties.dashStyle = dashStyle; 560 strokeStyleProperties.dashOffset = dashOffset; 561 strokeStyleProperties.transformType = transformType; 562 563 return strokeStyleProperties; 564 } 565 566 D2D1_IMAGE_BRUSH_PROPERTIES 567 ImageBrushProperties( 568 D2D1_RECT_F sourceRectangle, 569 D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, 570 D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, 571 D2D1_INTERPOLATION_MODE interpolationMode = D2D1_INTERPOLATION_MODE_LINEAR 572 ) 573 { 574 D2D1_IMAGE_BRUSH_PROPERTIES imageBrushProperties; 575 576 imageBrushProperties.extendModeX = extendModeX; 577 imageBrushProperties.extendModeY = extendModeY; 578 imageBrushProperties.interpolationMode = interpolationMode; 579 imageBrushProperties.sourceRectangle = sourceRectangle; 580 581 return imageBrushProperties; 582 } 583 584 D2D1_BITMAP_BRUSH_PROPERTIES1 585 BitmapBrushProperties1( 586 D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, 587 D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, 588 D2D1_INTERPOLATION_MODE interpolationMode = D2D1_INTERPOLATION_MODE_LINEAR 589 ) 590 { 591 D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrush1Properties; 592 593 bitmapBrush1Properties.extendModeX = extendModeX; 594 bitmapBrush1Properties.extendModeY = extendModeY; 595 bitmapBrush1Properties.interpolationMode = interpolationMode; 596 597 return bitmapBrush1Properties; 598 } 599 600 D2D1_PRINT_CONTROL_PROPERTIES 601 PrintControlProperties( 602 D2D1_PRINT_FONT_SUBSET_MODE fontSubsetMode = D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT, 603 FLOAT rasterDpi = 150.0f, 604 D2D1_COLOR_SPACE colorSpace = D2D1_COLOR_SPACE_SRGB 605 ) 606 { 607 D2D1_PRINT_CONTROL_PROPERTIES printControlProps; 608 609 printControlProps.fontSubset = fontSubsetMode; 610 printControlProps.rasterDPI = rasterDpi; 611 printControlProps.colorSpace = colorSpace; 612 613 return printControlProps; 614 } 615 616 D2D1_RENDERING_CONTROLS 617 RenderingControls( 618 D2D1_BUFFER_PRECISION bufferPrecision, 619 D2D1_SIZE_U tileSize 620 ) 621 { 622 D2D1_RENDERING_CONTROLS renderingControls; 623 624 renderingControls.bufferPrecision = bufferPrecision; 625 renderingControls.tileSize = tileSize; 626 627 return renderingControls; 628 } 629 630 D2D1_EFFECT_INPUT_DESCRIPTION 631 EffectInputDescription( 632 ID2D1Effect effect, 633 UINT32 inputIndex, 634 D2D1_RECT_F inputRectangle 635 ) 636 { 637 D2D1_EFFECT_INPUT_DESCRIPTION description; 638 639 description.effect = effect; 640 description.inputIndex = inputIndex; 641 description.inputRectangle = inputRectangle; 642 643 return description; 644 } 645 646 D2D1_CREATION_PROPERTIES 647 CreationProperties( 648 D2D1_THREADING_MODE threadingMode, 649 D2D1_DEBUG_LEVEL debugLevel, 650 D2D1_DEVICE_CONTEXT_OPTIONS options 651 ) 652 { 653 D2D1_CREATION_PROPERTIES creationProperties; 654 655 creationProperties.threadingMode = threadingMode; 656 creationProperties.debugLevel = debugLevel; 657 creationProperties.options = options; 658 659 return creationProperties; 660 } 661 662 D2D1_VECTOR_2F 663 Vector2F( 664 FLOAT x = 0.0f, 665 FLOAT y = 0.0f 666 ) 667 { 668 D2D1_VECTOR_2F vec2 = {x, y}; 669 return vec2; 670 } 671 672 D2D1_VECTOR_3F 673 Vector3F( 674 FLOAT x = 0.0f, 675 FLOAT y = 0.0f, 676 FLOAT z = 0.0f 677 ) 678 { 679 D2D1_VECTOR_3F vec3 = {x, y, z}; 680 return vec3; 681 } 682 683 D2D1_VECTOR_4F 684 Vector4F( 685 FLOAT x = 0.0f, 686 FLOAT y = 0.0f, 687 FLOAT z = 0.0f, 688 FLOAT w = 0.0f 689 ) 690 { 691 D2D1_VECTOR_4F vec4 = {x, y, z, w}; 692 return vec4; 693 } 694 695 D2D1_POINT_2L 696 Point2L( 697 INT32 x = 0, 698 INT32 y = 0 699 ) 700 { 701 return D2D1_POINT_2L(x, y); 702 } 703 704 D2D1_RECT_L 705 RectL( 706 INT32 left = 0, 707 INT32 top = 0, 708 INT32 right = 0, 709 INT32 bottom = 0 710 ) 711 { 712 return D2D1_RECT_L(left, top, right, bottom); 713 } 714 715 /// 716 /// Sets a bitmap as an effect input, while inserting a DPI compensation effect 717 /// to preserve visual appearance as the device context's DPI changes. 718 /// 719 HRESULT 720 SetDpiCompensatedEffectInput( 721 ID2D1DeviceContext deviceContext, 722 ID2D1Effect effect, 723 UINT32 inputIndex, 724 ID2D1Bitmap inputBitmap, 725 D2D1_INTERPOLATION_MODE interpolationMode = D2D1_INTERPOLATION_MODE_LINEAR, 726 D2D1_BORDER_MODE borderMode = D2D1_BORDER_MODE_HARD 727 ) 728 { 729 HRESULT hr = S_OK; 730 ID2D1Effect dpiCompensationEffect = null; 731 732 if (inputBitmap is null) 733 { 734 effect.SetInput(inputIndex, null); 735 return hr; 736 } 737 738 hr = deviceContext.CreateEffect(&CLSID_D2D1DpiCompensation, &dpiCompensationEffect); 739 740 if (SUCCEEDED(hr)) 741 { 742 if (SUCCEEDED(hr)) 743 { 744 dpiCompensationEffect.SetInput(0, inputBitmap); 745 746 D2D1_POINT_2F bitmapDpi; 747 inputBitmap.GetDpi(bitmapDpi.x, bitmapDpi.y); 748 hr = dpiCompensationEffect.SetValue(D2D1_DPICOMPENSATION_PROP_INPUT_DPI, bitmapDpi); 749 } 750 751 if (SUCCEEDED(hr)) 752 { 753 hr = dpiCompensationEffect.SetValue(D2D1_DPICOMPENSATION_PROP_INTERPOLATION_MODE, interpolationMode); 754 } 755 756 if (SUCCEEDED(hr)) 757 { 758 hr = dpiCompensationEffect.SetValue(D2D1_DPICOMPENSATION_PROP_BORDER_MODE, borderMode); 759 } 760 761 if (SUCCEEDED(hr)) 762 { 763 effect.SetInputEffect(inputIndex, dpiCompensationEffect); 764 } 765 766 if (dpiCompensationEffect !is null) 767 { 768 dpiCompensationEffect.Release(); 769 } 770 } 771 772 return hr; 773 }