mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Type: whitespace the primary font doesn't map takes the fallback face too (#1844)
An ideographic space in a face without U+3000 was shaped with that face and could set at zero width, removing an indent. Only what the layout handles itself (tab, line and paragraph breaks) stays with the primary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
a14942de9c
commit
4265c2f301
@@ -374,7 +374,10 @@ pub(crate) fn shape_range(
|
||||
// Digits are drawn in the style's numeral system: the font must cover that digit.
|
||||
let c = st.digits.map(c);
|
||||
let level = level_at(i);
|
||||
let covered = c.is_whitespace() || c.is_control() || pmap.as_ref().is_none_or(|m| m.map(c).is_some());
|
||||
// Whitespace the primary font doesn't map goes to the fallback face like any other
|
||||
// character (#1844): an ideographic space set at zero width would remove an indent.
|
||||
// What the layout handles itself (tab, line and paragraph breaks) stays.
|
||||
let covered = c.is_control() || pmap.as_ref().is_none_or(|m| m.map(c).is_some());
|
||||
let face = if covered {
|
||||
primary.clone()
|
||||
} else if let Some((_, f)) = cache.iter().find(|(k, _)| *k == c) {
|
||||
|
||||
@@ -405,6 +405,26 @@ fn fallback_font_per_character() {
|
||||
assert_eq!(l.glyphs[2].font_id, primary.id());
|
||||
}
|
||||
|
||||
/// A space the primary font doesn't map goes to the fallback face like any other character
|
||||
/// (#1844): an ideographic space in a face without U+3000 keeps its em, so an indent made with it
|
||||
/// isn't lost. A tab, which the layout handles itself, stays with the primary face. Needs a bundled
|
||||
/// face with U+3000 and あ (craft-fonts; skipped without it).
|
||||
#[test]
|
||||
fn whitespace_the_primary_font_lacks_takes_the_fallback_face() {
|
||||
let primary = db().face("Source Sans 3", "Regular").unwrap();
|
||||
assert!(!primary.covers('\u{3000}'));
|
||||
if ['\u{3000}', 'あ'].iter().any(|&c| db().fallback_for(c, primary.id()).is_none()) {
|
||||
eprintln!("skipped: built without craft-fonts (set CRAFT_FONTS_DIR to a craft-fonts checkout to run it)");
|
||||
return;
|
||||
}
|
||||
let l = layout(db(), &point("あ\u{3000}あ", style(20.0)));
|
||||
let width: f64 = l.glyphs.iter().map(|g| g.advance).sum();
|
||||
assert!((width - 60.0).abs() < 0.01, "あ あ sets at 3 em: {:?}", l.glyphs.iter().map(|g| g.advance).collect::<Vec<_>>());
|
||||
assert_ne!(l.glyphs[1].font_id, primary.id());
|
||||
let l = layout(db(), &point("a\tb", style(20.0)));
|
||||
assert!(l.glyphs.iter().all(|g| g.font_id == primary.id()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_runs_and_styles() {
|
||||
let mut t = point("", style(10.0));
|
||||
|
||||
Reference in New Issue
Block a user