1use crate::prelude::*;
2use crate::utils::FlString;
3use fltk_sys::surface::*;
4use std::ffi::CString;
5use std::path;
6
7pub struct ImageSurface {
23 inner: *mut Fl_Image_Surface,
24}
25
26impl SurfaceDevice for ImageSurface {
27 fn is_current(&self) -> bool {
28 unsafe { Fl_Surface_Device_is_current(self.inner as *mut _) != 0 }
29 }
30
31 fn surface() -> Self {
32 unsafe {
33 let ptr = Fl_Surface_Device_surface();
34 assert!(!ptr.is_null());
35 Self {
36 inner: ptr as *mut _,
37 }
38 }
39 }
40
41 fn push_current(new_current: &ImageSurface) {
42 unsafe { Fl_Surface_Device_push_current(new_current.inner as *mut _) }
43 }
44
45 fn pop_current() {
46 unsafe {
47 Fl_Surface_Device_pop_current();
48 }
49 }
50}
51
52impl ImageSurface {
53 pub fn new(w: i32, h: i32, high_res: bool) -> ImageSurface {
55 unsafe {
56 let ptr = Fl_Image_Surface_new(w, h, i32::from(high_res));
57 assert!(!ptr.is_null());
58 ImageSurface { inner: ptr }
59 }
60 }
61
62 pub fn image(&self) -> Option<crate::image::RgbImage> {
64 unsafe {
65 let ptr = Fl_Image_Surface_image(self.inner);
66 if ptr.is_null() {
67 None
68 } else {
69 Some(crate::image::RgbImage::from_image_ptr(ptr as *mut _))
70 }
71 }
72 }
73
74 #[cfg(feature = "use-images")]
75 pub fn highres_image(&self) -> Option<crate::image::SharedImage> {
77 unsafe {
78 let ptr = Fl_Image_Surface_highres_image(self.inner);
79 if ptr.is_null() {
80 None
81 } else {
82 Some(crate::image::SharedImage::from_image_ptr(ptr as *mut _))
83 }
84 }
85 }
86
87 pub fn origin(&self) -> (i32, i32) {
89 unsafe {
90 let mut x = 0;
91 let mut y = 0;
92 Fl_Image_Surface_origin(self.inner, &mut x, &mut y);
93 (x, y)
94 }
95 }
96
97 pub fn set_origin(&mut self, x: i32, y: i32) {
99 unsafe { Fl_Image_Surface_set_origin(self.inner, x, y) }
100 }
101
102 pub fn rescale(&mut self) {
104 unsafe { Fl_Image_Surface_rescale(self.inner) }
105 }
106
107 pub fn draw<W: WidgetExt>(&self, widget: &W, delta_x: i32, delta_y: i32) {
109 unsafe {
110 Fl_Image_Surface_draw(
111 self.inner,
112 widget.as_widget_ptr() as *mut _,
113 delta_x,
114 delta_y,
115 );
116 }
117 }
118
119 pub fn draw_decorated_window<W: WindowExt>(&self, win: &W, x_offset: i32, y_offset: i32) {
121 unsafe {
122 Fl_Image_Surface_draw_decorated_window(
123 self.inner,
124 win.as_widget_ptr() as *mut _,
125 x_offset,
126 y_offset,
127 );
128 }
129 }
130}
131
132impl Drop for ImageSurface {
133 fn drop(&mut self) {
134 unsafe { Fl_Image_Surface_delete(self.inner) }
135 }
136}
137
138pub struct SvgFileSurface {
156 inner: *mut Fl_SVG_File_Surface,
157}
158
159impl SurfaceDevice for SvgFileSurface {
160 fn is_current(&self) -> bool {
161 unsafe { Fl_Surface_Device_is_current(self.inner as *mut _) != 0 }
162 }
163
164 fn surface() -> Self {
165 unsafe {
166 let ptr = Fl_Surface_Device_surface();
167 assert!(!ptr.is_null());
168 Self {
169 inner: ptr as *mut _,
170 }
171 }
172 }
173
174 fn push_current(new_current: &SvgFileSurface) {
175 unsafe { Fl_Surface_Device_push_current(new_current.inner as *mut _) }
176 }
177
178 fn pop_current() {
179 unsafe {
180 Fl_Surface_Device_pop_current();
181 }
182 }
183}
184
185impl SvgFileSurface {
186 pub fn new<P: AsRef<path::Path>>(width: i32, height: i32, path: P) -> SvgFileSurface {
190 if path.as_ref().exists() {
191 let f = std::fs::File::open(path.as_ref()).unwrap();
192 assert!(!f.metadata().unwrap().permissions().readonly());
193 } else {
194 let f = std::fs::File::create(path.as_ref()).unwrap();
195 assert!(!f.metadata().unwrap().permissions().readonly());
196 }
197 let path = CString::safe_new(path.as_ref().to_str().unwrap());
198 unsafe {
199 let ptr = Fl_SVG_File_Surface_new(width, height, path.as_ptr());
200 assert!(!ptr.is_null());
201 SvgFileSurface { inner: ptr }
202 }
203 }
204
205 pub fn set_origin(&mut self, x: i32, y: i32) {
207 unsafe { Fl_SVG_File_Surface_origin(self.inner, x, y) }
208 }
209
210 pub fn printable_rect(&self) -> (i32, i32) {
212 unsafe {
213 let mut x = 0;
214 let mut y = 0;
215 Fl_SVG_File_Surface_printable_rect(self.inner, &mut x, &mut y);
216 (x, y)
217 }
218 }
219
220 pub fn draw<W: WidgetExt>(&self, widget: &W, delta_x: i32, delta_y: i32) {
223 unsafe {
224 Fl_SVG_File_Surface_draw(
225 self.inner,
226 widget.as_widget_ptr() as *mut _,
227 delta_x,
228 delta_y,
229 );
230 }
231 }
232
233 pub fn draw_decorated_window<W: WindowExt>(&self, win: &W, x_offset: i32, y_offset: i32) {
235 unsafe {
236 Fl_SVG_File_Surface_draw_decorated_window(
237 self.inner,
238 win.as_widget_ptr() as *mut _,
239 x_offset,
240 y_offset,
241 );
242 }
243 }
244}
245
246impl Drop for SvgFileSurface {
247 fn drop(&mut self) {
248 unsafe { Fl_SVG_File_Surface_delete(self.inner) }
249 }
250}