Text: a change of kenten character keeps the kerning across it

Pieces of a paragraph that differ only in how they are painted are
shaped together; the kenten character only picks the emphasis mark drawn
over the text, so it is one of those paint attributes, like kenten
itself.
This commit is contained in:
aiongg
2026-10-07 23:08:45 -04:00
parent 3a10a749db
commit 124bddaf8b
2 changed files with 29 additions and 0 deletions
+1
View File
@@ -127,6 +127,7 @@ fn shaping_key(p: &CharProps) -> CharProps {
strikethrough_tint: d.strikethrough_tint,
ruby: d.ruby,
kenten: d.kenten,
kenten_character: d.kenten_character,
conditions: d.conditions,
change: d.change,
xml_tag: d.xml_tag,
+28
View File
@@ -1101,6 +1101,34 @@ fn colour_change_keeps_kerning_and_ligatures_keep_colour() {
assert_ne!(at(2).as_deref(), Some("Cyan"));
}
/// The emphasis mark drawn over the text only paints: a change of kenten character keeps the
/// kerning across it.
#[test]
fn kenten_character_change_keeps_kerning() {
let mut d = Document::new(&NewDocument::default());
let lid = d.default_layer();
let (_, sid) = d.add_text_frame(SpreadRef::Doc(0), Rect::new(100.0, 100.0, 400.0, 200.0), lid, "ayay", ParaFormat::default()).unwrap();
d.story_mut(sid).unwrap().format_chars(0..4, |f| {
f.over.font_style = Some("Bold".into());
f.over.kenten = Some(true);
});
let xs = |d: &Document| {
let cs = compose_story(d, sid, &ComposeOptions::default());
cs.frames[0].lines[0].glyphs.iter().filter(|g| g.len > 0).map(|g| (g.byte, g.x, g.adv)).collect::<Vec<_>>()
};
let kerned = xs(&d);
d.story_mut(sid).unwrap().format_chars(0..4, |f| f.over.kerning = Some(designcraft_doc::Kerning::None));
assert_ne!(xs(&d), kerned, "Source Serif 4 Bold kerns a–y");
d.story_mut(sid).unwrap().format_chars(0..4, |f| f.over.kerning = Some(designcraft_doc::Kerning::Metrics));
d.story_mut(sid).unwrap().format_chars(0..1, |f| f.over.kenten_character = Some("●".into()));
assert_eq!(xs(&d), kerned, "a kenten character change must not change spacing");
let cs = compose_story(&d, sid, &ComposeOptions::default());
let mark = |b: usize| {
cs.frames[0].lines[0].glyphs.iter().find(|g| g.len > 0 && g.byte == b).map(|g| cs.styles[g.style as usize].kenten_character.clone())
};
assert_eq!((mark(0).as_deref(), mark(1).as_deref()), (Some("●"), Some("")));
}
#[test]
fn cjk_aki_adds_space_without_scaling_outlines() {
let (mut d, sid, _) = doc_with("AB", Rect::new(0.0, 0.0, 300.0, 100.0), ParaAttrs::default());