summaryrefslogtreecommitdiffstats
path: root/third_party/rust/dwrote/src/geometry_sink_impl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/dwrote/src/geometry_sink_impl.rs')
-rw-r--r--third_party/rust/dwrote/src/geometry_sink_impl.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/third_party/rust/dwrote/src/geometry_sink_impl.rs b/third_party/rust/dwrote/src/geometry_sink_impl.rs
new file mode 100644
index 0000000000..2f2f7550a2
--- /dev/null
+++ b/third_party/rust/dwrote/src/geometry_sink_impl.rs
@@ -0,0 +1,127 @@
+#![allow(non_snake_case, non_upper_case_globals)]
+
+use std::mem;
+use std::slice;
+use std::sync::atomic::AtomicUsize;
+use winapi::shared::guiddef::REFIID;
+use winapi::shared::minwindef::{UINT, ULONG};
+use winapi::shared::winerror::S_OK;
+use winapi::um::d2d1::{ID2D1SimplifiedGeometrySink, ID2D1SimplifiedGeometrySinkVtbl};
+use winapi::um::d2d1::{D2D1_BEZIER_SEGMENT, D2D1_FIGURE_BEGIN, D2D1_FIGURE_END};
+use winapi::um::d2d1::{D2D1_FIGURE_END_CLOSED, D2D1_FILL_MODE, D2D1_PATH_SEGMENT, D2D1_POINT_2F};
+use winapi::um::unknwnbase::{IUnknown, IUnknownVtbl};
+use winapi::um::winnt::HRESULT;
+
+use crate::com_helpers::Com;
+use crate::outline_builder::OutlineBuilder;
+
+static GEOMETRY_SINK_VTBL: ID2D1SimplifiedGeometrySinkVtbl = ID2D1SimplifiedGeometrySinkVtbl {
+ parent: implement_iunknown!(static ID2D1SimplifiedGeometrySink, GeometrySinkImpl),
+ BeginFigure: GeometrySinkImpl_BeginFigure,
+ EndFigure: GeometrySinkImpl_EndFigure,
+ AddLines: GeometrySinkImpl_AddLines,
+ AddBeziers: GeometrySinkImpl_AddBeziers,
+ Close: GeometrySinkImpl_Close,
+ SetFillMode: GeometrySinkImpl_SetFillMode,
+ SetSegmentFlags: GeometrySinkImpl_SetSegmentFlags,
+};
+
+#[repr(C)]
+pub struct GeometrySinkImpl {
+ // NB: This must be the first field.
+ _refcount: AtomicUsize,
+ outline_builder: Box<dyn OutlineBuilder>,
+}
+
+impl Com<ID2D1SimplifiedGeometrySink> for GeometrySinkImpl {
+ type Vtbl = ID2D1SimplifiedGeometrySinkVtbl;
+ #[inline]
+ fn vtbl() -> &'static ID2D1SimplifiedGeometrySinkVtbl {
+ &GEOMETRY_SINK_VTBL
+ }
+}
+
+impl Com<IUnknown> for GeometrySinkImpl {
+ type Vtbl = IUnknownVtbl;
+ #[inline]
+ fn vtbl() -> &'static IUnknownVtbl {
+ &GEOMETRY_SINK_VTBL.parent
+ }
+}
+
+impl GeometrySinkImpl {
+ pub fn new(outline_builder: Box<dyn OutlineBuilder>) -> GeometrySinkImpl {
+ GeometrySinkImpl {
+ _refcount: AtomicUsize::new(1),
+ outline_builder,
+ }
+ }
+}
+
+unsafe extern "system" fn GeometrySinkImpl_BeginFigure(
+ this: *mut ID2D1SimplifiedGeometrySink,
+ start_point: D2D1_POINT_2F,
+ _: D2D1_FIGURE_BEGIN,
+) {
+ let this = GeometrySinkImpl::from_interface(this);
+ (*this)
+ .outline_builder
+ .move_to(start_point.x, start_point.y)
+}
+
+unsafe extern "system" fn GeometrySinkImpl_EndFigure(
+ this: *mut ID2D1SimplifiedGeometrySink,
+ figure_end: D2D1_FIGURE_END,
+) {
+ let this = GeometrySinkImpl::from_interface(this);
+ if figure_end == D2D1_FIGURE_END_CLOSED {
+ (*this).outline_builder.close()
+ }
+}
+
+unsafe extern "system" fn GeometrySinkImpl_AddLines(
+ this: *mut ID2D1SimplifiedGeometrySink,
+ points: *const D2D1_POINT_2F,
+ points_count: UINT,
+) {
+ let this = GeometrySinkImpl::from_interface(this);
+ let points = slice::from_raw_parts(points, points_count as usize);
+ for point in points {
+ (*this).outline_builder.line_to(point.x, point.y)
+ }
+}
+
+unsafe extern "system" fn GeometrySinkImpl_AddBeziers(
+ this: *mut ID2D1SimplifiedGeometrySink,
+ beziers: *const D2D1_BEZIER_SEGMENT,
+ beziers_count: UINT,
+) {
+ let this = GeometrySinkImpl::from_interface(this);
+ let beziers = slice::from_raw_parts(beziers, beziers_count as usize);
+ for bezier in beziers {
+ (*this).outline_builder.curve_to(
+ bezier.point1.x,
+ bezier.point1.y,
+ bezier.point2.x,
+ bezier.point2.y,
+ bezier.point3.x,
+ bezier.point3.y,
+ )
+ }
+}
+
+unsafe extern "system" fn GeometrySinkImpl_Close(_: *mut ID2D1SimplifiedGeometrySink) -> HRESULT {
+ S_OK
+}
+
+unsafe extern "system" fn GeometrySinkImpl_SetFillMode(
+ _: *mut ID2D1SimplifiedGeometrySink,
+ _: D2D1_FILL_MODE,
+) {
+}
+
+unsafe extern "system" fn GeometrySinkImpl_SetSegmentFlags(
+ _: *mut ID2D1SimplifiedGeometrySink,
+ _: D2D1_PATH_SEGMENT,
+) {
+}