mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 20:01:43 +00:00
Type: a line holding right-to-left text pushes out
A line with right-to-left text is reordered before it is drawn, and justification closes the gaps between its glyphs in that order, which can differ from the gaps the push-in counted. Such a line could be taken as fitting and then run past its frame. Kinsoku Shori Type now pushes it out.
This commit is contained in:
@@ -518,8 +518,8 @@ const PUSH_IN_RUN: usize = 16;
|
||||
/// before it, makes room for them. Push In First tries this before it pushes out. Push Out First
|
||||
/// tries it only when pushing out, to the line's last allowed break `pushed_out`, would leave the
|
||||
/// line short by more than an em of the character before `j`. Push Out Only never pushes in, and
|
||||
/// neither does a line holding a tab, nor one where the characters taken in reach a space after a
|
||||
/// character that may not end a line. With `hanging` (Optical Margin Alignment or Roman Hanging
|
||||
/// neither does a line holding a tab or right-to-left text, nor one where the characters taken in
|
||||
/// reach a space after a character that may not end a line. With `hanging` (Optical Margin Alignment or Roman Hanging
|
||||
/// Punctuation), the gaps that hanging punctuation keeps open are not counted.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn push_in(
|
||||
@@ -569,6 +569,11 @@ fn push_in(
|
||||
while last > i && g[last - 1].is_space() {
|
||||
last -= 1;
|
||||
}
|
||||
// A line holding right-to-left text is reordered before it is drawn, and justification closes
|
||||
// the gaps between its glyphs in that order: it pushes out.
|
||||
if g[i..last].iter().any(|h| h.len > 0 && h.level.is_rtl()) {
|
||||
return None;
|
||||
}
|
||||
let punct = |k: usize| g.get(k).is_some_and(optical_punct);
|
||||
let quote = |k: usize| g.get(k).is_some_and(|h| is_quote(h.ch));
|
||||
let may_hang = |a: usize| {
|
||||
|
||||
@@ -223,4 +223,13 @@ fn kinsoku_shori_type_pushes_a_closing_bracket_in_or_out() {
|
||||
assert_eq!(end(tabbed, 146.0, Kinsoku::Hard, PushOutOnly), 12);
|
||||
assert_eq!(end(tabbed, 146.0, Kinsoku::Hard, PushOutFirst), 12);
|
||||
assert_eq!(end(tabbed, 146.0, Kinsoku::Hard, PushInFirst), 12);
|
||||
|
||||
// A line holding right-to-left text is reordered before it is drawn, so the gaps that close
|
||||
// differ from the ones counted here: it pushes out.
|
||||
let mixed = "一二三א五六七八九十一二三四五」六";
|
||||
let mut glyphs = full_width(mixed);
|
||||
glyphs[3].level = unicode_bidi::Level::rtl();
|
||||
let mixed_end = |ty: KinsokuShoriType| break_line(mixed, &glyphs, 0, 150.0, &[], 0.0, None, Burasagari::None, Kinsoku::Hard, ty, false).0;
|
||||
assert_eq!(mixed_end(PushInFirst), 14, "right-to-left text on the line: 五 is pushed out with 」");
|
||||
assert_eq!(mixed_end(PushOutOnly), 14);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user