RetroArch/gfx/include/dxsdk/d2d1helper.h

1032 lines
26 KiB
C++

/*=========================================================================*\
Copyright (c) Microsoft Corporation. All rights reserved.
File: D2D1helper.h
Module Name: D2D
Description: Helper files over the D2D interfaces and APIs.
\*=========================================================================*/
#pragma once
#ifndef _D2D1_HELPER_H_
#define _D2D1_HELPER_H_
#ifndef _D2D1_H_
#include <d2d1.h>
#endif // #ifndef _D2D1_H_
#ifndef D2D_USE_C_DEFINITIONS
namespace D2D1
{
//
// Forward declared IdentityMatrix function to allow matrix class to use
// these constructors.
//
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_MATRIX_3X2_F
IdentityMatrix();
//
// The default trait type for objects in D2D is float.
//
template<typename Type>
struct TypeTraits
{
typedef D2D1_POINT_2F Point;
typedef D2D1_SIZE_F Size;
typedef D2D1_RECT_F Rect;
};
template<>
struct TypeTraits<UINT32>
{
typedef D2D1_POINT_2U Point;
typedef D2D1_SIZE_U Size;
typedef D2D1_RECT_U Rect;
};
static
COM_DECLSPEC_NOTHROW
inline
FLOAT FloatMax()
{
#ifdef FLT_MAX
return FLT_MAX;
#else
return 3.402823466e+38F;
#endif
}
//
// Construction helpers
//
template<typename Type>
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
typename TypeTraits<Type>::Point
Point2(
Type x,
Type y
)
{
typename TypeTraits<Type>::Point point = { x, y };
return point;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_POINT_2F
Point2F(
FLOAT x = 0.f,
FLOAT y = 0.f
)
{
return Point2<FLOAT>(x, y);
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_POINT_2U
Point2U(
UINT32 x = 0,
UINT32 y = 0
)
{
return Point2<UINT32>(x, y);
}
template<typename Type>
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
typename TypeTraits<Type>::Size
Size(
Type width,
Type height
)
{
typename TypeTraits<Type>::Size size = { width, height };
return size;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_SIZE_F
SizeF(
FLOAT width = 0.f,
FLOAT height = 0.f
)
{
return Size<FLOAT>(width, height);
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_SIZE_U
SizeU(
UINT32 width = 0,
UINT32 height = 0
)
{
return Size<UINT32>(width, height);
}
template<typename Type>
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
typename TypeTraits<Type>::Rect
Rect(
Type left,
Type top,
Type right,
Type bottom
)
{
typename TypeTraits<Type>::Rect rect = { left, top, right, bottom };
return rect;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_RECT_F
RectF(
FLOAT left = 0.f,
FLOAT top = 0.f,
FLOAT right = 0.f,
FLOAT bottom = 0.f
)
{
return Rect<FLOAT>(left, top, right, bottom);
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_RECT_U
RectU(
UINT32 left = 0,
UINT32 top = 0,
UINT32 right = 0,
UINT32 bottom = 0
)
{
return Rect<UINT32>(left, top, right, bottom);
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_RECT_F
InfiniteRect()
{
D2D1_RECT_F rect = { -FloatMax(), -FloatMax(), FloatMax(), FloatMax() };
return rect;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_ARC_SEGMENT
ArcSegment(
_In_ CONST D2D1_POINT_2F &point,
_In_ CONST D2D1_SIZE_F &size,
_In_ FLOAT rotationAngle,
_In_ D2D1_SWEEP_DIRECTION sweepDirection,
_In_ D2D1_ARC_SIZE arcSize
)
{
D2D1_ARC_SEGMENT arcSegment = { point, size, rotationAngle, sweepDirection, arcSize };
return arcSegment;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_BEZIER_SEGMENT
BezierSegment(
_In_ CONST D2D1_POINT_2F &point1,
_In_ CONST D2D1_POINT_2F &point2,
_In_ CONST D2D1_POINT_2F &point3
)
{
D2D1_BEZIER_SEGMENT bezierSegment = { point1, point2, point3 };
return bezierSegment;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_ELLIPSE
Ellipse(
_In_ CONST D2D1_POINT_2F &center,
FLOAT radiusX,
FLOAT radiusY
)
{
D2D1_ELLIPSE ellipse;
ellipse.point = center;
ellipse.radiusX = radiusX;
ellipse.radiusY = radiusY;
return ellipse;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_ROUNDED_RECT
RoundedRect(
_In_ CONST D2D1_RECT_F &rect,
FLOAT radiusX,
FLOAT radiusY
)
{
D2D1_ROUNDED_RECT roundedRect;
roundedRect.rect = rect;
roundedRect.radiusX = radiusX;
roundedRect.radiusY = radiusY;
return roundedRect;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_BRUSH_PROPERTIES
BrushProperties(
_In_ FLOAT opacity = 1.0,
_In_ CONST D2D1_MATRIX_3X2_F &transform = D2D1::IdentityMatrix()
)
{
D2D1_BRUSH_PROPERTIES brushProperties;
brushProperties.opacity = opacity;
brushProperties.transform = transform;
return brushProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_GRADIENT_STOP
GradientStop(
FLOAT position,
_In_ CONST D2D1_COLOR_F &color
)
{
D2D1_GRADIENT_STOP gradientStop = { position, color };
return gradientStop;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_QUADRATIC_BEZIER_SEGMENT
QuadraticBezierSegment(
_In_ CONST D2D1_POINT_2F &point1,
_In_ CONST D2D1_POINT_2F &point2
)
{
D2D1_QUADRATIC_BEZIER_SEGMENT quadraticBezier = { point1, point2 };
return quadraticBezier;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_STROKE_STYLE_PROPERTIES
StrokeStyleProperties(
D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT,
D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT,
D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT,
D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER,
FLOAT miterLimit = 10.0f,
D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID,
FLOAT dashOffset = 0.0f
)
{
D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties;
strokeStyleProperties.startCap = startCap;
strokeStyleProperties.endCap = endCap;
strokeStyleProperties.dashCap = dashCap;
strokeStyleProperties.lineJoin = lineJoin;
strokeStyleProperties.miterLimit = miterLimit;
strokeStyleProperties.dashStyle = dashStyle;
strokeStyleProperties.dashOffset = dashOffset;
return strokeStyleProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_BITMAP_BRUSH_PROPERTIES
BitmapBrushProperties(
D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP,
D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP,
D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
)
{
D2D1_BITMAP_BRUSH_PROPERTIES bitmapBrushProperties;
bitmapBrushProperties.extendModeX = extendModeX;
bitmapBrushProperties.extendModeY = extendModeY;
bitmapBrushProperties.interpolationMode = interpolationMode;
return bitmapBrushProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES
LinearGradientBrushProperties(
_In_ CONST D2D1_POINT_2F &startPoint,
_In_ CONST D2D1_POINT_2F &endPoint
)
{
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties;
linearGradientBrushProperties.startPoint = startPoint;
linearGradientBrushProperties.endPoint = endPoint;
return linearGradientBrushProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES
RadialGradientBrushProperties(
_In_ CONST D2D1_POINT_2F &center,
_In_ CONST D2D1_POINT_2F &gradientOriginOffset,
FLOAT radiusX,
FLOAT radiusY
)
{
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties;
radialGradientBrushProperties.center = center;
radialGradientBrushProperties.gradientOriginOffset = gradientOriginOffset;
radialGradientBrushProperties.radiusX = radiusX;
radialGradientBrushProperties.radiusY = radiusY;
return radialGradientBrushProperties;
}
//
// PixelFormat
//
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_PIXEL_FORMAT
PixelFormat(
_In_ DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN,
_In_ D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_UNKNOWN
)
{
D2D1_PIXEL_FORMAT pixelFormat;
pixelFormat.format = dxgiFormat;
pixelFormat.alphaMode = alphaMode;
return pixelFormat;
}
//
// Bitmaps
//
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_BITMAP_PROPERTIES
BitmapProperties(
CONST D2D1_PIXEL_FORMAT &pixelFormat = D2D1::PixelFormat(),
FLOAT dpiX = 96.0f,
FLOAT dpiY = 96.0f
)
{
D2D1_BITMAP_PROPERTIES bitmapProperties;
bitmapProperties.pixelFormat = pixelFormat;
bitmapProperties.dpiX = dpiX;
bitmapProperties.dpiY = dpiY;
return bitmapProperties;
}
//
// Render Targets
//
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_RENDER_TARGET_PROPERTIES
RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE type = D2D1_RENDER_TARGET_TYPE_DEFAULT,
_In_ CONST D2D1_PIXEL_FORMAT &pixelFormat = D2D1::PixelFormat(),
FLOAT dpiX = 0.0,
FLOAT dpiY = 0.0,
D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL minLevel = D2D1_FEATURE_LEVEL_DEFAULT
)
{
D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties;
renderTargetProperties.type = type;
renderTargetProperties.pixelFormat = pixelFormat;
renderTargetProperties.dpiX = dpiX;
renderTargetProperties.dpiY = dpiY;
renderTargetProperties.usage = usage;
renderTargetProperties.minLevel = minLevel;
return renderTargetProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_HWND_RENDER_TARGET_PROPERTIES
HwndRenderTargetProperties(
_In_ HWND hwnd,
_In_ D2D1_SIZE_U pixelSize = D2D1::Size(static_cast<UINT32>(0), static_cast<UINT32>(0)),
_In_ D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE
)
{
D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderTargetProperties;
hwndRenderTargetProperties.hwnd = hwnd;
hwndRenderTargetProperties.pixelSize = pixelSize;
hwndRenderTargetProperties.presentOptions = presentOptions;
return hwndRenderTargetProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_LAYER_PARAMETERS
LayerParameters(
_In_ CONST D2D1_RECT_F &contentBounds = D2D1::InfiniteRect(),
_In_opt_ ID2D1Geometry *geometricMask = NULL,
D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
D2D1_MATRIX_3X2_F maskTransform = D2D1::IdentityMatrix(),
FLOAT opacity = 1.0,
_In_opt_ ID2D1Brush *opacityBrush = NULL,
D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE
)
{
D2D1_LAYER_PARAMETERS layerParameters = { 0 };
layerParameters.contentBounds = contentBounds;
layerParameters.geometricMask = geometricMask;
layerParameters.maskAntialiasMode = maskAntialiasMode;
layerParameters.maskTransform = maskTransform;
layerParameters.opacity = opacity;
layerParameters.opacityBrush = opacityBrush;
layerParameters.layerOptions = layerOptions;
return layerParameters;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_DRAWING_STATE_DESCRIPTION
DrawingStateDescription(
D2D1_ANTIALIAS_MODE antialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
D2D1_TAG tag1 = 0,
D2D1_TAG tag2 = 0,
_In_ const D2D1_MATRIX_3X2_F &transform = D2D1::IdentityMatrix()
)
{
D2D1_DRAWING_STATE_DESCRIPTION drawingStateDescription;
drawingStateDescription.antialiasMode = antialiasMode;
drawingStateDescription.textAntialiasMode = textAntialiasMode;
drawingStateDescription.tag1 = tag1;
drawingStateDescription.tag2 = tag2;
drawingStateDescription.transform = transform;
return drawingStateDescription;
}
//
// Colors, this enum defines a set of predefined colors.
//
class ColorF : public D2D1_COLOR_F
{
public:
enum Enum
{
AliceBlue = 0xF0F8FF,
AntiqueWhite = 0xFAEBD7,
Aqua = 0x00FFFF,
Aquamarine = 0x7FFFD4,
Azure = 0xF0FFFF,
Beige = 0xF5F5DC,
Bisque = 0xFFE4C4,
Black = 0x000000,
BlanchedAlmond = 0xFFEBCD,
Blue = 0x0000FF,
BlueViolet = 0x8A2BE2,
Brown = 0xA52A2A,
BurlyWood = 0xDEB887,
CadetBlue = 0x5F9EA0,
Chartreuse = 0x7FFF00,
Chocolate = 0xD2691E,
Coral = 0xFF7F50,
CornflowerBlue = 0x6495ED,
Cornsilk = 0xFFF8DC,
Crimson = 0xDC143C,
Cyan = 0x00FFFF,
DarkBlue = 0x00008B,
DarkCyan = 0x008B8B,
DarkGoldenrod = 0xB8860B,
DarkGray = 0xA9A9A9,
DarkGreen = 0x006400,
DarkKhaki = 0xBDB76B,
DarkMagenta = 0x8B008B,
DarkOliveGreen = 0x556B2F,
DarkOrange = 0xFF8C00,
DarkOrchid = 0x9932CC,
DarkRed = 0x8B0000,
DarkSalmon = 0xE9967A,
DarkSeaGreen = 0x8FBC8F,
DarkSlateBlue = 0x483D8B,
DarkSlateGray = 0x2F4F4F,
DarkTurquoise = 0x00CED1,
DarkViolet = 0x9400D3,
DeepPink = 0xFF1493,
DeepSkyBlue = 0x00BFFF,
DimGray = 0x696969,
DodgerBlue = 0x1E90FF,
Firebrick = 0xB22222,
FloralWhite = 0xFFFAF0,
ForestGreen = 0x228B22,
Fuchsia = 0xFF00FF,
Gainsboro = 0xDCDCDC,
GhostWhite = 0xF8F8FF,
Gold = 0xFFD700,
Goldenrod = 0xDAA520,
Gray = 0x808080,
Green = 0x008000,
GreenYellow = 0xADFF2F,
Honeydew = 0xF0FFF0,
HotPink = 0xFF69B4,
IndianRed = 0xCD5C5C,
Indigo = 0x4B0082,
Ivory = 0xFFFFF0,
Khaki = 0xF0E68C,
Lavender = 0xE6E6FA,
LavenderBlush = 0xFFF0F5,
LawnGreen = 0x7CFC00,
LemonChiffon = 0xFFFACD,
LightBlue = 0xADD8E6,
LightCoral = 0xF08080,
LightCyan = 0xE0FFFF,
LightGoldenrodYellow = 0xFAFAD2,
LightGreen = 0x90EE90,
LightGray = 0xD3D3D3,
LightPink = 0xFFB6C1,
LightSalmon = 0xFFA07A,
LightSeaGreen = 0x20B2AA,
LightSkyBlue = 0x87CEFA,
LightSlateGray = 0x778899,
LightSteelBlue = 0xB0C4DE,
LightYellow = 0xFFFFE0,
Lime = 0x00FF00,
LimeGreen = 0x32CD32,
Linen = 0xFAF0E6,
Magenta = 0xFF00FF,
Maroon = 0x800000,
MediumAquamarine = 0x66CDAA,
MediumBlue = 0x0000CD,
MediumOrchid = 0xBA55D3,
MediumPurple = 0x9370DB,
MediumSeaGreen = 0x3CB371,
MediumSlateBlue = 0x7B68EE,
MediumSpringGreen = 0x00FA9A,
MediumTurquoise = 0x48D1CC,
MediumVioletRed = 0xC71585,
MidnightBlue = 0x191970,
MintCream = 0xF5FFFA,
MistyRose = 0xFFE4E1,
Moccasin = 0xFFE4B5,
NavajoWhite = 0xFFDEAD,
Navy = 0x000080,
OldLace = 0xFDF5E6,
Olive = 0x808000,
OliveDrab = 0x6B8E23,
Orange = 0xFFA500,
OrangeRed = 0xFF4500,
Orchid = 0xDA70D6,
PaleGoldenrod = 0xEEE8AA,
PaleGreen = 0x98FB98,
PaleTurquoise = 0xAFEEEE,
PaleVioletRed = 0xDB7093,
PapayaWhip = 0xFFEFD5,
PeachPuff = 0xFFDAB9,
Peru = 0xCD853F,
Pink = 0xFFC0CB,
Plum = 0xDDA0DD,
PowderBlue = 0xB0E0E6,
Purple = 0x800080,
Red = 0xFF0000,
RosyBrown = 0xBC8F8F,
RoyalBlue = 0x4169E1,
SaddleBrown = 0x8B4513,
Salmon = 0xFA8072,
SandyBrown = 0xF4A460,
SeaGreen = 0x2E8B57,
SeaShell = 0xFFF5EE,
Sienna = 0xA0522D,
Silver = 0xC0C0C0,
SkyBlue = 0x87CEEB,
SlateBlue = 0x6A5ACD,
SlateGray = 0x708090,
Snow = 0xFFFAFA,
SpringGreen = 0x00FF7F,
SteelBlue = 0x4682B4,
Tan = 0xD2B48C,
Teal = 0x008080,
Thistle = 0xD8BFD8,
Tomato = 0xFF6347,
Turquoise = 0x40E0D0,
Violet = 0xEE82EE,
Wheat = 0xF5DEB3,
White = 0xFFFFFF,
WhiteSmoke = 0xF5F5F5,
Yellow = 0xFFFF00,
YellowGreen = 0x9ACD32,
};
//
// Construct a color, note that the alpha value from the "rgb" component
// is never used.
//
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
ColorF(
UINT32 rgb,
FLOAT a = 1.0
)
{
Init(rgb, a);
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
ColorF(
Enum knownColor,
FLOAT a = 1.0
)
{
Init(knownColor, a);
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
ColorF(
FLOAT red,
FLOAT green,
FLOAT blue,
FLOAT alpha = 1.0
)
{
r = red;
g = green;
b = blue;
a = alpha;
}
private:
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
void
Init(
UINT32 rgb,
FLOAT alpha
)
{
r = static_cast<FLOAT>((rgb & sc_redMask) >> sc_redShift) / 255.f;
g = static_cast<FLOAT>((rgb & sc_greenMask) >> sc_greenShift) / 255.f;
b = static_cast<FLOAT>((rgb & sc_blueMask) >> sc_blueShift) / 255.f;
a = alpha;
}
static const UINT32 sc_redShift = 16;
static const UINT32 sc_greenShift = 8;
static const UINT32 sc_blueShift = 0;
static const UINT32 sc_redMask = 0xff << sc_redShift;
static const UINT32 sc_greenMask = 0xff << sc_greenShift;
static const UINT32 sc_blueMask = 0xff << sc_blueShift;
};
class Matrix3x2F : public D2D1_MATRIX_3X2_F
{
public:
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F(
FLOAT m11,
FLOAT m12,
FLOAT m21,
FLOAT m22,
FLOAT m31,
FLOAT m32
)
{
_11 = m11;
_12 = m12;
_21 = m21;
_22 = m22;
_31 = m31;
_32 = m32;
}
//
// Creates an uninitialized matrix
//
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F(
)
{
}
//
// Named quasi-constructors
//
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Identity()
{
Matrix3x2F identity;
identity._11 = 1.f;
identity._12 = 0.f;
identity._21 = 0.f;
identity._22 = 1.f;
identity._31 = 0.f;
identity._32 = 0.f;
return identity;
}
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Translation(
D2D1_SIZE_F size
)
{
Matrix3x2F translation;
translation._11 = 1.0; translation._12 = 0.0;
translation._21 = 0.0; translation._22 = 1.0;
translation._31 = size.width; translation._32 = size.height;
return translation;
}
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Translation(
FLOAT x,
FLOAT y
)
{
return Translation(SizeF(x, y));
}
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Scale(
D2D1_SIZE_F size,
D2D1_POINT_2F center = D2D1::Point2F()
)
{
Matrix3x2F scale;
scale._11 = size.width; scale._12 = 0.0;
scale._21 = 0.0; scale._22 = size.height;
scale._31 = center.x - size.width * center.x;
scale._32 = center.y - size.height * center.y;
return scale;
}
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Scale(
FLOAT x,
FLOAT y,
D2D1_POINT_2F center = D2D1::Point2F()
)
{
return Scale(SizeF(x, y), center);
}
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Rotation(
FLOAT angle,
D2D1_POINT_2F center = D2D1::Point2F()
)
{
Matrix3x2F rotation;
D2D1MakeRotateMatrix(angle, center, &rotation);
return rotation;
}
static
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
Skew(
FLOAT angleX,
FLOAT angleY,
D2D1_POINT_2F center = D2D1::Point2F()
)
{
Matrix3x2F skew;
D2D1MakeSkewMatrix(angleX, angleY, center, &skew);
return skew;
}
//
// Functions for convertion from the base D2D1_MATRIX_3X2_F to this type
// without making a copy
//
static
COM_DECLSPEC_NOTHROW
inline
const Matrix3x2F*
ReinterpretBaseType(const D2D1_MATRIX_3X2_F *pMatrix)
{
return static_cast<const Matrix3x2F *>(pMatrix);
}
static
COM_DECLSPEC_NOTHROW
inline
Matrix3x2F*
ReinterpretBaseType(D2D1_MATRIX_3X2_F *pMatrix)
{
return static_cast<Matrix3x2F *>(pMatrix);
}
COM_DECLSPEC_NOTHROW
inline
FLOAT
Determinant() const
{
return (_11 * _22) - (_12 * _21);
}
COM_DECLSPEC_NOTHROW
inline
bool
IsInvertible() const
{
return !!D2D1IsMatrixInvertible(this);
}
COM_DECLSPEC_NOTHROW
inline
bool
Invert()
{
return !!D2D1InvertMatrix(this);
}
COM_DECLSPEC_NOTHROW
inline
bool
IsIdentity() const
{
return _11 == 1.f && _12 == 0.f
&& _21 == 0.f && _22 == 1.f
&& _31 == 0.f && _32 == 0.f;
}
COM_DECLSPEC_NOTHROW
inline
void SetProduct(
const Matrix3x2F &a,
const Matrix3x2F &b
)
{
_11 = a._11 * b._11 + a._12 * b._21;
_12 = a._11 * b._12 + a._12 * b._22;
_21 = a._21 * b._11 + a._22 * b._21;
_22 = a._21 * b._12 + a._22 * b._22;
_31 = a._31 * b._11 + a._32 * b._21 + b._31;
_32 = a._31 * b._12 + a._32 * b._22 + b._32;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
Matrix3x2F
operator*(
const Matrix3x2F &matrix
) const
{
Matrix3x2F result;
result.SetProduct(*this, matrix);
return result;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_POINT_2F
TransformPoint(
D2D1_POINT_2F point
) const
{
D2D1_POINT_2F result =
{
point.x * _11 + point.y * _21 + _31,
point.x * _12 + point.y * _22 + _32
};
return result;
}
};
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_POINT_2F
operator*(
const D2D1_POINT_2F &point,
const D2D1_MATRIX_3X2_F &matrix
)
{
return Matrix3x2F::ReinterpretBaseType(&matrix)->TransformPoint(point);
}
COM_DECLSPEC_NOTHROW
D2D1_MATRIX_3X2_F
IdentityMatrix()
{
return Matrix3x2F::Identity();
}
} // namespace D2D1
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_MATRIX_3X2_F
operator*(
const D2D1_MATRIX_3X2_F &matrix1,
const D2D1_MATRIX_3X2_F &matrix2
)
{
return
(*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix1)) *
(*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix2));
}
COM_DECLSPEC_NOTHROW
inline
bool
operator==(const D2D1_SIZE_U &size1, const D2D1_SIZE_U &size2)
{
return (size1.width == size2.width) && (size1.height == size2.height);
}
COM_DECLSPEC_NOTHROW
inline
bool
operator==(const D2D1_RECT_U &rect1, const D2D1_RECT_U &rect2)
{
return (rect1.left == rect2.left) && (rect1.top == rect2.top) &&
(rect1.right == rect2.right) && (rect1.bottom == rect2.bottom);
}
#endif // #ifndef D2D_USE_C_DEFINITIONS
#endif // #ifndef _D2D1_HELPER_H_