mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 02:19:56 -06:00
Merge pull request #6274 from dotCooCoo/fix/push-in-keeps-inline-art-gap
Type: a pushed-in line leaves the gap after inline art open
This commit is contained in:
@@ -607,6 +607,17 @@ fn is_cjk_gap(glyph: usize, held: &[usize], after: &[Option<usize>], index: usiz
|
||||
})
|
||||
}
|
||||
|
||||
// May a pushed-in line close a CJK gap after `g`? Not after a list marker or an inline graphic,
|
||||
// which the push-in's room does not count either.
|
||||
fn may_squeeze(g: &SGlyph) -> bool {
|
||||
g.len > 0 && g.inline.is_none()
|
||||
}
|
||||
|
||||
// How much a pushed-in line's `squeeze` adds to the CJK gap after `g`.
|
||||
fn squeeze_after(g: &SGlyph, squeeze: f64, vertical: bool) -> f64 {
|
||||
if may_squeeze(g) { squeeze * squeeze_em(g, vertical) } else { 0.0 }
|
||||
}
|
||||
|
||||
// What justification may change of glyph `j`: nothing of a `held` glyph, and no glyph
|
||||
// scaling of a `hung` one.
|
||||
fn flow_line_flex(glyph: usize, flex: &[Flex], held: &[usize], hung: &[usize]) -> Flex {
|
||||
@@ -672,8 +683,10 @@ fn justify_flow_line(cx: &Ctx<'_>, paragraph: &ParagraphData<'_, '_>, line: &Lin
|
||||
// the same share of the em of the glyph before it, at most [`PUSH_IN_SQUEEZE`].
|
||||
let pushed_in = line.position.pushed_in && paragraph.regions.is_some() && cjk_gaps > 0 && width > room + EPS;
|
||||
if pushed_in {
|
||||
let ems: f64 =
|
||||
(line.index..line.body).filter(|&j| is_cjk_gap(j, held, &after, line.index, sg)).map(|j| squeeze_em(&sg[j], cx.vertical)).sum();
|
||||
let ems: f64 = (line.index..line.body)
|
||||
.filter(|&j| is_cjk_gap(j, held, &after, line.index, sg) && may_squeeze(&sg[j]))
|
||||
.map(|j| squeeze_em(&sg[j], cx.vertical))
|
||||
.sum();
|
||||
if ems > EPS {
|
||||
squeeze = ((room - width) / ems).max(-PUSH_IN_SQUEEZE);
|
||||
}
|
||||
@@ -778,7 +791,7 @@ fn emit_flow_line(cx: &mut Ctx<'_>, pen: &mut Pen<'_>, paragraph: &ParagraphData
|
||||
advance += justification.per_space;
|
||||
} else if justification.per_cjk != 0.0 || justification.squeeze != 0.0 {
|
||||
if is_cjk_gap(glyph_index, &line.held, &justification.after, index, sg) {
|
||||
advance += justification.per_cjk + justification.squeeze * squeeze_em(glyph, cx.vertical);
|
||||
advance += justification.per_cjk + squeeze_after(glyph, justification.squeeze, cx.vertical);
|
||||
}
|
||||
} else if !line.held.contains(&glyph_index)
|
||||
&& drawn_after(index, glyph_index, &justification.after).and_then(|next| sg.get(next)).is_some_and(|next| !next.continues_tcy())
|
||||
|
||||
@@ -347,6 +347,25 @@ fn top_to_top_leading_spaces_inline_art_by_its_run() {
|
||||
assert!((small0 - tall0).abs() < 1e-6 && (small1 - tall1).abs() < 1e-6, "{small0} {small1} / {tall0} {tall1}");
|
||||
}
|
||||
|
||||
/// A pushed-in line closes the gaps next to its CJK characters and leaves the gap after inline art
|
||||
/// open. Needs a font with full-width Japanese (skipped without one).
|
||||
#[test]
|
||||
fn a_pushed_in_line_leaves_the_gap_after_inline_art() {
|
||||
let mut t = TextObject::point(Point::ZERO, "一二", style(20.0));
|
||||
t.xf = Affine::IDENTITY;
|
||||
t.runs.push(TextRun::inline(art(0.5), style(20.0)));
|
||||
t.runs.push(TextRun::new("四五六七八九十一二三四五」六", style(20.0)));
|
||||
t.para.kinsoku_type = vectorcraft_doc::KinsokuShoriType::PushInFirst;
|
||||
t.kind = TextKind::Area { frame: PathData::from_bezpath(&Rect::new(0.0, 0.0, 300.0, 200.0).to_path(0.1)) };
|
||||
let l = layout(FontDb::global(), &t);
|
||||
if (l.glyphs[0].advance - 20.0).abs() > 2.0 {
|
||||
return; // no font with full-width Japanese here
|
||||
}
|
||||
assert!(l.glyphs[1].advance < 20.0 - 0.5, "the other gaps close up: {}", l.glyphs[1].advance);
|
||||
let art = inline_glyph(&l);
|
||||
assert!((art.advance - 20.0).abs() < 1e-6, "the art keeps its advance: {}", art.advance);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_art_moves_with_vertically_aligned_lines() {
|
||||
use vectorcraft_doc::text::{AreaOptions, VerticalAlign};
|
||||
|
||||
Reference in New Issue
Block a user