mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 21:56:24 +00:00
Merge pull request #6565 from dotCooCoo/fix/glyph-alternate-noop-ligature
Glyphs: gid null inside a ligature reports the ligature
This commit is contained in:
@@ -1321,6 +1321,16 @@ fn set_glyph_alternate(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
}
|
||||
if held == choice && (choice.is_none() || alone) {
|
||||
// The text is left as it is, so the glyph is the one the unchanged text draws. The probe
|
||||
// splits a run that holds an earlier character's choice, and the split can break a ligature
|
||||
// that takes in this character.
|
||||
let drawn = match &choice {
|
||||
None if probe.runs != t.runs => {
|
||||
let lay = vectorcraft_text::layout(vectorcraft_text::FontDb::global(), &t);
|
||||
drawn_glyph(&plain, &lay, ch, &bytes, &face).or_else(|| shaped_alone(&t, ch, &bytes, &face).1).unwrap_or(default)
|
||||
}
|
||||
_ => drawn,
|
||||
};
|
||||
return Ok(json!({"id": id.0, "start": bytes.start, "end": bytes.end, "gid": drawn}));
|
||||
}
|
||||
s.edit("Glyphs", |d, _| {
|
||||
|
||||
@@ -3511,6 +3511,31 @@ fn a_glyph_choice_taken_away_reports_the_glyph_drawn() {
|
||||
assert_eq!(chosen(&mut s, caps, 1), json!(drawn));
|
||||
}
|
||||
|
||||
/// A run that holds a choice for its first character and goes on past it, as a file may have,
|
||||
/// draws Source Serif 4's fi ligature for the f and the i after that character. `gid: null` for the
|
||||
/// i leaves the text as it is and reports the ligature, as `text.glyphAlternates` does.
|
||||
#[test]
|
||||
fn a_glyph_choice_taken_away_inside_a_ligature_reports_the_ligature() {
|
||||
let db = vectorcraft_text::FontDb::global();
|
||||
let face = db.face("Source Serif 4", "Regular").expect("the bundled face");
|
||||
let mut s = session();
|
||||
let r = s.execute("text.create", &json!({"x": 100, "y": 100, "text": "xfin", "size": 40, "font": "Source Serif 4"})).unwrap();
|
||||
let id = NodeId(r["id"].as_u64().unwrap());
|
||||
let mut runs = obj(&s, id).runs;
|
||||
runs[0].style.glyph_alternate = Some(face.choice('x', face.glyph_for('x')));
|
||||
let doc = std::sync::Arc::make_mut(&mut s.doc_mut().unwrap().doc);
|
||||
let Some(NodeKind::Text(text)) = doc.node_mut(id).map(|n| &mut n.kind) else { panic!("text") };
|
||||
text.runs = runs.clone();
|
||||
let ligature = vectorcraft_text::layout(db, &obj(&s, id)).glyphs.iter().find(|g| g.byte == 1 && g.len == 2).expect("f + i is one glyph").gid;
|
||||
let chosen = s.execute("text.glyphAlternates", &json!({"id": id.0, "start": 2})).unwrap()["chosen"].clone();
|
||||
assert_eq!(chosen, json!(ligature));
|
||||
let undo = s.doc().unwrap().history.undo.len();
|
||||
let r = s.execute("text.setGlyphAlternate", &json!({"id": id.0, "start": 2, "gid": null})).unwrap();
|
||||
assert_eq!(r["gid"], chosen, "the ligature drawn for the i");
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), undo, "no edit");
|
||||
assert_eq!(obj(&s, id).runs, runs, "the runs are kept");
|
||||
}
|
||||
|
||||
/// A fallback face draws Ka with the vowel sign I in one cluster, the vowel sign first. The glyph
|
||||
/// reported for Ka is the fallback face's glyph for Ka, laid out or overflowing, not the vowel
|
||||
/// sign's.
|
||||
|
||||
Reference in New Issue
Block a user