mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-02 16:30:36 -06:00
Merge pull request #1639
Text: scale down insets when wider than the shape (#1632)
This commit is contained in:
@@ -93,12 +93,24 @@ impl BoxGeom {
|
||||
} else {
|
||||
text_rect
|
||||
};
|
||||
let inner = Rect::new(
|
||||
r.x0 + bp.inset_l.unwrap_or(7.2),
|
||||
r.y0 + bp.inset_t.unwrap_or(3.6),
|
||||
(r.x1 - bp.inset_r.unwrap_or(7.2)).max(r.x0 + bp.inset_l.unwrap_or(7.2)),
|
||||
(r.y1 - bp.inset_b.unwrap_or(3.6)).max(r.y0 + bp.inset_t.unwrap_or(3.6)),
|
||||
);
|
||||
// Insets wider than the shape scale down proportionally to fit inside it (#1632).
|
||||
let (mut ins_l, mut ins_r) = (bp.inset_l.unwrap_or(7.2), bp.inset_r.unwrap_or(7.2));
|
||||
let (mut ins_t, mut ins_b) = (bp.inset_t.unwrap_or(3.6), bp.inset_b.unwrap_or(3.6));
|
||||
let w = r.width().max(0.0);
|
||||
let total_x = ins_l + ins_r;
|
||||
if ins_l >= 0.0 && ins_r >= 0.0 && total_x > w && total_x > 0.0 {
|
||||
let s = w / total_x;
|
||||
ins_l *= s;
|
||||
ins_r *= s;
|
||||
}
|
||||
let h = r.height().max(0.0);
|
||||
let total_y = ins_t + ins_b;
|
||||
if ins_t >= 0.0 && ins_b >= 0.0 && total_y > h && total_y > 0.0 {
|
||||
let s = h / total_y;
|
||||
ins_t *= s;
|
||||
ins_b *= s;
|
||||
}
|
||||
let inner = Rect::new(r.x0 + ins_l, r.y0 + ins_t, (r.x1 - ins_r).max(r.x0 + ins_l), (r.y1 - ins_b).max(r.y0 + ins_t));
|
||||
// Text that follows a WordArt arch or circle is set on one line per paragraph.
|
||||
let follow = bp.warp.as_deref().is_some_and(deckcraft_geom::warp::is_follow);
|
||||
let wrap = bp.wrap.unwrap_or(true) && !follow && !matches!(bp.autofit, Some(AutoFit::Shape) if shape.text_box && !bp.wrap.unwrap_or(true));
|
||||
|
||||
@@ -1946,3 +1946,39 @@ fn a_paragraph_with_its_own_start_at_restarts_the_count_there() {
|
||||
// A later paragraph with a new start begins a fresh run.
|
||||
check(&[1, 1, 7, 7], &[1, 2, 7, 8]);
|
||||
}
|
||||
|
||||
/// #1632: when insets are wider than the shape, they scale down proportionally so the text
|
||||
/// rectangle stays inside the shape bounds and unwrapped text does not project outside it.
|
||||
#[test]
|
||||
fn insets_wider_than_the_shape_scale_down_within_the_shape_bounds() {
|
||||
let (p, mut sh) = setup("Collaboration Hub", 14.17, 14.17);
|
||||
sh.ph = None;
|
||||
let bp = &mut sh.text.as_mut().unwrap().body;
|
||||
bp.wrap = Some(false);
|
||||
bp.inset_l = Some(127.5);
|
||||
bp.inset_r = Some(11.33);
|
||||
bp.inset_t = Some(11.33);
|
||||
bp.inset_b = Some(11.33);
|
||||
sh.text.as_mut().unwrap().paragraphs[0].props = deckcraft_model::text::ParaProps { align: Some(Align::Center), ..Default::default() };
|
||||
let l = lay(&p, &sh, 14.17, 14.17);
|
||||
assert_eq!(l.lines.len(), 1);
|
||||
let line = &l.lines[0];
|
||||
let mid = (line.caret_x[0] + *line.caret_x.last().unwrap()) / 2.0;
|
||||
// The text center must remain inside the 14.17 pt wide shape, not pushed ~127.5 pt to the right.
|
||||
assert!((0.0..=14.17).contains(&mid), "line center {mid} should be within [0, 14.17]");
|
||||
}
|
||||
|
||||
/// #1632: signed insets (e.g. negative left inset with positive right inset) are preserved when
|
||||
/// their sum fits within the shape bounds.
|
||||
#[test]
|
||||
fn signed_insets_are_preserved_when_they_fit() {
|
||||
let (p, mut sh) = setup("Text", 100.0, 50.0);
|
||||
sh.ph = None;
|
||||
let bp = &mut sh.text.as_mut().unwrap().body;
|
||||
bp.inset_l = Some(-10.0);
|
||||
bp.inset_r = Some(10.0);
|
||||
sh.text.as_mut().unwrap().paragraphs[0].props = deckcraft_model::text::ParaProps { align: Some(Align::Left), ..Default::default() };
|
||||
let l = lay(&p, &sh, 100.0, 50.0);
|
||||
assert_eq!(l.lines.len(), 1);
|
||||
assert_eq!(l.inner.x0, -10.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user