use cranpose_ui::{Color, text::TextMotion};
use cranpose_ui_graphics::whole;
use crate::{
glyph_mask::{GlyphMaskCache, GlyphMaskKey},
text_glyphs::{SpanPaints, visit_placed_glyphs},
text_raster::TextRasterRequest,
};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AtlasGlyph {
pub key: GlyphMaskKey,
pub x: i32,
pub y: i32,
pub width: usize,
pub height: usize,
pub color: Color,
}
pub fn collect_solid_text_atlas_run(
request: TextRasterRequest<'_>,
glyph_cache: &mut GlyphMaskCache,
out: &mut Vec<AtlasGlyph>,
) -> Option<()> {
if request.is_degenerate() {
return Some(());
}
let paints = SpanPaints::of(request.text, request.style, request.fallback_color);
if request.motion() != TextMotion::Static
|| !paints.all(|paint| {
paint.solid_color().is_some() && paint.shadow.is_none() && paint.stroke.is_none()
})
{
return None;
}
let origin = request.origin;
visit_placed_glyphs(
request.layout,
&paints,
(origin, request.scale),
TextMotion::Static,
|glyph| {
let Some(color) = glyph.paint.solid_color() else {
return;
};
let key = GlyphMaskKey::of(glyph.typeface, glyph.glyph, glyph.size, glyph.raster);
let Some(mask) =
glyph_cache.mask(glyph.typeface, glyph.glyph, glyph.size, glyph.raster)
else {
return;
};
out.push(AtlasGlyph {
key,
x: whole::to_i32(whole::round(glyph.x - origin.x)) + mask.left,
y: whole::to_i32(whole::round(glyph.y - origin.y)) + mask.top,
width: mask.width,
height: mask.height,
color,
});
},
);
Some(())
}