Fix cỡ chữ ÂM với file toạ độ lật (Canva): pdfium-render lấy vertical scale = matrix.d CÓ DẤU — chuẩn hoá .abs() tại mọi điểm đọc cỡ trong engine (list/geo/anchor/inplace/capture). Cỡ âm làm UI kẹp ô sửa về 6px (sai vị trí/style) và reflow đo bề rộng âm → không bẻ dòng, chữ mới văng khỏi trang (cổng pass vì ít pixel) → 'text biến mất'. Kèm 2 test fixture form MA TRẬN LẬT (cỡ dương ~24, reflow đặt chữ đúng vùng cũ)
Build Windows portable / build (push) Canceled after 0s

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-08 18:15:23 +07:00
co-authored by Claude Fable 5
parent a009568b9b
commit 390fb82dd6
2 changed files with 112 additions and 8 deletions
+13 -8
View File
@@ -550,7 +550,9 @@ pub fn list_objects(
info.font_italic = Some(italic);
info.font_embedded = t.font().is_embedded().ok();
// Cỡ hiển thị = cỡ đã scale của run × scale dọc của form chứa nó.
info.font_size = Some(t.scaled_font_size().value * mat_vscale(entry.acc));
// .abs(): pdfium-render lấy scale = matrix.d CÓ DẤU — file Canva
// dùng hệ toạ độ lật (d<0) làm cỡ chữ ÂM, vỡ mọi công thức phía sau.
info.font_size = Some((t.scaled_font_size().value * mat_vscale(entry.acc)).abs());
info.color = t
.fill_color()
.ok()
@@ -874,8 +876,11 @@ pub fn apply_edits(
return Ok(None);
};
let vs = mat_vscale(entry.acc);
let (tf, scaled) =
(t.unscaled_font_size().value, t.scaled_font_size().value * vs);
// .abs(): matrix lật (Canva) cho cỡ ÂM — chuẩn hoá dương.
let (tf, scaled) = (
t.unscaled_font_size().value.abs(),
(t.scaled_font_size().value * vs).abs(),
);
let m = obj.matrix().map_err(err)?;
let (_, fy) = mat_apply(entry.acc, m.e(), m.f());
let b_raw = obj.bounds().map(|q| quad_to_rect(&q)).unwrap_or(Rect {
@@ -968,9 +973,9 @@ pub fn apply_edits(
let m = anchor.matrix().map_err(err)?;
let mc = mat_mul(mat_of(&m), entry.acc);
let tok = t.font().token();
let unscaled = t.unscaled_font_size().value;
let unscaled = t.unscaled_font_size().value.abs();
let scaled =
(t.scaled_font_size().value * mat_vscale(entry.acc)).max(1.0);
(t.scaled_font_size().value * mat_vscale(entry.acc)).abs().max(1.0);
let color = t.fill_color().unwrap_or(PdfColor::new(0, 0, 0, 255));
let embedded = t.font().is_embedded().unwrap_or(false);
let data = t.font().data().ok();
@@ -1234,7 +1239,7 @@ pub fn apply_edits(
// Cỡ hiển thị so theo KHÔNG GIAN TRANG (nhân scale form) — target
// từ UI cũng theo trang; hệ số k không đổi khi áp trong form.
let (old_text, scaled) = match obj.as_text_object() {
Some(t) => (t.text(), t.scaled_font_size().value * mat_vscale(entry.acc)),
Some(t) => (t.text(), (t.scaled_font_size().value * mat_vscale(entry.acc)).abs()),
None => continue,
};
if *text != old_text {
@@ -1295,8 +1300,8 @@ pub fn apply_edits(
let vs = mat_vscale(entry.acc);
let (unscaled, scaled, color) = if let Some(t) = obj.as_text_object() {
(
t.unscaled_font_size().value,
t.scaled_font_size().value * vs,
t.unscaled_font_size().value.abs(),
(t.scaled_font_size().value * vs).abs(),
t.fill_color().unwrap_or(PdfColor::new(0, 0, 0, 255)),
)
} else {