Edit mode: zoom + chuyển trang + dòng lẫn nhiều style (thường/đậm/mono)
Build Windows portable / build (push) Canceled after 0s
Build Windows portable / build (push) Canceled after 0s
3 vấn đề user báo trong chế độ Sửa nội dung:
1. ZOOM: stage sửa trước đây cứng 820px — nút +/-, dropdown %, Vừa rộng/
Vừa trang và Ctrl+lăn chuột đều vô tác dụng. Giờ editZoom riêng (kế thừa
zoom viewer khi vào): co giãn ảnh + overlay NGAY (CSS, mượt), render nét
PDFium sau 220ms ngừng thao tác; mọi nút zoom/fit + Ctrl+wheel hoạt động;
fix flex-center overflow (margin auto) để zoom to không cắt mép trái.
2. CHUYỂN TRANG: nút ▲▼/ô nhập trang trước đây chỉ điều khiển viewer đang
ẩn. Giờ goToPage/gotoPrev/Next nhận biết edit mode → switchEditPage
(đóng ô sửa đang mở, giữ nguyên undo/thay đổi các trang khác vì dùng
chung editBase).
3. DÒNG LẪN STYLE (thường + đậm/mono): ô sửa trước áp 1 style/dòng nên
"windowsInitialPassword" đậm hiện thành chữ thường, commit còn ép cả
dòng về 1 font. Giờ:
- UI: mỗi nhóm run liền kề cùng style = 1 SPAN riêng (đúng font/cỡ/màu
từng phần khi gõ); commit đọc theo đoạn style (text node trần mượn
style span kề); >=2 style gửi kèm richLines.
- Engine: ReflowText thêm rich (Vec<Vec<RichSeg>>) — resolve thang
giữ-font RIÊNG cho từng style-run (probe token gốc/nhúng lại bytes/
builtin/cùng họ), token hoá theo từ giữ style + glue giữa đoạn dính
liền, bẻ dòng chung cả khối, vẽ mỗi cụm cùng-style thành 1 object
đúng font/cỡ/màu, tự kiểm + fallback từng từ như đường 1-style.
- fitEditLinesToPdf: đo text node sâu trong span; hiệu chỉnh cỡ scale
cả span. Tầng-0 token gốc tắt khi KHỐI có run nested (trước chỉ xét
anchor — token vô hiệu sau khi mở lại document hậu phẫu thuật).
- Test: fixture 1 dòng Helvetica + Courier-Bold → sửa phần thường,
phần mono giữ nguyên BaseFont Courier-Bold, cùng baseline đúng thứ tự.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -741,6 +741,18 @@ struct EditOpDto {
|
||||
/// reflowText: index các run của khối đoạn văn.
|
||||
#[serde(default)]
|
||||
indices: Vec<u16>,
|
||||
/// reflowText nhiều style: mỗi dòng cứng = danh sách đoạn (text + run
|
||||
/// mang style). None/thiếu = khối 1 style.
|
||||
#[serde(default)]
|
||||
rich_lines: Option<Vec<Vec<RichSegDto>>>,
|
||||
}
|
||||
|
||||
/// 1 đoạn cùng style trong reflow nhiều-style.
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct RichSegDto {
|
||||
text: String,
|
||||
style: u16,
|
||||
}
|
||||
|
||||
fn one() -> f32 {
|
||||
@@ -771,7 +783,20 @@ fn edit_op_from_dto(d: EditOpDto) -> Result<ff_engine::EditOp, String> {
|
||||
bold: d.bold.unwrap_or(false),
|
||||
italic: d.italic.unwrap_or(false),
|
||||
},
|
||||
"reflowText" => ff_engine::EditOp::ReflowText { indices: d.indices, text: d.text },
|
||||
"reflowText" => ff_engine::EditOp::ReflowText {
|
||||
indices: d.indices,
|
||||
text: d.text,
|
||||
rich: d.rich_lines.map(|lines| {
|
||||
lines
|
||||
.into_iter()
|
||||
.map(|line| {
|
||||
line.into_iter()
|
||||
.map(|s| ff_engine::RichSeg { text: s.text, style: s.style })
|
||||
.collect()
|
||||
})
|
||||
.collect()
|
||||
}),
|
||||
},
|
||||
"addImage" => ff_engine::EditOp::AddImage {
|
||||
x: d.x,
|
||||
y: d.y,
|
||||
|
||||
Reference in New Issue
Block a user