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