use crate::prelude::*;
use crate::utils::FlString;
use fltk_sys::surface::*;
use std::ffi::CString;
use std::path;
pub struct ImageSurface {
inner: *mut Fl_Image_Surface,
}
impl SurfaceDevice for ImageSurface {
fn is_current(&self) -> bool {
unsafe { Fl_Surface_Device_is_current(self.inner as *mut _) != 0 }
}
fn surface() -> Self {
unsafe {
let ptr = Fl_Surface_Device_surface();
assert!(!ptr.is_null());
Self {
inner: ptr as *mut _,
}
}
}
fn push_current(new_current: &ImageSurface) {
unsafe { Fl_Surface_Device_push_current(new_current.inner as *mut _) }
}
fn pop_current() {
unsafe {
Fl_Surface_Device_pop_current();
}
}
}
impl ImageSurface {
pub fn new(w: i32, h: i32, high_res: bool) -> ImageSurface {
unsafe {
let ptr = Fl_Image_Surface_new(w, h, high_res as i32);
assert!(!ptr.is_null());
ImageSurface { inner: ptr }
}
}
pub fn image(&self) -> Option<crate::image::RgbImage> {
unsafe {
let ptr = Fl_Image_Surface_image(self.inner);
if ptr.is_null() {
None
} else {
Some(crate::image::RgbImage::from_image_ptr(ptr as *mut _))
}
}
}
pub fn highres_image(&self) -> Option<crate::image::SharedImage> {
unsafe {
let ptr = Fl_Image_Surface_highres_image(self.inner);
if ptr.is_null() {
None
} else {
Some(crate::image::SharedImage::from_image_ptr(ptr as *mut _))
}
}
}
pub fn origin(&self) -> (i32, i32) {
unsafe {
let mut x = 0;
let mut y = 0;
Fl_Image_Surface_origin(self.inner, &mut x, &mut y);
(x, y)
}
}
pub fn set_origin(&mut self, x: i32, y: i32) {
unsafe { Fl_Image_Surface_set_origin(self.inner, x, y) }
}
pub fn rescale(&mut self) {
unsafe { Fl_Image_Surface_rescale(self.inner) }
}
pub fn draw<W: WidgetExt>(&self, widget: &W, delta_x: i32, delta_y: i32) {
unsafe {
Fl_Image_Surface_draw(
self.inner,
widget.as_widget_ptr() as *mut _,
delta_x,
delta_y,
)
}
}
pub fn draw_decorated_window<W: WindowExt>(&self, win: &W, x_offset: i32, y_offset: i32) {
unsafe {
Fl_Image_Surface_draw_decorated_window(
self.inner,
win.as_widget_ptr() as *mut _,
x_offset,
y_offset,
)
}
}
}
impl Drop for ImageSurface {
fn drop(&mut self) {
unsafe { Fl_Image_Surface_delete(self.inner) }
}
}
pub struct SvgFileSurface {
inner: *mut Fl_SVG_File_Surface,
}
impl SurfaceDevice for SvgFileSurface {
fn is_current(&self) -> bool {
unsafe { Fl_Surface_Device_is_current(self.inner as *mut _) != 0 }
}
fn surface() -> Self {
unsafe {
let ptr = Fl_Surface_Device_surface();
assert!(!ptr.is_null());
Self {
inner: ptr as *mut _,
}
}
}
fn push_current(new_current: &SvgFileSurface) {
unsafe { Fl_Surface_Device_push_current(new_current.inner as *mut _) }
}
fn pop_current() {
unsafe {
Fl_Surface_Device_pop_current();
}
}
}
impl SvgFileSurface {
pub fn new<P: AsRef<path::Path>>(width: i32, height: i32, path: P) -> SvgFileSurface {
if path.as_ref().exists() {
let f = std::fs::File::open(path.as_ref()).unwrap();
assert!(!f.metadata().unwrap().permissions().readonly());
} else {
let f = std::fs::File::create(path.as_ref()).unwrap();
assert!(!f.metadata().unwrap().permissions().readonly());
}
let path = CString::safe_new(path.as_ref().to_str().unwrap());
unsafe {
let ptr = Fl_SVG_File_Surface_new(width, height, path.as_ptr());
assert!(!ptr.is_null());
SvgFileSurface { inner: ptr }
}
}
pub fn set_origin(&mut self, x: i32, y: i32) {
unsafe { Fl_SVG_File_Surface_origin(self.inner, x, y) }
}
pub fn printable_rect(&self) -> (i32, i32) {
unsafe {
let mut x = 0;
let mut y = 0;
Fl_SVG_File_Surface_printable_rect(self.inner, &mut x, &mut y);
(x, y)
}
}
pub fn draw<W: WidgetExt>(&self, widget: &W, delta_x: i32, delta_y: i32) {
unsafe {
Fl_SVG_File_Surface_draw(
self.inner,
widget.as_widget_ptr() as *mut _,
delta_x,
delta_y,
)
}
}
pub fn draw_decorated_window<W: WindowExt>(&self, win: &W, x_offset: i32, y_offset: i32) {
unsafe {
Fl_SVG_File_Surface_draw_decorated_window(
self.inner,
win.as_widget_ptr() as *mut _,
x_offset,
y_offset,
)
}
}
}
impl Drop for SvgFileSurface {
fn drop(&mut self) {
unsafe { Fl_SVG_File_Surface_delete(self.inner) }
}
}