576YRB7XSKS6Q265TEJQS7HUGMKSGHGDRGVP6WBZS7XMK6RVJRNQC struct FontState {data: Vec<u8>,pub rustybuzz_faces: Vec<rustybuzz::Face<'static>>,pub fontdue_faces: Vec<fontdue::Font>,font_cache: HashMap<(FontIndex, GlyphIndex), (Metrics, Vec<u8>)>,}impl FontState {fn new() -> Result<Self, Box<dyn Error>> {// TODO: Use `fontdb`// let data = include_bytes!("/usr/share/fonts/TTF/Manjari-Regular.ttf");let data = include_bytes!("/usr/share/fonts/TTF/Iosevka.ttc");let rustybuzz_face =rustybuzz::Face::from_slice(data, 0).ok_or("Failed to load rustybuzz font")?;let fontdue_face = fontdue::Font::from_bytes(&data[..], FontSettings::default())?;Ok(Self {data: Vec::from(data),rustybuzz_faces: vec![rustybuzz_face],fontdue_faces: vec![fontdue_face],font_cache: HashMap::new(),})}/// Rasterizes a glyph./// Returns slice containing pixels as RGB8fn render_glyph(&mut self,font_index: FontIndex,glyph_index: GlyphIndex,) -> (&Metrics, &[u8]) {let res = self.font_cache.entry((font_index, glyph_index)).or_insert_with(|| {// TODO: Support other sizesself.fontdue_faces[font_index].rasterize_indexed_subpixel(glyph_index, 32.0)});(&res.0, &res.1)}/// Shapes some textpub fn shape(&self, font_index: FontIndex, ubuf: UnicodeBuffer) -> GlyphBuffer {rustybuzz::shape(&self.rustybuzz_faces[font_index], &[], ubuf)}}
fn redraw(rs: &mut RenderState, fs: &mut FontState) {let mut ubuf = UnicodeBuffer::new();// ubuf.push_str("പിന്നോട്ടു മാത്രം മടങ്ങുന്ന കാലുകൊണ്ടല്ലയോ മുന്നോട്ടു പായുന്നിതാളുകൾ ");ubuf.push_str("θ̂");let gbuf = fs.shape(0, ubuf);let mut x = 0;let mut y = 100;// >i vjfor (gpos, ginfo) in gbuf.glyph_positions().iter().zip(gbuf.glyph_infos()) {let (metrics, data) = fs.render_glyph(0, ginfo.glyph_id as u16);for i in 0..metrics.width {for j in 0..metrics.height {let py = y + j as i32 - (gpos.y_offset / 64) - metrics.height as i32 - metrics.ymin;let px = x + i as i32 + (gpos.x_offset / 64) + metrics.xmin;let pidx = (py * rs.pixmap.width() as i32 + px) as usize * 4;
fn redraw(rs: &mut RenderState) {let rect = tiny_skia::Rect::from_xywh(20.0, 20.0, 300.0, 200.0).unwrap();let mut paint = Paint::default();paint.set_color_rgba8(0, 0, 255, 255);paint.anti_alias = true;rs.pixmap.fill_rect(rect, &paint, Transform::identity(), None);
if pidx >= rs.pixmap.data().len() {continue;}let didx = (j * metrics.width + i) * 3;let data_mut = rs.pixmap.data_mut();for k in 0..3 {data_mut[pidx + k] = data_mut[pidx + k].max(data[didx + k]);}data_mut[pidx + 3] = 255;}}// Rustybuzz renders things with 2048 font size// We need it in 32 sizex += gpos.x_advance / 64;y += gpos.y_advance / 64;}