From a288f1d77547c8d5ae1c3ac63225952fb3f55391 Mon Sep 17 00:00:00 2001 From: Todd York Date: Thu, 1 Jan 2026 14:45:26 +0800 Subject: [PATCH] Shape as fake italic if no matching italic font exists --- src/font/mod.rs | 4 +++- src/shape.rs | 34 +++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/font/mod.rs b/src/font/mod.rs index 869833e..f7b09e0 100644 --- a/src/font/mod.rs +++ b/src/font/mod.rs @@ -15,7 +15,7 @@ use core::fmt; use alloc::sync::Arc; #[cfg(not(feature = "std"))] use alloc::vec::Vec; - +use fontdb::Style; use self_cell::self_cell; pub mod fallback; @@ -54,6 +54,7 @@ pub struct Font { data: FontData, id: fontdb::ID, monospace_fallback: Option, + pub(crate) italic_or_oblique: bool, } impl fmt::Debug for Font { @@ -234,6 +235,7 @@ impl Font { ) .ok()?, data: FontData::new(Blob::new(data), info.index), + italic_or_oblique: info.style == Style::Italic || info.style == Style::Oblique, }) } } diff --git a/src/shape.rs b/src/shape.rs index 839630a..6e2f1b8 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -4,7 +4,7 @@ use crate::fallback::FontFallbackIter; use crate::{ - math, Align, AttrsList, CacheKeyFlags, Color, Font, FontSystem, Hinting, LayoutGlyph, + math, Align, Attrs, AttrsList, CacheKeyFlags, Color, Font, FontSystem, Hinting, LayoutGlyph, LayoutLine, Metrics, Wrap, }; #[cfg(not(feature = "std"))] @@ -18,6 +18,7 @@ use core::ops::Range; #[cfg(not(feature = "std"))] use core_maths::CoreFloat; +use fontdb::Style; use unicode_script::{Script, UnicodeScript}; use unicode_segmentation::UnicodeSegmentation; @@ -233,7 +234,7 @@ fn shape_fallback( //TODO: color should not be related to shaping color_opt: attrs.color_opt, metadata: attrs.metadata, - cache_key_flags: attrs.cache_key_flags, + cache_key_flags: override_fake_italic(attrs.cache_key_flags, font, &attrs), metrics_opt: attrs.metrics_opt.map(Into::into), }); } @@ -496,11 +497,11 @@ fn shape_skip( let font = font_iter.next().expect("no default font found"); let font_id = font.id(); let font_monospace_em_width = font.monospace_em_width(); - let font = font.as_swash(); + let swash_font = font.as_swash(); - let charmap = font.charmap(); - let metrics = font.metrics(&[]); - let glyph_metrics = font.glyph_metrics(&[]).scale(1.0); + let charmap = swash_font.charmap(); + let metrics = swash_font.metrics(&[]); + let glyph_metrics = swash_font.glyph_metrics(&[]).scale(1.0); let ascent = metrics.ascent / f32::from(metrics.units_per_em); let descent = metrics.descent / f32::from(metrics.units_per_em); @@ -529,13 +530,32 @@ fn shape_skip( glyph_id, color_opt: attrs.color_opt, metadata: attrs.metadata, - cache_key_flags: attrs.cache_key_flags, + cache_key_flags: override_fake_italic( + attrs.cache_key_flags, + font.as_ref(), + &attrs, + ), metrics_opt: attrs.metrics_opt.map(Into::into), } }), ); } +fn override_fake_italic( + cache_key_flags: CacheKeyFlags, + font: &Font, + attrs: &Attrs, +) -> CacheKeyFlags { + cache_key_flags + | if !font.italic_or_oblique + && (attrs.style == Style::Italic || attrs.style == Style::Oblique) + { + CacheKeyFlags::FAKE_ITALIC + } else { + CacheKeyFlags::empty() + } +} + /// A shaped glyph #[derive(Clone, Debug)] pub struct ShapeGlyph {