use image::{DynamicImage, GenericImage, GrayImage, ImageBuffer, Luma, Rgba};
use imageproc::morphology::{grayscale_dilate, Mask};
use rusttype::{Font, Scale};
use crate::draw;
const WHITE_PIXEL: Rgba<u8> = Rgba([255, 255, 255, 255]);
const BLACK_PIXEL: Rgba<u8> = Rgba([0, 0, 0, 255]);
pub fn render_line(
text: &str,
y_offset: i32,
root_position: (u32, u32),
text_dimensions: (u32, u32),
scale_factor: f32,
font: &Font,
pixels: &mut DynamicImage,
) {
use crate::{AA_FACTOR, AA_FACTOR_FLOAT};
let (text_width, text_height) = text_dimensions;
let scale = Scale::uniform(scale_factor * AA_FACTOR_FLOAT);
let (x, y) = root_position;
let x = x * AA_FACTOR;
let y = (y as i32 + y_offset) as u32 * AA_FACTOR;
let mask_w = text_width * AA_FACTOR;
let mask_h = text_height * AA_FACTOR;
let mut text_mask: GrayImage = ImageBuffer::from_pixel(mask_w, mask_h, Luma([0u8]));
draw::text(&mut text_mask, Luma([255u8]), 0, 0, scale, font, text);
let radius = (0.09 * scale_factor) as i32;
let ring_dim = (2 * radius + 1) as u32;
let mut ring_img: GrayImage = ImageBuffer::from_pixel(ring_dim, ring_dim, Luma([0u8]));
for ry in 0..ring_dim {
for rx in 0..ring_dim {
let dx = rx as i32 - radius;
let dy = ry as i32 - radius;
let dist = ((dx * dx + dy * dy) as f64).sqrt();
if (dist - radius as f64).abs() < 0.5 {
ring_img.put_pixel(rx, ry, Luma([255u8]));
}
}
}
let ring_mask = Mask::from_image(&ring_img, radius as u8, radius as u8);
let outline = grayscale_dilate(&text_mask, &ring_mask);
let (max_x, max_y) = (pixels.width() as i32, pixels.height() as i32);
for (idx, outline_px) in outline.pixels().enumerate() {
if outline_px[0] > 0 {
let idx = idx as u32;
let px = idx % mask_w + x;
let py = idx / mask_w + y;
let pxi = px as i32;
let pyi = py as i32;
if pxi >= 0 && pxi < max_x && pyi >= 0 && pyi < max_y {
pixels.put_pixel(px, py, BLACK_PIXEL);
}
}
}
draw::text(pixels, WHITE_PIXEL, x, y, scale, font, text);
}