O sua dung FONT NHUNG cua PDF (FontFace): het "mat in dam" do may thieu font
Build Windows portable / build (push) Canceled after 0s

User bao: chu mono von in dam (NotoSansMono-Bold), mo o sua thi "ve chu
thuong". Chan doan bang CSS.getPlatformFontsForNode: span da co
font-weight:700 dung, nhung may khong cai font cua tai lieu nen WebView thay
the — mono roi ve Consolas-Bold (net manh hon han NotoSansMono-Bold, nhin
nhu khong dam), chu thuong roi ve Arial.

Fix WYSIWYG font that:
- Engine: ff_engine::font_data(input, page, index) — bytes font nhung (sau
  giai nen) cua 1 text run, index PHANG nhu list_objects (vao duoc run trong
  Form XObject).
- Tauri: command edit_font_data tra base64.
- UI: nap luoi theo TEN font khi loadEditPage (dedup, 1 lan/font), dang ky
  FontFace voi weight/style theo run (khong synthesize chong), dat family
  nhung LEN DAU stack cua div/span trong o sua; glyph thieu trong subset tu
  roi xuong stack he thong; doi phien sua thi bo face cu (subset khac
  coverage). Loi (font khong nhung/khong parse) -> giu stack cu.

Smoke test tren app that (CDP): FontFace tu ArrayBuffer + gan vao span mono
=> getPlatformFontsForNode tra isCustomFont:true. E2E day du sau build CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 11:02:27 +07:00
co-authored by Claude Fable 5
parent c885567b26
commit f2ebf2deff
4 changed files with 110 additions and 3 deletions
+37
View File
@@ -488,6 +488,43 @@ fn text_object_style(t: &PdfPageTextObject) -> (String, bool, bool) {
}
/// Liệt kê các page object của 1 trang để UI vẽ overlay chỉnh sửa.
/// Bytes font NHÚNG của 1 text object (sau giải nén). UI nạp vào WebView qua
/// FontFace để ô sửa hiển thị ĐÚNG font tài liệu: máy người dùng thường thiếu
/// font (NotoSansMono-Bold rơi về Consolas nét mảnh → trông như "mất in
/// đậm"). `object_index` = index PHẲNG như list_objects (vào được cả run
/// trong Form XObject).
pub fn font_data(
pdfium: &Pdfium,
input: &Path,
page_index: u16,
object_index: u16,
password: Option<&str>,
) -> Result<Vec<u8>, EngineError> {
let document = pdfium
.load_pdf_from_file(input, password)
.map_err(|e| EngineError::Pdfium(e.to_string()))?;
let page = document
.pages()
.get(page_index)
.map_err(|e| EngineError::Pdfium(format!("không lấy được trang {page_index}: {e}")))?;
let entries = collect_flat(&page);
let entry = entries
.get(object_index as usize)
.ok_or_else(|| EngineError::Pdfium(format!("object {object_index} ngoài phạm vi")))?;
let obj = object_at_path(&page, &entry.path)?;
let t = obj
.as_text_object()
.ok_or_else(|| EngineError::Pdfium("object không phải text".into()))?;
let data = t
.font()
.data()
.map_err(|e| EngineError::Pdfium(format!("không đọc được font nhúng: {e}")))?;
if data.is_empty() {
return Err(EngineError::Pdfium("font không nhúng trong file".into()));
}
Ok(data.to_vec())
}
pub fn list_objects(
pdfium: &Pdfium,
input: &Path,
+1 -1
View File
@@ -23,7 +23,7 @@ pub mod watermark;
pub use annot::{
apply_annotations, count_annotations, list_annotations, AnnotInfo, AnnotKind, AnnotSpec,
};
pub use edit::{apply_edits, flatten_form_xobjects, list_objects, EditOp, ObjectInfo, ObjectKind, RichSeg};
pub use edit::{apply_edits, flatten_form_xobjects, font_data, list_objects, EditOp, ObjectInfo, ObjectKind, RichSeg};
pub use meta::{outline, page_dims, strip_metadata, OutlineItem, PageDim};
pub use organize::{
build_document, delete_pages, extract_pages, identity_plan, merge_files, rotate_pages,