Fonts: a letter with combining marks the run's font lacks takes a face that has them all
"Z̴̡̛͓a̸̧̘l̵̩g̶̞o̸̤" in an Aptos run drew its marks as missing-glyph boxes: no face in the chain covered the whole cluster and the fallback for its base letter neither, so the run's own font was kept. PowerPoint draws the marks stacked. A loaded plain face that covers the whole cluster is now taken before falling back to the run's font. w09-scripts s1 8.40 -> 7.86. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c858c11bf6
commit
f495922c4e
|
|
@ -185,7 +185,10 @@ impl FontDb {
|
|||
let f = match self.fallback_for(key, exclude) {
|
||||
Some(f) if covers_cluster(&f, cluster) => f,
|
||||
Some(f) if chain.iter().all(|c| !c.covers(key)) => f,
|
||||
_ => first(),
|
||||
// A letter with marks the run's font lacks (stacked combining marks): a loaded plain
|
||||
// face that draws the whole cluster, as PowerPoint draws the marks, before the run's
|
||||
// font with missing-glyph boxes.
|
||||
_ => self.read_faces().iter().find(|f| !f.is_color() && covers_cluster(f, cluster)).cloned().unwrap_or_else(first),
|
||||
};
|
||||
// A pictograph that defaults to text presentation (⚠ ♥ ⬆ ▶) whose first fallback is the
|
||||
// colour emoji font: PowerPoint draws it from a plain symbol font.
|
||||
|
|
|
|||
|
|
@ -1196,3 +1196,23 @@ fn rtl_columns_start_on_the_right_and_just_anchoring_sits_at_the_bottom() {
|
|||
assert!((lay(&p, &sh, 400.0, 300.0).lines[0].top - b).abs() < 0.01, "{a:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stacked_combining_marks_take_a_face_that_draws_them() {
|
||||
// A letter with marks the run's font lacks draws in a face that has them all (no boxes).
|
||||
let db = FontDb::global();
|
||||
let cluster = ['Z', '\u{0334}', '\u{0321}', '\u{031B}'];
|
||||
let run_face = db.face("Inter", "Regular");
|
||||
let f = db.cascade(&cluster, std::slice::from_ref(&run_face), "Regular");
|
||||
if !deckcraft_fonts::covers_cluster(&run_face, &cluster) && ["DejaVu Sans", "Segoe UI"].iter().any(|fam| db.has_family(fam)) {
|
||||
// Make sure a face with the marks is loaded, then the cluster must take one.
|
||||
for fam in ["DejaVu Sans", "Segoe UI"] {
|
||||
if db.has_family(fam) {
|
||||
let _ = db.face(fam, "Regular");
|
||||
}
|
||||
}
|
||||
let f = db.cascade(&cluster, std::slice::from_ref(&run_face), "Regular");
|
||||
assert!(deckcraft_fonts::covers_cluster(&f, &cluster), "{} lacks the marks", f.family);
|
||||
}
|
||||
let _ = f;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue