mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 07:13:46 +00:00
Merge pull request #6480 from dotCooCoo/fix/vertical-styles-keep-horizontal-ligatures
Type: vertical-only settings keep horizontal ligatures whole
This commit is contained in:
@@ -796,6 +796,23 @@ fn source_run_at(runs: &[(Range<usize>, &CharStyle)], span: &Range<usize>, byte:
|
||||
source.get(i).filter(|(range, _)| range.contains(&byte)).map(|_| span.start + i)
|
||||
}
|
||||
|
||||
/// Can one glyph draw characters in styles `a` and `b`? Only when the styles are equal, except that
|
||||
/// horizontal type (`vertical` false) does not read Standard Vertical Roman Alignment or the
|
||||
/// tate-chu-yoko offsets, so styles that differ only in those are drawn alike there.
|
||||
fn drawn_alike(a: &CharStyle, b: &CharStyle, vertical: bool) -> bool {
|
||||
if a == b {
|
||||
return true;
|
||||
}
|
||||
!vertical
|
||||
&& *a
|
||||
== CharStyle {
|
||||
standard_vertical_roman: a.standard_vertical_roman,
|
||||
tcy_up_down: a.tcy_up_down,
|
||||
tcy_left_right: a.tcy_left_right,
|
||||
..b.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Do text runs in styles `a` and `b` shape alike, so that they are shaped as one piece of text?
|
||||
/// They do when they differ only in paint and stroke, underline and strikethrough, overprint, the
|
||||
/// character style's name, leading, baseline shift, rotation, Character Alignment, Character
|
||||
@@ -1275,9 +1292,10 @@ fn shape_segment(text: &str, context: &Range<usize>, seg: &Segment, feats: &OtFe
|
||||
cluster_starts.dedup();
|
||||
// A glyph is drawn in one style: where a cluster would take in characters of runs in different
|
||||
// styles, the runs are shaped apart, as runs that do not shape alike are.
|
||||
// Except at harakat styled apart only in paint ([`crate::harakat`]).
|
||||
// Except at harakat styled apart only in paint ([`crate::harakat`]), and, in horizontal type, where
|
||||
// the runs differ only in settings that vertical type alone reads.
|
||||
let inside_clusters: Vec<usize> = boundaries()
|
||||
.filter(|&b| cluster_starts.binary_search(&b).is_err() && run_at(b - 1).1 != run_at(b).1)
|
||||
.filter(|&b| cluster_starts.binary_search(&b).is_err() && !drawn_alike(run_at(b - 1).1, run_at(b).1, feats.vertical))
|
||||
.filter(|b| mark_boundaries.binary_search(b).is_err())
|
||||
.collect();
|
||||
if !inside_clusters.is_empty() {
|
||||
|
||||
@@ -629,6 +629,31 @@ fn an_upright_ligature_takes_its_caret_down_its_cell() {
|
||||
assert!((at(900) - 0.5).abs() < 1e-9, "{}", at(900));
|
||||
}
|
||||
|
||||
/// Horizontal type does not read Standard Vertical Roman Alignment or the tate-chu-yoko offsets, so
|
||||
/// setting one of them on the f of "fi" keeps the ligature. Vertical type reads them per glyph, so
|
||||
/// there the f is shaped apart from the i.
|
||||
#[test]
|
||||
fn vertical_only_settings_keep_a_horizontal_ligature_whole() {
|
||||
let db = db_with(vertical_ligature_caret_font(280));
|
||||
let marks: [fn(&mut CharStyle); 3] = [|s| s.standard_vertical_roman = true, |s| s.tcy_up_down = 10.0, |s| s.tcy_left_right = 10.0];
|
||||
for (i, mark) in marks.into_iter().enumerate() {
|
||||
for vertical in [false, true] {
|
||||
let mut t = point("fi", VERTICAL_LIGATURE_CARET_FAMILY);
|
||||
t.vertical = vertical;
|
||||
let plain = t.runs[0].style.clone();
|
||||
let mut marked = plain.clone();
|
||||
mark(&mut marked);
|
||||
t.runs = vec![
|
||||
vectorcraft_doc::TextRun { text: "f".into(), style: marked, inline: None },
|
||||
vectorcraft_doc::TextRun { text: "i".into(), style: plain, inline: None },
|
||||
];
|
||||
let l = layout(&db, &t);
|
||||
let joined = l.glyphs.iter().any(|g| g.len == 2);
|
||||
assert_eq!(joined, !vertical, "setting {i}, vertical {vertical}: {:?}", l.glyphs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// On a path, an upright ligature in vertical type stands with its top toward the path's start, and
|
||||
/// its cell runs from 0.12 em before the pen to 0.88 em after it, with or without the font's vertical
|
||||
/// metrics. The inner stop lies at the middle of that cell, and the first character's selection ends
|
||||
|
||||
Reference in New Issue
Block a user