use core_graphics::sys::CGContextRef;
use core_text::font::CTFont;
use crate::backend::ImagePaintResult;
use crate::paint_surface::PaintSurface;
use crate::{Color, Image, Point, Rect, Viewport};
use super::text::{draw_text, measure_text};
pub(crate) struct CgSurface<'a> {
pub(crate) ctx: CGContextRef,
pub(crate) font: Option<&'a CTFont>,
}
impl<'a> CgSurface<'a> {
fn font_or_panic(&self) -> &'a CTFont {
self.font
.expect("CgSurface: text verb called without a CTFont")
}
}
impl PaintSurface for CgSurface<'_> {
fn surface_begin_frame(&mut self, _viewport: Viewport) {
unreachable!("CgSurface has no backend frame lifecycle to begin")
}
fn surface_end_frame(&mut self) {
unreachable!("CgSurface has no backend frame lifecycle to end")
}
fn surface_viewport(&self) -> Viewport {
unreachable!("CgSurface has no backend viewport")
}
fn surface_line_height(&self) -> f32 {
unreachable!("CgSurface has no backend line height")
}
fn surface_char_width(&self) -> f32 {
unreachable!("CgSurface has no backend char width")
}
fn surface_measure_text(&self, text: &str) -> (f32, f32) {
let (w, h) = measure_text(self.font_or_panic(), text);
(w as f32, h as f32)
}
fn surface_fill_rect(&mut self, rect: Rect, color: Color) {
unsafe { super::backend::ns_fill_rect(self.ctx, rect, color) };
}
fn surface_fill_rounded_rect(&mut self, rect: Rect, radius: f32, color: Color) {
unsafe { super::backend::ns_fill_rounded_rect(self.ctx, rect, radius, color) };
}
fn surface_stroke_rect(&mut self, rect: Rect, color: Color, stroke_width: f32) {
unsafe { super::backend::ns_stroke_rect(self.ctx, rect, color, stroke_width as f64) };
}
fn surface_stroke_rounded_rect(
&mut self,
rect: Rect,
radius: f32,
color: Color,
stroke_width: f32,
) {
unsafe {
super::backend::ns_stroke_rounded_rect(
self.ctx,
rect,
radius,
color,
stroke_width as f64,
)
};
}
fn surface_draw_text_run(&mut self, rect: Rect, text: &str, color: Color) {
let font = self.font_or_panic();
unsafe {
draw_text(
self.ctx,
font,
text,
rect.x as f64,
rect.y as f64,
super::backend::ns_color_to_cg(color),
);
}
}
fn surface_draw_line(&mut self, from: Point, to: Point, color: Color, stroke_width: f32) {
unsafe {
super::backend::ns_draw_line(
self.ctx,
from.x as f64,
from.y as f64,
to.x as f64,
to.y as f64,
color,
stroke_width as f64,
);
}
}
fn surface_push_clip(&mut self, rect: Rect) {
unsafe { super::backend::ns_push_clip(self.ctx, rect) };
}
fn surface_pop_clip(&mut self) {
unsafe { super::backend::ns_pop_clip(self.ctx) };
}
fn surface_draw_image(&mut self, _rect: Rect, _image: &Image) -> ImagePaintResult {
ImagePaintResult::Unsupported
}
}