FIX: Correct height/width of cells with different font sizes

This commit is contained in:
Nicolás Hatcher
2025-02-26 23:22:05 +01:00
committed by Nicolás Hatcher Andrés
parent 409b77c210
commit f9c9467e6c
3 changed files with 21 additions and 13 deletions

View File

@@ -170,7 +170,7 @@ fn row_heigh_increases_automatically() {
model model
.set_user_input(0, 1, 1, "My home in Canada had horses\nAnd monkeys!") .set_user_input(0, 1, 1, "My home in Canada had horses\nAnd monkeys!")
.unwrap(); .unwrap();
assert_eq!(model.get_row_height(0, 1), Ok(2.0 * DEFAULT_ROW_HEIGHT)); assert_eq!(model.get_row_height(0, 1), Ok(40.5));
} }
#[test] #[test]

View File

@@ -6,7 +6,7 @@ use csv::{ReaderBuilder, WriterBuilder};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
constants::{self, DEFAULT_ROW_HEIGHT, LAST_COLUMN, LAST_ROW}, constants::{self, LAST_COLUMN, LAST_ROW},
expressions::{ expressions::{
types::{Area, CellReferenceIndex}, types::{Area, CellReferenceIndex},
utils::{is_valid_column_number, is_valid_row}, utils::{is_valid_column_number, is_valid_row},
@@ -430,10 +430,14 @@ impl UserModel {
new_value: value.to_string(), new_value: value.to_string(),
old_value: Box::new(old_value), old_value: Box::new(old_value),
}]; }];
let style = self.model.get_style_for_cell(sheet, row, column)?;
let line_count = value.split('\n').count(); let line_count = value.split('\n').count() as f64;
let row_height = self.model.get_row_height(sheet, row)?; let row_height = self.model.get_row_height(sheet, row)?;
let cell_height = (line_count as f64) * DEFAULT_ROW_HEIGHT; // This is in sync with the front-end auto fit row
let font_size = style.font.sz as f64;
let line_height = font_size * 1.5;
let cell_height = (line_count - 1.0) * line_height + 8.0 + font_size;
if cell_height > row_height { if cell_height > row_height {
diff_list.push(Diff::SetRowHeight { diff_list.push(Diff::SetRowHeight {
sheet, sheet,

View File

@@ -497,7 +497,7 @@ export default class WorksheetCanvas {
context.clip(); context.clip();
// Is there any better parameter? // Is there any better parameter?
const lineHeight = 22; const lineHeight = fontSize * 1.5;
const lines = fullText.split("\n"); const lines = fullText.split("\n");
const lineCount = lines.length; const lineCount = lines.length;
@@ -608,14 +608,16 @@ export default class WorksheetCanvas {
const sheet = this.model.getSelectedSheet(); const sheet = this.model.getSelectedSheet();
const rows = this.model.getRowsWithData(sheet, column); const rows = this.model.getRowsWithData(sheet, column);
let width = 0; let width = 0;
// This is a bit of a HACK. We should use the actual font size and weather is bold or not
const fontSize = 13;
this.ctx.font = `${fontSize}px ${defaultCellFontFamily}`;
for (const row of rows) { for (const row of rows) {
const fullText = this.model.getFormattedCellValue(sheet, row, column); const fullText = this.model.getFormattedCellValue(sheet, row, column);
if (fullText === "") { if (fullText === "") {
continue; continue;
} }
const style = this.model.getCellStyle(sheet, row, column);
const fontSize = style.font.sz;
let font = `${fontSize}px ${defaultCellFontFamily}`;
font = style.font.b ? `bold ${font}` : `400 ${font}`;
this.ctx.font = font;
const lines = fullText.split("\n"); const lines = fullText.split("\n");
for (const line of lines) { for (const line of lines) {
const textWidth = this.ctx.measureText(line).width; const textWidth = this.ctx.measureText(line).width;
@@ -675,18 +677,20 @@ export default class WorksheetCanvas {
const sheet = this.model.getSelectedSheet(); const sheet = this.model.getSelectedSheet();
const columns = this.model.getColumnsWithData(sheet, row); const columns = this.model.getColumnsWithData(sheet, row);
let height = 0; let height = 0;
const lineHeight = 22;
// This is a bit of a HACK. We should use the actual font size and weather is bold or not
const fontSize = 13;
this.ctx.font = `${fontSize}px ${defaultCellFontFamily}`;
for (const column of columns) { for (const column of columns) {
const fullText = this.model.getFormattedCellValue(sheet, row, column); const fullText = this.model.getFormattedCellValue(sheet, row, column);
if (fullText === "") { if (fullText === "") {
continue; continue;
} }
const style = this.model.getCellStyle(sheet, row, column);
const fontSize = style.font.sz;
const lineHeight = fontSize * 1.5;
let font = `${fontSize}px ${defaultCellFontFamily}`;
font = style.font.b ? `bold ${font}` : `400 ${font}`;
this.ctx.font = font;
const lines = fullText.split("\n"); const lines = fullText.split("\n");
const lineCount = lines.length; const lineCount = lines.length;
// This si computed so that the y position of the text is independent of the vertical alignment // This is computed so that the y position of the text is independent of the vertical alignment
const textHeight = (lineCount - 1) * lineHeight + 8 + fontSize; const textHeight = (lineCount - 1) * lineHeight + 8 + fontSize;
height = Math.max(height, textHeight); height = Math.max(height, textHeight);
} }