Bỏ qua để đến nội dung

Khắc phục sự cố: phông chữ, subset hóa và gắn thẻ

Các mục này bao quát những lỗi phân giải và phân tích cú pháp phông chữ phát sinh qua NextPDF\Exception\FontNotFoundExceptionNextPDF\Exception\FontParsingException. Chúng cũng bao gồm phần chẩn đoán phạm vi bao phủ tiếng Trung, tiếng Nhật và tiếng Hàn (CJK), cùng các vấn đề về cây cấu trúc ảnh hưởng đến đầu ra được gắn thẻ. Mỗi mục nêu rõ ngoại lệ hoặc bài kiểm thử chính xác để bạn có thể xác minh nguyên nhân.

  • Triệu chứng. FontNotFoundException với thông báo có dạng Font "<name>" not found. Searched: [<paths>].
  • Nguyên nhân có thể. Họ phông chữ hoặc đường dẫn tệp được yêu cầu không tồn tại, không đọc được, hoặc nằm trong thư mục phông chữ mà runtime không thể truy cập. Dữ liệu phông chữ có thể hợp lệ, nhưng engine vẫn không truy cập được dữ liệu đó.
  • Bằng chứng / chẩn đoán. getContext() trả về font_name, search_pathsfallback_attempted. Dùng search_paths để xem lại tất cả vị trí mà engine đã thử. Dùng fallback_attempted để xác nhận một phương án dự phòng đã chạy hay chưa.
  • Cách giải quyết.
    1. So sánh font_name được yêu cầu với tệp phông chữ thực tế đang có.
    2. Thêm thư mục chứa phông chữ vào danh sách thư mục phông chữ đã cấu hình, hoặc sửa lại đường dẫn mà bạn đã truyền.
    3. Xác minh rằng người dùng runtime có thể đọc được tệp.
    4. Chạy lại lệnh gọi.
  • Liên quan. Tham chiếu ngoại lệ.

Mục: tệp phông chữ không phân tích cú pháp được

Phần tiêu đề “Mục: tệp phông chữ không phân tích cú pháp được”
  • Triệu chứng. FontParsingException với thông báo có dạng Failed to parse font file "<file>": <reason>.
  • Nguyên nhân có thể. Engine đã tìm thấy tệp phông chữ, nhưng không thể sử dụng nội dung của tệp: header bị cắt cụt, thư mục bảng không hợp lệ, hoặc thiếu một bảng bắt buộc như head, hhea hoặc OS/2.
  • Bằng chứng / chẩn đoán. getContext() trả về font_fileparse_error. parse_error nêu rõ vấn đề về cấu trúc.
  • Cách giải quyết.
    1. Đọc parse_error để xác định khiếm khuyết về cấu trúc.
    2. Thay thế tệp phông chữ bằng một bản sao đã biết là tốt của cùng kiểu chữ đó.
    3. Chạy lại lệnh gọi.
  • Liên quan. Tham chiếu ngoại lệ.

Mục: subset hóa thất bại trên một bảng phông chữ bị hỏng định dạng

Phần tiêu đề “Mục: subset hóa thất bại trên một bảng phông chữ bị hỏng định dạng”
  • Triệu chứng. FontParsingException với giá trị font_filefont-subset và một parse_error như Invalid head table: too short, Invalid hhea table: too short, Invalid maxp table: too short hoặc Failed to unpack font data.
  • Nguyên nhân có thể. Phông chữ đã qua bước nạp ban đầu, nhưng một bảng cần cho việc subset hóa bị cắt cụt hoặc không thể giải nén. Bộ subset hóa từ chối phông chữ thay vì phát ra một subset bị hỏng.
  • Bằng chứng / chẩn đoán. Khi bảng head, hhea hoặc maxp quá ngắn, hoặc khi việc giải nén thất bại, src/Typography/FontSubsetter.php phát sinh FontParsingException với token nguyên văn font-subset làm tên tệp. Token này cho biết lỗi xảy ra trong quá trình subset hóa, không phải khi nạp ban đầu.
  • Cách giải quyết.
    1. Thay thế phông chữ nguồn bằng một bản sao đầy đủ, không bị cắt cụt, của cùng kiểu chữ đó.
    2. Nếu công cụ build tạo ra phông chữ, hãy tạo lại phông chữ đó và xác minh rằng các bảng head, hheamaxp đầy đủ.
    3. Chạy lại quá trình build.
  • Liên quan. Xác thực PDF/A và PDF/UA.

Mục: văn bản CJK kết xuất với glyph bị thiếu

Phần tiêu đề “Mục: văn bản CJK kết xuất với glyph bị thiếu”
  • Triệu chứng. Văn bản tiếng Trung, tiếng Nhật hoặc tiếng Hàn kết xuất thành ô trống hoặc bị thiếu ký tự, trong khi phạm vi bao phủ CJK của phông chữ chưa chắc chắn.
  • Nguyên nhân có thể. Phông chữ được chọn không bao phủ các khối Unicode mà chữ viết này yêu cầu. Mỗi chữ viết CJK cần các khối riêng bên cạnh các khối biểu ý dùng chung.
  • Bằng chứng / chẩn đoán. src/Typography/CjkFontValidator.php cung cấp validateCoverage(FontInfo $font, CjkScript $script). Phương thức này trả về một CjkCoverageResult với phần trăm bao phủ và mọi khối nằm dưới ngưỡng báo cáo 50%. Bộ xác thực lấy mẫu các điểm mã. Đây là công cụ chẩn đoán và không thay đổi việc nạp phông chữ.
  • Cách giải quyết.
    1. Chạy CjkFontValidator::validateCoverage() cho phông chữ và chữ viết mục tiêu.
    2. Đọc missingRanges để xem những khối nào chưa được bao phủ, ví dụ Bopomofo cho tiếng Trung phồn thể, Hiragana và Katakana cho tiếng Nhật, và Hangul Syllables cho tiếng Hàn.
    3. Chọn một phông chữ bao phủ các khối đó, hoặc thêm một phông chữ dự phòng có phạm vi bao phủ tương ứng.
    4. Chạy lại quá trình kết xuất và kiểm tra lại phạm vi bao phủ.
  • Liên quan. Tham chiếu ngoại lệ.

Mục: CMap định nghĩa sẵn không khớp với chữ viết CJK

Phần tiêu đề “Mục: CMap định nghĩa sẵn không khớp với chữ viết CJK”
  • Triệu chứng. Văn bản CJK ánh xạ sang sai glyph, hoặc tài liệu dùng một CMap định nghĩa sẵn không khớp với ngôn ngữ của tài liệu.
  • Nguyên nhân có thể. Chữ viết được phát hiện sẽ quyết định tên CMap định nghĩa sẵn của Adobe. Theo thiết kế, một phông chữ chỉ bao phủ khối biểu ý dùng chung, nhưng không có khối riêng cho chữ viết, sẽ được phát hiện là tiếng Trung giản thể.
  • Bằng chứng / chẩn đoán. CjkFontValidator::detectScript() trả về chữ viết được phát hiện, và resolvePredefinedCMapName() ánh xạ chữ viết đó: tiếng Trung giản thể sang UniGB-UTF16-H, tiếng Trung phồn thể sang UniCNS-UTF16-H, tiếng Nhật sang UniJIS-UTF16-H và tiếng Hàn sang UniKS-UTF16-H. Nếu không có khối riêng cho chữ viết, việc phát hiện sẽ quay về tiếng Trung giản thể.
  • Cách giải quyết.
    1. Xác nhận rằng phông chữ có kèm khối riêng cho chữ viết: Bopomofo cho tiếng Trung phồn thể, Hiragana hoặc Katakana cho tiếng Nhật, và Hangul cho tiếng Hàn.
    2. Nếu tài liệu là tiếng Trung phồn thể nhưng phông chữ không có khối Bopomofo, hãy chọn một phông chữ có khối này để việc phát hiện phân giải đúng chữ viết mong muốn.
    3. Chạy lại quá trình kết xuất.
  • Liên quan. Tham chiếu ngoại lệ.

Mục: nội dung được gắn thẻ không tạo ra cây cấu trúc dùng được

Phần tiêu đề “Mục: nội dung được gắn thẻ không tạo ra cây cấu trúc dùng được”
  • Triệu chứng. Một bản build được gắn thẻ không tạo ra cấu trúc nào, hoặc một bước kiểm tra trợ năng phía sau báo cáo rằng cây cấu trúc rỗng hoặc bị thiếu.
  • Nguyên nhân có thể. Bản build đã phát ra nội dung bên ngoài đường dẫn gắn thẻ, nên không tạo ra phần tử cấu trúc nào. Cây cấu trúc vì vậy vẫn rỗng.
  • Bằng chứng / chẩn đoán. src/Accessibility/StructureTree.phpsrc/Accessibility/TaggedContentEmitter.php dựng cây cấu trúc từ nội dung được gắn thẻ. Bài kiểm thử tests/Integration/Accessibility/EmptyTaggedPdfDoesNotAdvertisePdfUa2Test.php xác nhận rằng cây cấu trúc rỗng không quảng bá PDF/UA-2.
  • Cách giải quyết.
    1. Xác nhận nội dung được phát ra qua đường dẫn gắn thẻ để các phần tử cấu trúc được tạo ra.
    2. Xác minh rằng mỗi chuỗi nội dung được đánh dấu ánh xạ tới một phần tử cấu trúc.
    3. Chạy lại quá trình build và kiểm tra cây cấu trúc.
  • Liên quan. Xác thực PDF/A và PDF/UA.

Mục: thẻ ngôn ngữ của phần tử cấu trúc bị từ chối

Phần tiêu đề “Mục: thẻ ngôn ngữ của phần tử cấu trúc bị từ chối”
  • Triệu chứng. Một bản build thất bại vì giá trị ngôn ngữ trên một phần tử cấu trúc hoặc trên tài liệu không phải là thẻ hợp lệ.
  • Nguyên nhân có thể. Ngôn ngữ được cung cấp không phải là thẻ BCP-47 hợp lệ. Bộ xác thực từ chối các thẻ sai định dạng thay vì phát ra chúng.
  • Bằng chứng / chẩn đoán. src/Accessibility/Bcp47Validator.php xác thực thẻ. Một thẻ không hợp lệ làm phát sinh src/Accessibility/InvalidBcp47TagException.php. tests/Unit/Conformance/PdfUa2Section844LangStrictTest.php kiểm tra yêu cầu nghiêm ngặt về ngôn ngữ của PDF/UA-2.
  • Cách giải quyết.
    1. Thay giá trị ngôn ngữ bằng một thẻ BCP-47 hợp lệ, chẳng hạn en-US, de-DE hoặc zh-Hant-TW.
    2. Đặt ngôn ngữ trên phần tử cấu trúc cụ thể khi một đoạn khác với ngôn ngữ của tài liệu.
    3. Chạy lại quá trình build.
  • Liên quan. Xác thực PDF/A và PDF/UA.

Trường hợp đặc biệt & điều cần lưu ý

Phần tiêu đề “Trường hợp đặc biệt & điều cần lưu ý”
  • FontNotFoundExceptionFontParsingException báo cáo những lỗi khác nhau. Không tìm thấy nghĩa là không truy cập được tệp. Phân tích cú pháp nghĩa là đã truy cập được tệp, nhưng các byte của tệp không dùng được. Đọc lớp để xác định lỗi nào đã xảy ra.
  • font-subset trong font_file là dấu hiệu cố ý cho giai đoạn subset hóa, không phải đường dẫn thực. Đừng tìm một tệp có tên font-subset.
  • CjkFontValidator lấy mẫu các điểm mã thay vì kiểm tra từng điểm một, nên con số bao phủ của nó là ước tính để chọn phông chữ, không phải một bản kiểm toán chính xác đến từng byte.
  • Theo thiết kế, cây cấu trúc rỗng được báo cáo là không phải PDF/UA-2. Đây là hành vi đã được ghi tài liệu của engine, không phải lỗi.

Bảng thuật ngữ: subset hóa phông chữ · phạm vi bao phủ CJK · cây cấu trúc