mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-31 06:06:48 -06:00
Center Across Selection: center text over the empty cells to its right (#479)
This commit is contained in:
@@ -1027,6 +1027,21 @@ fn empty_for_overflow(sh: &Sheet, c: CellRef, merges: &[RangeRef]) -> bool {
|
||||
sh.value_ref(c).is_none_or(|v| v.is_empty()) && !merges.iter().any(|m| m.contains(c))
|
||||
}
|
||||
|
||||
/// Unscaled width of the empty Center Across Selection cells right of `c`, which its text is centred over too.
|
||||
fn center_across_width(styles: &StyleTable, sh: &Sheet, c: CellRef, merges: &[RangeRef]) -> f32 {
|
||||
let mut ext = 0.0;
|
||||
let mut col = c.col + 1;
|
||||
while col < MAX_COLS && ext < 20_000.0 {
|
||||
let nc = CellRef::new(c.row, col);
|
||||
if !empty_for_overflow(sh, nc, merges) || styles.get(sh.style_id(nc)).align.h != HAlign::CenterAcross {
|
||||
break;
|
||||
}
|
||||
ext += sh.col_width(col);
|
||||
col += 1;
|
||||
}
|
||||
ext
|
||||
}
|
||||
|
||||
fn draw_text(pg: &mut Page, b: &Block, c: CellRef, l: &Look, rect: (f32, f32, f32, f32), merged: bool, merges: &[RangeRef], limits: (f32, f32)) {
|
||||
let (x, y, w, h) = rect;
|
||||
let sh = b.sh;
|
||||
@@ -1110,8 +1125,11 @@ fn draw_text(pg: &mut Page, b: &Block, c: CellRef, l: &Look, rect: (f32, f32, f3
|
||||
VAlign::Bottom => y + h - pad - size * 0.22 - (n - 1.0) * line_h,
|
||||
};
|
||||
// Overflow into empty neighbours (single-line text, not merged).
|
||||
let (mut clip_l, mut clip_r) = (x, x + w);
|
||||
if !wrap && !merged && !is_num && rot.abs() != 90 && tw + 2.0 * pad + indent > w {
|
||||
// Center Across Selection spans the empty Center Across cells to its right; the text stays within that run.
|
||||
let spans = st.align.h == HAlign::CenterAcross && !wrap && !merged && rot == 0;
|
||||
let across = if spans { center_across_width(&wb.styles, sh, c, merges) * b.k } else { 0.0 };
|
||||
let (mut clip_l, mut clip_r) = (x, x + w + across);
|
||||
if !wrap && !merged && !is_num && rot.abs() != 90 && across <= 0.0 && tw + 2.0 * pad + indent > w {
|
||||
let need = tw + 2.0 * pad + indent - w;
|
||||
let grow = |dir: i64, mut need: f32| -> f32 {
|
||||
let mut ext = 0.0;
|
||||
@@ -1183,7 +1201,7 @@ fn draw_text(pg: &mut Page, b: &Block, c: CellRef, l: &Look, rect: (f32, f32, f3
|
||||
let lw = gridcraft_pdf::text_width(font, size, line);
|
||||
let lx = match h_align {
|
||||
HAlign::Right => x + w - pad - lw - indent,
|
||||
HAlign::Center => x + (w - lw) / 2.0,
|
||||
HAlign::Center => x + (w + across - lw) / 2.0,
|
||||
_ => x + pad + indent,
|
||||
};
|
||||
let ly = first_baseline + i as f32 * line_h;
|
||||
@@ -2063,6 +2081,23 @@ mod tests {
|
||||
assert!(w.len() > 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn center_across_spans_following_empty_center_across_cells() {
|
||||
let mut styles = StyleTable::default();
|
||||
let across = styles.intern(Style { align: Alignment { h: HAlign::CenterAcross, ..Alignment::default() }, ..Style::default() });
|
||||
let mut sh = Sheet::new("S");
|
||||
for col in 0..3 {
|
||||
sh.set_style(CellRef::new(0, col), across);
|
||||
}
|
||||
sh.set_value(CellRef::new(0, 0), Value::Text("Title".into()));
|
||||
let a1 = CellRef::new(0, 0);
|
||||
assert_eq!(center_across_width(&styles, &sh, a1, &[]), sh.col_width(1) + sh.col_width(2));
|
||||
sh.set_value(CellRef::new(0, 2), Value::Text("x".into()));
|
||||
assert_eq!(center_across_width(&styles, &sh, a1, &[]), sh.col_width(1));
|
||||
let merged = [RangeRef::new(CellRef::new(0, 1), CellRef::new(1, 1))];
|
||||
assert_eq!(center_across_width(&styles, &sh, a1, &merged), 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rotated_wrapped_text_prints_rotated() {
|
||||
// Upright headers over narrow columns (mark sheets) combine rotation with Wrap Text.
|
||||
|
||||
Reference in New Issue
Block a user