Fix font/size preservation and startup freeze

- WYSIWYG editor: Calculate per-line line-heights based on original PDF spacing (gap between lines) instead of uniform height. Each line now gets its own advance value, preserving the exact layout when editing multi-line text with different font sizes (e.g., 22pt heading + 16pt body).

- Startup freeze: Make organize_identity_plan non-blocking. Initialize pagePlan with default identity immediately, then load the real plan in the background. This prevents the UI from freezing when opening large PDFs while PDFium processes all pages.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgnbPwSoRGNH7LHsDUmRpk
This commit is contained in:
Claude
2026-07-16 16:43:41 +00:00
parent 58cba1f415
commit 1171101166
+30 -6
View File
@@ -107,7 +107,14 @@ async function loadDocument(path) {
updateCurrentPage(); updateCurrentPage();
updateZoomLabel(); updateZoomLabel();
state.pagePlan = await invoke("organize_identity_plan", { path: state.path, password: null }).catch(() => []); // Khởi tạo plan mặc định ngay (tất cả trang theo thứ tự gốc).
// Load plan thực tế ở background để không block UI khi mở file.
state.pagePlan = state.pages.map((p) => ({ page: p.index, rotate: 0 }));
invoke("organize_identity_plan", { path: state.path, password: null })
.then((plan) => {
state.pagePlan = plan;
})
.catch(() => {});
state.orgSelected = new Set(); state.orgSelected = new Set();
state.orgAnchor = null; state.orgAnchor = null;
state.orgThumbs = new Map(); state.orgThumbs = new Map();
@@ -2525,24 +2532,41 @@ function startBlockTextEdit(o, lines, ev) {
// còn bbox PDF ôm sát glyph → đẩy khung lên (advPx − cỡ chữ)/2 cho trùng. // còn bbox PDF ôm sát glyph → đẩy khung lên (advPx − cỡ chữ)/2 cho trùng.
const fs0 = (lines[0].fs || o.font_size || 12) * s; const fs0 = (lines[0].fs || o.font_size || 12) * s;
const topPx = Math.max(0, (p.heightPt - union.top) * s - Math.max(0, (advPx - fs0) / 2)); const topPx = Math.max(0, (p.heightPt - union.top) * s - Math.max(0, (advPx - fs0) / 2));
// Tính advance cho TỪNG DÒNG dựa trên vị trí gốc trong PDF để giữ layout.
const perLineAdvances = [];
for (let i = 0; i < lines.length; i++) {
let linAdvPx;
if (i < lines.length - 1) {
// Advance = khoảng cách giữa dòng này và dòng tiếp theo (giữ nguyên từ PDF).
const gap = lines[i].rect.bottom - lines[i + 1].rect.top;
linAdvPx = Math.max(8, gap * s);
} else {
// Dòng cuối: dùng cỡ chữ × 1.25.
linAdvPx = Math.max(8, (lines[i].fs || 12) * s * 1.25);
}
perLineAdvances.push(linAdvPx);
}
const totalHeightPx = perLineAdvances.reduce((a, b) => a + b, 0);
Object.assign(ce.style, { Object.assign(ce.style, {
left: leftPt * s + "px", left: leftPt * s + "px",
top: topPx + "px", top: topPx + "px",
width: widthPt * s + "px", width: widthPt * s + "px",
minHeight: lines.length * advPx + 4 + "px", minHeight: totalHeightPx + 4 + "px",
textAlign: centered ? "center" : "left", textAlign: centered ? "center" : "left",
}); });
// MỖI DÒNG 1 div với đúng cỡ/màu/kiểu của dòng đó (WYSIWYG khi gõ). for (let i = 0; i < lines.length; i++) {
for (const l of lines) { const l = lines[i];
const rep = l.runs.find((r) => (r.text || "").trim()) || l.runs[0] || o; const rep = l.runs.find((r) => (r.text || "").trim()) || l.runs[0] || o;
const div = document.createElement("div"); const div = document.createElement("div");
div.className = "edit-line"; div.className = "edit-line";
const t = composeLineText(l.runs); const t = composeLineText(l.runs);
if (t) div.textContent = t; if (t) div.textContent = t;
else div.innerHTML = "<br>"; else div.innerHTML = "<br>";
div.style.fontSize = Math.max(6, (l.fs || 12) * s) + "px"; const divFs = Math.max(6, (l.fs || 12) * s);
div.style.lineHeight = advPx + "px"; div.style.fontSize = divFs + "px";
div.style.lineHeight = perLineAdvances[i] + "px";
div.style.fontFamily = cssFontStack(rep.font_family || o.font_family); div.style.fontFamily = cssFontStack(rep.font_family || o.font_family);
div.style.fontWeight = (rep.font_bold != null ? rep.font_bold : o.font_bold) ? "bold" : "normal"; div.style.fontWeight = (rep.font_bold != null ? rep.font_bold : o.font_bold) ? "bold" : "normal";
div.style.fontStyle = (rep.font_italic != null ? rep.font_italic : o.font_italic) ? "italic" : "normal"; div.style.fontStyle = (rep.font_italic != null ? rep.font_italic : o.font_italic) ? "italic" : "normal";