Phase 4 Iteration 3: reflow đoạn văn 'như Word' (EditOp::ReflowText)
Engine:
- EditOp::ReflowText { indices, text }: engine tự suy hình học từ các run
(lề trái/bề rộng từ bounds, baseline từ matrix.f gom cụm ±1pt, khoảng cách
dòng = median hiệu baseline); bẻ dòng greedy đo bằng hmtx của font thật
(fontmatch::wrap_lines + char_advance, ttf-parser); \n = ngắt dòng cứng,
từ quá dài cắt theo ký tự, dòng rỗng giữ nhịp baseline
- Giữ font theo thang 4 mức nhất quán với iteration 2: (1) font nhúng parse
được + phủ đủ glyph → nhúng lại chính bytes đó; (2) family base-14 + ASCII
→ font chuẩn PDF qua FPDFText_LoadStandardFont (BaseFont giữ tên chuẩn,
không nhúng, file không phình; đo bằng font metric-compatible); (3) font
hệ thống cùng họ; (4) fallback. FontLoad enum Bytes/Builtin cho pha nạp font
- Dòng mới giữ phần tuyến tính matrix của run neo (scale/nghiêng), Tf =
unscaled run neo → cỡ hiển thị không đổi
UI + Tauri:
- paragraphLines: gom đoạn nhiều dòng (baseline cách đều ±25%, cỡ chữ tương
đồng, giao ngang ≥30%); double-click đoạn ≥2 dòng → textarea sửa CẢ ĐOẠN
WYSIWYG (đúng font/cỡ/màu/kiểu + line-height đúng nhịp baseline)
- Enter = xuống dòng cứng · Ctrl+Enter/bấm ra ngoài = áp dụng · Esc = huỷ;
1 commit = 1 op reflowText = 1 nấc undo
- DTO reflowText (indices) trong Tauri
Test: 3 integration mới (wrap giữ font nhúng + tiếng Việt + baseline đều;
hard break; base-14 giữ BaseFont Helvetica chuẩn) + 3 unit wrap_lines.
Toàn bộ suite engine ngoài qpdf: 52/52 xanh.
Docs: 12 (Iteration 3 + giới hạn v1), 13 (E26–E30), 14 (mục 3.1 → đã giải,
cập nhật thứ tự việc tiếp theo), README.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgnbPwSoRGNH7LHsDUmRpk
This commit is contained in:
@@ -51,21 +51,17 @@ tác tầng PDF object trực tiếp.
|
||||
|
||||
Xếp theo mức độ ảnh hưởng trải nghiệm:
|
||||
|
||||
### 3.1 Reflow đoạn văn nhiều dòng ("sửa như Word") — GAP LỚN NHẤT CÒN LẠI
|
||||
- **Hiện tại:** sửa được cả dòng (Iteration 2), chưa tự bẻ dòng lại cả đoạn.
|
||||
- **Foxit:** click vào đoạn → gõ → chữ tự chảy xuống dòng trong khối.
|
||||
- **Giải pháp (Iteration 3, khả thi với stack hiện tại):**
|
||||
1. Gom block: các dòng có baseline cách đều (±20%), cùng lề trái/phải giao nhau.
|
||||
2. Đo width chính xác tầng engine bằng `hmtx` của đúng font bytes
|
||||
(`ttf-parser` đã có trong cây phụ thuộc; với font không nhúng thì đo bằng
|
||||
font hệ thống đã match — chấp nhận sai số như chính Foxit).
|
||||
3. UI: textarea phủ block; engine nhận `ReflowBlock { runs, new_text, box }`
|
||||
→ tự bẻ dòng theo width, sinh dãy SetText/AddText/Delete với baseline
|
||||
spacing gốc.
|
||||
4. Nghiệm thu so với Foxit: gõ giữa đoạn 5 dòng → không tràn box, giãn dòng
|
||||
giữ nguyên, font giữ nguyên.
|
||||
- **Rủi ro:** đoạn justify (giãn từ) và kerning → v1 chấp nhận căn trái/đều
|
||||
theo heuristic, như mức "Edit Text" thường của Foxit.
|
||||
### 3.1 Reflow đoạn văn nhiều dòng ("sửa như Word") — ✅ ĐÃ GIẢI (Iteration 3)
|
||||
- **Đã làm đúng kế hoạch:** UI gom block theo baseline cách đều + giao ngang;
|
||||
engine `EditOp::ReflowText` tự suy hình học từ matrix/bounds các run, đo
|
||||
width bằng `hmtx` (ttf-parser), bẻ dòng greedy (`\n` = ngắt cứng), tạo lại
|
||||
các dòng đúng baseline spacing; font giữ theo thang 4 mức (bytes nhúng →
|
||||
font chuẩn base-14 qua `FPDFText_LoadStandardFont` → cùng họ → fallback).
|
||||
3 test integration + 3 unit — xem `docs/12` mục Iteration 3.
|
||||
- **Còn lại của mục này (v2):** đoạn justify reflow về căn trái; chưa kerning;
|
||||
khối text xoay chưa reflow theo hướng xoay; đoạn lẫn nhiều font thống nhất
|
||||
theo run neo. Đây là các case Foxit xử lý tốt hơn — nâng khi gặp tài liệu
|
||||
thực tế, không chặn trải nghiệm chính.
|
||||
|
||||
### 3.2 Hiệu năng phiên sửa trên file rất lớn
|
||||
- **Hiện tại:** mô hình "materialize tức thì" — mỗi thao tác lưu toàn bộ tài
|
||||
@@ -133,16 +129,16 @@ Foxit hơn" — chi phí khổng lồ, không giải quyết gap nào ở mục
|
||||
## 5. Tiến độ so với đích + thứ tự việc đề xuất
|
||||
|
||||
Đã xong (lõi, có test): Viewer ✅ · Annotate ✅ · Organize + lưu vững ✅ ·
|
||||
**Edit text/object giữ font ✅ (iteration 2)**.
|
||||
**Edit text/object giữ font ✅ (iteration 2) · Reflow đoạn "như Word" ✅
|
||||
(iteration 3)**.
|
||||
|
||||
Thứ tự đề xuất tiếp theo, bám giá trị người dùng:
|
||||
1. **Iteration 3 của Edit: reflow đoạn** (mục 3.1) — hoàn tất lời hứa "sửa như
|
||||
Word", gap trải nghiệm cuối cùng của tính năng moat.
|
||||
2. **Phase 5 Bảo mật + "Lưu tối ưu"** (mục 3.3 gộp vào đây): mã hoá UI (nợ
|
||||
1. **Phase 5 Bảo mật + "Lưu tối ưu"** (mục 3.3 gộp vào đây): mã hoá UI (nợ
|
||||
Phase 3), redaction thật, subset font, dọn rác, chữ ký số.
|
||||
3. Phase 6 Form → Phase 7 OCR/Convert → Phase 8 phát hành (theo roadmap).
|
||||
4. Song song, rải theo từng phase: mở rộng font matching (3.4) và nấc 1 của
|
||||
hiệu năng phiên sửa (3.2) khi chạm file lớn thực tế.
|
||||
2. Phase 6 Form → Phase 7 OCR/Convert → Phase 8 phát hành (theo roadmap).
|
||||
3. Song song, rải theo từng phase: mở rộng font matching (3.4), nấc 1 của
|
||||
hiệu năng phiên sửa (3.2) khi chạm file lớn thực tế, và v2 của reflow
|
||||
(justify/xoay — mục 3.1).
|
||||
|
||||
## 6. Checklist FINAL TARGET & RULE cho chính tài liệu này
|
||||
- [x] Đối chiếu từng tính năng với hành vi Foxit làm chuẩn nghiệm thu.
|
||||
|
||||
Reference in New Issue
Block a user