diff --git a/crates/compose/src/shape.rs b/crates/compose/src/shape.rs index b50b39d1e..7b6549c4a 100644 --- a/crates/compose/src/shape.rs +++ b/crates/compose/src/shape.rs @@ -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, diff --git a/crates/compose/src/tests.rs b/crates/compose/src/tests.rs index 6cd4105d4..acbda209b 100644 --- a/crates/compose/src/tests.rs +++ b/crates/compose/src/tests.rs @@ -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::>() + }; + 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());