1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
use crate::*; #[derive(Clone, PartialEq, Eq)] pub struct Path(pub(crate) ID2D1PathGeometry); impl Fill for Path { #[inline] fn fill(&self, dc: &ID2D1DeviceContext, brush: &ID2D1Brush) { unsafe { dc.FillGeometry(&self.0, brush, None); } } } impl Stroke for Path { #[inline] fn stroke( &self, dc: &ID2D1DeviceContext, brush: &ID2D1Brush, width: f32, style: Option<ID2D1StrokeStyle>, ) { unsafe { dc.DrawGeometry(&self.0, brush, width, style); } } } #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[repr(u32)] pub enum FigureEnd { Open = D2D1_FIGURE_END_OPEN.0, Closed = D2D1_FIGURE_END_CLOSED.0, } pub struct PathBuilder { geometry: ID2D1PathGeometry, sink: ID2D1GeometrySink, } pub struct Figure { geometry: ID2D1PathGeometry, sink: ID2D1GeometrySink, } impl PathBuilder { #[inline] pub(crate) fn new(geometry: ID2D1PathGeometry) -> Self { unsafe { let sink = { geometry.Open().unwrap() }; Self { geometry, sink } } } #[inline] pub fn begin(self, point: impl Into<Point>) -> Figure { unsafe { let point: D2D_POINT_2F = Inner(point.into()).into(); self.sink.BeginFigure(&point, D2D1_FIGURE_BEGIN_FILLED); Figure { geometry: self.geometry, sink: self.sink, } } } #[inline] pub fn build(self) -> Path { unsafe { self.sink.Close().unwrap(); Path(self.geometry) } } } impl Figure { #[inline] pub fn line_to(self, point: impl Into<Point>) -> Self { unsafe { let point: D2D_POINT_2F = Inner(point.into()).into(); self.sink.AddLine(point); self } } #[inline] pub fn quadratic_bezier_to(self, ctrl: impl Into<Point>, to: impl Into<Point>) -> Self { unsafe { let ctrl: D2D_POINT_2F = Inner(ctrl.into()).into(); let to: D2D_POINT_2F = Inner(to.into()).into(); self.sink .AddQuadraticBezier(&D2D1_QUADRATIC_BEZIER_SEGMENT { point1: ctrl, point2: to, }); self } } #[inline] pub fn cubic_bezier_to( self, c0: impl Into<Point>, c1: impl Into<Point>, to: impl Into<Point>, ) -> Self { unsafe { let c0: D2D_POINT_2F = Inner(c0.into()).into(); let c1: D2D_POINT_2F = Inner(c1.into()).into(); let to: D2D_POINT_2F = Inner(to.into()).into(); self.sink.AddBezier(&D2D1_BEZIER_SEGMENT { point1: c0, point2: c1, point3: to, }); self } } #[inline] pub fn end(self, t: FigureEnd) -> PathBuilder { unsafe { self.sink.EndFigure(D2D1_FIGURE_END(t as u32)); PathBuilder { geometry: self.geometry, sink: self.sink, } } } }