Merge pull request #649 from MarekSpodBiedry:issue-479
This commit is contained in:
commit
181915ee57
|
|
@ -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;
|
||||
|
|
@ -2088,6 +2106,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.
|
||||
|
|
|
|||
|
|
@ -373,6 +373,15 @@ fn numfmt_color(c: gridcraft_engine::numfmt::FormatColor) -> Color32 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Last column of a Center Across Selection run starting at `start`: it extends over following columns (up to `limit`) while `continues` holds.
|
||||
fn center_across_end(start: u32, limit: u32, continues: impl Fn(u32) -> bool) -> u32 {
|
||||
let mut end = start;
|
||||
while end < limit && end + 1 < MAX_COLS && continues(end + 1) {
|
||||
end += 1;
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
fn look(wb: &Workbook, si: usize, sh: &Sheet, c: CellRef, cf: &mut CfCache) -> (Look, Option<CfLook>) {
|
||||
let mut style = wb.styles.get(sh.style_id(c)).clone();
|
||||
if let Some(t) = sh.table_at(c) {
|
||||
|
|
@ -1047,17 +1056,25 @@ pub(crate) fn paint_quadrant(
|
|||
galley = p.layout_no_wrap(s, font.clone(), color);
|
||||
w = galley.size().x;
|
||||
}
|
||||
// Center Across Selection: the text is centred over this cell and the empty cells to its right that also use it.
|
||||
let across_end = if halign == HAlign::CenterAcross && !rotated && in_merge(c).is_none() {
|
||||
center_across_end(c.col, c1 + 20, |col| {
|
||||
let n = CellRef::new(c.row, col);
|
||||
empty_ok(n) && wb.styles.get(sh.style_id(n)).align.h == HAlign::CenterAcross
|
||||
})
|
||||
} else {
|
||||
c.col
|
||||
};
|
||||
// Overflow into empty neighbours for text (not upright text, whose width is its line height).
|
||||
let mut clip = *rect;
|
||||
if filter_space == 0.0
|
||||
&& !numeric
|
||||
&& !matches!(v, Value::Number(_))
|
||||
&& st.align.rotation.abs() != 90
|
||||
&& w > rect.width() - 2.0 * pad
|
||||
&& in_merge(c).is_none()
|
||||
let overflows = !numeric && !matches!(v, Value::Number(_)) && st.align.rotation.abs() != 90 && w > rect.width() - 2.0 * pad;
|
||||
if filter_space == 0.0 && (overflows || across_end > c.col) && in_merge(c).is_none()
|
||||
{
|
||||
let mut right = rect.right();
|
||||
let mut left = rect.left();
|
||||
if across_end > c.col {
|
||||
right = geo.x(sh, across_end + 1);
|
||||
}
|
||||
if matches!(halign, HAlign::Left | HAlign::Center | HAlign::Justify) {
|
||||
let mut cc = c.col + 1;
|
||||
while right - rect.left() < w + 2.0 * pad && cc < MAX_COLS && empty_ok(CellRef::new(c.row, cc)) && cc <= c1 + 20 {
|
||||
|
|
@ -1087,7 +1104,8 @@ pub(crate) fn paint_quadrant(
|
|||
}
|
||||
}
|
||||
let x = match halign {
|
||||
HAlign::Center | HAlign::CenterAcross | HAlign::Distributed => rect.center().x - w / 2.0,
|
||||
HAlign::CenterAcross => clip.center().x - w / 2.0,
|
||||
HAlign::Center | HAlign::Distributed => rect.center().x - w / 2.0,
|
||||
HAlign::Right => rect.right() - pad - w - indent,
|
||||
_ => text_left + pad + indent,
|
||||
};
|
||||
|
|
@ -3129,6 +3147,13 @@ mod selection_fill_tests {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn center_across_run_stops_at_first_non_continuing_column() {
|
||||
assert_eq!(center_across_end(0, 20, |c| c <= 2), 2);
|
||||
assert_eq!(center_across_end(0, 20, |_| false), 0);
|
||||
assert_eq!(center_across_end(0, 1, |_| true), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filter_menu_uses_the_table_whose_header_was_clicked() {
|
||||
use gridcraft_engine::model::Table;
|
||||
|
|
|
|||
Loading…
Reference in New Issue