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