Glyphs: overflowing vertical type keeps a chosen default glyph

Squashed from #5676 onto main.
This commit is contained in:
dotCooCoo
2026-11-05 02:23:42 +07:00
committed by bflatastic
parent f10ab42c05
commit 440b3b7444
2 changed files with 28 additions and 2 deletions
+3 -2
View File
@@ -1174,7 +1174,7 @@ fn set_glyph_alternate(s: &mut Session, p: &Value) -> Result<Value> {
// The glyph the character is drawn with when it holds no choice, drawn alone in its face: a
// feature of its style (`salt`, a stylistic set) can draw another glyph than the default one.
// The default glyph is then kept as a choice, so that it is drawn. A character that is not laid
// out (overflowing text) is shaped alone in its style. A character that starts a longer
// out (overflowing text) is shaped alone in its style and writing direction. A character that starts a longer
// grapheme (a letter and its combining marks) is drawn in the grapheme's cluster, and is shaped
// with the grapheme. Of a cluster of several glyphs (a mark, a vowel sign drawn before the
// letter), the character's glyph is its default glyph or one of its alternates.
@@ -1205,7 +1205,8 @@ fn set_glyph_alternate(s: &mut Session, p: &Value) -> Result<Value> {
let db = vectorcraft_text::FontDb::global();
alone_in_face(&vectorcraft_text::layout(db, &probe)).unwrap_or_else(|| {
let st = CharStyle { glyph_alternate: None, ..run.style.clone() };
let single = TextObject::point(Point::ZERO, &grapheme, st);
let mut single = TextObject::point(Point::ZERO, &grapheme, st);
single.vertical = t.vertical;
own_glyph(&vectorcraft_text::layout(db, &single), 0)
})
}
+25
View File
@@ -2536,6 +2536,31 @@ fn the_glyph_drawn_for_a_character_with_a_combining_mark_is_reported() {
assert_eq!(r["gid"], json!(g('b')), "the overflowing a is shaped with its mark");
}
/// Vertical type draws `vert` glyphs (the test font's `vert` draws ! as I). A character of
/// vertical type that overflows its area is shaped as vertical type, so choosing its default glyph
/// keeps the choice.
#[test]
fn the_default_glyph_chosen_in_overflowing_vertical_type_is_kept() {
use vectorcraft_text::test_fonts::{VERTICAL_PUNCTUATION_FAMILY, vertical_punctuation_font};
let _fonts = crate::adding_fonts();
let db = vectorcraft_text::FontDb::global();
db.add_font(vertical_punctuation_font(true).expect("the test font builds"));
let face = db.face(VERTICAL_PUNCTUATION_FAMILY, "Regular").expect("the test face");
let g = |c| face.glyph_for(c);
let mut s = session();
let text = |area: Value| json!({"x": 0, "y": 0, "text": "!!", "size": 20, "font": VERTICAL_PUNCTUATION_FAMILY, "vertical": true, "area": area});
let open = NodeId(s.execute("text.create", &text(json!({"width": 200, "height": 200}))).unwrap()["id"].as_u64().unwrap());
let gids: Vec<_> = vectorcraft_text::layout(db, &obj(&s, open)).glyphs.iter().map(|g| g.gid).collect();
assert_eq!(gids, [g('I'), g('I')], "vert draws each ! as I");
let boxed = NodeId(s.execute("text.create", &text(json!({"width": 4, "height": 4}))).unwrap()["id"].as_u64().unwrap());
assert!(vectorcraft_text::layout(db, &obj(&s, boxed)).glyphs.is_empty(), "the text overflows");
let r = s.execute("text.setGlyphAlternate", &json!({"id": boxed.0, "start": 0, "gid": g('!')})).unwrap();
assert_eq!(r["gid"], json!(g('!')));
let held: Vec<_> = obj(&s, boxed).runs.iter().filter_map(|r| r.style.glyph_alternate.as_ref().map(|c| c.gid)).collect();
assert_eq!(held, [g('!')], "the default glyph is kept as the choice");
}
#[test]
fn glyph_alternates_query_reports_the_fallback_glyph_that_is_drawn() {
use vectorcraft_text::test_fonts::{alternates_family, alternates_font};