use std::cmp::min; use eframe::egui; use eframe::egui::Color32; use image::{GenericImage, Pixel, Rgb, Rgba}; use rusttype::{point, Font, Scale}; use crate::canvas::Canvas; impl Canvas { pub fn text_center( &mut self, font: &Font, color: egui::Color32, x: f32, y: f32, text: &str, scale: Scale, ) { self.refresh(); let v_metrics = font.v_metrics(scale); let glyphs: Vec<_> = font .layout(text, scale, point(0.0, 0.0 + v_metrics.ascent)) .collect(); let (width, height) = { let mut min_x = i32::MAX; let mut min_y = i32::MAX; let mut max_x = i32::MIN; let mut max_y = i32::MIN; for g in glyphs.iter() .map(|p|p.pixel_bounding_box()) .flatten() { min_x = min_x.min(g.min.x); min_y = min_y.min(g.min.y); max_x = max_x.max(g.max.x); max_y = max_y.max(g.max.y); // self.debug_rect( // Color32::GREEN, // g.min.x as _, // g.min.y as _, // g.max.x as _, // g.max.y as _, // ); } // self.debug_rect( // Color32::PURPLE, // min_x as _, min_y as _, // max_x as _, max_y as _); ((max_x/* - min_x*/) as f32, (max_y/* - min_y*/) as f32) }; let (x, y) = ( x - (width / 2.0), y - (height / 2.0) ); // self.debug_rect(Color32::RED, x, y, x + width, y + height); let glyphs: Vec<_> = font .layout(text, scale, point(x, y + v_metrics.ascent)) .collect(); for glyph in glyphs { if let Some(bounding_box) = glyph.pixel_bounding_box() { // self.debug_rect( // Color32::RED, // bounding_box.min.x as _, // bounding_box.min.y as _, // bounding_box.max.x as _, // bounding_box.max.y as _); glyph.draw(|x, y, v| { let p = self.image.get_pixel_mut( x + bounding_box.min.x as u32, y + bounding_box.min.y as u32, ); let mut op = p.to_rgba(); let np = Rgba([ color.r(), color.g(), color.b(), (color.a() as f32 * v) as u8 ]); op.blend(&np); *p = op.to_rgb() }); } } } fn debug_rect( &mut self, color: Color32, mnx: f32, mny: f32, mxx: f32, mxy: f32, ) { self.refresh(); // sort the values just in case let (mnx, mxx) = (mnx.min(mxx), mxx.max(mxx)); let (mny, mxy) = (mny.min(mxy), mxy.max(mxy)); let rgb = Rgb([ color.r(), color.g(), color.b(), ]); let w = (mxx - mnx) as u32; let h = (mxy - mny) as u32; for w in 0..w { self.image.put_pixel(mnx as u32 + w, mny as u32, rgb); self.image.put_pixel(mnx as u32 + w, mxy as u32, rgb); self.image.put_pixel(mnx as u32 + w, mny as u32 + h, rgb); } for h in 0..h { self.image.put_pixel(mnx as u32, mny as u32 + h, rgb); self.image.put_pixel(mxx as u32, mny as u32 + h, rgb); } } }