use windows::Win32::Graphics::Direct2D::ID2D1RenderTarget;
use crate::backend::ImagePaintResult;
use crate::paint_surface::PaintSurface;
use crate::{Color, Image, Point, Rect, Viewport};
use super::text::{
draw_line, fill_rect, fill_rounded_rect, pop_clip, push_clip, stroke_rect,
with_horizontal_scale, DWrite,
};
pub(crate) struct D2dSurface<'a> {
pub(crate) target: &'a ID2D1RenderTarget,
pub(crate) dwrite: Option<&'a DWrite>,
}
impl<'a> D2dSurface<'a> {
fn dwrite_or_panic(&self) -> &'a DWrite {
self.dwrite
.expect("D2dSurface: text verb called without a DWrite instance")
}
}
impl PaintSurface for D2dSurface<'_> {
fn surface_begin_frame(&mut self, _viewport: Viewport) {
unreachable!("D2dSurface has no backend frame lifecycle to begin")
}
fn surface_end_frame(&mut self) {
unreachable!("D2dSurface has no backend frame lifecycle to end")
}
fn surface_viewport(&self) -> Viewport {
unreachable!("D2dSurface has no backend viewport")
}
fn surface_line_height(&self) -> f32 {
unreachable!("D2dSurface has no backend line height")
}
fn surface_char_width(&self) -> f32 {
unreachable!("D2dSurface has no backend char width")
}
fn surface_measure_text(&self, text: &str) -> (f32, f32) {
self.dwrite_or_panic()
.measure_text(text)
.unwrap_or((0.0, 0.0))
}
fn surface_measure_text_styled(&self, text: &str, bold: bool) -> (f32, f32) {
self.dwrite_or_panic()
.measure_text_styled(text, bold)
.unwrap_or((0.0, 0.0))
}
fn surface_fill_rect(&mut self, rect: Rect, color: Color) {
let _ = fill_rect(self.target, rect, color);
}
fn surface_fill_rounded_rect(&mut self, rect: Rect, radius: f32, color: Color) {
let _ = fill_rounded_rect(self.target, rect, radius, color);
}
fn surface_stroke_rect(&mut self, rect: Rect, color: Color, stroke_width: f32) {
let _ = stroke_rect(self.target, rect, color, stroke_width);
}
fn surface_draw_text_run(&mut self, rect: Rect, text: &str, color: Color) {
let _ = self
.dwrite_or_panic()
.draw_text(self.target, text, rect, color);
}
#[allow(clippy::too_many_arguments)]
fn surface_draw_text_run_styled(
&mut self,
rect: Rect,
text: &str,
color: Color,
bold: bool,
italic: bool,
underline: bool,
scale_x: f32,
) {
let _ = (italic, underline);
let dwrite = self.dwrite_or_panic();
if (scale_x - 1.0).abs() > f32::EPSILON {
with_horizontal_scale(self.target, scale_x, rect.x, || {
let _ = dwrite.draw_text_styled(self.target, text, rect, color, bold);
});
} else {
let _ = dwrite.draw_text_styled(self.target, text, rect, color, bold);
}
}
fn surface_draw_line(&mut self, from: Point, to: Point, color: Color, stroke_width: f32) {
let _ = draw_line(self.target, from.x, from.y, to.x, to.y, color, stroke_width);
}
fn surface_push_clip(&mut self, rect: Rect) {
push_clip(self.target, rect);
}
fn surface_pop_clip(&mut self) {
pop_clip(self.target);
}
fn surface_draw_image(&mut self, _rect: Rect, _image: &Image) -> ImagePaintResult {
ImagePaintResult::Unsupported
}
}