1use std::ffi::{CStr, CString};
17use std::fmt;
18
19use crate::bindings;
20
21use crate::result::MagickError;
22use crate::result::Result;
23use crate::{
24 AlignType, ClipPathUnits, DecorationType, DirectionType, FillRule, GravityType, LineCap,
25 LineJoin, PaintMethod, StretchType, StyleType,
26};
27
28wand_common!(
29 DrawingWand,
30 NewDrawingWand,
31 ClearDrawingWand,
32 IsDrawingWand,
33 CloneDrawingWand,
34 DestroyDrawingWand,
35 DrawClearException,
36 DrawGetExceptionType,
37 DrawGetException
38);
39
40impl DrawingWand {
41 pub fn draw_annotation(&mut self, x: f64, y: f64, text: &str) -> Result<()> {
43 let c_string = CString::new(text).map_err(|_| "could not convert to cstring")?;
44 unsafe { bindings::DrawAnnotation(self.wand, x, y, c_string.as_ptr() as *const _) };
45 Ok(())
46 }
47
48 pub fn draw_circle(&mut self, ox: f64, oy: f64, px: f64, py: f64) {
51 unsafe {
52 bindings::DrawCircle(self.wand, ox, oy, px, py);
53 }
54 }
55
56 pub fn draw_rectangle(
59 &mut self,
60 upper_left_x: f64,
61 upper_left_y: f64,
62 lower_right_x: f64,
63 lower_right_y: f64,
64 ) {
65 unsafe {
66 bindings::DrawRectangle(
67 self.wand,
68 upper_left_x,
69 upper_left_y,
70 lower_right_x,
71 lower_right_y,
72 );
73 }
74 }
75
76 pub fn draw_round_rectangle(
79 &mut self,
80 upper_left_x: f64,
81 upper_left_y: f64,
82 lower_right_x: f64,
83 lower_right_y: f64,
84 rx: f64,
85 ry: f64,
86 ) {
87 unsafe {
88 bindings::DrawRoundRectangle(
89 self.wand,
90 upper_left_x,
91 upper_left_y,
92 lower_right_x,
93 lower_right_y,
94 rx,
95 ry,
96 );
97 }
98 }
99
100 pub fn draw_line(&mut self, sx: f64, sy: f64, ex: f64, ey: f64) {
103 unsafe {
104 bindings::DrawLine(self.wand, sx, sy, ex, ey);
105 }
106 }
107
108 pub fn draw_point(&mut self, x: f64, y: f64) {
110 unsafe {
111 bindings::DrawPoint(self.wand, x, y);
112 }
113 }
114
115 pub fn draw_arc(
118 &mut self,
119 sx: f64,
120 sy: f64,
121 ex: f64,
122 ey: f64,
123 start_degrees: f64,
124 end_degrees: f64,
125 ) {
126 unsafe {
127 bindings::DrawArc(self.wand, sx, sy, ex, ey, start_degrees, end_degrees);
128 }
129 }
130
131 pub fn draw_ellipse(
134 &mut self,
135 ox: f64,
136 oy: f64,
137 rx: f64,
138 ry: f64,
139 start_degrees: f64,
140 end_degrees: f64,
141 ) {
142 unsafe {
143 bindings::DrawEllipse(self.wand, ox, oy, rx, ry, start_degrees, end_degrees);
144 }
145 }
146
147 pub fn draw_polygon(&mut self, coordinates: &[(f64, f64)]) {
149 let points = Self::to_point_info(coordinates);
150 unsafe {
151 bindings::DrawPolygon(self.wand, points.len(), points.as_ptr());
152 }
153 }
154
155 pub fn draw_polyline(&mut self, coordinates: &[(f64, f64)]) {
158 let points = Self::to_point_info(coordinates);
159 unsafe {
160 bindings::DrawPolyline(self.wand, points.len(), points.as_ptr());
161 }
162 }
163
164 pub fn draw_bezier(&mut self, coordinates: &[(f64, f64)]) {
166 let points = Self::to_point_info(coordinates);
167 unsafe {
168 bindings::DrawBezier(self.wand, points.len(), points.as_ptr());
169 }
170 }
171
172 pub fn draw_color(&mut self, x: f64, y: f64, paint_method: PaintMethod) {
175 unsafe {
176 bindings::DrawColor(self.wand, x, y, paint_method);
177 }
178 }
179
180 fn to_point_info(coordinates: &[(f64, f64)]) -> Vec<bindings::PointInfo> {
181 coordinates
182 .iter()
183 .map(|&(x, y)| bindings::PointInfo { x, y })
184 .collect()
185 }
186
187 string_set_get!(
188 get_font, set_font, DrawGetFont, DrawSetFont
189 get_font_family, set_font_family, DrawGetFontFamily, DrawSetFontFamily
190 get_vector_graphics, set_vector_graphics, DrawGetVectorGraphics, DrawSetVectorGraphics
191 get_clip_path, set_clip_path, DrawGetClipPath, DrawSetClipPath
192 );
193
194 string_set_get_unchecked!(
195 get_text_encoding,
196 set_text_encoding,
197 DrawGetTextEncoding,
198 DrawSetTextEncoding
199 );
200
201 pixel_set_get!(
202 get_border_color, set_border_color, DrawGetBorderColor, DrawSetBorderColor
203 get_fill_color, set_fill_color, DrawGetFillColor, DrawSetFillColor
204 get_stroke_color, set_stroke_color, DrawGetStrokeColor, DrawSetStrokeColor
205 get_text_under_color, set_text_under_color, DrawGetTextUnderColor, DrawSetTextUnderColor
206 );
207
208 set_get_unchecked!(
209 get_gravity, set_gravity, DrawGetGravity, DrawSetGravity, GravityType
210 get_opacity, set_opacity, DrawGetOpacity, DrawSetOpacity, f64
211 get_clip_rule, set_clip_rule, DrawGetClipRule, DrawSetClipRule, FillRule
212 get_clip_units, set_clip_units, DrawGetClipUnits, DrawSetClipUnits, ClipPathUnits
213 get_fill_rule, set_fill_rule, DrawGetFillRule, DrawSetFillRule, FillRule
214 get_fill_opacity, set_fill_opacity, DrawGetFillOpacity, DrawSetFillOpacity, f64
215
216 get_font_size, set_font_size, DrawGetFontSize, DrawSetFontSize, f64
217 get_font_style, set_font_style, DrawGetFontStyle, DrawSetFontStyle, StyleType
218 get_font_weight, set_font_weight, DrawGetFontWeight, DrawSetFontWeight, usize
219 get_font_stretch, set_font_stretch, DrawGetFontStretch, DrawSetFontStretch, StretchType
220
221 get_stroke_dash_offset, set_stroke_dash_offset, DrawGetStrokeDashOffset, DrawSetStrokeDashOffset, f64
222 get_stroke_line_cap, set_stroke_line_cap, DrawGetStrokeLineCap, DrawSetStrokeLineCap, LineCap
223 get_stroke_line_join, set_stroke_line_join, DrawGetStrokeLineJoin, DrawSetStrokeLineJoin, LineJoin
224 get_stroke_miter_limit, set_stroke_miter_limit, DrawGetStrokeMiterLimit, DrawSetStrokeMiterLimit, usize
225 get_stroke_opacity, set_stroke_opacity, DrawGetStrokeOpacity, DrawSetStrokeOpacity, f64
226 get_stroke_width, set_stroke_width, DrawGetStrokeWidth, DrawSetStrokeWidth, f64
227 get_stroke_antialias, set_stroke_antialias, DrawGetStrokeAntialias, DrawSetStrokeAntialias, bindings::MagickBooleanType
228
229 get_text_alignment, set_text_alignment, DrawGetTextAlignment, DrawSetTextAlignment, AlignType
230 get_text_antialias, set_text_antialias, DrawGetTextAntialias, DrawSetTextAntialias, bindings::MagickBooleanType
231 get_text_decoration, set_text_decoration, DrawGetTextDecoration, DrawSetTextDecoration, DecorationType
232 get_text_direction, set_text_direction, DrawGetTextDirection, DrawSetTextDirection, DirectionType
233 get_text_kerning, set_text_kerning, DrawGetTextKerning, DrawSetTextKerning, f64
234 get_text_interline_spacing, set_text_interline_spacing, DrawGetTextInterlineSpacing, DrawSetTextInterlineSpacing, f64
235 get_text_interword_spacing, set_text_interword_spacing, DrawGetTextInterwordSpacing, DrawSetTextInterwordSpacing, f64
236 );
237}
238
239impl fmt::Debug for DrawingWand {
240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
241 writeln!(f, "DrawingWand {{")?;
242 writeln!(f, " Exception: {:?}", self.get_exception())?;
243 writeln!(f, " IsWand: {:?}", self.is_wand())?;
244 self.fmt_unchecked_settings(f, " ")?;
245 self.fmt_string_settings(f, " ")?;
246 self.fmt_string_unchecked_settings(f, " ")?;
247 self.fmt_pixel_settings(f, " ")?;
248 writeln!(f, "}}")
249 }
250}