Skip to main content

dxplr/d2d1/
d2d1.rs

1#![allow(dead_code)]
2
3use crate::dxgi;
4use crate::result::{hresult, HResult};
5use crate::Interface;
6use crate::{impl_bitflag_operators, impl_interface};
7use com_ptr::ComPtr;
8use winapi::shared::minwindef::TRUE;
9use winapi::shared::windef::{HDC, HWND};
10use winapi::um::d2d1::*;
11use winapi::um::d2d1effectauthor::*;
12use winapi::um::d2d1effects::*;
13use winapi::um::dcommon::*;
14use winapi::um::winnt::HRESULT;
15
16#[cfg(feature = "d2d1_1")]
17use winapi::um::d2d1_1::*;
18
19#[derive(Clone, Copy, PartialEq, Eq, Debug)]
20pub struct Tag(pub u64);
21
22#[derive(Clone, Copy, PartialEq, Eq, Debug)]
23#[repr(u32)]
24pub enum _2DAffineTransformInterpolationMode {
25    NearestNeighbor = D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
26    Linear = D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_LINEAR,
27    Cubic = D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_CUBIC,
28    MultiSampleLinear = D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR,
29    Anisotropic = D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_ANISOTROPIC,
30    HighQualityCubic = D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC,
31}
32
33#[derive(Clone, Copy, PartialEq, Eq, Debug)]
34#[repr(u32)]
35pub enum _2DAffineTransformProp {
36    InterpolationMode = D2D1_2DAFFINETRANSFORM_PROP_INTERPOLATION_MODE,
37    BorderMode = D2D1_2DAFFINETRANSFORM_PROP_BORDER_MODE,
38    TransformMatrix = D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX,
39    Sharpness = D2D1_2DAFFINETRANSFORM_PROP_SHARPNESS,
40}
41
42#[derive(Clone, Copy, PartialEq, Eq, Debug)]
43#[repr(u32)]
44pub enum _3DPerspectiveTransformInterpolationMode {
45    NearestNeighbor = D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
46    Linear = D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_LINEAR,
47    Cubic = D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_CUBIC,
48    MultiSampleLinear = D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR,
49    Anisotropic = D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_ANISOTROPIC,
50}
51
52#[derive(Clone, Copy, PartialEq, Eq, Debug)]
53#[repr(u32)]
54pub enum _3DPerspectiveTransformProp {
55    InterpolationMode = D2D1_3DPERSPECTIVETRANSFORM_PROP_INTERPOLATION_MODE,
56    BorderMode = D2D1_3DPERSPECTIVETRANSFORM_PROP_BORDER_MODE,
57    Depth = D2D1_3DPERSPECTIVETRANSFORM_PROP_DEPTH,
58    PerspectiveOrigin = D2D1_3DPERSPECTIVETRANSFORM_PROP_PERSPECTIVE_ORIGIN,
59    LocalOffset = D2D1_3DPERSPECTIVETRANSFORM_PROP_LOCAL_OFFSET,
60    GlobalOffset = D2D1_3DPERSPECTIVETRANSFORM_PROP_GLOBAL_OFFSET,
61    RotationOrigin = D2D1_3DPERSPECTIVETRANSFORM_PROP_ROTATION_ORIGIN,
62    Rotation = D2D1_3DPERSPECTIVETRANSFORM_PROP_ROTATION,
63}
64
65#[derive(Clone, Copy, PartialEq, Eq, Debug)]
66#[repr(u32)]
67pub enum _3DTransformInterpolationMode {
68    NearestNeighbor = D2D1_3DTRANSFORM_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
69    Linear = D2D1_3DTRANSFORM_INTERPOLATION_MODE_LINEAR,
70    Cubic = D2D1_3DTRANSFORM_INTERPOLATION_MODE_CUBIC,
71    MultiSampleLinear = D2D1_3DTRANSFORM_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR,
72    Anisotropic = D2D1_3DTRANSFORM_INTERPOLATION_MODE_ANISOTROPIC,
73}
74
75#[derive(Clone, Copy, PartialEq, Eq, Debug)]
76#[repr(u32)]
77pub enum _3DTransformProp {
78    InterpolationMode = D2D1_3DTRANSFORM_PROP_INTERPOLATION_MODE,
79    BorderMode = D2D1_3DTRANSFORM_PROP_BORDER_MODE,
80    TransformMatrix = D2D1_3DTRANSFORM_PROP_TRANSFORM_MATRIX,
81}
82
83#[derive(Clone, Copy, PartialEq, Eq, Debug)]
84#[repr(u32)]
85pub enum AlphaMode {
86    Unknown = D2D1_ALPHA_MODE_UNKNOWN,
87    Premultiplied = D2D1_ALPHA_MODE_PREMULTIPLIED,
88    Straight = D2D1_ALPHA_MODE_STRAIGHT,
89    Ignore = D2D1_ALPHA_MODE_IGNORE,
90}
91
92#[derive(Clone, Copy, PartialEq, Eq, Debug)]
93#[repr(u32)]
94pub enum AntialiasMode {
95    PerPrimitive = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
96    Aliased = D2D1_ANTIALIAS_MODE_ALIASED,
97}
98
99#[derive(Clone, Copy, PartialEq, Eq, Debug)]
100#[repr(u32)]
101pub enum ArcSize {
102    Small = D2D1_ARC_SIZE_SMALL,
103    Large = D2D1_ARC_SIZE_LARGE,
104}
105
106#[derive(Clone, Copy, PartialEq, Eq, Debug)]
107#[repr(u32)]
108pub enum ArithmeticCompositeProp {
109    Coefficients = D2D1_ARITHMETICCOMPOSITE_PROP_COEFFICIENTS,
110    ClampOutput = D2D1_ARITHMETICCOMPOSITE_PROP_CLAMP_OUTPUT,
111}
112
113#[derive(Clone, Copy, PartialEq, Eq, Debug)]
114#[repr(u32)]
115pub enum AtlasProp {
116    InputRect = D2D1_ATLAS_PROP_INPUT_RECT,
117    InputPadingRect = D2D1_ATLAS_PROP_INPUT_PADDING_RECT,
118}
119
120#[derive(Clone, Copy, PartialEq, Eq, Debug)]
121#[repr(u32)]
122pub enum BitmapSourceAlphaMode {
123    Premultiplied = D2D1_BITMAPSOURCE_ALPHA_MODE_PREMULTIPLIED,
124    Straight = D2D1_BITMAPSOURCE_ALPHA_MODE_STRAIGHT,
125}
126
127#[derive(Clone, Copy, PartialEq, Eq, Debug)]
128#[repr(u32)]
129pub enum BitmapSourceInterpolationMode {
130    NearstNeighbor = D2D1_BITMAPSOURCE_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
131    Linear = D2D1_BITMAPSOURCE_INTERPOLATION_MODE_LINEAR,
132    Cubic = D2D1_BITMAPSOURCE_INTERPOLATION_MODE_CUBIC,
133    Fant = D2D1_BITMAPSOURCE_INTERPOLATION_MODE_FANT,
134    MipmapLinear = D2D1_BITMAPSOURCE_INTERPOLATION_MODE_MIPMAP_LINEAR,
135}
136
137#[derive(Clone, Copy, PartialEq, Eq, Debug)]
138#[repr(u32)]
139pub enum BitmapSourceOrientation {
140    Default = D2D1_BITMAPSOURCE_ORIENTATION_DEFAULT,
141    FlipHorizontal = D2D1_BITMAPSOURCE_ORIENTATION_FLIP_HORIZONTAL,
142    RotateClockwise180 = D2D1_BITMAPSOURCE_ORIENTATION_ROTATE_CLOCKWISE180,
143    RotateClockwise180FlipHorizontal =
144        D2D1_BITMAPSOURCE_ORIENTATION_ROTATE_CLOCKWISE180_FLIP_HORIZONTAL,
145    RotateClockwise270FlipHorizontal =
146        D2D1_BITMAPSOURCE_ORIENTATION_ROTATE_CLOCKWISE270_FLIP_HORIZONTAL,
147    RotateClockwise90 = D2D1_BITMAPSOURCE_ORIENTATION_ROTATE_CLOCKWISE90,
148    RotateClockwise90FlipHorizontal =
149        D2D1_BITMAPSOURCE_ORIENTATION_ROTATE_CLOCKWISE90_FLIP_HORIZONTAL,
150    RotateClockwise270 = D2D1_BITMAPSOURCE_ORIENTATION_ROTATE_CLOCKWISE270,
151}
152
153#[derive(Clone, Copy, PartialEq, Eq, Debug)]
154#[repr(u32)]
155pub enum BitmapSourceProp {
156    WICBitmapSource = D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE,
157    Scale = D2D1_BITMAPSOURCE_PROP_SCALE,
158    InterpolationMode = D2D1_BITMAPSOURCE_PROP_INTERPOLATION_MODE,
159    EnableDPICorrection = D2D1_BITMAPSOURCE_PROP_ENABLE_DPI_CORRECTION,
160    AlphaMode = D2D1_BITMAPSOURCE_PROP_ALPHA_MODE,
161    Orientation = D2D1_BITMAPSOURCE_PROP_ORIENTATION,
162}
163
164#[derive(Clone, Copy, PartialEq, Eq, Debug)]
165#[repr(u32)]
166pub enum BitmapInterpolationMode {
167    NearestNeighbor = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
168    Linear = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
169    #[cfg(feature = "d2d1_1")]
170    Cubic = D2D1_INTERPOLATION_MODE_CUBIC,
171    #[cfg(feature = "d2d1_1")]
172    MultiSampleLinear = D2D1_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR,
173    #[cfg(feature = "d2d1_1")]
174    Anisotropic = D2D1_INTERPOLATION_MODE_ANISOTROPIC,
175    #[cfg(feature = "d2d1_1")]
176    HighQualityCubic = D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC,
177}
178
179#[derive(Clone, Copy, PartialEq, Eq, Debug)]
180#[repr(u32)]
181pub enum Blend {
182    Zero = D2D1_BLEND_ZERO,
183    One = D2D1_BLEND_ONE,
184    SrcColor = D2D1_BLEND_SRC_COLOR,
185    InvSrcColor = D2D1_BLEND_INV_SRC_COLOR,
186    SrcAlpha = D2D1_BLEND_SRC_ALPHA,
187    InvSrcAlpha = D2D1_BLEND_INV_SRC_ALPHA,
188    DestAlpha = D2D1_BLEND_DEST_ALPHA,
189    InvDestAlpha = D2D1_BLEND_INV_DEST_ALPHA,
190    DestColor = D2D1_BLEND_DEST_COLOR,
191    InvDestColor = D2D1_BLEND_INV_DEST_COLOR,
192    SrcAlphaSat = D2D1_BLEND_SRC_ALPHA_SAT,
193    BlendFactor = D2D1_BLEND_BLEND_FACTOR,
194    InvBlendFactor = D2D1_BLEND_INV_BLEND_FACTOR,
195}
196
197#[derive(Clone, Copy, PartialEq, Eq, Debug)]
198#[repr(u32)]
199pub enum BlendMode {
200    Multiply = D2D1_BLEND_MODE_MULTIPLY,
201    Screen = D2D1_BLEND_MODE_SCREEN,
202    Darken = D2D1_BLEND_MODE_DARKEN,
203    Lighten = D2D1_BLEND_MODE_LIGHTEN,
204    Dissolve = D2D1_BLEND_MODE_DISSOLVE,
205    ColorBurn = D2D1_BLEND_MODE_COLOR_BURN,
206    LinearBurn = D2D1_BLEND_MODE_LINEAR_BURN,
207    DarkerColor = D2D1_BLEND_MODE_DARKER_COLOR,
208    LighterColor = D2D1_BLEND_MODE_LIGHTER_COLOR,
209    ColorDodge = D2D1_BLEND_MODE_COLOR_DODGE,
210    LinearDodge = D2D1_BLEND_MODE_LINEAR_DODGE,
211    Overlay = D2D1_BLEND_MODE_OVERLAY,
212    SoftLight = D2D1_BLEND_MODE_SOFT_LIGHT,
213    HardLight = D2D1_BLEND_MODE_HARD_LIGHT,
214    VividLight = D2D1_BLEND_MODE_VIVID_LIGHT,
215    LinearLight = D2D1_BLEND_MODE_LINEAR_LIGHT,
216    PinLight = D2D1_BLEND_MODE_PIN_LIGHT,
217    HardMix = D2D1_BLEND_MODE_HARD_MIX,
218    Difference = D2D1_BLEND_MODE_DIFFERENCE,
219    Exclusion = D2D1_BLEND_MODE_EXCLUSION,
220    Hue = D2D1_BLEND_MODE_HUE,
221    Saturation = D2D1_BLEND_MODE_SATURATION,
222    Color = D2D1_BLEND_MODE_COLOR,
223    Luminosity = D2D1_BLEND_MODE_LUMINOSITY,
224    Subtract = D2D1_BLEND_MODE_SUBTRACT,
225    Division = D2D1_BLEND_MODE_DIVISION,
226}
227
228#[derive(Clone, Copy, PartialEq, Eq, Debug)]
229#[repr(u32)]
230pub enum BlendOperation {
231    Add = D2D1_BLEND_OPERATION_ADD,
232    Subtract = D2D1_BLEND_OPERATION_SUBTRACT,
233    RevSubtract = D2D1_BLEND_OPERATION_REV_SUBTRACT,
234    Min = D2D1_BLEND_OPERATION_MIN,
235    Max = D2D1_BLEND_OPERATION_MAX,
236}
237
238#[derive(Clone, Copy, PartialEq, Eq, Debug)]
239#[repr(u32)]
240pub enum BlendProp {
241    Mode = D2D1_BLEND_PROP_MODE,
242}
243
244#[derive(Clone, Copy, PartialEq, Eq, Debug)]
245#[repr(u32)]
246pub enum BorderEdgeMode {
247    Clamp = D2D1_BORDER_EDGE_MODE_CLAMP,
248    Wrap = D2D1_BORDER_EDGE_MODE_WRAP,
249    Mirror = D2D1_BORDER_EDGE_MODE_MIRROR,
250}
251
252#[derive(Clone, Copy, PartialEq, Eq, Debug)]
253#[repr(u32)]
254pub enum BorderMode {
255    Soft = D2D1_BORDER_MODE_SOFT,
256    Hard = D2D1_BORDER_MODE_HARD,
257}
258
259#[derive(Clone, Copy, PartialEq, Eq, Debug)]
260#[repr(u32)]
261pub enum BorderProp {
262    EdgeModeX = D2D1_BORDER_PROP_EDGE_MODE_X,
263    EdgeModeY = D2D1_BORDER_PROP_EDGE_MODE_Y,
264}
265
266#[derive(Clone, Copy, PartialEq, Eq, Debug)]
267#[repr(u32)]
268pub enum BrightnessProp {
269    WhitePoint = D2D1_BRIGHTNESS_PROP_WHITE_POINT,
270    BlackPoint = D2D1_BRIGHTNESS_PROP_BLACK_POINT,
271}
272
273#[derive(Clone, Copy, PartialEq, Eq, Debug)]
274#[repr(u32)]
275pub enum CapStyle {
276    Flat = D2D1_CAP_STYLE_FLAT,
277    Square = D2D1_CAP_STYLE_SQUARE,
278    Round = D2D1_CAP_STYLE_ROUND,
279    Triangle = D2D1_CAP_STYLE_TRIANGLE,
280}
281
282#[derive(Clone, Copy, PartialEq, Eq, Debug)]
283#[repr(u32)]
284pub enum ChangeType {
285    None = D2D1_CHANGE_TYPE_NONE,
286    Properties = D2D1_CHANGE_TYPE_PROPERTIES,
287    Context = D2D1_CHANGE_TYPE_CONTEXT,
288    Graph = D2D1_CHANGE_TYPE_GRAPH,
289}
290
291#[derive(Clone, Copy, PartialEq, Eq, Debug)]
292#[repr(u32)]
293pub enum ChannelDepth {
294    Default = D2D1_CHANNEL_DEPTH_DEFAULT,
295    _1 = D2D1_CHANNEL_DEPTH_1,
296    _4 = D2D1_CHANNEL_DEPTH_4,
297}
298
299#[derive(Clone, Copy, PartialEq, Eq, Debug)]
300#[repr(u32)]
301pub enum ChannelSelector {
302    R = D2D1_CHANNEL_SELECTOR_R,
303    G = D2D1_CHANNEL_SELECTOR_G,
304    B = D2D1_CHANNEL_SELECTOR_B,
305    A = D2D1_CHANNEL_SELECTOR_A,
306}
307
308#[derive(Clone, Copy, PartialEq, Eq, Debug)]
309#[repr(u32)]
310pub enum ColorManagementAlphaMode {
311    Premultiplied = D2D1_COLORMANAGEMENT_ALPHA_MODE_PREMULTIPLIED,
312    Straight = D2D1_COLORMANAGEMENT_ALPHA_MODE_STRAIGHT,
313}
314
315#[derive(Clone, Copy, PartialEq, Eq, Debug)]
316#[repr(u32)]
317pub enum ColorManagementProp {
318    SourceColorContext = D2D1_COLORMANAGEMENT_PROP_SOURCE_COLOR_CONTEXT,
319    SourceRenderingIntent = D2D1_COLORMANAGEMENT_PROP_SOURCE_RENDERING_INTENT,
320    DestinationColorContext = D2D1_COLORMANAGEMENT_PROP_DESTINATION_COLOR_CONTEXT,
321    DestinationRenderingIntent = D2D1_COLORMANAGEMENT_PROP_DESTINATION_RENDERING_INTENT,
322    AlphaMode = D2D1_COLORMANAGEMENT_PROP_ALPHA_MODE,
323    Quality = D2D1_COLORMANAGEMENT_PROP_QUALITY,
324}
325
326#[derive(Clone, Copy, PartialEq, Eq, Debug)]
327#[repr(u32)]
328pub enum ColorManagementQuality {
329    Proof = D2D1_COLORMANAGEMENT_QUALITY_PROOF,
330    Normal = D2D1_COLORMANAGEMENT_QUALITY_NORMAL,
331    QualityBest = D2D1_COLORMANAGEMENT_QUALITY_BEST,
332}
333
334#[derive(Clone, Copy, PartialEq, Eq, Debug)]
335#[repr(u32)]
336pub enum ColorManagementRenderingIntent {
337    Perceptual = D2D1_COLORMANAGEMENT_RENDERING_INTENT_PERCEPTUAL,
338    RelativeColormetric = D2D1_COLORMANAGEMENT_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
339    Saturation = D2D1_COLORMANAGEMENT_RENDERING_INTENT_SATURATION,
340    AbsoluteColormetric = D2D1_COLORMANAGEMENT_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC,
341}
342
343#[derive(Clone, Copy, PartialEq, Eq, Debug)]
344#[repr(u32)]
345pub enum ColorMatrixAlphaMode {
346    Premultiplied = D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED,
347    Straight = D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT,
348}
349
350#[derive(Clone, Copy, PartialEq, Eq, Debug)]
351#[repr(u32)]
352pub enum ColorMatrixProp {
353    ColorMatrix = D2D1_COLORMATRIX_PROP_COLOR_MATRIX,
354    AlphaMode = D2D1_COLORMATRIX_PROP_ALPHA_MODE,
355    ClampOutput = D2D1_COLORMATRIX_PROP_CLAMP_OUTPUT,
356}
357#[derive(Clone, Copy, PartialEq, Eq, Debug)]
358#[repr(u32)]
359pub enum CombineMode {
360    Union = D2D1_COMBINE_MODE_UNION,
361    Intersect = D2D1_COMBINE_MODE_INTERSECT,
362    Xor = D2D1_COMBINE_MODE_XOR,
363    Exclude = D2D1_COMBINE_MODE_EXCLUDE,
364}
365
366#[derive(Clone, Copy, PartialEq, Eq, Debug)]
367#[repr(u32)]
368pub enum CompatibleRenderTargetOptions {
369    None = D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,
370    GDICompatible = D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE,
371}
372
373#[derive(Clone, Copy, PartialEq, Eq, Debug)]
374#[repr(u32)]
375pub enum CompositeProp {
376    Mode = D2D1_COMPOSITE_PROP_MODE,
377}
378
379#[derive(Clone, Copy, PartialEq, Eq, Debug)]
380#[repr(u32)]
381pub enum ConvolveMatrixProp {
382    KernelUnitLength = D2D1_CONVOLVEMATRIX_PROP_KERNEL_UNIT_LENGTH,
383    ScaleMode = D2D1_CONVOLVEMATRIX_PROP_SCALE_MODE,
384    KernelSizeX = D2D1_CONVOLVEMATRIX_PROP_KERNEL_SIZE_X,
385    KernelSizeY = D2D1_CONVOLVEMATRIX_PROP_KERNEL_SIZE_Y,
386    KernelMatrix = D2D1_CONVOLVEMATRIX_PROP_KERNEL_MATRIX,
387    Divisor = D2D1_CONVOLVEMATRIX_PROP_DIVISOR,
388    Bias = D2D1_CONVOLVEMATRIX_PROP_BIAS,
389    KernelOffset = D2D1_CONVOLVEMATRIX_PROP_KERNEL_OFFSET,
390    PreserveAlpha = D2D1_CONVOLVEMATRIX_PROP_PRESERVE_ALPHA,
391    BorderMode = D2D1_CONVOLVEMATRIX_PROP_BORDER_MODE,
392    ClampOutput = D2D1_CONVOLVEMATRIX_PROP_CLAMP_OUTPUT,
393}
394
395#[derive(Clone, Copy, PartialEq, Eq, Debug)]
396#[repr(u32)]
397pub enum ConvolveMatrixScaleMode {
398    NearestNeighbor = D2D1_CONVOLVEMATRIX_SCALE_MODE_NEAREST_NEIGHBOR,
399    Linear = D2D1_CONVOLVEMATRIX_SCALE_MODE_LINEAR,
400    Cubic = D2D1_CONVOLVEMATRIX_SCALE_MODE_CUBIC,
401    MultiSampleLinear = D2D1_CONVOLVEMATRIX_SCALE_MODE_MULTI_SAMPLE_LINEAR,
402    Anisotropic = D2D1_CONVOLVEMATRIX_SCALE_MODE_ANISOTROPIC,
403    HighQualityCubic = D2D1_CONVOLVEMATRIX_SCALE_MODE_HIGH_QUALITY_CUBIC,
404}
405
406#[derive(Clone, Copy, PartialEq, Eq, Debug)]
407#[repr(u32)]
408pub enum CropProp {
409    Rect = D2D1_CROP_PROP_RECT,
410    BorderMode = D2D1_CROP_PROP_BORDER_MODE,
411}
412
413#[derive(Clone, Copy, PartialEq, Eq, Debug)]
414#[repr(u32)]
415pub enum DashStyle {
416    Solid = D2D1_DASH_STYLE_SOLID,
417    Dash = D2D1_DASH_STYLE_DASH,
418    Dot = D2D1_DASH_STYLE_DOT,
419    DashDot = D2D1_DASH_STYLE_DASH_DOT,
420    DastDotDot = D2D1_DASH_STYLE_DASH_DOT_DOT,
421    Custom = D2D1_DASH_STYLE_CUSTOM,
422}
423
424#[derive(Clone, Copy, PartialEq, Eq, Debug)]
425#[repr(u32)]
426pub enum DCInitializeMode {
427    Copy = D2D1_DC_INITIALIZE_MODE_COPY,
428    Clear = D2D1_DC_INITIALIZE_MODE_CLEAR,
429}
430
431#[derive(Clone, Copy, PartialEq, Eq, Debug)]
432#[repr(u32)]
433pub enum DebugLevel {
434    None = D2D1_DEBUG_LEVEL_NONE,
435    Error = D2D1_DEBUG_LEVEL_ERROR,
436    Warning = D2D1_DEBUG_LEVEL_WARNING,
437    Information = D2D1_DEBUG_LEVEL_INFORMATION,
438}
439#[derive(Clone, Copy, PartialEq, Eq, Debug)]
440#[repr(u32)]
441pub enum DirectionalBlurOptimization {
442    Speed = D2D1_DIRECTIONALBLUR_OPTIMIZATION_SPEED,
443    Balanced = D2D1_DIRECTIONALBLUR_OPTIMIZATION_BALANCED,
444    Quality = D2D1_DIRECTIONALBLUR_OPTIMIZATION_QUALITY,
445}
446
447#[derive(Clone, Copy, PartialEq, Eq, Debug)]
448#[repr(u32)]
449pub enum DirectionalBlurProp {
450    StandardDeviation = D2D1_DIRECTIONALBLUR_PROP_STANDARD_DEVIATION,
451    Angle = D2D1_DIRECTIONALBLUR_PROP_ANGLE,
452    Optimization = D2D1_DIRECTIONALBLUR_PROP_OPTIMIZATION,
453    BorderMode = D2D1_DIRECTIONALBLUR_PROP_BORDER_MODE,
454}
455
456#[derive(Clone, Copy, PartialEq, Eq, Debug)]
457#[repr(u32)]
458pub enum DiscreteTransferProp {
459    RedTable = D2D1_DISCRETETRANSFER_PROP_RED_TABLE,
460    RedDisable = D2D1_DISCRETETRANSFER_PROP_RED_DISABLE,
461    GreenTable = D2D1_DISCRETETRANSFER_PROP_GREEN_TABLE,
462    GreenDisable = D2D1_DISCRETETRANSFER_PROP_GREEN_DISABLE,
463    BlueTable = D2D1_DISCRETETRANSFER_PROP_BLUE_TABLE,
464    BlueDisable = D2D1_DISCRETETRANSFER_PROP_BLUE_DISABLE,
465    AlphaTable = D2D1_DISCRETETRANSFER_PROP_ALPHA_TABLE,
466    AlphaDisable = D2D1_DISCRETETRANSFER_PROP_ALPHA_DISABLE,
467    ClampOutput = D2D1_DISCRETETRANSFER_PROP_CLAMP_OUTPUT,
468}
469
470#[derive(Clone, Copy, PartialEq, Eq, Debug)]
471#[repr(u32)]
472pub enum DisplacementMapProp {
473    Scale = D2D1_DISPLACEMENTMAP_PROP_SCALE,
474    XChannelSelect = D2D1_DISPLACEMENTMAP_PROP_X_CHANNEL_SELECT,
475    YChannelSelect = D2D1_DISPLACEMENTMAP_PROP_Y_CHANNEL_SELECT,
476}
477
478#[derive(Clone, Copy, PartialEq, Eq, Debug)]
479#[repr(u32)]
480pub enum DistantDiffuseProp {
481    Azimuth = D2D1_DISTANTDIFFUSE_PROP_AZIMUTH,
482    Elevation = D2D1_DISTANTDIFFUSE_PROP_ELEVATION,
483    DiffuseConstant = D2D1_DISTANTDIFFUSE_PROP_DIFFUSE_CONSTANT,
484    SurfaceScale = D2D1_DISTANTDIFFUSE_PROP_SURFACE_SCALE,
485    Color = D2D1_DISTANTDIFFUSE_PROP_COLOR,
486    KernelUnitLength = D2D1_DISTANTDIFFUSE_PROP_KERNEL_UNIT_LENGTH,
487    ScaleMode = D2D1_DISTANTDIFFUSE_PROP_SCALE_MODE,
488}
489
490#[derive(Clone, Copy, PartialEq, Eq, Debug)]
491#[repr(u32)]
492pub enum DistantDiffuseScaleMode {
493    NearestNeighbor = D2D1_DISTANTDIFFUSE_SCALE_MODE_NEAREST_NEIGHBOR,
494    Linear = D2D1_DISTANTDIFFUSE_SCALE_MODE_LINEAR,
495    Cubic = D2D1_DISTANTDIFFUSE_SCALE_MODE_CUBIC,
496    MultiSampleLinear = D2D1_DISTANTDIFFUSE_SCALE_MODE_MULTI_SAMPLE_LINEAR,
497    Anisotropic = D2D1_DISTANTDIFFUSE_SCALE_MODE_ANISOTROPIC,
498    HighQualityCubic = D2D1_DISTANTDIFFUSE_SCALE_MODE_HIGH_QUALITY_CUBIC,
499}
500
501#[derive(Clone, Copy, PartialEq, Eq, Debug)]
502#[repr(u32)]
503pub enum DistantSpecularProp {
504    Azimuth = D2D1_DISTANTSPECULAR_PROP_AZIMUTH,
505    Elevation = D2D1_DISTANTSPECULAR_PROP_ELEVATION,
506    SpecularExponent = D2D1_DISTANTSPECULAR_PROP_SPECULAR_EXPONENT,
507    SpecularConstant = D2D1_DISTANTSPECULAR_PROP_SPECULAR_CONSTANT,
508    SurfaceScale = D2D1_DISTANTSPECULAR_PROP_SURFACE_SCALE,
509    Color = D2D1_DISTANTSPECULAR_PROP_COLOR,
510    KernelUnitLength = D2D1_DISTANTSPECULAR_PROP_KERNEL_UNIT_LENGTH,
511    ScaleMode = D2D1_DISTANTSPECULAR_PROP_SCALE_MODE,
512}
513
514#[derive(Clone, Copy, PartialEq, Eq, Debug)]
515#[repr(u32)]
516pub enum DistantSpecularScaleMode {
517    NearestNeighbor = D2D1_DISTANTSPECULAR_SCALE_MODE_NEAREST_NEIGHBOR,
518    Linear = D2D1_DISTANTSPECULAR_SCALE_MODE_LINEAR,
519    Cubic = D2D1_DISTANTSPECULAR_SCALE_MODE_CUBIC,
520    MultiSampleLinear = D2D1_DISTANTSPECULAR_SCALE_MODE_MULTI_SAMPLE_LINEAR,
521    Anisotropic = D2D1_DISTANTSPECULAR_SCALE_MODE_ANISOTROPIC,
522    HighQualityCubic = D2D1_DISTANTSPECULAR_SCALE_MODE_HIGH_QUALITY_CUBIC,
523}
524
525#[derive(Clone, Copy, PartialEq, Eq, Debug)]
526#[repr(u32)]
527pub enum DPICompensationInterpolationMode {
528    NearestNeighbor = D2D1_DPICOMPENSATION_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
529    Linear = D2D1_DPICOMPENSATION_INTERPOLATION_MODE_LINEAR,
530    Cubic = D2D1_DPICOMPENSATION_INTERPOLATION_MODE_CUBIC,
531    MultiSampleLinear = D2D1_DPICOMPENSATION_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR,
532    Anisotropic = D2D1_DPICOMPENSATION_INTERPOLATION_MODE_ANISOTROPIC,
533    HighQualityCubic = D2D1_DPICOMPENSATION_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC,
534}
535
536#[derive(Clone, Copy, PartialEq, Eq, Debug)]
537#[repr(u32)]
538pub enum DPICompensationProp {
539    InterpolationMode = D2D1_DPICOMPENSATION_PROP_INTERPOLATION_MODE,
540    BorderMode = D2D1_DPICOMPENSATION_PROP_BORDER_MODE,
541    InputDPI = D2D1_DPICOMPENSATION_PROP_INPUT_DPI,
542}
543
544#[derive(Clone, Copy, PartialEq, Eq, Debug)]
545pub struct DrawTextOptions(u32);
546#[allow(non_upper_case_globals)]
547impl DrawTextOptions {
548    pub const NoSnap: Self = Self(D2D1_DRAW_TEXT_OPTIONS_NO_SNAP);
549    pub const Clip: Self = Self(D2D1_DRAW_TEXT_OPTIONS_CLIP);
550    pub const EnableColorFont: Self = Self(D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
551    pub const DisableColorBitmapSnapping: Self = Self(0x00000008);
552    pub const None: Self = Self(D2D1_DRAW_TEXT_OPTIONS_NONE);
553}
554impl_bitflag_operators!(DrawTextOptions);
555
556#[derive(Clone, Copy, PartialEq, Eq, Debug)]
557#[repr(u32)]
558pub enum ExtendMode {
559    Clamp = D2D1_EXTEND_MODE_CLAMP,
560    Wrap = D2D1_EXTEND_MODE_WRAP,
561    Mirror = D2D1_EXTEND_MODE_MIRROR,
562}
563
564#[derive(Clone, Copy, PartialEq, Eq, Debug)]
565#[repr(u32)]
566pub enum FactoryType {
567    SingleThreaded = D2D1_FACTORY_TYPE_SINGLE_THREADED,
568    MultiThreaded = D2D1_FACTORY_TYPE_MULTI_THREADED,
569}
570
571#[derive(Clone, Copy, PartialEq, Eq, Debug)]
572#[repr(u32)]
573pub enum Feature {
574    Doubles = D2D1_FEATURE_DOUBLES,
575    D3D10XHardwareOptions = D2D1_FEATURE_D3D10_X_HARDWARE_OPTIONS,
576}
577
578#[derive(Clone, Copy, PartialEq, Eq, Debug)]
579#[repr(u32)]
580pub enum FeatureLevel {
581    Default = D2D1_FEATURE_LEVEL_DEFAULT,
582    _9 = D2D1_FEATURE_LEVEL_9,
583    _10 = D2D1_FEATURE_LEVEL_10,
584}
585
586#[derive(Clone, Copy, PartialEq, Eq, Debug)]
587#[repr(u32)]
588pub enum FigureBegin {
589    Filled = D2D1_FIGURE_BEGIN_FILLED,
590    Hollow = D2D1_FIGURE_BEGIN_HOLLOW,
591}
592
593#[derive(Clone, Copy, PartialEq, Eq, Debug)]
594#[repr(u32)]
595pub enum FigureEnd {
596    Open = D2D1_FIGURE_END_OPEN,
597    Closed = D2D1_FIGURE_END_CLOSED,
598}
599
600#[derive(Clone, Copy, PartialEq, Eq, Debug)]
601#[repr(u32)]
602pub enum FillMode {
603    Alternate = D2D1_FILL_MODE_ALTERNATE,
604    Winding = D2D1_FILL_MODE_WINDING,
605}
606
607#[derive(Clone, Copy, PartialEq, Eq, Debug)]
608#[repr(u32)]
609pub enum Filter {
610    MinMagMipPoint = D2D1_FILTER_MIN_MAG_MIP_POINT,
611    MinMagPointMipLinear = D2D1_FILTER_MIN_MAG_POINT_MIP_LINEAR,
612    MinPointMagLinearMipPoint = D2D1_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
613    MinPointMagMipLinear = D2D1_FILTER_MIN_POINT_MAG_MIP_LINEAR,
614    MinLinearMagMipPoint = D2D1_FILTER_MIN_LINEAR_MAG_MIP_POINT,
615    MinLinearMagPointMipLinear = D2D1_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
616    MinMagLinearMipPoint = D2D1_FILTER_MIN_MAG_LINEAR_MIP_POINT,
617    MinMagMipLinear = D2D1_FILTER_MIN_MAG_MIP_LINEAR,
618    Anisotropic = D2D1_FILTER_ANISOTROPIC,
619}
620
621#[derive(Clone, Copy, PartialEq, Eq, Debug)]
622#[repr(u32)]
623pub enum FloodProp {
624    Color = D2D1_FLOOD_PROP_COLOR,
625}
626
627#[derive(Clone, Copy, PartialEq, Eq, Debug)]
628#[repr(u32)]
629pub enum Gamma {
630    _2_2 = D2D1_GAMMA_2_2,
631    _1_0 = D2D1_GAMMA_1_0,
632}
633
634#[derive(Clone, Copy, PartialEq, Eq, Debug)]
635#[repr(u32)]
636pub enum GammaTransferProp {
637    RedAmplitude = D2D1_GAMMATRANSFER_PROP_RED_AMPLITUDE,
638    RedExponent = D2D1_GAMMATRANSFER_PROP_RED_EXPONENT,
639    RedOffset = D2D1_GAMMATRANSFER_PROP_RED_OFFSET,
640    RedDisable = D2D1_GAMMATRANSFER_PROP_RED_DISABLE,
641    GreenAmplitude = D2D1_GAMMATRANSFER_PROP_GREEN_AMPLITUDE,
642    GreenExponent = D2D1_GAMMATRANSFER_PROP_GREEN_EXPONENT,
643    GreenOffset = D2D1_GAMMATRANSFER_PROP_GREEN_OFFSET,
644    GreenDisable = D2D1_GAMMATRANSFER_PROP_GREEN_DISABLE,
645    BlueAmplitude = D2D1_GAMMATRANSFER_PROP_BLUE_AMPLITUDE,
646    BlueExponent = D2D1_GAMMATRANSFER_PROP_BLUE_EXPONENT,
647    BlueOffset = D2D1_GAMMATRANSFER_PROP_BLUE_OFFSET,
648    BlueDisable = D2D1_GAMMATRANSFER_PROP_BLUE_DISABLE,
649    AlphaAmplitude = D2D1_GAMMATRANSFER_PROP_ALPHA_AMPLITUDE,
650    AlphaExponent = D2D1_GAMMATRANSFER_PROP_ALPHA_EXPONENT,
651    AlphaOffset = D2D1_GAMMATRANSFER_PROP_ALPHA_OFFSET,
652    AlphaDisable = D2D1_GAMMATRANSFER_PROP_ALPHA_DISABLE,
653    ClampOutput = D2D1_GAMMATRANSFER_PROP_CLAMP_OUTPUT,
654}
655
656#[derive(Clone, Copy, PartialEq, Eq, Debug)]
657#[repr(u32)]
658pub enum GaussianBlurOptimization {
659    Speed = D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED,
660    Balanced = D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED,
661    Quality = D2D1_GAUSSIANBLUR_OPTIMIZATION_QUALITY,
662}
663
664#[derive(Clone, Copy, PartialEq, Eq, Debug)]
665#[repr(u32)]
666pub enum GaussianBlurProp {
667    StandardDeviation = D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION,
668    Optimization = D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION,
669    BorderMode = D2D1_GAUSSIANBLUR_PROP_BORDER_MODE,
670}
671#[derive(Clone, Copy, PartialEq, Eq, Debug)]
672#[repr(u32)]
673pub enum GeometryRelation {
674    Unknown = D2D1_GEOMETRY_RELATION_UNKNOWN,
675    Disjoint = D2D1_GEOMETRY_RELATION_DISJOINT,
676    IsContained = D2D1_GEOMETRY_RELATION_IS_CONTAINED,
677    Contains = D2D1_GEOMETRY_RELATION_CONTAINS,
678    Overlap = D2D1_GEOMETRY_RELATION_OVERLAP,
679}
680
681#[derive(Clone, Copy, PartialEq, Eq, Debug)]
682#[repr(u32)]
683pub enum GeometrySimplificationOption {
684    CubicsAndLines = D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
685    Lines = D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
686}
687#[derive(Clone, Copy, PartialEq, Eq, Debug)]
688#[repr(u32)]
689pub enum HistogramProp {
690    NumBins = D2D1_HISTOGRAM_PROP_NUM_BINS,
691    ChannelSelect = D2D1_HISTOGRAM_PROP_CHANNEL_SELECT,
692    HistogramOutput = D2D1_HISTOGRAM_PROP_HISTOGRAM_OUTPUT,
693}
694
695#[derive(Clone, Copy, PartialEq, Eq, Debug)]
696#[repr(u32)]
697pub enum HueRotationProp {
698    Angle = D2D1_HUEROTATION_PROP_ANGLE,
699}
700
701#[derive(Clone, Copy, PartialEq, Eq, Debug)]
702#[repr(u32)]
703pub enum LayerOptions {
704    None = D2D1_LAYER_OPTIONS_NONE,
705    InitializeForClearType = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE,
706}
707
708#[derive(Clone, Copy, PartialEq, Eq, Debug)]
709#[repr(u32)]
710pub enum LinearTransferProp {
711    RedYIntercept = D2D1_LINEARTRANSFER_PROP_RED_Y_INTERCEPT,
712    RedSlope = D2D1_LINEARTRANSFER_PROP_RED_SLOPE,
713    RedDisable = D2D1_LINEARTRANSFER_PROP_RED_DISABLE,
714    GreenYIntercept = D2D1_LINEARTRANSFER_PROP_GREEN_Y_INTERCEPT,
715    GreenSlope = D2D1_LINEARTRANSFER_PROP_GREEN_SLOPE,
716    GreenDisable = D2D1_LINEARTRANSFER_PROP_GREEN_DISABLE,
717    BlueYIntercept = D2D1_LINEARTRANSFER_PROP_BLUE_Y_INTERCEPT,
718    BlueSlope = D2D1_LINEARTRANSFER_PROP_BLUE_SLOPE,
719    BlueDisable = D2D1_LINEARTRANSFER_PROP_BLUE_DISABLE,
720    AlphaYIntercept = D2D1_LINEARTRANSFER_PROP_ALPHA_Y_INTERCEPT,
721    AlphaSlope = D2D1_LINEARTRANSFER_PROP_ALPHA_SLOPE,
722    AlphaDisable = D2D1_LINEARTRANSFER_PROP_ALPHA_DISABLE,
723    ClampOutput = D2D1_LINEARTRANSFER_PROP_CLAMP_OUTPUT,
724}
725
726#[derive(Clone, Copy, PartialEq, Eq, Debug)]
727#[repr(u32)]
728pub enum LineJoin {
729    Miter = D2D1_LINE_JOIN_MITER,
730    Bevel = D2D1_LINE_JOIN_BEVEL,
731    Round = D2D1_LINE_JOIN_ROUND,
732    MiterOrBevel = D2D1_LINE_JOIN_MITER_OR_BEVEL,
733}
734
735#[derive(Clone, Copy, PartialEq, Eq, Debug)]
736#[repr(u32)]
737pub enum MorphologyMode {
738    Erode = D2D1_MORPHOLOGY_MODE_ERODE,
739    Dilate = D2D1_MORPHOLOGY_MODE_DILATE,
740}
741
742#[derive(Clone, Copy, PartialEq, Eq, Debug)]
743#[repr(u32)]
744pub enum MorphologyProp {
745    Mode = D2D1_MORPHOLOGY_PROP_MODE,
746    Width = D2D1_MORPHOLOGY_PROP_WIDTH,
747    Height = D2D1_MORPHOLOGY_PROP_HEIGHT,
748}
749
750#[derive(Clone, Copy, PartialEq, Eq, Debug)]
751#[repr(u32)]
752pub enum OpacityMetadataProp {
753    InputOpaqueRect = D2D1_OPACITYMETADATA_PROP_INPUT_OPAQUE_RECT,
754}
755
756#[derive(Clone, Copy, PartialEq, Eq, Debug)]
757#[repr(u32)]
758pub enum OpacityMaskContent {
759    Graphics = D2D1_OPACITY_MASK_CONTENT_GRAPHICS,
760    Natural = D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL,
761    GDICompatible = D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE,
762}
763
764#[derive(Clone, Copy, PartialEq, Eq, Debug)]
765#[repr(u32)]
766pub enum PathSegment {
767    None = D2D1_PATH_SEGMENT_NONE,
768    ForceUnstroked = D2D1_PATH_SEGMENT_FORCE_UNSTROKED,
769    RoundLineJoin = D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN,
770}
771
772#[derive(Clone, Copy, PartialEq, Eq, Debug)]
773#[repr(u32)]
774pub enum PixelOptions {
775    None = D2D1_PIXEL_OPTIONS_NONE,
776    TrivialSampling = D2D1_PIXEL_OPTIONS_TRIVIAL_SAMPLING,
777}
778
779#[derive(Clone, Copy, PartialEq, Eq, Debug)]
780#[repr(u32)]
781pub enum PointDiffuseProp {
782    LightPosition = D2D1_POINTDIFFUSE_PROP_LIGHT_POSITION,
783    DiffuseConstant = D2D1_POINTDIFFUSE_PROP_DIFFUSE_CONSTANT,
784    SurfaceScale = D2D1_POINTDIFFUSE_PROP_SURFACE_SCALE,
785    Color = D2D1_POINTDIFFUSE_PROP_COLOR,
786    KernelUnitLength = D2D1_POINTDIFFUSE_PROP_KERNEL_UNIT_LENGTH,
787    ScaleMode = D2D1_POINTDIFFUSE_PROP_SCALE_MODE,
788}
789
790#[derive(Clone, Copy, PartialEq, Eq, Debug)]
791#[repr(u32)]
792pub enum PointDiffuseScaleMode {
793    NearestNeighbor = D2D1_POINTDIFFUSE_SCALE_MODE_NEAREST_NEIGHBOR,
794    Linear = D2D1_POINTDIFFUSE_SCALE_MODE_LINEAR,
795    Cubic = D2D1_POINTDIFFUSE_SCALE_MODE_CUBIC,
796    MultiSampleLinear = D2D1_POINTDIFFUSE_SCALE_MODE_MULTI_SAMPLE_LINEAR,
797    Anisotropic = D2D1_POINTDIFFUSE_SCALE_MODE_ANISOTROPIC,
798    HighQualityCubic = D2D1_POINTDIFFUSE_SCALE_MODE_HIGH_QUALITY_CUBIC,
799}
800
801#[derive(Clone, Copy, PartialEq, Eq, Debug)]
802#[repr(u32)]
803pub enum PointSpecularProp {
804    LightPosition = D2D1_POINTSPECULAR_PROP_LIGHT_POSITION,
805    SpecularExponent = D2D1_POINTSPECULAR_PROP_SPECULAR_EXPONENT,
806    SpecularConstant = D2D1_POINTSPECULAR_PROP_SPECULAR_CONSTANT,
807    SurfaceScale = D2D1_POINTSPECULAR_PROP_SURFACE_SCALE,
808    Color = D2D1_POINTSPECULAR_PROP_COLOR,
809    KernelUnitLength = D2D1_POINTSPECULAR_PROP_KERNEL_UNIT_LENGTH,
810    ScaleMode = D2D1_POINTSPECULAR_PROP_SCALE_MODE,
811}
812
813#[derive(Clone, Copy, PartialEq, Eq, Debug)]
814#[repr(u32)]
815pub enum PointSpecularScaleMode {
816    NearestNeighbor = D2D1_POINTSPECULAR_SCALE_MODE_NEAREST_NEIGHBOR,
817    Linear = D2D1_POINTSPECULAR_SCALE_MODE_LINEAR,
818    Cubic = D2D1_POINTSPECULAR_SCALE_MODE_CUBIC,
819    MultiSampleLinear = D2D1_POINTSPECULAR_SCALE_MODE_MULTI_SAMPLE_LINEAR,
820    Anisotropic = D2D1_POINTSPECULAR_SCALE_MODE_ANISOTROPIC,
821    HighQualityCubic = D2D1_POINTSPECULAR_SCALE_MODE_HIGH_QUALITY_CUBIC,
822}
823
824#[derive(Clone, Copy, PartialEq, Eq, Debug)]
825#[repr(u32)]
826pub enum PresentOptions {
827    None = D2D1_PRESENT_OPTIONS_NONE,
828    RetainContents = D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS,
829    Immediately = D2D1_PRESENT_OPTIONS_IMMEDIATELY,
830}
831
832#[derive(Clone, Copy, PartialEq, Eq, Debug)]
833#[repr(u32)]
834pub enum RenderTargetType {
835    Default = D2D1_RENDER_TARGET_TYPE_DEFAULT,
836    Software = D2D1_RENDER_TARGET_TYPE_SOFTWARE,
837    Hardware = D2D1_RENDER_TARGET_TYPE_HARDWARE,
838}
839
840#[derive(Clone, Copy, PartialEq, Eq, Debug)]
841#[repr(u32)]
842pub enum RenderTargetUsage {
843    None = D2D1_RENDER_TARGET_USAGE_NONE,
844    ForceBitmapRemoting = D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING,
845    GDICompatible = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
846}
847
848#[derive(Clone, Copy, PartialEq, Eq, Debug)]
849#[repr(u32)]
850pub enum SaturationProp {
851    Saturation = D2D1_SATURATION_PROP_SATURATION,
852}
853
854#[derive(Clone, Copy, PartialEq, Eq, Debug)]
855#[repr(u32)]
856pub enum ScaleInterpolationMode {
857    NearestNeighbor = D2D1_SCALE_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
858    Linear = D2D1_SCALE_INTERPOLATION_MODE_LINEAR,
859    Cubic = D2D1_SCALE_INTERPOLATION_MODE_CUBIC,
860    MultiSampleLinear = D2D1_SCALE_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR,
861    Anisotropic = D2D1_SCALE_INTERPOLATION_MODE_ANISOTROPIC,
862    HighQualityCubic = D2D1_SCALE_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC,
863}
864
865#[derive(Clone, Copy, PartialEq, Eq, Debug)]
866#[repr(u32)]
867pub enum ScaleProp {
868    Scale = D2D1_SCALE_PROP_SCALE,
869    CenterPoint = D2D1_SCALE_PROP_CENTER_POINT,
870    InterpolationMode = D2D1_SCALE_PROP_INTERPOLATION_MODE,
871    BorderMode = D2D1_SCALE_PROP_BORDER_MODE,
872    Sharpness = D2D1_SCALE_PROP_SHARPNESS,
873}
874
875#[derive(Clone, Copy, PartialEq, Eq, Debug)]
876#[repr(u32)]
877pub enum ShadowOptimization {
878    Speed = D2D1_SHADOW_OPTIMIZATION_SPEED,
879    Balanced = D2D1_SHADOW_OPTIMIZATION_BALANCED,
880    Quality = D2D1_SHADOW_OPTIMIZATION_QUALITY,
881}
882
883#[derive(Clone, Copy, PartialEq, Eq, Debug)]
884#[repr(u32)]
885pub enum ShadowProp {
886    BlurStandardDeviation = D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION,
887    Color = D2D1_SHADOW_PROP_COLOR,
888    Optimization = D2D1_SHADOW_PROP_OPTIMIZATION,
889}
890
891#[derive(Clone, Copy, PartialEq, Eq, Debug)]
892#[repr(u32)]
893pub enum SpotDiffuseProp {
894    LightPosition = D2D1_SPOTDIFFUSE_PROP_LIGHT_POSITION,
895    PointsAt = D2D1_SPOTDIFFUSE_PROP_POINTS_AT,
896    Focus = D2D1_SPOTDIFFUSE_PROP_FOCUS,
897    LimitingConeAngle = D2D1_SPOTDIFFUSE_PROP_LIMITING_CONE_ANGLE,
898    DiffuseConstant = D2D1_SPOTDIFFUSE_PROP_DIFFUSE_CONSTANT,
899    SurfaceScale = D2D1_SPOTDIFFUSE_PROP_SURFACE_SCALE,
900    Color = D2D1_SPOTDIFFUSE_PROP_COLOR,
901    KernelUnitLength = D2D1_SPOTDIFFUSE_PROP_KERNEL_UNIT_LENGTH,
902    ScaleMode = D2D1_SPOTDIFFUSE_PROP_SCALE_MODE,
903}
904
905#[derive(Clone, Copy, PartialEq, Eq, Debug)]
906#[repr(u32)]
907pub enum SpotDiffuseScaleMode {
908    NearestNeighbor = D2D1_SPOTDIFFUSE_SCALE_MODE_NEAREST_NEIGHBOR,
909    Linear = D2D1_SPOTDIFFUSE_SCALE_MODE_LINEAR,
910    Cubic = D2D1_SPOTDIFFUSE_SCALE_MODE_CUBIC,
911    MultiSampleLinear = D2D1_SPOTDIFFUSE_SCALE_MODE_MULTI_SAMPLE_LINEAR,
912    Anisotropic = D2D1_SPOTDIFFUSE_SCALE_MODE_ANISOTROPIC,
913    HighQualityCubic = D2D1_SPOTDIFFUSE_SCALE_MODE_HIGH_QUALITY_CUBIC,
914}
915
916#[derive(Clone, Copy, PartialEq, Eq, Debug)]
917#[repr(u32)]
918pub enum SpotSpecularProp {
919    LightPosition = D2D1_SPOTSPECULAR_PROP_LIGHT_POSITION,
920    PointsAt = D2D1_SPOTSPECULAR_PROP_POINTS_AT,
921    Focus = D2D1_SPOTSPECULAR_PROP_FOCUS,
922    LimitingConeAngle = D2D1_SPOTSPECULAR_PROP_LIMITING_CONE_ANGLE,
923    SpecularExponent = D2D1_SPOTSPECULAR_PROP_SPECULAR_EXPONENT,
924    SpecularConstant = D2D1_SPOTSPECULAR_PROP_SPECULAR_CONSTANT,
925    SurfaceScale = D2D1_SPOTSPECULAR_PROP_SURFACE_SCALE,
926    Color = D2D1_SPOTSPECULAR_PROP_COLOR,
927    KernelUintLength = D2D1_SPOTSPECULAR_PROP_KERNEL_UNIT_LENGTH,
928    ScaleMode = D2D1_SPOTSPECULAR_PROP_SCALE_MODE,
929}
930
931#[derive(Clone, Copy, PartialEq, Eq, Debug)]
932#[repr(u32)]
933pub enum SpotSpecularScaleMode {
934    NearestNeighbor = D2D1_SPOTSPECULAR_SCALE_MODE_NEAREST_NEIGHBOR,
935    Linear = D2D1_SPOTSPECULAR_SCALE_MODE_LINEAR,
936    Cubic = D2D1_SPOTSPECULAR_SCALE_MODE_CUBIC,
937    MultiSampleLinear = D2D1_SPOTSPECULAR_SCALE_MODE_MULTI_SAMPLE_LINEAR,
938    Anisotropic = D2D1_SPOTSPECULAR_SCALE_MODE_ANISOTROPIC,
939    HighQualityCubic = D2D1_SPOTSPECULAR_SCALE_MODE_HIGH_QUALITY_CUBIC,
940}
941#[derive(Clone, Copy, PartialEq, Eq, Debug)]
942#[repr(u32)]
943pub enum SweepDirection {
944    CounterClockwise = D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
945    Clockwise = D2D1_SWEEP_DIRECTION_CLOCKWISE,
946}
947
948#[derive(Clone, Copy, PartialEq, Eq, Debug)]
949#[repr(u32)]
950pub enum TableTransferProp {
951    RedTable = D2D1_TABLETRANSFER_PROP_RED_TABLE,
952    RedDisable = D2D1_TABLETRANSFER_PROP_RED_DISABLE,
953    GreenTable = D2D1_TABLETRANSFER_PROP_GREEN_TABLE,
954    GreenDisable = D2D1_TABLETRANSFER_PROP_GREEN_DISABLE,
955    BlueTable = D2D1_TABLETRANSFER_PROP_BLUE_TABLE,
956    BlueDisable = D2D1_TABLETRANSFER_PROP_BLUE_DISABLE,
957    AlphaTable = D2D1_TABLETRANSFER_PROP_ALPHA_TABLE,
958    AlphaDisable = D2D1_TABLETRANSFER_PROP_ALPHA_DISABLE,
959    ClampOutput = D2D1_TABLETRANSFER_PROP_CLAMP_OUTPUT,
960}
961
962#[derive(Clone, Copy, PartialEq, Eq, Debug)]
963#[repr(u32)]
964pub enum TextAntialiasMode {
965    Default = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
966    ClearType = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
967    GrayScale = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
968    Aliased = D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
969}
970
971#[derive(Clone, Copy, PartialEq, Eq, Debug)]
972#[repr(u32)]
973pub enum TileProp {
974    Rect = D2D1_TILE_PROP_RECT,
975}
976
977#[derive(Clone, Copy, PartialEq, Eq, Debug)]
978#[repr(u32)]
979pub enum TurbulenceNoise {
980    FractalSum = D2D1_TURBULENCE_NOISE_FRACTAL_SUM,
981    Turbulence = D2D1_TURBULENCE_NOISE_TURBULENCE,
982}
983
984#[derive(Clone, Copy, PartialEq, Eq, Debug)]
985#[repr(u32)]
986pub enum TurbulenceProp {
987    Offset = D2D1_TURBULENCE_PROP_OFFSET,
988    Size = D2D1_TURBULENCE_PROP_SIZE,
989    BaseFrequency = D2D1_TURBULENCE_PROP_BASE_FREQUENCY,
990    NumOctaves = D2D1_TURBULENCE_PROP_NUM_OCTAVES,
991    Seed = D2D1_TURBULENCE_PROP_SEED,
992    Noise = D2D1_TURBULENCE_PROP_NOISE,
993    Stitchable = D2D1_TURBULENCE_PROP_STITCHABLE,
994}
995#[derive(Clone, Copy, PartialEq, Eq, Debug)]
996#[repr(u32)]
997pub enum VertexOptions {
998    None = D2D1_VERTEX_OPTIONS_NONE,
999    DoNotClear = D2D1_VERTEX_OPTIONS_DO_NOT_CLEAR,
1000    UseDepthBuffer = D2D1_VERTEX_OPTIONS_USE_DEPTH_BUFFER,
1001    AssumeNoOverlap = D2D1_VERTEX_OPTIONS_ASSUME_NO_OVERLAP,
1002}
1003
1004#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1005#[repr(u32)]
1006pub enum VertexUsage {
1007    Static = D2D1_VERTEX_USAGE_STATIC,
1008    Dynamic = D2D1_VERTEX_USAGE_DYNAMIC,
1009}
1010
1011#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1012#[repr(u32)]
1013pub enum WindowState {
1014    None = D2D1_WINDOW_STATE_NONE,
1015    Occluded = D2D1_WINDOW_STATE_OCCLUDED,
1016}
1017
1018pub type ColorF = crate::dxgi::RGBA;
1019
1020macro_rules! impl_matrix {
1021    ($name: ident, $r: expr, $c: expr) => {
1022        impl $name {
1023            pub fn new() -> Self {
1024                Self { m: [0.0; $r * $c] }
1025            }
1026        }
1027        impl Default for $name {
1028            fn default() -> Self {
1029                Self::new()
1030            }
1031        }
1032        impl std::ops::Index<(u32, u32)> for $name {
1033            type Output = f32;
1034
1035            fn index(&self, idx: (u32, u32)) -> &f32 {
1036                &self.m[(idx.0 * $c + idx.1) as usize]
1037            }
1038        }
1039        impl std::ops::IndexMut<(u32, u32)> for $name {
1040            fn index_mut(&mut self, idx: (u32, u32)) -> &mut f32 {
1041                &mut self.m[(idx.0 * $c + idx.1) as usize]
1042            }
1043        }
1044    };
1045}
1046
1047#[derive(Clone, Copy, Debug)]
1048#[repr(C)]
1049pub struct Matrix3x2F {
1050    m: [f32; 3 * 2],
1051}
1052impl_matrix!(Matrix3x2F, 3, 2);
1053impl Matrix3x2F {
1054    fn as_c_ptr(&self) -> *const D2D_MATRIX_3X2_F {
1055        self.m.as_ptr() as *const D2D_MATRIX_3X2_F
1056    }
1057}
1058impl From<Matrix3x2F> for D2D_MATRIX_3X2_F {
1059    fn from(src: Matrix3x2F) -> D2D_MATRIX_3X2_F {
1060        Self {
1061            matrix: [
1062                [src.m[0], src.m[1]],
1063                [src.m[2], src.m[3]],
1064                [src.m[4], src.m[5]],
1065            ],
1066        }
1067    }
1068}
1069impl From<D2D_MATRIX_3X2_F> for Matrix3x2F {
1070    fn from(src: D2D_MATRIX_3X2_F) -> Matrix3x2F {
1071        Self {
1072            m: [
1073                src.matrix[0][0],
1074                src.matrix[0][1],
1075                src.matrix[1][0],
1076                src.matrix[1][1],
1077                src.matrix[2][0],
1078                src.matrix[2][1],
1079            ],
1080        }
1081    }
1082}
1083
1084#[derive(Clone, Copy, Debug)]
1085#[repr(C)]
1086pub struct Matrix4x3F {
1087    m: [f32; 4 * 3],
1088}
1089impl_matrix!(Matrix4x3F, 4, 3);
1090impl From<Matrix4x3F> for D2D_MATRIX_4X3_F {
1091    fn from(src: Matrix4x3F) -> D2D_MATRIX_4X3_F {
1092        Self {
1093            matrix: [
1094                [src.m[0], src.m[1], src.m[2]],
1095                [src.m[3], src.m[4], src.m[5]],
1096                [src.m[6], src.m[7], src.m[8]],
1097                [src.m[9], src.m[10], src.m[11]],
1098            ],
1099        }
1100    }
1101}
1102impl From<D2D_MATRIX_4X3_F> for Matrix4x3F {
1103    fn from(src: D2D_MATRIX_4X3_F) -> Matrix4x3F {
1104        Self {
1105            m: [
1106                src.matrix[0][0],
1107                src.matrix[0][1],
1108                src.matrix[0][2],
1109                src.matrix[1][0],
1110                src.matrix[1][1],
1111                src.matrix[1][2],
1112                src.matrix[2][0],
1113                src.matrix[2][1],
1114                src.matrix[2][2],
1115                src.matrix[3][0],
1116                src.matrix[3][1],
1117                src.matrix[3][2],
1118            ],
1119        }
1120    }
1121}
1122
1123#[derive(Clone, Copy, Debug)]
1124#[repr(C)]
1125pub struct Matrix4x4F {
1126    m: [f32; 4 * 4],
1127}
1128impl_matrix!(Matrix4x4F, 4, 4);
1129impl From<Matrix4x4F> for D2D_MATRIX_4X4_F {
1130    fn from(src: Matrix4x4F) -> D2D_MATRIX_4X4_F {
1131        Self {
1132            matrix: [
1133                [src.m[0], src.m[1], src.m[2], src.m[3]],
1134                [src.m[4], src.m[5], src.m[6], src.m[7]],
1135                [src.m[8], src.m[9], src.m[10], src.m[11]],
1136                [src.m[12], src.m[13], src.m[14], src.m[15]],
1137            ],
1138        }
1139    }
1140}
1141impl From<D2D_MATRIX_4X4_F> for Matrix4x4F {
1142    fn from(src: D2D_MATRIX_4X4_F) -> Matrix4x4F {
1143        Self {
1144            m: [
1145                src.matrix[0][0],
1146                src.matrix[0][1],
1147                src.matrix[0][2],
1148                src.matrix[0][3],
1149                src.matrix[1][0],
1150                src.matrix[1][1],
1151                src.matrix[1][2],
1152                src.matrix[1][3],
1153                src.matrix[2][0],
1154                src.matrix[2][1],
1155                src.matrix[2][2],
1156                src.matrix[2][3],
1157                src.matrix[3][0],
1158                src.matrix[3][1],
1159                src.matrix[3][2],
1160                src.matrix[3][3],
1161            ],
1162        }
1163    }
1164}
1165
1166#[derive(Clone, Copy, Debug)]
1167#[repr(C)]
1168pub struct Matrix5x4F {
1169    m: [f32; 5 * 4],
1170}
1171impl_matrix!(Matrix5x4F, 5, 4);
1172impl From<Matrix5x4F> for D2D_MATRIX_5X4_F {
1173    fn from(src: Matrix5x4F) -> D2D_MATRIX_5X4_F {
1174        Self {
1175            matrix: [
1176                [src.m[0], src.m[1], src.m[2], src.m[3]],
1177                [src.m[4], src.m[5], src.m[6], src.m[7]],
1178                [src.m[8], src.m[9], src.m[10], src.m[11]],
1179                [src.m[12], src.m[13], src.m[14], src.m[15]],
1180                [src.m[16], src.m[17], src.m[18], src.m[19]],
1181            ],
1182        }
1183    }
1184}
1185impl From<D2D_MATRIX_5X4_F> for Matrix5x4F {
1186    fn from(src: D2D_MATRIX_5X4_F) -> Matrix5x4F {
1187        Self {
1188            m: [
1189                src.matrix[0][0],
1190                src.matrix[0][1],
1191                src.matrix[0][2],
1192                src.matrix[0][3],
1193                src.matrix[1][0],
1194                src.matrix[1][1],
1195                src.matrix[1][2],
1196                src.matrix[1][3],
1197                src.matrix[2][0],
1198                src.matrix[2][1],
1199                src.matrix[2][2],
1200                src.matrix[2][3],
1201                src.matrix[3][0],
1202                src.matrix[3][1],
1203                src.matrix[3][2],
1204                src.matrix[3][3],
1205                src.matrix[4][0],
1206                src.matrix[4][1],
1207                src.matrix[4][2],
1208                src.matrix[4][3],
1209            ],
1210        }
1211    }
1212}
1213
1214pub type Point2F = crate::api::Point<f32>;
1215
1216impl From<Point2F> for D2D_POINT_2F {
1217    fn from(src: Point2F) -> D2D_POINT_2F {
1218        D2D_POINT_2F { x: src.x, y: src.y }
1219    }
1220}
1221impl From<D2D_POINT_2F> for Point2F {
1222    fn from(src: D2D_POINT_2F) -> Point2F {
1223        Point2F { x: src.x, y: src.y }
1224    }
1225}
1226impl AsRef<D2D_POINT_2F> for Point2F {
1227    fn as_ref(&self) -> &D2D_POINT_2F {
1228        unsafe {
1229            (self as *const Point2F as *const D2D_POINT_2F)
1230                .as_ref()
1231                .unwrap()
1232        }
1233    }
1234}
1235
1236pub type Point2L = crate::api::Point<i32>;
1237
1238pub type Point2U = crate::api::Point<u32>;
1239
1240impl From<Point2U> for D2D_POINT_2U {
1241    fn from(src: Point2U) -> D2D_POINT_2U {
1242        D2D_POINT_2U { x: src.x, y: src.y }
1243    }
1244}
1245impl From<D2D_POINT_2U> for Point2U {
1246    fn from(src: D2D_POINT_2U) -> Point2U {
1247        Point2U { x: src.x, y: src.y }
1248    }
1249}
1250impl AsRef<D2D_POINT_2U> for Point2U {
1251    fn as_ref(&self) -> &D2D_POINT_2U {
1252        unsafe {
1253            (self as *const Point2U as *const D2D_POINT_2U)
1254                .as_ref()
1255                .unwrap()
1256        }
1257    }
1258}
1259
1260pub type RectF = crate::api::Rect<f32>;
1261
1262impl From<RectF> for D2D_RECT_F {
1263    fn from(src: RectF) -> D2D_RECT_F {
1264        D2D_RECT_F {
1265            left: src.left,
1266            top: src.top,
1267            right: src.right,
1268            bottom: src.bottom,
1269        }
1270    }
1271}
1272impl From<D2D_RECT_F> for RectF {
1273    fn from(src: D2D_RECT_F) -> RectF {
1274        RectF {
1275            left: src.left,
1276            top: src.top,
1277            right: src.right,
1278            bottom: src.bottom,
1279        }
1280    }
1281}
1282impl AsRef<D2D_RECT_F> for RectF {
1283    fn as_ref(&self) -> &D2D_RECT_F {
1284        unsafe {
1285            (self as *const RectF as *const D2D_RECT_F)
1286                .as_ref()
1287                .unwrap()
1288        }
1289    }
1290}
1291
1292pub type RectL = crate::api::Rect<i32>;
1293
1294pub type RectU = crate::api::Rect<u32>;
1295
1296impl From<RectU> for D2D_RECT_U {
1297    fn from(src: RectU) -> D2D_RECT_U {
1298        D2D_RECT_U {
1299            left: src.left,
1300            top: src.top,
1301            right: src.right,
1302            bottom: src.bottom,
1303        }
1304    }
1305}
1306impl From<D2D_RECT_U> for RectU {
1307    fn from(src: D2D_RECT_U) -> RectU {
1308        RectU {
1309            left: src.left,
1310            top: src.top,
1311            right: src.right,
1312            bottom: src.bottom,
1313        }
1314    }
1315}
1316impl AsRef<D2D_RECT_U> for RectU {
1317    fn as_ref(&self) -> &D2D_RECT_U {
1318        unsafe {
1319            (self as *const RectU as *const D2D_RECT_U)
1320                .as_ref()
1321                .unwrap()
1322        }
1323    }
1324}
1325
1326pub type SizeF = crate::api::Size<f32>;
1327
1328impl From<SizeF> for D2D_SIZE_F {
1329    fn from(src: SizeF) -> D2D_SIZE_F {
1330        D2D_SIZE_F {
1331            width: src.width,
1332            height: src.height,
1333        }
1334    }
1335}
1336impl From<D2D_SIZE_F> for SizeF {
1337    fn from(src: D2D_SIZE_F) -> SizeF {
1338        SizeF {
1339            width: src.width,
1340            height: src.height,
1341        }
1342    }
1343}
1344impl AsRef<D2D_SIZE_F> for SizeF {
1345    fn as_ref(&self) -> &D2D_SIZE_F {
1346        unsafe {
1347            (self as *const SizeF as *const D2D_SIZE_F)
1348                .as_ref()
1349                .unwrap()
1350        }
1351    }
1352}
1353
1354pub type SizeU = crate::api::Size<u32>;
1355
1356impl From<SizeU> for D2D_SIZE_U {
1357    fn from(src: SizeU) -> D2D_SIZE_U {
1358        D2D_SIZE_U {
1359            width: src.width,
1360            height: src.height,
1361        }
1362    }
1363}
1364impl From<D2D_SIZE_U> for SizeU {
1365    fn from(src: D2D_SIZE_U) -> SizeU {
1366        SizeU {
1367            width: src.width,
1368            height: src.height,
1369        }
1370    }
1371}
1372impl AsRef<D2D_SIZE_U> for SizeU {
1373    fn as_ref(&self) -> &D2D_SIZE_U {
1374        unsafe {
1375            (self as *const SizeU as *const D2D_SIZE_U)
1376                .as_ref()
1377                .unwrap()
1378        }
1379    }
1380}
1381
1382#[derive(Clone, Copy, Debug)]
1383#[repr(C)]
1384pub struct Vector2F {
1385    pub x: f32,
1386    pub y: f32,
1387}
1388impl Vector2F {
1389    pub fn new(x: f32, y: f32) -> Self {
1390        Self { x, y }
1391    }
1392}
1393impl From<Vector2F> for D2D_VECTOR_2F {
1394    fn from(src: Vector2F) -> D2D_VECTOR_2F {
1395        D2D_VECTOR_2F { x: src.x, y: src.y }
1396    }
1397}
1398impl From<D2D_VECTOR_2F> for Vector2F {
1399    fn from(src: D2D_VECTOR_2F) -> Vector2F {
1400        Vector2F { x: src.x, y: src.y }
1401    }
1402}
1403impl AsRef<D2D_VECTOR_2F> for Vector2F {
1404    fn as_ref(&self) -> &D2D_VECTOR_2F {
1405        unsafe {
1406            (self as *const Vector2F as *const D2D_VECTOR_2F)
1407                .as_ref()
1408                .unwrap()
1409        }
1410    }
1411}
1412
1413#[derive(Clone, Copy, Debug)]
1414#[repr(C)]
1415pub struct Vector3F {
1416    pub x: f32,
1417    pub y: f32,
1418    pub z: f32,
1419}
1420impl Vector3F {
1421    pub fn new(x: f32, y: f32, z: f32) -> Self {
1422        Self { x, y, z }
1423    }
1424}
1425impl From<Vector3F> for D2D_VECTOR_3F {
1426    fn from(src: Vector3F) -> D2D_VECTOR_3F {
1427        D2D_VECTOR_3F {
1428            x: src.x,
1429            y: src.y,
1430            z: src.z,
1431        }
1432    }
1433}
1434impl From<D2D_VECTOR_3F> for Vector3F {
1435    fn from(src: D2D_VECTOR_3F) -> Vector3F {
1436        Vector3F {
1437            x: src.x,
1438            y: src.y,
1439            z: src.z,
1440        }
1441    }
1442}
1443impl AsRef<D2D_VECTOR_3F> for Vector3F {
1444    fn as_ref(&self) -> &D2D_VECTOR_3F {
1445        unsafe {
1446            (self as *const Vector3F as *const D2D_VECTOR_3F)
1447                .as_ref()
1448                .unwrap()
1449        }
1450    }
1451}
1452
1453#[derive(Clone, Copy, Debug)]
1454#[repr(C)]
1455pub struct Vector4F {
1456    pub x: f32,
1457    pub y: f32,
1458    pub z: f32,
1459    pub w: f32,
1460}
1461impl Vector4F {
1462    pub fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
1463        Self { x, y, z, w }
1464    }
1465}
1466impl From<Vector4F> for D2D_VECTOR_4F {
1467    fn from(src: Vector4F) -> D2D_VECTOR_4F {
1468        D2D_VECTOR_4F {
1469            x: src.x,
1470            y: src.y,
1471            z: src.z,
1472            w: src.w,
1473        }
1474    }
1475}
1476impl From<D2D_VECTOR_4F> for Vector4F {
1477    fn from(src: D2D_VECTOR_4F) -> Vector4F {
1478        Vector4F {
1479            x: src.x,
1480            y: src.y,
1481            z: src.z,
1482            w: src.w,
1483        }
1484    }
1485}
1486impl AsRef<D2D_VECTOR_4F> for Vector4F {
1487    fn as_ref(&self) -> &D2D_VECTOR_4F {
1488        unsafe {
1489            (self as *const Vector4F as *const D2D_VECTOR_4F)
1490                .as_ref()
1491                .unwrap()
1492        }
1493    }
1494}
1495
1496#[derive(Clone, Debug)]
1497pub struct ArcSegment {
1498    pub point: Point2F,
1499    pub size: SizeF,
1500    pub rotation_angle: f32,
1501    pub sweep_direction: SweepDirection,
1502    pub arc_size: ArcSize,
1503}
1504impl ArcSegment {
1505    fn to_c_struct(&self) -> D2D1_ARC_SEGMENT {
1506        D2D1_ARC_SEGMENT {
1507            point: self.point.into(),
1508            size: self.size.into(),
1509            rotationAngle: self.rotation_angle,
1510            sweepDirection: self.sweep_direction as u32,
1511            arcSize: self.arc_size as u32,
1512        }
1513    }
1514}
1515
1516#[derive(Clone, Debug)]
1517pub struct BezierSegment {
1518    pub point1: Point2F,
1519    pub point2: Point2F,
1520    pub point3: Point2F,
1521}
1522impl BezierSegment {
1523    pub fn new(
1524        point1: impl Into<Point2F>,
1525        point2: impl Into<Point2F>,
1526        point3: impl Into<Point2F>,
1527    ) -> Self {
1528        BezierSegment {
1529            point1: point1.into(),
1530            point2: point2.into(),
1531            point3: point3.into(),
1532        }
1533    }
1534    fn to_c_struct(&self) -> D2D1_BEZIER_SEGMENT {
1535        D2D1_BEZIER_SEGMENT {
1536            point1: self.point1.into(),
1537            point2: self.point2.into(),
1538            point3: self.point3.into(),
1539        }
1540    }
1541}
1542
1543#[derive(Clone, Debug)]
1544pub struct BitmapBrushProperties {
1545    pub extend_mode_x: ExtendMode,
1546    pub extend_mode_y: ExtendMode,
1547    pub interpolation_mode: BitmapInterpolationMode,
1548}
1549impl BitmapBrushProperties {
1550    fn to_c_struct(&self) -> D2D1_BITMAP_BRUSH_PROPERTIES {
1551        D2D1_BITMAP_BRUSH_PROPERTIES {
1552            extendModeX: self.extend_mode_x as u32,
1553            extendModeY: self.extend_mode_y as u32,
1554            interpolationMode: self.interpolation_mode as u32,
1555        }
1556    }
1557}
1558
1559#[derive(Clone, Debug)]
1560pub struct BitmapProperties {
1561    pub pixel_format: PixelFormat,
1562    pub dpi_x: f32,
1563    pub dpi_y: f32,
1564}
1565impl BitmapProperties {
1566    fn to_c_struct(&self) -> D2D1_BITMAP_PROPERTIES {
1567        D2D1_BITMAP_PROPERTIES {
1568            pixelFormat: self.pixel_format.to_c_struct(),
1569            dpiX: self.dpi_x,
1570            dpiY: self.dpi_y,
1571        }
1572    }
1573}
1574
1575#[derive(Clone, Debug)]
1576pub struct BlendDescription {
1577    pub source_blend: Blend,
1578    pub destination_blend: Blend,
1579    pub blend_operation: BlendOperation,
1580    pub source_blend_alpha: Blend,
1581    pub destination_blend_alpha: Blend,
1582    pub blend_operation_alpha: BlendOperation,
1583    pub blend_factor: [f32; 4],
1584}
1585impl BlendDescription {
1586    fn to_c_struct(&self) -> D2D1_BLEND_DESCRIPTION {
1587        D2D1_BLEND_DESCRIPTION {
1588            sourceBlend: self.source_blend as u32,
1589            destinationBlend: self.destination_blend as u32,
1590            blendOperation: self.blend_operation as u32,
1591            sourceBlendAlpha: self.source_blend_alpha as u32,
1592            destinationBlendAlpha: self.destination_blend_alpha as u32,
1593            blendOperationAlpha: self.blend_operation_alpha as u32,
1594            blendFactor: self.blend_factor.clone(),
1595        }
1596    }
1597}
1598impl From<D2D1_BLEND_DESCRIPTION> for BlendDescription {
1599    fn from(src: D2D1_BLEND_DESCRIPTION) -> BlendDescription {
1600        unsafe {
1601            BlendDescription {
1602                source_blend: std::mem::transmute(src.sourceBlend),
1603                destination_blend: std::mem::transmute(src.destinationBlend),
1604                blend_operation: std::mem::transmute(src.blendOperation),
1605                source_blend_alpha: std::mem::transmute(src.sourceBlendAlpha),
1606                destination_blend_alpha: std::mem::transmute(src.destinationBlendAlpha),
1607                blend_operation_alpha: std::mem::transmute(src.blendOperationAlpha),
1608                blend_factor: src.blendFactor,
1609            }
1610        }
1611    }
1612}
1613
1614#[derive(Clone, Copy, Debug)]
1615pub struct BrushProperties {
1616    pub opacity: f32,
1617    pub transform: Matrix3x2F,
1618}
1619impl BrushProperties {
1620    fn to_c_struct(&self) -> D2D1_BRUSH_PROPERTIES {
1621        D2D1_BRUSH_PROPERTIES {
1622            opacity: self.opacity,
1623            transform: self.transform.into(),
1624        }
1625    }
1626}
1627#[derive(Clone, Debug)]
1628pub struct CustomVertexBufferProperties<'a, 'b> {
1629    pub shader_buffer_with_input_signature: &'a [u8],
1630    pub input_elements: &'b [InputElementDesc<'b>],
1631    pub stride: u32,
1632}
1633impl<'a, 'b> CustomVertexBufferProperties<'a, 'b> {
1634    fn to_c_struct(
1635        &self,
1636    ) -> (
1637        D2D1_CUSTOM_VERTEX_BUFFER_PROPERTIES,
1638        Vec<D2D1_INPUT_ELEMENT_DESC>,
1639        Vec<std::ffi::CString>,
1640    ) {
1641        let (input_elements, names): (Vec<_>, Vec<_>) =
1642            self.input_elements.iter().map(|i| i.to_c_struct()).unzip();
1643        (
1644            D2D1_CUSTOM_VERTEX_BUFFER_PROPERTIES {
1645                shaderBufferWithInputSignature: self.shader_buffer_with_input_signature.as_ptr()
1646                    as *const u8,
1647                shaderBufferSize: self.shader_buffer_with_input_signature.len() as u32,
1648                inputElements: input_elements.as_ptr(),
1649                elementCount: input_elements.len() as u32,
1650                stride: self.stride,
1651            },
1652            input_elements,
1653            names,
1654        )
1655    }
1656}
1657
1658#[derive(Clone, Debug)]
1659pub struct DrawingStateDescription {
1660    pub antialias_mode: AntialiasMode,
1661    pub text_antialias_mode: TextAntialiasMode,
1662    pub tag1: Tag,
1663    pub tag2: Tag,
1664    pub transform: Matrix3x2F,
1665}
1666impl DrawingStateDescription {
1667    fn to_c_struct(&self) -> D2D1_DRAWING_STATE_DESCRIPTION {
1668        D2D1_DRAWING_STATE_DESCRIPTION {
1669            antialiasMode: self.antialias_mode as u32,
1670            textAntialiasMode: self.text_antialias_mode as u32,
1671            tag1: self.tag1.0,
1672            tag2: self.tag2.0,
1673            transform: self.transform.into(),
1674        }
1675    }
1676}
1677impl From<D2D1_DRAWING_STATE_DESCRIPTION> for DrawingStateDescription {
1678    fn from(src: D2D1_DRAWING_STATE_DESCRIPTION) -> DrawingStateDescription {
1679        unsafe {
1680            DrawingStateDescription {
1681                antialias_mode: std::mem::transmute(src.antialiasMode),
1682                text_antialias_mode: std::mem::transmute(src.textAntialiasMode),
1683                tag1: Tag(src.tag1),
1684                tag2: Tag(src.tag2),
1685                transform: src.transform.into(),
1686            }
1687        }
1688    }
1689}
1690
1691#[derive(Clone, Debug)]
1692pub struct Ellipse {
1693    pub point: Point2F,
1694    pub radius_x: f32,
1695    pub radius_y: f32,
1696}
1697impl Ellipse {
1698    fn to_c_struct(&self) -> D2D1_ELLIPSE {
1699        D2D1_ELLIPSE {
1700            point: self.point.into(),
1701            radiusX: self.radius_x,
1702            radiusY: self.radius_y,
1703        }
1704    }
1705}
1706impl From<D2D1_ELLIPSE> for Ellipse {
1707    fn from(src: D2D1_ELLIPSE) -> Ellipse {
1708        Ellipse {
1709            point: src.point.into(),
1710            radius_x: src.radiusX,
1711            radius_y: src.radiusY,
1712        }
1713    }
1714}
1715
1716#[derive(Clone, Debug)]
1717pub struct FactoryOptions {
1718    pub debug_level: DebugLevel,
1719}
1720impl FactoryOptions {
1721    fn to_c_struct(&self) -> D2D1_FACTORY_OPTIONS {
1722        D2D1_FACTORY_OPTIONS {
1723            debugLevel: self.debug_level as u32,
1724        }
1725    }
1726}
1727
1728#[derive(Clone, Debug)]
1729pub struct FeatureDataDoubles {
1730    pub double_precision_float_shader_ops: bool,
1731}
1732
1733#[derive(Clone, Debug)]
1734pub struct FeatureDataD3D10XHardwareOptions {
1735    pub compute_shaders_plus_raw_and_structured_buffers_via_shader_4_x: bool,
1736}
1737
1738#[derive(Clone, Debug)]
1739pub struct GradientStop {
1740    pub position: f32,
1741    pub color: ColorF,
1742}
1743impl GradientStop {
1744    fn to_c_struct(&self) -> D2D1_GRADIENT_STOP {
1745        D2D1_GRADIENT_STOP {
1746            position: self.position,
1747            color: self.color.into(),
1748        }
1749    }
1750}
1751impl From<D2D1_GRADIENT_STOP> for GradientStop {
1752    fn from(src: D2D1_GRADIENT_STOP) -> GradientStop {
1753        GradientStop {
1754            position: src.position,
1755            color: src.color.into(),
1756        }
1757    }
1758}
1759
1760#[derive(Clone, Debug)]
1761pub struct HwndRenderTargetProperties {
1762    pub hwnd: HWND,
1763    pub pixel_size: SizeU,
1764    pub present_options: Option<PresentOptions>,
1765}
1766impl HwndRenderTargetProperties {
1767    pub fn new(hwnd: &impl crate::api::WindowHandle) -> Self {
1768        Self {
1769            hwnd: hwnd.as_hwnd(),
1770            pixel_size: SizeU::new(0, 0),
1771            present_options: None,
1772        }
1773    }
1774    pub fn pixel_size(mut self, pixel_size: impl Into<SizeU>) -> Self {
1775        self.pixel_size = pixel_size.into();
1776        self
1777    }
1778    pub fn present_options(mut self, options: PresentOptions) -> Self {
1779        self.present_options = Some(options);
1780        self
1781    }
1782    fn to_c_struct(&self) -> D2D1_HWND_RENDER_TARGET_PROPERTIES {
1783        D2D1_HWND_RENDER_TARGET_PROPERTIES {
1784            hwnd: self.hwnd,
1785            pixelSize: self.pixel_size.into(),
1786            presentOptions: self
1787                .present_options
1788                .map_or(PresentOptions::None as u32, |v| v as u32),
1789        }
1790    }
1791}
1792
1793#[derive(Clone, Debug)]
1794pub struct InputDescription {
1795    pub filter: Filter,
1796    pub level_of_detail_count: u32,
1797}
1798impl InputDescription {
1799    fn to_c_struct(&self) -> D2D1_INPUT_DESCRIPTION {
1800        D2D1_INPUT_DESCRIPTION {
1801            filter: self.filter as u32,
1802            // typo in winapi-rs
1803            leveOfDetailCount: self.level_of_detail_count,
1804        }
1805    }
1806}
1807
1808#[derive(Clone, Debug)]
1809pub struct InputElementDesc<'a> {
1810    pub semantic_name: &'a str,
1811    pub semantic_index: u32,
1812    pub format: dxgi::Format,
1813    pub input_slot: u32,
1814    pub aligned_byte_offset: u32,
1815}
1816impl<'a> InputElementDesc<'a> {
1817    fn to_c_struct(&self) -> (D2D1_INPUT_ELEMENT_DESC, std::ffi::CString) {
1818        let name = std::ffi::CString::new(self.semantic_name).unwrap();
1819        (
1820            D2D1_INPUT_ELEMENT_DESC {
1821                semanticName: self.semantic_name.as_ptr() as *const i8,
1822                semanticIndex: self.semantic_index,
1823                format: self.format as u32,
1824                inputSlot: self.input_slot,
1825                alignedByteOffset: self.aligned_byte_offset,
1826            },
1827            name,
1828        )
1829    }
1830}
1831
1832#[derive(Clone, Debug)]
1833pub struct LayerParameters {
1834    pub content_bounds: RectF,
1835    pub geometric_mask: Geometry,
1836    pub mask_antialias_mode: AntialiasMode,
1837    pub mask_transform: Matrix3x2F,
1838    pub opacity: f32,
1839    pub opacity_brush: Brush,
1840    pub layer_options: Option<LayerOptions>,
1841}
1842impl LayerParameters {
1843    fn to_c_struct(&self) -> D2D1_LAYER_PARAMETERS {
1844        D2D1_LAYER_PARAMETERS {
1845            contentBounds: self.content_bounds.into(),
1846            geometricMask: self.geometric_mask.0.as_ptr() as *mut _,
1847            maskAntialiasMode: self.mask_antialias_mode as u32,
1848            maskTransform: self.mask_transform.into(),
1849            opacity: self.opacity,
1850            opacityBrush: self.opacity_brush.0.as_ptr() as *mut _,
1851            layerOptions: self
1852                .layer_options
1853                .map_or(LayerOptions::None as u32, |v| v as u32),
1854        }
1855    }
1856}
1857
1858#[derive(Clone, Debug)]
1859pub struct LinearGradientBrushProperties {
1860    pub start_point: Point2F,
1861    pub end_point: Point2F,
1862}
1863impl LinearGradientBrushProperties {
1864    fn to_c_struct(&self) -> D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES {
1865        D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES {
1866            startPoint: self.start_point.into(),
1867            endPoint: self.end_point.into(),
1868        }
1869    }
1870}
1871#[derive(Clone, Debug)]
1872pub struct PixelFormat {
1873    pub format: dxgi::Format,
1874    pub alpha_mode: AlphaMode,
1875}
1876impl PixelFormat {
1877    pub fn new() -> Self {
1878        Default::default()
1879    }
1880    fn to_c_struct(&self) -> D2D1_PIXEL_FORMAT {
1881        D2D1_PIXEL_FORMAT {
1882            format: self.format as u32,
1883            alphaMode: self.alpha_mode as u32,
1884        }
1885    }
1886}
1887impl Default for PixelFormat {
1888    fn default() -> Self {
1889        Self {
1890            format: dxgi::Format::Unknown,
1891            alpha_mode: AlphaMode::Unknown,
1892        }
1893    }
1894}
1895impl From<D2D1_PIXEL_FORMAT> for PixelFormat {
1896    fn from(src: D2D1_PIXEL_FORMAT) -> PixelFormat {
1897        unsafe {
1898            PixelFormat {
1899                format: std::mem::transmute(src.format),
1900                alpha_mode: std::mem::transmute(src.alphaMode),
1901            }
1902        }
1903    }
1904}
1905
1906/*
1907#[derive(Clone, Debug)]
1908pub struct PropertyBinding {
1909    pub property_name: String,
1910    pub set_function: fn(effect: &dyn IEffect, data: &[u8]) -> Result<(), HResult>,
1911    pub get_function: fn(effect: &dyn IEffect, data: &[u8], actualSize: &mut u32) -> Result<(), HResult>,
1912}
1913*/
1914
1915#[derive(Clone, Debug)]
1916pub struct QuadraticBezierSegment {
1917    pub point1: Point2F,
1918    pub point2: Point2F,
1919}
1920impl QuadraticBezierSegment {
1921    fn to_c_struct(&self) -> D2D1_QUADRATIC_BEZIER_SEGMENT {
1922        D2D1_QUADRATIC_BEZIER_SEGMENT {
1923            point1: self.point1.into(),
1924            point2: self.point2.into(),
1925        }
1926    }
1927}
1928
1929#[derive(Clone, Debug)]
1930pub struct RadialGradientBrushProperties {
1931    pub center: Point2F,
1932    pub gradient_origin_offset: Point2F,
1933    pub radius_x: f32,
1934    pub radius_y: f32,
1935}
1936impl RadialGradientBrushProperties {
1937    fn to_c_struct(&self) -> D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES {
1938        D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES {
1939            center: self.center.into(),
1940            gradientOriginOffset: self.gradient_origin_offset.into(),
1941            radiusX: self.radius_x,
1942            radiusY: self.radius_y,
1943        }
1944    }
1945}
1946/*
1947#[derive(Clone, Debug)]
1948pub struct ResourceUsage {
1949    pub working_texture_area_memory: usize,
1950    pub caching_texture_area_memory: usize,
1951    pub shader_cache_memory: usize,
1952}
1953impl ResourceUsage {
1954    fn to_c_struct(&self) -> D2D1_RESOURCE_USAGE {
1955        D2D1_RESOURCE_USAGE {
1956            workingTextureAreaMemory: self.working_texture_area_memory,
1957            cachingTextureAreaMemory: self.caching_texture_area_memory,
1958            shaderCacheMemory: self.shader_cache_memory,
1959        }
1960    }
1961}
1962*/
1963
1964#[derive(Clone, Debug)]
1965pub struct RenderTargetProperties {
1966    pub ty: RenderTargetType,
1967    pub pixel_format: PixelFormat,
1968    pub dpi_x: f32,
1969    pub dpi_y: f32,
1970    pub usage: RenderTargetUsage,
1971    pub min_level: FeatureLevel,
1972}
1973impl RenderTargetProperties {
1974    pub fn new() -> Self {
1975        Default::default()
1976    }
1977    pub fn render_target_type(mut self, ty: RenderTargetType) -> Self {
1978        self.ty = ty;
1979        self
1980    }
1981    pub fn pixel_format(mut self, format: PixelFormat) -> Self {
1982        self.pixel_format = format;
1983        self
1984    }
1985    pub fn dpi(mut self, x: f32, y: f32) -> Self {
1986        self.dpi_x = x;
1987        self.dpi_y = y;
1988        self
1989    }
1990    pub fn usage(mut self, usage: RenderTargetUsage) -> Self {
1991        self.usage = usage;
1992        self
1993    }
1994    pub fn min_level(mut self, min_level: FeatureLevel) -> Self {
1995        self.min_level = min_level;
1996        self
1997    }
1998    fn to_c_struct(&self) -> D2D1_RENDER_TARGET_PROPERTIES {
1999        D2D1_RENDER_TARGET_PROPERTIES {
2000            _type: self.ty as u32,
2001            pixelFormat: self.pixel_format.to_c_struct(),
2002            dpiX: self.dpi_x,
2003            dpiY: self.dpi_y,
2004            usage: self.usage as u32,
2005            minLevel: self.min_level as u32,
2006        }
2007    }
2008}
2009impl Default for RenderTargetProperties {
2010    fn default() -> Self {
2011        Self {
2012            ty: RenderTargetType::Default,
2013            pixel_format: Default::default(),
2014            dpi_x: 0.0,
2015            dpi_y: 0.0,
2016            usage: RenderTargetUsage::None,
2017            min_level: FeatureLevel::Default,
2018        }
2019    }
2020}
2021#[derive(Clone, Debug)]
2022pub struct RoundedRect {
2023    pub rect: RectF,
2024    pub radius_x: f32,
2025    pub radius_y: f32,
2026}
2027impl RoundedRect {
2028    fn to_c_struct(&self) -> D2D1_ROUNDED_RECT {
2029        D2D1_ROUNDED_RECT {
2030            rect: self.rect.into(),
2031            radiusX: self.radius_x,
2032            radiusY: self.radius_y,
2033        }
2034    }
2035}
2036impl From<D2D1_ROUNDED_RECT> for RoundedRect {
2037    fn from(src: D2D1_ROUNDED_RECT) -> RoundedRect {
2038        RoundedRect {
2039            rect: src.rect.into(),
2040            radius_x: src.radiusX,
2041            radius_y: src.radiusY,
2042        }
2043    }
2044}
2045
2046#[derive(Clone, Debug)]
2047pub struct StrokeStyleProperties {
2048    pub start_cap: CapStyle,
2049    pub end_cap: CapStyle,
2050    pub dash_cap: CapStyle,
2051    pub line_join: LineJoin,
2052    pub miter_limit: f32,
2053    pub dash_style: DashStyle,
2054    pub dash_offset: f32,
2055}
2056impl StrokeStyleProperties {
2057    fn to_c_struct(&self) -> D2D1_STROKE_STYLE_PROPERTIES {
2058        D2D1_STROKE_STYLE_PROPERTIES {
2059            startCap: self.start_cap as u32,
2060            endCap: self.end_cap as u32,
2061            dashCap: self.dash_cap as u32,
2062            lineJoin: self.line_join as u32,
2063            miterLimit: self.miter_limit,
2064            dashStyle: self.dash_style as u32,
2065            dashOffset: self.dash_offset,
2066        }
2067    }
2068}
2069
2070#[derive(Clone, Debug)]
2071pub struct Triangle {
2072    pub point1: Point2F,
2073    pub point2: Point2F,
2074    pub point3: Point2F,
2075}
2076impl Triangle {
2077    fn to_c_struct(&self) -> D2D1_TRIANGLE {
2078        D2D1_TRIANGLE {
2079            point1: self.point1.into(),
2080            point2: self.point2.into(),
2081            point3: self.point3.into(),
2082        }
2083    }
2084}
2085
2086#[derive(Clone, Debug)]
2087pub struct VertexBufferProperties<'a> {
2088    pub input_count: u32,
2089    pub usage: VertexUsage,
2090    pub data: &'a [u8],
2091    pub byte_width: u32,
2092}
2093impl<'a> VertexBufferProperties<'a> {
2094    fn to_c_struct(&self) -> D2D1_VERTEX_BUFFER_PROPERTIES {
2095        D2D1_VERTEX_BUFFER_PROPERTIES {
2096            inputCount: self.input_count,
2097            usage: self.usage as u32,
2098            data: self.data.as_ptr(),
2099            byteWidth: self.byte_width,
2100        }
2101    }
2102}
2103
2104#[derive(Clone, Debug)]
2105pub struct VertexRange {
2106    pub start_vertex: u32,
2107    pub vertex_count: u32,
2108}
2109impl VertexRange {
2110    fn to_c_struct(&self) -> D2D1_VERTEX_RANGE {
2111        D2D1_VERTEX_RANGE {
2112            startVertex: self.start_vertex,
2113            vertexCount: self.vertex_count,
2114        }
2115    }
2116}
2117
2118macro_rules! impl_bitmap {
2119    ($s: ident, $interface: ident) => {
2120        impl_image!($s, $interface);
2121        impl IBitmap for $s {
2122            fn copy_from_bitmap(
2123                &self,
2124                dest_point: impl Into<Point2U>,
2125                bitmap: &impl IBitmap,
2126                src_rect: impl Into<RectU>,
2127            ) -> Result<(), HResult> {
2128                unsafe {
2129                    hresult(
2130                        (),
2131                        self.0.CopyFromBitmap(
2132                            &dest_point.into().into(),
2133                            bitmap.as_ptr() as *mut _,
2134                            &src_rect.into().into(),
2135                        ),
2136                    )
2137                }
2138            }
2139            unsafe fn copy_from_memory<T>(
2140                &self,
2141                dest_rect: impl Into<RectU>,
2142                src_data: *const T,
2143                pitch: u32,
2144            ) -> Result<(), HResult> {
2145                hresult(
2146                    (),
2147                    self.0
2148                        .CopyFromMemory(&dest_rect.into().into(), src_data as *const _, pitch),
2149                )
2150            }
2151            fn copy_from_render_target(
2152                &self,
2153                dest_point: impl Into<Point2U>,
2154                render_target: &impl IRenderTarget,
2155                src_rect: impl Into<RectU>,
2156            ) -> Result<(), HResult> {
2157                unsafe {
2158                    hresult(
2159                        (),
2160                        self.0.CopyFromRenderTarget(
2161                            &dest_point.into().into(),
2162                            render_target.as_ptr() as *mut _,
2163                            &src_rect.into().into(),
2164                        ),
2165                    )
2166                }
2167            }
2168            fn get_dpi(&self) -> Vector2F {
2169                unsafe {
2170                    let mut v = Vector2F::new(0.0, 0.0);
2171                    self.0.GetDpi(&mut v.x, &mut v.y);
2172                    v
2173                }
2174            }
2175            fn get_pixel_format(&self) -> PixelFormat {
2176                unsafe { std::mem::transmute(self.0.GetPixelFormat()) }
2177            }
2178            fn get_pixel_size(&self) -> SizeU {
2179                unsafe { self.0.GetPixelSize().into() }
2180            }
2181            fn get_size(&self) -> SizeF {
2182                unsafe { self.0.GetSize().into() }
2183            }
2184        }
2185    };
2186}
2187
2188macro_rules! impl_bitmap_brush {
2189    ($s: ident, $interface: ident) => {
2190        impl_brush!($s, $interface);
2191        impl IBitmapBrush for $s {
2192            fn get_bitmap(&self) -> Option<Bitmap> {
2193                unsafe {
2194                    let mut p = std::ptr::null_mut();
2195                    self.0.GetBitmap(&mut p);
2196                    if p == std::ptr::null_mut() {
2197                        None
2198                    } else {
2199                        Some(Bitmap(ComPtr::from_raw(p)))
2200                    }
2201                }
2202            }
2203            fn get_extend_mode_x(&self) -> ExtendMode {
2204                unsafe { std::mem::transmute(self.0.GetExtendModeX()) }
2205            }
2206            fn get_extend_mode_y(&self) -> ExtendMode {
2207                unsafe { std::mem::transmute(self.0.GetExtendModeY()) }
2208            }
2209            fn get_interpolation_mode(&self) -> BitmapInterpolationMode {
2210                unsafe { std::mem::transmute(self.0.GetInterpolationMode()) }
2211            }
2212            fn set_bitmap(&self, bitmap: &impl IBitmap) {
2213                unsafe {
2214                    self.0.SetBitmap(bitmap.as_ptr() as *mut _);
2215                }
2216            }
2217            fn set_extend_mode_x(&self, mode: ExtendMode) {
2218                unsafe {
2219                    self.0.SetExtendModeX(mode as u32);
2220                }
2221            }
2222            fn set_extend_mode_y(&self, mode: ExtendMode) {
2223                unsafe {
2224                    self.0.SetExtendModeY(mode as u32);
2225                }
2226            }
2227            fn set_interpolation_mode(&self, mode: BitmapInterpolationMode) {
2228                unsafe {
2229                    self.0.SetInterpolationMode(mode as u32);
2230                }
2231            }
2232        }
2233    };
2234}
2235
2236macro_rules! impl_bitmap_render_target {
2237    ($s: ident, $interface: ident) => {
2238        impl_render_target!($s, $interface);
2239        impl IBitmapRenderTarget for $s {
2240            fn get_bitmap(&self) -> Result<Bitmap, HResult> {
2241                Ok(Bitmap(ComPtr::new(|| unsafe {
2242                    let mut p = std::ptr::null_mut();
2243                    let ret = self.0.GetBitmap(&mut p);
2244                    hresult(p, ret)
2245                })?))
2246            }
2247        }
2248    };
2249}
2250
2251macro_rules! impl_brush {
2252    ($s: ident, $interface: ident) => {
2253        impl_resource!($s, $interface);
2254        impl IBrush for $s {
2255            fn get_opacity(&self) -> f32 {
2256                unsafe { self.0.GetOpacity() }
2257            }
2258            fn get_transform(&self) -> Matrix3x2F {
2259                unsafe {
2260                    let mut m = Default::default();
2261                    self.0.GetTransform(&mut m);
2262                    m.into()
2263                }
2264            }
2265            fn set_opacity(&self, opacity: f32) {
2266                unsafe {
2267                    self.0.SetOpacity(opacity);
2268                }
2269            }
2270            fn set_transform(&self, m: &Matrix3x2F) {
2271                unsafe {
2272                    self.0.SetTransform(&m.clone().into());
2273                }
2274            }
2275        }
2276    };
2277}
2278
2279macro_rules! impl_dc_render_target {
2280    ($s: ident, $interface: ident) => {
2281        impl_render_target!($s, $interface);
2282        impl IDCRenderTarget for $s {
2283            fn bind_dc(
2284                &self,
2285                hdc: &impl crate::api::DeviceContextHandle,
2286                sub_rect: impl Into<RectL>,
2287            ) -> Result<(), HResult> {
2288                unsafe { hresult((), self.0.BindDC(hdc.as_hdc(), &sub_rect.into().into())) }
2289            }
2290        }
2291    };
2292}
2293
2294macro_rules! impl_drawing_state_block {
2295    ($s: ident, $interface: ident) => {
2296        impl_resource!($s, $interface);
2297        impl IDrawingStateBlock for $s {
2298            fn get_description(&self) -> DrawingStateDescription {
2299                unsafe {
2300                    let mut desc = Default::default();
2301                    self.0.GetDescription(&mut desc);
2302                    desc.into()
2303                }
2304            }
2305            #[cfg(feature = "dwrite")]
2306            fn get_text_rendering_params(&self) -> Option<crate::dwrite::RenderingParams> {
2307                unsafe {
2308                    let mut p = std::ptr::null_mut();
2309                    self.0.GetTextRenderingParams(&mut p);
2310                    if p == std::ptr::null_mut() {
2311                        None
2312                    } else {
2313                        Some(crate::dwrite::RenderingParams(ComPtr::from_raw(p)))
2314                    }
2315                }
2316            }
2317            fn set_description(&self, desc: &DrawingStateDescription) {
2318                unsafe {
2319                    self.0.SetDescription(&desc.to_c_struct());
2320                }
2321            }
2322            #[cfg(feature = "dwrite")]
2323            fn set_text_rendering_params(&self, params: &impl crate::dwrite::IRenderingParams) {
2324                unsafe {
2325                    self.0.SetTextRenderingParams(params.as_ptr() as *mut _);
2326                }
2327            }
2328        }
2329    };
2330}
2331
2332macro_rules! impl_ellipse_geometry {
2333    ($s: ident, $interface: ident) => {
2334        impl_geometry!($s, $interface);
2335        impl IEllipseGeometry for $s {
2336            fn get_ellipse(&self) -> Ellipse {
2337                unsafe {
2338                    let mut ellipse = Default::default();
2339                    self.0.GetEllipse(&mut ellipse);
2340                    ellipse.into()
2341                }
2342            }
2343        }
2344    };
2345}
2346
2347macro_rules! impl_factory {
2348    ($s: ident, $interface: ident) => {
2349        impl_interface!($s, $interface);
2350        impl IFactory for $s {
2351            fn create_dc_render_target(
2352                &self,
2353                props: &RenderTargetProperties,
2354            ) -> Result<DCRenderTarget, HResult> {
2355                Ok(DCRenderTarget(ComPtr::new(|| unsafe {
2356                    let mut p = std::ptr::null_mut();
2357                    let ret = self.0.CreateDCRenderTarget(&props.to_c_struct(), &mut p);
2358                    hresult(p, ret)
2359                })?))
2360            }
2361            #[cfg(feature = "dwrite")]
2362            fn create_drawing_state_block(
2363                &self,
2364                desc: &DrawingStateDescription,
2365                params: Option<&crate::dwrite::RenderingParams>,
2366            ) -> Result<DrawingStateBlock, HResult> {
2367                Ok(DrawingStateBlock(ComPtr::new(|| unsafe {
2368                    let mut p = std::ptr::null_mut();
2369                    let ret = self.0.CreateDrawingStateBlock(
2370                        &desc.to_c_struct(),
2371                        params.map_or(std::ptr::null_mut(), |p| p.as_ptr() as *mut _),
2372                        &mut p,
2373                    );
2374                    hresult(p, ret)
2375                })?))
2376            }
2377            #[cfg(feature = "dxgi")]
2378            fn create_dxgi_surface_render_target(
2379                &self,
2380                surface: &impl dxgi::ISurface,
2381                props: &RenderTargetProperties,
2382            ) -> Result<RenderTarget, HResult> {
2383                Ok(RenderTarget(ComPtr::new(|| unsafe {
2384                    let mut p = std::ptr::null_mut();
2385                    let ret = self.0.CreateDxgiSurfaceRenderTarget(
2386                        surface.as_ptr() as *mut _,
2387                        &props.to_c_struct(),
2388                        &mut p,
2389                    );
2390                    hresult(p, ret)
2391                })?))
2392            }
2393            fn create_ellipse_geometry(
2394                &self,
2395                ellipse: &Ellipse,
2396            ) -> Result<EllipseGeometry, HResult> {
2397                Ok(EllipseGeometry(ComPtr::new(|| unsafe {
2398                    let mut p = std::ptr::null_mut();
2399                    let ret = self.0.CreateEllipseGeometry(&ellipse.to_c_struct(), &mut p);
2400                    hresult(p, ret)
2401                })?))
2402            }
2403            fn create_geometry_group(
2404                &self,
2405                fill_mode: FillMode,
2406                geometries: &[&impl IGeometry],
2407            ) -> Result<GeometryGroup, HResult> {
2408                let mut geometries = geometries
2409                    .iter()
2410                    .map(|p| p.as_ptr() as *mut _)
2411                    .collect::<Vec<_>>();
2412                Ok(GeometryGroup(ComPtr::new(|| unsafe {
2413                    let mut p = std::ptr::null_mut();
2414                    let ret = self.0.CreateGeometryGroup(
2415                        fill_mode as u32,
2416                        geometries.as_mut_ptr(),
2417                        geometries.len() as u32,
2418                        &mut p,
2419                    );
2420                    hresult(p, ret)
2421                })?))
2422            }
2423            fn create_hwnd_render_target(
2424                &self,
2425                props: &RenderTargetProperties,
2426                hwnd_props: &HwndRenderTargetProperties,
2427            ) -> Result<HwndRenderTarget, HResult> {
2428                Ok(HwndRenderTarget(ComPtr::new(|| unsafe {
2429                    let mut p = std::ptr::null_mut();
2430                    let ret = self.0.CreateHwndRenderTarget(
2431                        &props.to_c_struct(),
2432                        &hwnd_props.to_c_struct(),
2433                        &mut p,
2434                    );
2435                    hresult(p, ret)
2436                })?))
2437            }
2438            fn create_path_geometry(&self) -> Result<PathGeometry, HResult> {
2439                Ok(PathGeometry(ComPtr::new(|| unsafe {
2440                    let mut p = std::ptr::null_mut();
2441                    let ret = self.0.CreatePathGeometry(&mut p);
2442                    hresult(p, ret)
2443                })?))
2444            }
2445            fn create_rectangle_geometry(
2446                &self,
2447                rc: impl Into<RectF>,
2448            ) -> Result<RectangleGeometry, HResult> {
2449                Ok(RectangleGeometry(ComPtr::new(|| unsafe {
2450                    let mut p = std::ptr::null_mut();
2451                    let ret = self.0.CreateRectangleGeometry(rc.into().as_ref(), &mut p);
2452                    hresult(p, ret)
2453                })?))
2454            }
2455            fn create_rounded_rectangle_geometry(
2456                &self,
2457                rc: &RoundedRect,
2458            ) -> Result<RoundedRectangleGeometry, HResult> {
2459                Ok(RoundedRectangleGeometry(ComPtr::new(|| unsafe {
2460                    let mut p = std::ptr::null_mut();
2461                    let ret = self
2462                        .0
2463                        .CreateRoundedRectangleGeometry(&rc.to_c_struct(), &mut p);
2464                    hresult(p, ret)
2465                })?))
2466            }
2467            fn create_stroke_style(
2468                &self,
2469                props: &StrokeStyleProperties,
2470                dashes: Option<&[f32]>,
2471            ) -> Result<StrokeStyle, HResult> {
2472                Ok(StrokeStyle(ComPtr::new(|| unsafe {
2473                    let mut p = std::ptr::null_mut();
2474                    let ret = self.0.CreateStrokeStyle(
2475                        &props.to_c_struct(),
2476                        dashes.map_or(std::ptr::null(), |d| d.as_ptr()),
2477                        dashes.map_or(0, |d| d.len() as u32),
2478                        &mut p,
2479                    );
2480                    hresult(p, ret)
2481                })?))
2482            }
2483            fn create_transformed_geometry(
2484                &self,
2485                src: &impl IGeometry,
2486                transform: Option<&Matrix3x2F>,
2487            ) -> Result<TransformedGeometry, HResult> {
2488                let transform = transform.map(|m| m.clone().into());
2489                Ok(TransformedGeometry(ComPtr::new(|| unsafe {
2490                    let mut p = std::ptr::null_mut();
2491                    let ret = self.0.CreateTransformedGeometry(
2492                        src.as_ptr() as *mut _,
2493                        transform
2494                            .as_ref()
2495                            .map_or(std::ptr::null(), |m| m as *const _),
2496                        &mut p,
2497                    );
2498                    hresult(p, ret)
2499                })?))
2500            }
2501            fn get_desktop_dpi(&self) -> Vector2F {
2502                unsafe {
2503                    let mut v = Vector2F::new(0.0, 0.0);
2504                    self.0.GetDesktopDpi(&mut v.x, &mut v.y);
2505                    v
2506                }
2507            }
2508            fn reload_system_metrics(&self) -> Result<(), HResult> {
2509                unsafe { hresult((), self.0.ReloadSystemMetrics()) }
2510            }
2511        }
2512    };
2513}
2514
2515macro_rules! impl_gdi_interop_render_target {
2516    ($s: ident, $interface: ident) => {
2517        impl_interface!($s, $interface);
2518        impl IGdiInteropRenderTarget for $s {
2519            fn get_dc(&self, mode: DCInitializeMode) -> Result<HDC, HResult> {
2520                unsafe {
2521                    let mut hdc = std::ptr::null_mut();
2522                    let ret = self.0.GetDC(mode as u32, &mut hdc);
2523                    hresult(hdc, ret)
2524                }
2525            }
2526            fn release_dc(&self, update: impl Into<crate::api::Rect<i32>>) -> Result<(), HResult> {
2527                unsafe { hresult((), self.0.ReleaseDC(update.into().as_ref())) }
2528            }
2529        }
2530    };
2531}
2532
2533macro_rules! impl_geometry {
2534    ($s: ident, $interface: ident) => {
2535        impl_resource!($s, $interface);
2536        impl IGeometry for $s {
2537            fn combine_with_geometry(
2538                &self,
2539                input: &impl IGeometry,
2540                mode: CombineMode,
2541                transform: Option<&Matrix3x2F>,
2542                tolerance: f32,
2543                sink: &impl ISimplifiedGeometrySink,
2544            ) -> Result<(), HResult> {
2545                let transform = transform.map(|m| m.clone().into());
2546                unsafe {
2547                    hresult(
2548                        (),
2549                        self.0.CombineWithGeometry(
2550                            input.as_ptr() as *mut _,
2551                            mode as u32,
2552                            transform
2553                                .as_ref()
2554                                .map_or(std::ptr::null(), |m| m as *const _),
2555                            tolerance,
2556                            sink.as_ptr() as *mut _,
2557                        ),
2558                    )
2559                }
2560            }
2561            fn compute_area(
2562                &self,
2563                transform: Option<&Matrix3x2F>,
2564                tolerance: f32,
2565            ) -> Result<f32, HResult> {
2566                let transform = transform.map(|m| m.clone().into());
2567                unsafe {
2568                    let mut area = 0.0;
2569                    let ret = self.0.ComputeArea(
2570                        transform
2571                            .as_ref()
2572                            .map_or(std::ptr::null(), |m| m as *const _),
2573                        tolerance,
2574                        &mut area,
2575                    );
2576                    hresult(area, ret)
2577                }
2578            }
2579            fn compute_length(
2580                &self,
2581                transform: Option<&Matrix3x2F>,
2582                tolerance: f32,
2583            ) -> Result<f32, HResult> {
2584                let transform = transform.map(|m| m.clone().into());
2585                unsafe {
2586                    let mut len = 0.0;
2587                    let ret = self.0.ComputeLength(
2588                        transform
2589                            .as_ref()
2590                            .map_or(std::ptr::null(), |m| m as *const _),
2591                        tolerance,
2592                        &mut len,
2593                    );
2594                    hresult(len, ret)
2595                }
2596            }
2597            fn compute_point_at_length(
2598                &self,
2599                length: f32,
2600                transform: Option<&Matrix3x2F>,
2601                tolerance: f32,
2602            ) -> Result<ComputePointAtLengthResult, HResult> {
2603                let transform = transform.map(|m| m.clone().into());
2604                unsafe {
2605                    let mut point = Default::default();
2606                    let mut unit_tangent_vector = Default::default();
2607                    let ret = self.0.ComputePointAtLength(
2608                        length,
2609                        transform
2610                            .as_ref()
2611                            .map_or(std::ptr::null(), |m| m as *const _),
2612                        tolerance,
2613                        &mut point,
2614                        &mut unit_tangent_vector,
2615                    );
2616                    hresult(
2617                        ComputePointAtLengthResult {
2618                            point: point.into(),
2619                            unit_tangent_vector: unit_tangent_vector.into(),
2620                        },
2621                        ret,
2622                    )
2623                }
2624            }
2625            fn fill_contains_point(
2626                &self,
2627                point: impl Into<Point2F>,
2628                transform: Option<&Matrix3x2F>,
2629                tolerance: f32,
2630            ) -> Result<bool, HResult> {
2631                let transform = transform.map(|m| m.clone().into());
2632                unsafe {
2633                    let mut contains = 0;
2634                    let ret = self.0.FillContainsPoint(
2635                        point.into().into(),
2636                        transform
2637                            .as_ref()
2638                            .map_or(std::ptr::null(), |m| m as *const _),
2639                        tolerance,
2640                        &mut contains,
2641                    );
2642                    hresult(contains == TRUE, ret)
2643                }
2644            }
2645            fn get_bounds(&self, transform: Option<&Matrix3x2F>) -> Result<RectF, HResult> {
2646                let transform = transform.map(|m| m.clone().into());
2647                unsafe {
2648                    let mut rc = Default::default();
2649                    let ret = self.0.GetBounds(
2650                        transform
2651                            .as_ref()
2652                            .map_or(std::ptr::null(), |m| m as *const _),
2653                        &mut rc,
2654                    );
2655                    hresult(rc.into(), ret)
2656                }
2657            }
2658            fn get_widened_bounds(
2659                &self,
2660                width: f32,
2661                stroke_style: &impl IStrokeStyle,
2662                transform: Option<&Matrix3x2F>,
2663                tolerance: f32,
2664            ) -> Result<RectF, HResult> {
2665                let transform = transform.map(|m| m.clone().into());
2666                unsafe {
2667                    let mut rc = Default::default();
2668                    let ret = self.0.GetWidenedBounds(
2669                        width,
2670                        stroke_style.as_ptr() as *mut _,
2671                        transform
2672                            .as_ref()
2673                            .map_or(std::ptr::null(), |m| m as *const _),
2674                        tolerance,
2675                        &mut rc,
2676                    );
2677                    hresult(rc.into(), ret)
2678                }
2679            }
2680            fn outline(
2681                &self,
2682                transform: Option<&Matrix3x2F>,
2683                tolerance: f32,
2684                sink: &impl ISimplifiedGeometrySink,
2685            ) -> Result<(), HResult> {
2686                let transform = transform.map(|m| m.clone().into());
2687                unsafe {
2688                    hresult(
2689                        (),
2690                        self.0.Outline(
2691                            transform
2692                                .as_ref()
2693                                .map_or(std::ptr::null(), |m| m as *const _),
2694                            tolerance,
2695                            sink.as_ptr() as *mut _,
2696                        ),
2697                    )
2698                }
2699            }
2700            fn simplify(
2701                &self,
2702                option: GeometrySimplificationOption,
2703                transform: Option<&Matrix3x2F>,
2704                tolerance: f32,
2705                sink: &impl ISimplifiedGeometrySink,
2706            ) -> Result<(), HResult> {
2707                let transform = transform.map(|m| m.clone().into());
2708                unsafe {
2709                    hresult(
2710                        (),
2711                        self.0.Simplify(
2712                            option as u32,
2713                            transform
2714                                .as_ref()
2715                                .map_or(std::ptr::null(), |m| m as *const _),
2716                            tolerance,
2717                            sink.as_ptr() as *mut _,
2718                        ),
2719                    )
2720                }
2721            }
2722            fn stroke_contains_point(
2723                &self,
2724                point: impl Into<Point2F>,
2725                width: f32,
2726                stroke_style: &impl IStrokeStyle,
2727                transform: Option<&Matrix3x2F>,
2728                tolerance: f32,
2729            ) -> Result<bool, HResult> {
2730                let transform = transform.map(|m| m.clone().into());
2731                unsafe {
2732                    let mut contains = 0;
2733                    let ret = self.0.StrokeContainsPoint(
2734                        point.into().into(),
2735                        width,
2736                        stroke_style.as_ptr() as *mut _,
2737                        transform
2738                            .as_ref()
2739                            .map_or(std::ptr::null(), |m| m as *const _),
2740                        tolerance,
2741                        &mut contains,
2742                    );
2743                    hresult(contains == TRUE, ret)
2744                }
2745            }
2746            fn tessellate(
2747                &self,
2748                transform: Option<&Matrix3x2F>,
2749                tolerance: f32,
2750                sink: &impl ITessellationSink,
2751            ) -> Result<(), HResult> {
2752                let transform = transform.map(|m| m.clone().into());
2753                unsafe {
2754                    hresult(
2755                        (),
2756                        self.0.Tessellate(
2757                            transform
2758                                .as_ref()
2759                                .map_or(std::ptr::null(), |m| m as *const _),
2760                            tolerance,
2761                            sink.as_ptr() as *mut _,
2762                        ),
2763                    )
2764                }
2765            }
2766            fn widen(
2767                &self,
2768                width: f32,
2769                stroke_style: &impl IStrokeStyle,
2770                transform: Option<&Matrix3x2F>,
2771                tolerance: f32,
2772                sink: &impl ISimplifiedGeometrySink,
2773            ) -> Result<(), HResult> {
2774                let transform = transform.map(|m| m.clone().into());
2775                unsafe {
2776                    hresult(
2777                        (),
2778                        self.0.Widen(
2779                            width,
2780                            stroke_style.as_ptr() as *mut _,
2781                            transform
2782                                .as_ref()
2783                                .map_or(std::ptr::null(), |m| m as *const _),
2784                            tolerance,
2785                            sink.as_ptr() as *mut _,
2786                        ),
2787                    )
2788                }
2789            }
2790        }
2791    };
2792}
2793
2794macro_rules! impl_geometry_group {
2795    ($s: ident, $interface: ident) => {
2796        impl_geometry!($s, $interface);
2797        impl IGeometryGroup for $s {
2798            fn get_fill_mode(&self) -> FillMode {
2799                unsafe { std::mem::transmute(self.0.GetFillMode()) }
2800            }
2801            fn get_source_geometries(&self) -> Vec<Geometry> {
2802                let len = self.get_source_geometry_count();
2803                unsafe {
2804                    let mut v = vec![std::ptr::null_mut(); len as usize];
2805                    self.0.GetSourceGeometries(v.as_mut_ptr(), len);
2806                    v.into_iter()
2807                        .map(|p| Geometry(ComPtr::from_raw(p)))
2808                        .collect::<Vec<_>>()
2809                }
2810            }
2811            fn get_source_geometry_count(&self) -> u32 {
2812                unsafe { self.0.GetSourceGeometryCount() }
2813            }
2814        }
2815    };
2816}
2817
2818macro_rules! impl_geometry_sink {
2819    ($s: ident, $interface: ident) => {
2820        impl_simplified_geometry_sink!($s, $interface);
2821        impl IGeometrySink for $s {
2822            fn add_arc(&self, arc: &ArcSegment) {
2823                unsafe { self.0.AddArc(&arc.to_c_struct()) }
2824            }
2825            fn add_bezier(&self, bezier: &BezierSegment) {
2826                unsafe { self.0.AddBezier(&bezier.to_c_struct()) }
2827            }
2828            fn add_line(&self, point: impl Into<Point2F>) {
2829                unsafe { self.0.AddLine(point.into().into()) }
2830            }
2831            fn add_quadratic_bezier(&self, bezier: &QuadraticBezierSegment) {
2832                unsafe { self.0.AddQuadraticBezier(&bezier.to_c_struct()) }
2833            }
2834            fn add_quadratic_beziers(&self, beziers: &[&QuadraticBezierSegment]) {
2835                let beziers = beziers
2836                    .iter()
2837                    .map(|seg| seg.to_c_struct())
2838                    .collect::<Vec<_>>();
2839                unsafe {
2840                    self.0
2841                        .AddQuadraticBeziers(beziers.as_ptr(), beziers.len() as u32);
2842                }
2843            }
2844        }
2845    };
2846}
2847
2848macro_rules! impl_gradient_stop_collection {
2849    ($s: ident, $interface: ident) => {
2850        impl_resource!($s, $interface);
2851        impl IGradientStopCollection for $s {
2852            fn get_color_interpolation_gamma(&self) -> Gamma {
2853                unsafe { std::mem::transmute(self.0.GetColorInterpolationGamma()) }
2854            }
2855            fn get_extend_mode(&self) -> ExtendMode {
2856                unsafe { std::mem::transmute(self.0.GetExtendMode()) }
2857            }
2858            fn get_gradient_stop_count(&self) -> u32 {
2859                unsafe { self.0.GetGradientStopCount() }
2860            }
2861            fn get_gradient_stops(&self) -> Vec<GradientStop> {
2862                let len = self.get_gradient_stop_count();
2863                unsafe {
2864                    let mut v = vec![Default::default(); len as usize];
2865                    self.0.GetGradientStops(v.as_mut_ptr(), len);
2866                    v.into_iter().map(|s| s.into()).collect::<Vec<_>>()
2867                }
2868            }
2869        }
2870    };
2871}
2872
2873macro_rules! impl_hwnd_render_target {
2874    ($s: ident, $interface: ident) => {
2875        impl_render_target!($s, $interface);
2876        impl IHwndRenderTarget for $s {
2877            fn check_window_state(&self) -> WindowState {
2878                unsafe { std::mem::transmute(self.0.CheckWindowState()) }
2879            }
2880            fn get_hwnd(&self) -> HWND {
2881                unsafe { self.0.GetHwnd() }
2882            }
2883            fn resize(&self, size: impl Into<SizeU>) -> Result<(), HResult> {
2884                unsafe { hresult((), self.0.Resize(size.into().as_ref())) }
2885            }
2886        }
2887    };
2888}
2889
2890macro_rules! impl_image {
2891    ($s: ident, $interface: ident) => {
2892        impl_resource!($s, $interface);
2893        impl IImage for $s {}
2894    };
2895}
2896
2897macro_rules! impl_layer {
2898    ($s: ident, $interface: ident) => {
2899        impl_resource!($s, $interface);
2900        impl ILayer for $s {
2901            fn get_size(&self) -> SizeF {
2902                unsafe { self.0.GetSize().into() }
2903            }
2904        }
2905    };
2906}
2907
2908macro_rules! impl_linear_gradient_brush {
2909    ($s: ident, $interface: ident) => {
2910        impl_brush!($s, $interface);
2911        impl ILinearGradientBrush for $s {
2912            fn get_end_point(&self) -> Point2F {
2913                unsafe { self.0.GetEndPoint().into() }
2914            }
2915            fn get_gradient_stop_collection(&self) -> GradientStopCollection {
2916                unsafe {
2917                    let mut p = std::ptr::null_mut();
2918                    self.0.GetGradientStopCollection(&mut p);
2919                    GradientStopCollection(ComPtr::from_raw(p))
2920                }
2921            }
2922            fn get_start_point(&self) -> Point2F {
2923                unsafe { self.0.GetStartPoint().into() }
2924            }
2925            fn set_end_point(&self, point: impl Into<Point2F>) {
2926                unsafe {
2927                    self.0.SetEndPoint(point.into().into());
2928                }
2929            }
2930            fn set_start_point(&self, point: impl Into<Point2F>) {
2931                unsafe {
2932                    self.0.SetStartPoint(point.into().into());
2933                }
2934            }
2935        }
2936    };
2937}
2938
2939macro_rules! impl_mesh {
2940    ($s: ident, $interface: ident) => {
2941        impl_resource!($s, $interface);
2942        impl IMesh for $s {
2943            fn open(&self) -> Result<TessellationSink, HResult> {
2944                Ok(TessellationSink(ComPtr::new(|| unsafe {
2945                    let mut p = std::ptr::null_mut();
2946                    let ret = self.0.Open(&mut p);
2947                    hresult(p, ret)
2948                })?))
2949            }
2950        }
2951    };
2952}
2953
2954macro_rules! impl_path_geometry {
2955    ($s: ident, $interface: ident) => {
2956        impl_geometry!($s, $interface);
2957        impl IPathGeometry for $s {
2958            fn get_figure_count(&self) -> Result<u32, HResult> {
2959                unsafe {
2960                    let mut count = 0;
2961                    let ret = self.0.GetFigureCount(&mut count);
2962                    hresult(count, ret)
2963                }
2964            }
2965            fn get_segment_count(&self) -> Result<u32, HResult> {
2966                unsafe {
2967                    let mut count = 0;
2968                    let ret = self.0.GetSegmentCount(&mut count);
2969                    hresult(count, ret)
2970                }
2971            }
2972            fn open(&self) -> Result<GeometrySink, HResult> {
2973                Ok(GeometrySink(ComPtr::new(|| unsafe {
2974                    let mut p = std::ptr::null_mut();
2975                    let ret = self.0.Open(&mut p);
2976                    hresult(p, ret)
2977                })?))
2978            }
2979            fn stream(&self, sink: &impl IGeometrySink) -> Result<(), HResult> {
2980                unsafe { hresult((), self.0.Stream(sink.as_ptr() as *mut _)) }
2981            }
2982        }
2983    };
2984}
2985
2986macro_rules! impl_radial_gradient_brush {
2987    ($s: ident, $interface: ident) => {
2988        impl_brush!($s, $interface);
2989        impl IRadialGradientBrush for $s {
2990            fn get_center(&self) -> Point2F {
2991                unsafe { self.0.GetCenter().into() }
2992            }
2993            fn get_gradient_origin_offset(&self) -> Point2F {
2994                unsafe { self.0.GetGradientOriginOffset().into() }
2995            }
2996            fn get_gradient_stop_collection(&self) -> GradientStopCollection {
2997                unsafe {
2998                    let mut p = std::ptr::null_mut();
2999                    self.0.GetGradientStopCollection(&mut p);
3000                    GradientStopCollection(ComPtr::from_raw(p))
3001                }
3002            }
3003            fn get_radius_x(&self) -> f32 {
3004                unsafe { self.0.GetRadiusX() }
3005            }
3006            fn get_radius_y(&self) -> f32 {
3007                unsafe { self.0.GetRadiusY() }
3008            }
3009            fn set_center(&self, center: impl Into<Point2F>) {
3010                unsafe {
3011                    self.0.SetCenter(center.into().into());
3012                }
3013            }
3014            fn set_gradient_origin_offset(&self, offset: impl Into<Point2F>) {
3015                unsafe { self.0.SetGradientOriginOffset(offset.into().into()) }
3016            }
3017            fn set_radius_x(&self, x: f32) {
3018                unsafe {
3019                    self.0.SetRadiusX(x);
3020                }
3021            }
3022            fn set_radius_y(&self, y: f32) {
3023                unsafe {
3024                    self.0.SetRadiusY(y);
3025                }
3026            }
3027        }
3028    };
3029}
3030
3031macro_rules! impl_rectangle_geometry {
3032    ($s: ident, $interface: ident) => {
3033        impl_geometry!($s, $interface);
3034        impl IRectangleGeometry for $s {
3035            fn get_rect(&self) -> RectF {
3036                unsafe {
3037                    let mut rc = Default::default();
3038                    self.0.GetRect(&mut rc);
3039                    rc.into()
3040                }
3041            }
3042        }
3043    };
3044}
3045
3046macro_rules! impl_render_target {
3047    ($s: ident, $interface: ident) => {
3048        impl_resource!($s, $interface);
3049        impl IRenderTarget for $s {
3050            fn begin_draw(&self) {
3051                unsafe {
3052                    self.0.BeginDraw();
3053                }
3054            }
3055            fn clear(&self, color: impl Into<ColorF>) {
3056                let color = color.into();
3057                unsafe {
3058                    self.0.Clear(&color.into());
3059                }
3060            }
3061            unsafe fn create_bitmap(
3062                &self,
3063                size: impl Into<SizeU>,
3064                src_data: Option<&[u8]>,
3065                pitch: u32,
3066                props: &BitmapProperties,
3067            ) -> Result<Bitmap, HResult> {
3068                Ok(Bitmap(ComPtr::new(|| {
3069                    let mut p = std::ptr::null_mut();
3070                    let ret = self.0.CreateBitmap(
3071                        size.into().into(),
3072                        src_data.map_or(std::ptr::null(), |d| d.as_ptr() as *const _),
3073                        pitch,
3074                        &props.to_c_struct(),
3075                        &mut p,
3076                    );
3077                    hresult(p, ret)
3078                })?))
3079            }
3080            fn create_bitmap_brush(
3081                &self,
3082                bitmap: &impl IBitmap,
3083                props: Option<&BitmapBrushProperties>,
3084                brush_props: Option<&BrushProperties>,
3085            ) -> Result<BitmapBrush, HResult> {
3086                let props = props.map(|p| p.to_c_struct());
3087                let brush_props = brush_props.map(|p| p.to_c_struct());
3088                Ok(BitmapBrush(ComPtr::new(|| unsafe {
3089                    let mut p = std::ptr::null_mut();
3090                    let ret = self.0.CreateBitmapBrush(
3091                        bitmap.as_ptr() as *mut _,
3092                        props.as_ref().map_or(std::ptr::null(), |p| p as *const _),
3093                        brush_props
3094                            .as_ref()
3095                            .map_or(std::ptr::null(), |p| p as *const _),
3096                        &mut p,
3097                    );
3098                    hresult(p, ret)
3099                })?))
3100            }
3101            fn create_compatible_render_target(
3102                &self,
3103                size: Option<SizeF>,
3104                pixel_size: Option<SizeU>,
3105                format: Option<&PixelFormat>,
3106                options: CompatibleRenderTargetOptions,
3107            ) -> Result<BitmapRenderTarget, HResult> {
3108                let size = size.map(|s| D2D_SIZE_F::from(s));
3109                let pixel_size = pixel_size.map(|s| D2D_SIZE_U::from(s));
3110                let format = format.map(|f| f.to_c_struct());
3111                Ok(BitmapRenderTarget(ComPtr::new(|| unsafe {
3112                    let mut p = std::ptr::null_mut();
3113                    let ret = self.0.CreateCompatibleRenderTarget(
3114                        size.as_ref().map_or(std::ptr::null(), |s| s as *const _),
3115                        pixel_size
3116                            .as_ref()
3117                            .map_or(std::ptr::null(), |s| s as *const _),
3118                        format.as_ref().map_or(std::ptr::null(), |f| f as *const _),
3119                        options as u32,
3120                        &mut p,
3121                    );
3122                    hresult(p, ret)
3123                })?))
3124            }
3125            fn create_gradient_stop_collection(
3126                &self,
3127                stops: &[GradientStop],
3128                gamma: Gamma,
3129                mode: ExtendMode,
3130            ) -> Result<GradientStopCollection, HResult> {
3131                let stops = stops.iter().map(|s| s.to_c_struct()).collect::<Vec<_>>();
3132                Ok(GradientStopCollection(ComPtr::new(|| unsafe {
3133                    let mut p = std::ptr::null_mut();
3134                    let ret = self.0.CreateGradientStopCollection(
3135                        stops.as_ptr(),
3136                        stops.len() as u32,
3137                        gamma as u32,
3138                        mode as u32,
3139                        &mut p,
3140                    );
3141                    hresult(p, ret)
3142                })?))
3143            }
3144            fn create_layer(&self, size: Option<SizeF>) -> Result<Layer, HResult> {
3145                let size = size.map(|s| s.into());
3146                Ok(Layer(ComPtr::new(|| unsafe {
3147                    let mut p = std::ptr::null_mut();
3148                    let ret = self.0.CreateLayer(
3149                        size.as_ref().map_or(std::ptr::null(), |s| s as *const _),
3150                        &mut p,
3151                    );
3152                    hresult(p, ret)
3153                })?))
3154            }
3155            fn create_linear_gradient_brush(
3156                &self,
3157                props: &LinearGradientBrushProperties,
3158                brush_props: Option<&BrushProperties>,
3159                gradient: &impl IGradientStopCollection,
3160            ) -> Result<LinearGradientBrush, HResult> {
3161                let brush_props = brush_props.map(|p| p.to_c_struct());
3162                Ok(LinearGradientBrush(ComPtr::new(|| unsafe {
3163                    let mut p = std::ptr::null_mut();
3164                    let ret = self.0.CreateLinearGradientBrush(
3165                        &props.to_c_struct(),
3166                        brush_props
3167                            .as_ref()
3168                            .map_or(std::ptr::null(), |p| p as *const _),
3169                        gradient.as_ptr() as *mut _,
3170                        &mut p,
3171                    );
3172                    hresult(p, ret)
3173                })?))
3174            }
3175            fn create_mesh(&self) -> Result<Mesh, HResult> {
3176                Ok(Mesh(ComPtr::new(|| unsafe {
3177                    let mut p = std::ptr::null_mut();
3178                    let ret = self.0.CreateMesh(&mut p);
3179                    hresult(p, ret)
3180                })?))
3181            }
3182            fn create_radial_gradient_brush(
3183                &self,
3184                props: &RadialGradientBrushProperties,
3185                brush_props: Option<&BrushProperties>,
3186                gradient: &impl IGradientStopCollection,
3187            ) -> Result<RadialGradientBrush, HResult> {
3188                let brush_props = brush_props.map(|p| p.to_c_struct());
3189                Ok(RadialGradientBrush(ComPtr::new(|| unsafe {
3190                    let mut p = std::ptr::null_mut();
3191                    let ret = self.0.CreateRadialGradientBrush(
3192                        &props.to_c_struct(),
3193                        brush_props
3194                            .as_ref()
3195                            .map_or(std::ptr::null(), |p| p as *const _),
3196                        gradient.as_ptr() as *mut _,
3197                        &mut p,
3198                    );
3199                    hresult(p, ret)
3200                })?))
3201            }
3202            fn create_solid_color_brush(
3203                &self,
3204                color: impl Into<ColorF>,
3205                brush_props: Option<&BrushProperties>,
3206            ) -> Result<SolidColorBrush, HResult> {
3207                let brush_props = brush_props.map(|p| p.to_c_struct());
3208                Ok(SolidColorBrush(ComPtr::new(|| unsafe {
3209                    let mut p = std::ptr::null_mut();
3210                    let ret = self.0.CreateSolidColorBrush(
3211                        &color.into().into(),
3212                        brush_props
3213                            .as_ref()
3214                            .map_or(std::ptr::null(), |p| p as *const _),
3215                        &mut p,
3216                    );
3217                    hresult(p, ret)
3218                })?))
3219            }
3220            fn draw_bitmap(
3221                &self,
3222                bitmap: &impl IBitmap,
3223                dest_rect: Option<&RectF>,
3224                opacity: Option<f32>,
3225                interpolation: Option<BitmapInterpolationMode>,
3226                src_rect: Option<&RectF>,
3227            ) {
3228                let dest_rect = dest_rect.map(|rc| rc.clone().into());
3229                let src_rect = src_rect.map(|rc| rc.clone().into());
3230                unsafe {
3231                    self.0.DrawBitmap(
3232                        bitmap.as_ptr() as *mut _,
3233                        dest_rect
3234                            .as_ref()
3235                            .map_or(std::ptr::null(), |rc| rc as *const _),
3236                        opacity.unwrap_or(1.0),
3237                        interpolation.map_or(0, |i| i as u32),
3238                        src_rect
3239                            .as_ref()
3240                            .map_or(std::ptr::null(), |rc| rc as *const _),
3241                    );
3242                }
3243            }
3244            fn draw_ellipse(
3245                &self,
3246                ellipse: &Ellipse,
3247                brush: &impl IBrush,
3248                width: Option<f32>,
3249                stroke_style: Option<&StrokeStyle>,
3250            ) {
3251                unsafe {
3252                    self.0.DrawEllipse(
3253                        &ellipse.to_c_struct(),
3254                        brush.as_ptr() as *mut _,
3255                        width.unwrap_or(1.0),
3256                        stroke_style.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3257                    );
3258                }
3259            }
3260            fn draw_geometry(
3261                &self,
3262                geometry: &impl IGeometry,
3263                brush: &impl IBrush,
3264                width: Option<f32>,
3265                stroke_style: Option<&StrokeStyle>,
3266            ) {
3267                unsafe {
3268                    self.0.DrawGeometry(
3269                        geometry.as_ptr() as *mut _,
3270                        brush.as_ptr() as *mut _,
3271                        width.unwrap_or(1.0),
3272                        stroke_style.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3273                    );
3274                }
3275            }
3276            #[cfg(feature = "dwrite")]
3277            fn draw_glyph_run(
3278                &self,
3279                baseline_origin: impl Into<Point2F>,
3280                glyph_run: &crate::dwrite::GlyphRun,
3281                brush: &impl IBrush,
3282                mode: crate::dwrite::MeasuringMode,
3283            ) {
3284                let (glyph_run, _) = glyph_run.to_c_struct();
3285                unsafe {
3286                    self.0.DrawGlyphRun(
3287                        baseline_origin.into().into(),
3288                        &glyph_run,
3289                        brush.as_ptr() as *mut _,
3290                        mode as u32,
3291                    );
3292                }
3293            }
3294            fn draw_line(
3295                &self,
3296                point0: impl Into<Point2F>,
3297                point1: impl Into<Point2F>,
3298                brush: &impl IBrush,
3299                width: Option<f32>,
3300                stroke_style: Option<&StrokeStyle>,
3301            ) {
3302                unsafe {
3303                    self.0.DrawLine(
3304                        point0.into().into(),
3305                        point1.into().into(),
3306                        brush.as_ptr() as *mut _,
3307                        width.unwrap_or(1.0),
3308                        stroke_style.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3309                    );
3310                }
3311            }
3312            fn draw_rectangle(
3313                &self,
3314                rect: impl Into<RectF>,
3315                brush: &impl IBrush,
3316                width: Option<f32>,
3317                stroke_style: Option<&StrokeStyle>,
3318            ) {
3319                unsafe {
3320                    self.0.DrawRectangle(
3321                        rect.into().as_ref(),
3322                        brush.as_ptr() as *mut _,
3323                        width.unwrap_or(1.0),
3324                        stroke_style.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3325                    );
3326                }
3327            }
3328            fn draw_rounded_rectangle(
3329                &self,
3330                round: &RoundedRect,
3331                brush: &impl IBrush,
3332                width: Option<f32>,
3333                stroke_style: Option<&StrokeStyle>,
3334            ) {
3335                unsafe {
3336                    self.0.DrawRoundedRectangle(
3337                        &round.to_c_struct(),
3338                        brush.as_ptr() as *mut _,
3339                        width.unwrap_or(1.0),
3340                        stroke_style.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3341                    );
3342                }
3343            }
3344            #[cfg(feature = "dwrite")]
3345            fn draw_text(
3346                &self,
3347                string: impl AsRef<str>,
3348                format: &impl crate::dwrite::ITextFormat,
3349                rect: impl Into<RectF>,
3350                fill_brush: &impl IBrush,
3351                options: Option<DrawTextOptions>,
3352                measure_mode: Option<crate::dwrite::MeasuringMode>,
3353            ) {
3354                let string = string
3355                    .as_ref()
3356                    .encode_utf16()
3357                    .chain(Some(0))
3358                    .collect::<Vec<_>>();
3359                unsafe {
3360                    self.0.DrawText(
3361                        string.as_ptr(),
3362                        string.len() as u32,
3363                        format.as_ptr() as *mut _,
3364                        rect.into().as_ref(),
3365                        fill_brush.as_ptr() as *mut _,
3366                        options.map_or(DrawTextOptions::None.0, |o| o.0),
3367                        measure_mode
3368                            .map_or(crate::dwrite::MeasuringMode::Natural as u32, |m| m as u32),
3369                    );
3370                }
3371            }
3372            #[cfg(feature = "dwrite")]
3373            fn draw_text_layout(
3374                &self,
3375                origin: impl Into<Point2F>,
3376                layout: &impl crate::dwrite::ITextLayout,
3377                fill_brush: &impl IBrush,
3378                options: Option<DrawTextOptions>,
3379            ) {
3380                unsafe {
3381                    self.0.DrawTextLayout(
3382                        origin.into().into(),
3383                        layout.as_ptr() as *mut _,
3384                        fill_brush.as_ptr() as *mut _,
3385                        options.map_or(DrawTextOptions::None.0, |o| o.0),
3386                    );
3387                }
3388            }
3389            fn end_draw(&self) -> Result<(), HResultWithTags> {
3390                unsafe {
3391                    let mut tag1 = 0;
3392                    let mut tag2 = 0;
3393                    let ret = self.0.EndDraw(&mut tag1, &mut tag2);
3394                    if ret < 0 {
3395                        return Err(HResultWithTags::new(ret, tag1, tag2));
3396                    }
3397                    Ok(())
3398                }
3399            }
3400            fn fill_ellipse(&self, ellipse: &Ellipse, brush: &impl IBrush) {
3401                unsafe {
3402                    self.0
3403                        .FillEllipse(&ellipse.to_c_struct(), brush.as_ptr() as *mut _);
3404                }
3405            }
3406            fn fill_geometry(
3407                &self,
3408                geometry: &impl IGeometry,
3409                brush: &impl IBrush,
3410                opacity: Option<&Brush>,
3411            ) {
3412                unsafe {
3413                    self.0.FillGeometry(
3414                        geometry.as_ptr() as *mut _,
3415                        brush.as_ptr() as *mut _,
3416                        opacity.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3417                    );
3418                }
3419            }
3420            fn fill_mesh(&self, mesh: &impl IMesh, brush: &impl IBrush) {
3421                unsafe {
3422                    self.0
3423                        .FillMesh(mesh.as_ptr() as *mut _, brush.as_ptr() as *mut _);
3424                }
3425            }
3426            fn fill_opacity_mask(
3427                &self,
3428                mask: &impl IBitmap,
3429                brush: &impl IBrush,
3430                content: OpacityMaskContent,
3431                dest_rect: Option<&RectF>,
3432                src_rect: Option<&RectF>,
3433            ) {
3434                unsafe {
3435                    self.0.FillOpacityMask(
3436                        mask.as_ptr() as *mut _,
3437                        brush.as_ptr() as *mut _,
3438                        content as u32,
3439                        dest_rect.map_or(std::ptr::null(), |rc| rc.as_ref()),
3440                        src_rect.map_or(std::ptr::null(), |rc| rc.as_ref()),
3441                    );
3442                }
3443            }
3444            fn fill_rectangle(&self, rect: impl Into<RectF>, brush: &impl IBrush) {
3445                unsafe {
3446                    self.0
3447                        .FillRectangle(rect.into().as_ref(), brush.as_ptr() as *mut _);
3448                }
3449            }
3450            fn fill_rounded_rectangle(&self, rounded: &RoundedRect, brush: &impl IBrush) {
3451                unsafe {
3452                    self.0
3453                        .FillRoundedRectangle(&rounded.to_c_struct(), brush.as_ptr() as *mut _);
3454                }
3455            }
3456            fn flush(&self) -> Result<(), HResultWithTags> {
3457                unsafe {
3458                    let mut tag1 = 0;
3459                    let mut tag2 = 0;
3460                    let ret = self.0.Flush(&mut tag1, &mut tag2);
3461                    if ret < 0 {
3462                        return Err(HResultWithTags::new(ret, tag1, tag2));
3463                    }
3464                    Ok(())
3465                }
3466            }
3467            fn get_antialias_mode(&self) -> AntialiasMode {
3468                unsafe { std::mem::transmute(self.0.GetAntialiasMode()) }
3469            }
3470            fn get_dpi(&self) -> Vector2F {
3471                unsafe {
3472                    let mut x = 0.0;
3473                    let mut y = 0.0;
3474                    self.0.GetDpi(&mut x, &mut y);
3475                    Vector2F::new(x, y)
3476                }
3477            }
3478            fn get_maximum_bitmap_size(&self) -> u32 {
3479                unsafe { self.0.GetMaximumBitmapSize() }
3480            }
3481            fn get_pixel_format(&self) -> PixelFormat {
3482                unsafe { self.0.GetPixelFormat().into() }
3483            }
3484            fn get_pixel_size(&self) -> SizeU {
3485                unsafe { self.0.GetPixelSize().into() }
3486            }
3487            fn get_size(&self) -> SizeF {
3488                unsafe { self.0.GetSize().into() }
3489            }
3490            fn get_tags(&self) -> (Tag, Tag) {
3491                unsafe {
3492                    let mut tag1 = 0;
3493                    let mut tag2 = 0;
3494                    self.0.GetTags(&mut tag1, &mut tag2);
3495                    (Tag(tag1), Tag(tag2))
3496                }
3497            }
3498            fn get_text_antialias_mode(&self) -> TextAntialiasMode {
3499                unsafe { std::mem::transmute(self.0.GetTextAntialiasMode()) }
3500            }
3501            #[cfg(feature = "dwrite")]
3502            fn get_text_rendering(&self) -> Option<crate::dwrite::RenderingParams> {
3503                unsafe {
3504                    let mut p = std::ptr::null_mut();
3505                    self.0.GetTextRenderingParams(&mut p);
3506                    if p == std::ptr::null_mut() {
3507                        None
3508                    } else {
3509                        Some(crate::dwrite::RenderingParams(ComPtr::from_raw(p)))
3510                    }
3511                }
3512            }
3513            fn get_transform(&self) -> Matrix3x2F {
3514                unsafe {
3515                    let mut m = Default::default();
3516                    self.0.GetTransform(&mut m);
3517                    m.into()
3518                }
3519            }
3520            fn is_supported(&self, props: &RenderTargetProperties) -> bool {
3521                unsafe { self.0.IsSupported(&props.to_c_struct()) == TRUE }
3522            }
3523            fn pop_axis_aligned_clip(&self) {
3524                unsafe {
3525                    self.0.PopAxisAlignedClip();
3526                }
3527            }
3528            fn pop_layer(&self) {
3529                unsafe {
3530                    self.0.PopLayer();
3531                }
3532            }
3533            fn push_axis_aligned_clip(&self, rect: impl Into<RectF>, mode: AntialiasMode) {
3534                unsafe {
3535                    self.0
3536                        .PushAxisAlignedClip(rect.into().as_ref(), mode as u32);
3537                }
3538            }
3539            fn push_layer(&self, params: &LayerParameters, layer: Option<&Layer>) {
3540                unsafe {
3541                    self.0.PushLayer(
3542                        &params.to_c_struct(),
3543                        layer.map_or(std::ptr::null_mut(), |p| p.0.as_ptr()),
3544                    );
3545                }
3546            }
3547            fn restore_drawing_state(&self, block: &impl IDrawingStateBlock) {
3548                unsafe {
3549                    self.0.RestoreDrawingState(block.as_ptr() as *mut _);
3550                }
3551            }
3552            fn save_drawing_state(&self, block: &impl IDrawingStateBlock) {
3553                unsafe {
3554                    self.0.SaveDrawingState(block.as_ptr() as *mut _);
3555                }
3556            }
3557            fn set_antialias_mode(&self, mode: AntialiasMode) {
3558                unsafe {
3559                    self.0.SetAntialiasMode(mode as u32);
3560                }
3561            }
3562            fn set_dpi(&self, x: f32, y: f32) {
3563                unsafe {
3564                    self.0.SetDpi(x, y);
3565                }
3566            }
3567            fn set_tags(&self, tag1: Tag, tag2: Tag) {
3568                unsafe {
3569                    self.0.SetTags(tag1.0, tag2.0);
3570                }
3571            }
3572            fn set_text_antialias_mode(&self, mode: TextAntialiasMode) {
3573                unsafe {
3574                    self.0.SetTextAntialiasMode(mode as u32);
3575                }
3576            }
3577            #[cfg(feature = "dwrite")]
3578            fn set_text_rendering_params(&self, params: Option<&crate::dwrite::RenderingParams>) {
3579                unsafe {
3580                    self.0.SetTextRenderingParams(
3581                        params.map_or(std::ptr::null_mut(), |p| p.0.as_ptr() as *mut _),
3582                    );
3583                }
3584            }
3585            fn set_transform(&self, m: &Matrix3x2F) {
3586                unsafe {
3587                    self.0.SetTransform(&m.clone().into());
3588                }
3589            }
3590        }
3591    };
3592}
3593
3594macro_rules! impl_resource {
3595    ($s: ident, $interface: ident) => {
3596        impl_interface!($s, $interface);
3597        impl IResource for $s {
3598            fn get_factory(&self) -> Factory {
3599                unsafe {
3600                    let mut p = std::ptr::null_mut();
3601                    self.0.GetFactory(&mut p);
3602                    Factory(ComPtr::from_raw(p))
3603                }
3604            }
3605        }
3606    };
3607}
3608
3609macro_rules! impl_rounded_rectangle_geometry {
3610    ($s: ident, $interface: ident) => {
3611        impl_geometry!($s, $interface);
3612        impl IRoundedRectangleGeometry for $s {
3613            fn get_rounded_rect(&self) -> RoundedRect {
3614                unsafe {
3615                    let mut rc = Default::default();
3616                    self.0.GetRoundedRect(&mut rc);
3617                    rc.into()
3618                }
3619            }
3620        }
3621    };
3622}
3623
3624macro_rules! impl_simplified_geometry_sink {
3625    ($s: ident, $interface: ident) => {
3626        impl_interface!($s, $interface);
3627        impl ISimplifiedGeometrySink for $s {
3628            fn add_beziers(&self, beziers: &[BezierSegment]) {
3629                let beziers = beziers.iter().map(|b| b.to_c_struct()).collect::<Vec<_>>();
3630                unsafe {
3631                    self.0.AddBeziers(beziers.as_ptr(), beziers.len() as u32);
3632                }
3633            }
3634            fn add_lines(&self, points: &[Point2F]) {
3635                let points = points.iter().map(|p| p.clone().into()).collect::<Vec<_>>();
3636                unsafe {
3637                    self.0.AddLines(points.as_ptr(), points.len() as u32);
3638                }
3639            }
3640            fn begin_figure(&self, point: impl Into<Point2F>, figure: FigureBegin) {
3641                unsafe {
3642                    self.0.BeginFigure(point.into().into(), figure as u32);
3643                }
3644            }
3645            fn close(&self) -> Result<(), HResult> {
3646                unsafe { hresult((), self.0.Close()) }
3647            }
3648            fn end_figure(&self, figure: FigureEnd) {
3649                unsafe {
3650                    self.0.EndFigure(figure as u32);
3651                }
3652            }
3653            fn set_fill_mode(&self, mode: FillMode) {
3654                unsafe {
3655                    self.0.SetFillMode(mode as u32);
3656                }
3657            }
3658            fn set_segment_flags(&self, flags: PathSegment) {
3659                unsafe {
3660                    self.0.SetSegmentFlags(flags as u32);
3661                }
3662            }
3663        }
3664    };
3665}
3666
3667macro_rules! impl_solid_color_brush {
3668    ($s: ident, $interface: ident) => {
3669        impl_brush!($s, $interface);
3670        impl ISolidColorBrush for $s {
3671            fn get_color(&self) -> ColorF {
3672                unsafe { self.0.GetColor().into() }
3673            }
3674            fn set_color(&self, color: impl Into<ColorF>) {
3675                unsafe {
3676                    self.0.SetColor(&color.into().into());
3677                }
3678            }
3679        }
3680    };
3681}
3682
3683macro_rules! impl_stroke_style {
3684    ($s: ident, $interface: ident) => {
3685        impl_resource!($s, $interface);
3686        impl IStrokeStyle for $s {
3687            fn get_dash_cap(&self) -> CapStyle {
3688                unsafe { std::mem::transmute(self.0.GetDashCap()) }
3689            }
3690            fn get_dashes(&self) -> Vec<f32> {
3691                let len = self.get_dashes_count();
3692                unsafe {
3693                    let mut v = vec![0.0; len as usize];
3694                    self.0.GetDashes(v.as_mut_ptr(), len);
3695                    v
3696                }
3697            }
3698            fn get_dashes_count(&self) -> u32 {
3699                unsafe { self.0.GetDashesCount() }
3700            }
3701            fn get_dash_offset(&self) -> f32 {
3702                unsafe { self.0.GetDashOffset() }
3703            }
3704            fn get_dash_style(&self) -> DashStyle {
3705                unsafe { std::mem::transmute(self.0.GetDashStyle()) }
3706            }
3707            fn get_end_cap(&self) -> CapStyle {
3708                unsafe { std::mem::transmute(self.0.GetEndCap()) }
3709            }
3710            fn get_line_join(&self) -> LineJoin {
3711                unsafe { std::mem::transmute(self.0.GetLineJoin()) }
3712            }
3713            fn get_miter_limit(&self) -> f32 {
3714                unsafe { self.0.GetMiterLimit() }
3715            }
3716            fn get_start_cap(&self) -> CapStyle {
3717                unsafe { std::mem::transmute(self.0.GetStartCap()) }
3718            }
3719        }
3720    };
3721}
3722
3723macro_rules! impl_tesselation_sink {
3724    ($s: ident, $interface: ident) => {
3725        impl_interface!($s, $interface);
3726        impl ITessellationSink for $s {
3727            fn add_triangles(&self, triangles: &[Triangle]) {
3728                let triangles = triangles
3729                    .iter()
3730                    .map(|t| t.to_c_struct())
3731                    .collect::<Vec<_>>();
3732                unsafe {
3733                    self.0
3734                        .AddTriangles(triangles.as_ptr(), triangles.len() as u32);
3735                }
3736            }
3737            fn close(&self) -> Result<(), HResult> {
3738                unsafe { hresult((), self.0.Close()) }
3739            }
3740        }
3741    };
3742}
3743
3744macro_rules! impl_transformed_geometry {
3745    ($s: ident, $interface: ident) => {
3746        impl_geometry!($s, $interface);
3747        impl ITransformedGeometry for $s {
3748            fn get_source_geometry(&self) -> Geometry {
3749                unsafe {
3750                    let mut p = std::ptr::null_mut();
3751                    self.0.GetSourceGeometry(&mut p);
3752                    Geometry(ComPtr::from_raw(p))
3753                }
3754            }
3755            fn get_transform(&self) -> Matrix3x2F {
3756                unsafe {
3757                    let mut m = Default::default();
3758                    self.0.GetTransform(&mut m);
3759                    m.into()
3760                }
3761            }
3762        }
3763    };
3764}
3765
3766pub const DEFAULT_FLATTENING_TOLERANCE: f32 = 0.25;
3767
3768pub trait IBitmap: IImage {
3769    fn copy_from_bitmap(
3770        &self,
3771        dest_point: impl Into<Point2U>,
3772        bitmap: &impl IBitmap,
3773        src_rect: impl Into<RectU>,
3774    ) -> Result<(), HResult>;
3775    unsafe fn copy_from_memory<T>(
3776        &self,
3777        dest_rect: impl Into<RectU>,
3778        src_data: *const T,
3779        pitch: u32,
3780    ) -> Result<(), HResult>;
3781    fn copy_from_render_target(
3782        &self,
3783        dest_point: impl Into<Point2U>,
3784        render_target: &impl IRenderTarget,
3785        src_rect: impl Into<RectU>,
3786    ) -> Result<(), HResult>;
3787    fn get_dpi(&self) -> Vector2F;
3788    fn get_pixel_format(&self) -> PixelFormat;
3789    fn get_pixel_size(&self) -> SizeU;
3790    fn get_size(&self) -> SizeF;
3791}
3792
3793#[derive(Clone, Debug)]
3794pub struct Bitmap(ComPtr<ID2D1Bitmap>);
3795impl_bitmap!(Bitmap, ID2D1Bitmap);
3796
3797pub trait IBitmapBrush: IBrush {
3798    fn get_bitmap(&self) -> Option<Bitmap>;
3799    fn get_extend_mode_x(&self) -> ExtendMode;
3800    fn get_extend_mode_y(&self) -> ExtendMode;
3801    fn get_interpolation_mode(&self) -> BitmapInterpolationMode;
3802    fn set_bitmap(&self, bitmap: &impl IBitmap);
3803    fn set_extend_mode_x(&self, mode: ExtendMode);
3804    fn set_extend_mode_y(&self, mode: ExtendMode);
3805    fn set_interpolation_mode(&self, mode: BitmapInterpolationMode);
3806}
3807
3808#[derive(Clone, Debug)]
3809pub struct BitmapBrush(ComPtr<ID2D1BitmapBrush>);
3810impl_bitmap_brush!(BitmapBrush, ID2D1BitmapBrush);
3811
3812pub trait IBitmapRenderTarget: IRenderTarget {
3813    fn get_bitmap(&self) -> Result<Bitmap, HResult>;
3814}
3815
3816#[derive(Clone, Debug)]
3817pub struct BitmapRenderTarget(ComPtr<ID2D1BitmapRenderTarget>);
3818impl_bitmap_render_target!(BitmapRenderTarget, ID2D1BitmapRenderTarget);
3819
3820pub trait IBrush: IResource {
3821    fn get_opacity(&self) -> f32;
3822    fn get_transform(&self) -> Matrix3x2F;
3823    fn set_opacity(&self, opacity: f32);
3824    fn set_transform(&self, m: &Matrix3x2F);
3825}
3826
3827#[derive(Clone, Debug)]
3828pub struct Brush(ComPtr<ID2D1Brush>);
3829impl_brush!(Brush, ID2D1Brush);
3830
3831pub trait IDCRenderTarget: IRenderTarget {
3832    fn bind_dc(
3833        &self,
3834        hdc: &impl crate::api::DeviceContextHandle,
3835        sub_rect: impl Into<RectL>,
3836    ) -> Result<(), HResult>;
3837}
3838
3839#[derive(Clone, Debug)]
3840pub struct DCRenderTarget(ComPtr<ID2D1DCRenderTarget>);
3841impl_dc_render_target!(DCRenderTarget, ID2D1DCRenderTarget);
3842
3843pub trait IDrawingStateBlock: IResource {
3844    fn get_description(&self) -> DrawingStateDescription;
3845    #[cfg(feature = "dwrite")]
3846    fn get_text_rendering_params(&self) -> Option<crate::dwrite::RenderingParams>;
3847    fn set_description(&self, desc: &DrawingStateDescription);
3848    #[cfg(feature = "dwrite")]
3849    fn set_text_rendering_params(&self, params: &impl crate::dwrite::IRenderingParams);
3850}
3851
3852#[derive(Clone, Debug)]
3853pub struct DrawingStateBlock(ComPtr<ID2D1DrawingStateBlock>);
3854impl_drawing_state_block!(DrawingStateBlock, ID2D1DrawingStateBlock);
3855
3856pub trait IEllipseGeometry: IGeometry {
3857    fn get_ellipse(&self) -> Ellipse;
3858}
3859
3860#[derive(Clone, Debug)]
3861pub struct EllipseGeometry(ComPtr<ID2D1EllipseGeometry>);
3862impl_ellipse_geometry!(EllipseGeometry, ID2D1EllipseGeometry);
3863
3864pub trait IFactory: Interface {
3865    fn create_dc_render_target(
3866        &self,
3867        props: &RenderTargetProperties,
3868    ) -> Result<DCRenderTarget, HResult>;
3869    #[cfg(feature = "dwrite")]
3870    fn create_drawing_state_block(
3871        &self,
3872        desc: &DrawingStateDescription,
3873        params: Option<&crate::dwrite::RenderingParams>,
3874    ) -> Result<DrawingStateBlock, HResult>;
3875    #[cfg(feature = "dxgi")]
3876    fn create_dxgi_surface_render_target(
3877        &self,
3878        surface: &impl dxgi::ISurface,
3879        props: &RenderTargetProperties,
3880    ) -> Result<RenderTarget, HResult>;
3881    fn create_ellipse_geometry(&self, ellipse: &Ellipse) -> Result<EllipseGeometry, HResult>;
3882    fn create_geometry_group(
3883        &self,
3884        fill_mode: FillMode,
3885        geometries: &[&impl IGeometry],
3886    ) -> Result<GeometryGroup, HResult>;
3887    fn create_hwnd_render_target(
3888        &self,
3889        props: &RenderTargetProperties,
3890        hwnd_props: &HwndRenderTargetProperties,
3891    ) -> Result<HwndRenderTarget, HResult>;
3892    fn create_path_geometry(&self) -> Result<PathGeometry, HResult>;
3893    fn create_rectangle_geometry(&self, rc: impl Into<RectF>)
3894        -> Result<RectangleGeometry, HResult>;
3895    fn create_rounded_rectangle_geometry(
3896        &self,
3897        rc: &RoundedRect,
3898    ) -> Result<RoundedRectangleGeometry, HResult>;
3899    fn create_stroke_style(
3900        &self,
3901        props: &StrokeStyleProperties,
3902        dashes: Option<&[f32]>,
3903    ) -> Result<StrokeStyle, HResult>;
3904    fn create_transformed_geometry(
3905        &self,
3906        src: &impl IGeometry,
3907        transform: Option<&Matrix3x2F>,
3908    ) -> Result<TransformedGeometry, HResult>;
3909    // fn create_wic_bitmap_render_target;
3910    fn get_desktop_dpi(&self) -> Vector2F;
3911    fn reload_system_metrics(&self) -> Result<(), HResult>;
3912}
3913
3914#[derive(Clone, Debug)]
3915pub struct Factory(ComPtr<ID2D1Factory>);
3916impl_factory!(Factory, ID2D1Factory);
3917
3918pub fn create_factory<T: IFactory>(
3919    factory_type: FactoryType,
3920    options: Option<&FactoryOptions>,
3921) -> Result<T, HResult> {
3922    let options = options.map(|o| o.to_c_struct());
3923    Ok(T::new(ComPtr::new(|| unsafe {
3924        let mut p = std::ptr::null_mut();
3925        let ret = D2D1CreateFactory(
3926            factory_type as u32,
3927            &T::uuidof().into(),
3928            options.as_ref().map_or(std::ptr::null(), |o| o as *const _),
3929            &mut p,
3930        );
3931        hresult(p as *mut T::APIType, ret)
3932    })?))
3933}
3934
3935pub trait IGdiInteropRenderTarget: Interface {
3936    fn get_dc(&self, mode: DCInitializeMode) -> Result<HDC, HResult>;
3937    fn release_dc(&self, update: impl Into<crate::api::Rect<i32>>) -> Result<(), HResult>;
3938}
3939
3940#[derive(Clone, Debug)]
3941pub struct GdiInteropRenderTarget(ComPtr<ID2D1GdiInteropRenderTarget>);
3942impl_gdi_interop_render_target!(GdiInteropRenderTarget, ID2D1GdiInteropRenderTarget);
3943
3944#[derive(Clone, Debug)]
3945pub struct ComputePointAtLengthResult {
3946    pub point: Point2F,
3947    pub unit_tangent_vector: Point2F,
3948}
3949
3950pub trait IGeometry: IResource {
3951    fn combine_with_geometry(
3952        &self,
3953        input: &impl IGeometry,
3954        mode: CombineMode,
3955        transform: Option<&Matrix3x2F>,
3956        tolerance: f32,
3957        sink: &impl ISimplifiedGeometrySink,
3958    ) -> Result<(), HResult>;
3959    fn compute_area(&self, transform: Option<&Matrix3x2F>, tolerance: f32) -> Result<f32, HResult>;
3960    fn compute_length(
3961        &self,
3962        transform: Option<&Matrix3x2F>,
3963        tolerance: f32,
3964    ) -> Result<f32, HResult>;
3965    fn compute_point_at_length(
3966        &self,
3967        length: f32,
3968        transform: Option<&Matrix3x2F>,
3969        tolerance: f32,
3970    ) -> Result<ComputePointAtLengthResult, HResult>;
3971    fn fill_contains_point(
3972        &self,
3973        point: impl Into<Point2F>,
3974        transform: Option<&Matrix3x2F>,
3975        tolerance: f32,
3976    ) -> Result<bool, HResult>;
3977    fn get_bounds(&self, transform: Option<&Matrix3x2F>) -> Result<RectF, HResult>;
3978    fn get_widened_bounds(
3979        &self,
3980        width: f32,
3981        stroke_style: &impl IStrokeStyle,
3982        transform: Option<&Matrix3x2F>,
3983        tolerance: f32,
3984    ) -> Result<RectF, HResult>;
3985    fn outline(
3986        &self,
3987        transform: Option<&Matrix3x2F>,
3988        tolerance: f32,
3989        sink: &impl ISimplifiedGeometrySink,
3990    ) -> Result<(), HResult>;
3991    fn simplify(
3992        &self,
3993        option: GeometrySimplificationOption,
3994        transform: Option<&Matrix3x2F>,
3995        tolerance: f32,
3996        sink: &impl ISimplifiedGeometrySink,
3997    ) -> Result<(), HResult>;
3998    fn stroke_contains_point(
3999        &self,
4000        point: impl Into<Point2F>,
4001        width: f32,
4002        stroke_style: &impl IStrokeStyle,
4003        transform: Option<&Matrix3x2F>,
4004        tolerance: f32,
4005    ) -> Result<bool, HResult>;
4006    fn tessellate(
4007        &self,
4008        transform: Option<&Matrix3x2F>,
4009        tolerance: f32,
4010        sink: &impl ITessellationSink,
4011    ) -> Result<(), HResult>;
4012    fn widen(
4013        &self,
4014        width: f32,
4015        stroke_style: &impl IStrokeStyle,
4016        transform: Option<&Matrix3x2F>,
4017        tolerance: f32,
4018        sink: &impl ISimplifiedGeometrySink,
4019    ) -> Result<(), HResult>;
4020}
4021
4022#[derive(Clone, Debug)]
4023pub struct Geometry(ComPtr<ID2D1Geometry>);
4024impl_geometry!(Geometry, ID2D1Geometry);
4025
4026pub trait IGeometryGroup: IGeometry {
4027    fn get_fill_mode(&self) -> FillMode;
4028    fn get_source_geometries(&self) -> Vec<Geometry>;
4029    fn get_source_geometry_count(&self) -> u32;
4030}
4031
4032#[derive(Clone, Debug)]
4033pub struct GeometryGroup(ComPtr<ID2D1GeometryGroup>);
4034impl_geometry_group!(GeometryGroup, ID2D1GeometryGroup);
4035
4036pub trait IGeometrySink: ISimplifiedGeometrySink {
4037    fn add_arc(&self, arc: &ArcSegment);
4038    fn add_bezier(&self, bezier: &BezierSegment);
4039    fn add_line(&self, point: impl Into<Point2F>);
4040    fn add_quadratic_bezier(&self, bezier: &QuadraticBezierSegment);
4041    fn add_quadratic_beziers(&self, beziers: &[&QuadraticBezierSegment]);
4042}
4043
4044#[derive(Clone, Debug)]
4045pub struct GeometrySink(ComPtr<ID2D1GeometrySink>);
4046impl_geometry_sink!(GeometrySink, ID2D1GeometrySink);
4047
4048pub trait IGradientStopCollection: IResource {
4049    fn get_color_interpolation_gamma(&self) -> Gamma;
4050    fn get_extend_mode(&self) -> ExtendMode;
4051    fn get_gradient_stop_count(&self) -> u32;
4052    fn get_gradient_stops(&self) -> Vec<GradientStop>;
4053}
4054
4055#[derive(Clone, Debug)]
4056pub struct GradientStopCollection(ComPtr<ID2D1GradientStopCollection>);
4057impl_gradient_stop_collection!(GradientStopCollection, ID2D1GradientStopCollection);
4058
4059pub trait IHwndRenderTarget: IRenderTarget {
4060    fn check_window_state(&self) -> WindowState;
4061    fn get_hwnd(&self) -> HWND;
4062    fn resize(&self, size: impl Into<SizeU>) -> Result<(), HResult>;
4063}
4064
4065#[derive(Clone, Debug)]
4066pub struct HwndRenderTarget(ComPtr<ID2D1HwndRenderTarget>);
4067impl_hwnd_render_target!(HwndRenderTarget, ID2D1HwndRenderTarget);
4068
4069pub trait IImage: IResource {}
4070
4071#[derive(Clone, Debug)]
4072pub struct Image(ComPtr<ID2D1Image>);
4073impl_image!(Image, ID2D1Image);
4074
4075pub trait ILayer: IResource {
4076    fn get_size(&self) -> SizeF;
4077}
4078
4079#[derive(Clone, Debug)]
4080pub struct Layer(ComPtr<ID2D1Layer>);
4081impl_layer!(Layer, ID2D1Layer);
4082
4083pub trait ILinearGradientBrush: IBrush {
4084    fn get_end_point(&self) -> Point2F;
4085    fn get_gradient_stop_collection(&self) -> GradientStopCollection;
4086    fn get_start_point(&self) -> Point2F;
4087    fn set_end_point(&self, point: impl Into<Point2F>);
4088    fn set_start_point(&self, point: impl Into<Point2F>);
4089}
4090
4091#[derive(Clone, Debug)]
4092pub struct LinearGradientBrush(ComPtr<ID2D1LinearGradientBrush>);
4093impl_linear_gradient_brush!(LinearGradientBrush, ID2D1LinearGradientBrush);
4094
4095pub trait IMesh: IResource {
4096    fn open(&self) -> Result<TessellationSink, HResult>;
4097}
4098
4099#[derive(Clone, Debug)]
4100pub struct Mesh(ComPtr<ID2D1Mesh>);
4101impl_mesh!(Mesh, ID2D1Mesh);
4102
4103pub trait IPathGeometry: IGeometry {
4104    fn get_figure_count(&self) -> Result<u32, HResult>;
4105    fn get_segment_count(&self) -> Result<u32, HResult>;
4106    fn open(&self) -> Result<GeometrySink, HResult>;
4107    fn stream(&self, sink: &impl IGeometrySink) -> Result<(), HResult>;
4108}
4109
4110#[derive(Clone, Debug)]
4111pub struct PathGeometry(ComPtr<ID2D1PathGeometry>);
4112impl_path_geometry!(PathGeometry, ID2D1PathGeometry);
4113
4114pub trait IRadialGradientBrush: IBrush {
4115    fn get_center(&self) -> Point2F;
4116    fn get_gradient_origin_offset(&self) -> Point2F;
4117    fn get_gradient_stop_collection(&self) -> GradientStopCollection;
4118    fn get_radius_x(&self) -> f32;
4119    fn get_radius_y(&self) -> f32;
4120    fn set_center(&self, center: impl Into<Point2F>);
4121    fn set_gradient_origin_offset(&self, offset: impl Into<Point2F>);
4122    fn set_radius_x(&self, x: f32);
4123    fn set_radius_y(&self, y: f32);
4124}
4125
4126#[derive(Clone, Debug)]
4127pub struct RadialGradientBrush(ComPtr<ID2D1RadialGradientBrush>);
4128impl_radial_gradient_brush!(RadialGradientBrush, ID2D1RadialGradientBrush);
4129
4130pub trait IRectangleGeometry: IGeometry {
4131    fn get_rect(&self) -> RectF;
4132}
4133
4134#[derive(Clone, Debug)]
4135pub struct RectangleGeometry(ComPtr<ID2D1RectangleGeometry>);
4136impl_rectangle_geometry!(RectangleGeometry, ID2D1RectangleGeometry);
4137
4138#[derive(Clone, Debug)]
4139pub struct HResultWithTags {
4140    pub hresult: HResult,
4141    pub tags: (Tag, Tag),
4142}
4143impl HResultWithTags {
4144    fn new(hresult: HRESULT, tag1: u64, tag2: u64) -> Self {
4145        Self {
4146            hresult: hresult.into(),
4147            tags: (Tag(tag1), Tag(tag2)),
4148        }
4149    }
4150}
4151
4152pub trait IRenderTarget: IResource {
4153    fn begin_draw(&self);
4154    fn clear(&self, color: impl Into<ColorF>);
4155    unsafe fn create_bitmap(
4156        &self,
4157        size: impl Into<SizeU>,
4158        src_data: Option<&[u8]>,
4159        pitch: u32,
4160        props: &BitmapProperties,
4161    ) -> Result<Bitmap, HResult>;
4162    fn create_bitmap_brush(
4163        &self,
4164        bitmap: &impl IBitmap,
4165        props: Option<&BitmapBrushProperties>,
4166        brush_props: Option<&BrushProperties>,
4167    ) -> Result<BitmapBrush, HResult>;
4168    // fn create_bitmap_from_wic_bitmap;
4169    fn create_compatible_render_target(
4170        &self,
4171        size: Option<SizeF>,
4172        pixel_size: Option<SizeU>,
4173        format: Option<&PixelFormat>,
4174        options: CompatibleRenderTargetOptions,
4175    ) -> Result<BitmapRenderTarget, HResult>;
4176    fn create_gradient_stop_collection(
4177        &self,
4178        stops: &[GradientStop],
4179        gamma: Gamma,
4180        mode: ExtendMode,
4181    ) -> Result<GradientStopCollection, HResult>;
4182    fn create_layer(&self, size: Option<SizeF>) -> Result<Layer, HResult>;
4183    fn create_linear_gradient_brush(
4184        &self,
4185        props: &LinearGradientBrushProperties,
4186        brush_props: Option<&BrushProperties>,
4187        gradient: &impl IGradientStopCollection,
4188    ) -> Result<LinearGradientBrush, HResult>;
4189    fn create_mesh(&self) -> Result<Mesh, HResult>;
4190    fn create_radial_gradient_brush(
4191        &self,
4192        props: &RadialGradientBrushProperties,
4193        brush_props: Option<&BrushProperties>,
4194        gradient: &impl IGradientStopCollection,
4195    ) -> Result<RadialGradientBrush, HResult>;
4196    // fn create_shared_bitmap;
4197    fn create_solid_color_brush(
4198        &self,
4199        color: impl Into<ColorF>,
4200        brush_props: Option<&BrushProperties>,
4201    ) -> Result<SolidColorBrush, HResult>;
4202    fn draw_bitmap(
4203        &self,
4204        bitmap: &impl IBitmap,
4205        dest_rect: Option<&RectF>,
4206        opacity: Option<f32>,
4207        interpolation: Option<BitmapInterpolationMode>,
4208        src_rect: Option<&RectF>,
4209    );
4210    fn draw_ellipse(
4211        &self,
4212        ellipse: &Ellipse,
4213        brush: &impl IBrush,
4214        width: Option<f32>,
4215        stroke_style: Option<&StrokeStyle>,
4216    );
4217    fn draw_geometry(
4218        &self,
4219        geometry: &impl IGeometry,
4220        brush: &impl IBrush,
4221        width: Option<f32>,
4222        stroke_style: Option<&StrokeStyle>,
4223    );
4224    #[cfg(feature = "dwrite")]
4225    fn draw_glyph_run(
4226        &self,
4227        baseline_origin: impl Into<Point2F>,
4228        glyph_run: &crate::dwrite::GlyphRun,
4229        brush: &impl IBrush,
4230        mode: crate::dwrite::MeasuringMode,
4231    );
4232    fn draw_line(
4233        &self,
4234        point0: impl Into<Point2F>,
4235        point1: impl Into<Point2F>,
4236        brush: &impl IBrush,
4237        width: Option<f32>,
4238        stroke_style: Option<&StrokeStyle>,
4239    );
4240    fn draw_rectangle(
4241        &self,
4242        rect: impl Into<RectF>,
4243        brush: &impl IBrush,
4244        width: Option<f32>,
4245        stroke_style: Option<&StrokeStyle>,
4246    );
4247    fn draw_rounded_rectangle(
4248        &self,
4249        round: &RoundedRect,
4250        brush: &impl IBrush,
4251        width: Option<f32>,
4252        stroke_style: Option<&StrokeStyle>,
4253    );
4254    #[cfg(feature = "dwrite")]
4255    fn draw_text(
4256        &self,
4257        string: impl AsRef<str>,
4258        format: &impl crate::dwrite::ITextFormat,
4259        rect: impl Into<RectF>,
4260        fill_brush: &impl IBrush,
4261        options: Option<DrawTextOptions>,
4262        measure_mode: Option<crate::dwrite::MeasuringMode>,
4263    );
4264    #[cfg(feature = "dwrite")]
4265    fn draw_text_layout(
4266        &self,
4267        origin: impl Into<Point2F>,
4268        layout: &impl crate::dwrite::ITextLayout,
4269        fill_brush: &impl IBrush,
4270        options: Option<DrawTextOptions>,
4271    );
4272    fn end_draw(&self) -> Result<(), HResultWithTags>;
4273    fn fill_ellipse(&self, ellipse: &Ellipse, brush: &impl IBrush);
4274    fn fill_geometry(
4275        &self,
4276        geometry: &impl IGeometry,
4277        brush: &impl IBrush,
4278        opacity: Option<&Brush>,
4279    );
4280    fn fill_mesh(&self, mesh: &impl IMesh, brush: &impl IBrush);
4281    fn fill_opacity_mask(
4282        &self,
4283        mask: &impl IBitmap,
4284        brush: &impl IBrush,
4285        content: OpacityMaskContent,
4286        dest_rect: Option<&RectF>,
4287        src_rect: Option<&RectF>,
4288    );
4289    fn fill_rectangle(&self, rect: impl Into<RectF>, brush: &impl IBrush);
4290    fn fill_rounded_rectangle(&self, rounded: &RoundedRect, brush: &impl IBrush);
4291    fn flush(&self) -> Result<(), HResultWithTags>;
4292    fn get_antialias_mode(&self) -> AntialiasMode;
4293    fn get_dpi(&self) -> Vector2F;
4294    fn get_maximum_bitmap_size(&self) -> u32;
4295    fn get_pixel_format(&self) -> PixelFormat;
4296    fn get_pixel_size(&self) -> SizeU;
4297    fn get_size(&self) -> SizeF;
4298    fn get_tags(&self) -> (Tag, Tag);
4299    fn get_text_antialias_mode(&self) -> TextAntialiasMode;
4300    #[cfg(feature = "dwrite")]
4301    fn get_text_rendering(&self) -> Option<crate::dwrite::RenderingParams>;
4302    fn get_transform(&self) -> Matrix3x2F;
4303    fn is_supported(&self, props: &RenderTargetProperties) -> bool;
4304    fn pop_axis_aligned_clip(&self);
4305    fn pop_layer(&self);
4306    fn push_axis_aligned_clip(&self, rect: impl Into<RectF>, mode: AntialiasMode);
4307    fn push_layer(&self, params: &LayerParameters, layer: Option<&Layer>);
4308    fn restore_drawing_state(&self, block: &impl IDrawingStateBlock);
4309    fn save_drawing_state(&self, block: &impl IDrawingStateBlock);
4310    fn set_antialias_mode(&self, mode: AntialiasMode);
4311    fn set_dpi(&self, x: f32, y: f32);
4312    fn set_tags(&self, tag1: Tag, tag2: Tag);
4313    fn set_text_antialias_mode(&self, mode: TextAntialiasMode);
4314    #[cfg(feature = "dwrite")]
4315    fn set_text_rendering_params(&self, params: Option<&crate::dwrite::RenderingParams>);
4316    fn set_transform(&self, m: &Matrix3x2F);
4317}
4318
4319#[derive(Clone, Debug)]
4320pub struct RenderTarget(ComPtr<ID2D1RenderTarget>);
4321impl_render_target!(RenderTarget, ID2D1RenderTarget);
4322
4323pub trait IResource: Interface {
4324    fn get_factory(&self) -> Factory;
4325}
4326
4327#[derive(Clone, Debug)]
4328pub struct Resource(ComPtr<ID2D1Resource>);
4329impl_resource!(Resource, ID2D1Resource);
4330
4331pub trait IRoundedRectangleGeometry: IGeometry {
4332    fn get_rounded_rect(&self) -> RoundedRect;
4333}
4334
4335#[derive(Clone, Debug)]
4336pub struct RoundedRectangleGeometry(ComPtr<ID2D1RoundedRectangleGeometry>);
4337impl_rounded_rectangle_geometry!(RoundedRectangleGeometry, ID2D1RoundedRectangleGeometry);
4338
4339pub trait ISimplifiedGeometrySink: Interface {
4340    fn add_beziers(&self, beziers: &[BezierSegment]);
4341    fn add_lines(&self, points: &[Point2F]);
4342    fn begin_figure(&self, point: impl Into<Point2F>, figure: FigureBegin);
4343    fn close(&self) -> Result<(), HResult>;
4344    fn end_figure(&self, figure: FigureEnd);
4345    fn set_fill_mode(&self, mode: FillMode);
4346    fn set_segment_flags(&self, flags: PathSegment);
4347}
4348
4349#[derive(Clone, Debug)]
4350pub struct SimplifiedGeometrySink(ComPtr<ID2D1SimplifiedGeometrySink>);
4351impl_simplified_geometry_sink!(SimplifiedGeometrySink, ID2D1SimplifiedGeometrySink);
4352
4353pub trait ISolidColorBrush: IBrush {
4354    fn get_color(&self) -> ColorF;
4355    fn set_color(&self, color: impl Into<ColorF>);
4356}
4357
4358#[derive(Clone, Debug)]
4359pub struct SolidColorBrush(ComPtr<ID2D1SolidColorBrush>);
4360impl_solid_color_brush!(SolidColorBrush, ID2D1SolidColorBrush);
4361
4362pub trait IStrokeStyle: IResource {
4363    fn get_dash_cap(&self) -> CapStyle;
4364    fn get_dashes(&self) -> Vec<f32>;
4365    fn get_dashes_count(&self) -> u32;
4366    fn get_dash_offset(&self) -> f32;
4367    fn get_dash_style(&self) -> DashStyle;
4368    fn get_end_cap(&self) -> CapStyle;
4369    fn get_line_join(&self) -> LineJoin;
4370    fn get_miter_limit(&self) -> f32;
4371    fn get_start_cap(&self) -> CapStyle;
4372}
4373
4374#[derive(Clone, Debug)]
4375pub struct StrokeStyle(ComPtr<ID2D1StrokeStyle>);
4376impl_stroke_style!(StrokeStyle, ID2D1StrokeStyle);
4377
4378pub trait ITessellationSink: Interface {
4379    fn add_triangles(&self, triangles: &[Triangle]);
4380    fn close(&self) -> Result<(), HResult>;
4381}
4382
4383#[derive(Clone, Debug)]
4384pub struct TessellationSink(ComPtr<ID2D1TessellationSink>);
4385impl_tesselation_sink!(TessellationSink, ID2D1TessellationSink);
4386
4387pub trait ITransformedGeometry: IGeometry {
4388    fn get_source_geometry(&self) -> Geometry;
4389    fn get_transform(&self) -> Matrix3x2F;
4390}
4391
4392#[derive(Clone, Debug)]
4393pub struct TransformedGeometry(ComPtr<ID2D1TransformedGeometry>);
4394impl_transformed_geometry!(TransformedGeometry, ID2D1TransformedGeometry);