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 */