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