Merge pull request #7685 from dotCooCoo/fix/warichu-line-height-block-lines

Type: a warichu line holds the ascent and descent of its outer block lines
This commit is contained in:
BFlat
2026-11-15 06:15:52 +07:00
committed by GitHub
3 changed files with 28 additions and 4 deletions
+8 -3
View File
@@ -287,6 +287,10 @@ fn place_block(g: &mut [SGlyph], s: &WariStyle, (vertical, whole): (bool, bool))
let rtl = !vertical && g.first().is_some_and(|gl| gl.level.is_rtl());
let (inset, outset) = if rtl { (after, before) } else { (before, after) };
let length = inset + block + outset;
// How far the glyphs reach above and below the line's baseline, each from its block line's
// baseline.
let above = g.iter().zip(&places).map(|(gl, p)| gl.ascent - p.1).fold(0.0, f64::max);
let below = g.iter().zip(&places).map(|(gl, p)| gl.descent + p.1).fold(0.0, f64::max);
let glyphs = g.len();
for (i, (gl, (along, across, advance))) in g.iter_mut().zip(places).enumerate() {
let em = gl.face.units_per_em() * gl.sy / r;
@@ -300,9 +304,10 @@ fn place_block(g: &mut [SGlyph], s: &WariStyle, (vertical, whole): (bool, bool))
if i + 1 < glyphs {
gl.keeps_next = true;
}
// The line keeps the height of the block's own size, and holds the whole stack.
gl.ascent = (ascent / r).max(-top);
gl.descent = (descent / r).max(bottom);
// The line keeps the height of the block's own size, and holds the whole stack with each
// block line's glyphs.
gl.ascent = (ascent / r).max(-top).max(above);
gl.descent = (descent / r).max(bottom).max(below);
if s.auto_leading {
gl.leading /= r;
}
+18
View File
@@ -626,6 +626,24 @@ fn a_block_of_several_fonts_keeps_the_tallest_of_them() {
assert!(first_short.0 >= plain[pair.0].0 - 1e-6 && first_short.1 >= deepest - 1e-6, "{first_short:?} {plain:?}");
}
/// The line holds each block line's characters at their own height: with a wide Line Gap, the
/// ascent of the top block line's characters and the descent of the bottom one's stay inside the
/// line.
#[test]
fn a_wide_line_gap_keeps_the_outer_block_lines_inside_the_line() {
let small = layout(db(), &point("x", style(10.0)));
let (ascent, descent) = (small.lines[0].ascent, small.lines[0].descent);
for lines in [2, 3] {
let l = layout(db(), &with_block("cdefgh", CharStyle { warichu_lines: lines, warichu_gap: 20.0, ..marked(20.0) }));
let line = &l.lines[0];
let block = &l.glyphs[2..8];
let top = block.iter().map(|g| g.origin.y).fold(f64::INFINITY, f64::min);
let bottom = block.iter().map(|g| g.origin.y).fold(f64::NEG_INFINITY, f64::max);
assert!(line.baseline - line.ascent <= top - ascent + 1e-6, "{lines}: {} {} {top} {ascent}", line.baseline, line.ascent);
assert!(line.baseline + line.descent >= bottom + descent - 1e-6, "{lines}: {} {} {bottom} {descent}", line.baseline, line.descent);
}
}
/// Warichu Settings on characters not marked Warichu leave their shaping alone: "fi" keeps its
/// ligature when only the f has other settings.
#[test]
+2 -1
View File
@@ -9015,7 +9015,8 @@ Options). Warichu characters are set at `warichuScale` percent of their size (10
`warichuLines` lines (a whole number from 1 to 6, default 2) inside their line: one above the other in horizontal type
and side by side across the column in vertical type, the first line above or to the right. `warichuGap` is the space
between the lines in points (0 to 100, default 0, document points as `baselineShift`). The stack is centered across the
line on the center of the line's ideographic em box, and the line keeps the height of the characters' own size.
line on the center of the line's ideographic em box, and the line keeps the height of the characters' own size, or
more when the stack needs it: the line's ascent and descent take in the characters of the outer lines.
A stretch of warichu characters is one block that takes the settings of its first character; a character with other
settings, another size or the other kind of leading (Auto or a number) starts a new one, and a tab, a forced line break or a tate-chu-yoko character ends it. In
vertical type a character marked `tateChuYoko` as well is set as tate-chu-yoko at its own size, and two or three digits