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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
use std::convert::TryFrom; use mupdf_sys::*; use num_enum::TryFromPrimitive; use crate::{context, Error}; #[derive(Debug, Clone, Copy, PartialEq, TryFromPrimitive)] #[repr(u32)] pub enum LineCap { Butt = 0, Round = 1, Square = 2, Triangle = 3, } impl Default for LineCap { fn default() -> Self { Self::Butt } } #[derive(Debug, Clone, Copy, PartialEq, TryFromPrimitive)] #[repr(u32)] pub enum LineJoin { Miter = 0, Round = 1, Bevel = 2, MiterXps = 3, } impl Default for LineJoin { fn default() -> Self { Self::Miter } } #[derive(Debug)] pub struct StrokeState { pub(crate) inner: *mut fz_stroke_state, } impl StrokeState { pub fn new( start_cap: LineCap, dash_cap: LineCap, end_cap: LineCap, line_join: LineJoin, line_width: f32, miter_limit: f32, dash_phase: f32, dash: &[f32], ) -> Result<Self, Error> { let dash_len = dash.len() as i32; let inner = unsafe { ffi_try!(mupdf_new_stroke_state( context(), start_cap as fz_linecap, dash_cap as fz_linecap, end_cap as fz_linecap, line_join as fz_linejoin, line_width, miter_limit, dash_phase, dash.as_ptr(), dash_len )) }; Ok(Self { inner }) } pub fn try_clone(&self) -> Result<Self, Error> { let start_cap = self.start_cap(); let dash_cap = self.dash_cap(); let end_cap = self.end_cap(); let line_join = self.line_join(); let line_width = self.line_width(); let miter_limit = self.miter_limit(); let dash_phase = self.dash_phase(); let dashes = self.dashes(); Self::new( start_cap, dash_cap, end_cap, line_join, line_width, miter_limit, dash_phase, &dashes, ) } pub fn start_cap(&self) -> LineCap { LineCap::try_from(unsafe { (*self.inner).start_cap as u32 }).unwrap() } pub fn dash_cap(&self) -> LineCap { LineCap::try_from(unsafe { (*self.inner).dash_cap as u32 }).unwrap() } pub fn end_cap(&self) -> LineCap { LineCap::try_from(unsafe { (*self.inner).end_cap as u32 }).unwrap() } pub fn line_join(&self) -> LineJoin { LineJoin::try_from(unsafe { (*self.inner).linejoin as u32 }).unwrap() } pub fn line_width(&self) -> f32 { unsafe { (*self.inner).linewidth } } pub fn miter_limit(&self) -> f32 { unsafe { (*self.inner).miterlimit } } pub fn dash_phase(&self) -> f32 { unsafe { (*self.inner).dash_phase } } pub fn dashes(&self) -> Vec<f32> { unsafe { let dash_len = (*self.inner).dash_len as usize; let mut dash_list = Vec::with_capacity(dash_len); dash_list.extend_from_slice(&(*self.inner).dash_list[0..dash_len]); dash_list } } } impl Drop for StrokeState { fn drop(&mut self) { if !self.inner.is_null() { unsafe { fz_drop_stroke_state(context(), self.inner); } } } } impl Clone for StrokeState { fn clone(&self) -> StrokeState { self.try_clone().unwrap() } } impl Default for StrokeState { fn default() -> Self { let inner = unsafe { mupdf_default_stroke_state(context()) }; Self { inner } } } #[cfg(test)] mod test { use super::StrokeState; #[test] fn test_default_stroke_state() { let _stroke = StrokeState::default(); } }