フォント、サブセット化、タグ付けのトラブルシューティング
このページの各エントリでは、エンジンが NextPDF\Exception\FontNotFoundException および NextPDF\Exception\FontParsingException として発生させるフォントの resolve(解決)とパースの失敗を扱います。また、CJK カバレッジの診断、およびタグ付き出力に影響する構造ツリーの問題も扱います。各エントリでは、原因を確認できるよう、該当する例外またはテストを正確に示しています。
エントリ: フォントが見つからない
「エントリ: フォントが見つからない」という見出しのセクション- 症状
FontNotFoundExceptionが、Font "<name>" not found. Searched: [<paths>]という形式のメッセージとともに発生します。 - 考えられる原因 要求されたフォントファミリーまたはファイルパスが存在しない、読み取れない、または設定されたフォントディレクトリにアクセスできません。フォントデータ自体は有効でも、エンジンがその場所に到達できない場合があります。
- 証拠 / 診断
getContext()はfont_name、search_paths、fallback_attemptedを返します。search_pathsでエンジンが試したすべての場所を、fallback_attemptedでフォールバックがすでに試されたかどうかを確認できます。 - 解決方法
- 要求された
font_nameを、実際に存在するファイルと照合します。 - フォントが格納されているディレクトリを、設定済みのフォントディレクトリに追加するか、渡したパスを修正します。
- ランタイムユーザーがそのファイルを読み取れることを確認します。
- 呼び出しを再実行します。
- 要求された
- 関連項目 例外リファレンス。
エントリ: フォントファイルのパースに失敗する
「エントリ: フォントファイルのパースに失敗する」という見出しのセクション- 症状
FontParsingExceptionが、Failed to parse font file "<file>": <reason>という形式のメッセージとともに発生します。 - 考えられる原因 フォントファイルは見つかったものの、その内容が使用できません。ヘッダーが切り詰められている、テーブルディレクトリが無効である、または
head、hhea、OS/2などの必須テーブルが欠落している、といった状態です。 - 証拠 / 診断
getContext()はfont_fileとparse_errorを返します。parse_errorフィールドには、構造上の問題が示されます。 - 解決方法
- フィールド
parse_errorを読んで、構造上の欠陥を特定します。 - フォントファイルを、正常であることが分かっている同じフェイスのコピーに置き換えます。
- 呼び出しを再実行します。
- フィールド
- 関連項目 例外リファレンス。
エントリ: 不正なフォントテーブルでサブセット化が失敗する
「エントリ: 不正なフォントテーブルでサブセット化が失敗する」という見出しのセクション- 症状
FontParsingExceptionが、font_fileの値がfont-subset、parse_errorの値がInvalid head table: too short、Invalid hhea table: too short、Invalid maxp table: too short、Failed to unpack font dataなどの状態で発生します。 - 考えられる原因 フォントは初回ロードを通過したものの、サブセット化に必要なテーブルが切り詰められているか、アンパックできません。サブセッターは、破損したサブセットを出力するのではなく、そのフォントを拒否します。
- 証拠 / 診断
head、hhea、maxpのいずれかのテーブルが短すぎるか、アンパックに失敗すると、src/Typography/FontSubsetter.phpがFontParsingExceptionを、ファイル名にリテラルトークンfont-subsetを指定して発生させます。このトークンは、失敗が初回ロードではなくサブセット化の段階で発生したことを示します。 - 解決方法
- ソースフォントを、同じフェイスで切り詰められていないコピーに置き換えます。
- フォントがビルドツールによって生成されている場合は、再生成して
head、hhea、maxpの各テーブルが完全であることを確認します。 - ビルドを再実行します。
- 関連項目 PDF/A および PDF/UA の検証。
エントリ: CJK テキストがグリフ欠落でレンダリングされる
「エントリ: CJK テキストがグリフ欠落でレンダリングされる」という見出しのセクション- 症状 中国語、日本語、または韓国語のテキストが空白のボックスや欠落した文字としてレンダリングされ、フォントの CJK カバレッジが疑われます。
- 考えられる原因 選択したフォントが、そのスクリプトに必要な Unicode ブロックをカバーしていません。各 CJK スクリプトでは、共通の表意文字ブロックに加えて、固有のブロックが必要になります。
- 証拠 / 診断
src/Typography/CjkFontValidator.phpはvalidateCoverage(FontInfo $font, CjkScript $script)を提供します。これは、カバレッジの割合と、50% の報告しきい値を下回るブロックを含むCjkCoverageResultを返します。バリデーターはコードポイントをサンプリングします。これは診断用であり、フォントのロードを変更することはありません。 - 解決方法
- 対象のフォントとターゲットスクリプトに対して
CjkFontValidator::validateCoverage()を実行します。 - フィールド
missingRangesで、どのブロックがカバーされていないかを確認できます。たとえば、繁体字中国語では注音、日本語ではひらがなとカタカナ、韓国語ではハングル音節文字です。 - それらのブロックをカバーするフォントを選択するか、カバーできるフォールバックフォントを追加します。
- レンダリングを再実行し、カバレッジを再確認します。
- 対象のフォントとターゲットスクリプトに対して
- 関連項目 例外リファレンス。
エントリ: 定義済み CMap が CJK スクリプトと一致しない
「エントリ: 定義済み CMap が CJK スクリプトと一致しない」という見出しのセクション- 症状 CJK テキストが誤ったグリフにマッピングされる、またはドキュメントの言語と一致しない定義済み CMap が選択されます。
- 考えられる原因 検出されたスクリプトによって、Adobe 定義済み CMap 名が決まります。スクリプト固有のブロックがなく、共通の表意文字ブロックのみをカバーするフォントは、仕様上、簡体字中国語として検出されます。
- 証拠 / 診断
CjkFontValidator::detectScript()は検出されたスクリプトを返し、resolvePredefinedCMapName()がそれをマッピングします。簡体字中国語はUniGB-UTF16-H、繁体字中国語はUniCNS-UTF16-H、日本語はUniJIS-UTF16-H、韓国語はUniKS-UTF16-Hにマッピングされます。スクリプト固有のブロックが存在しない場合、検出は簡体字中国語にフォールバックします。 - 解決方法
- フォントがスクリプト固有のブロックを備えていることを確認します。繁体字中国語では注音、日本語ではひらがなまたはカタカナ、韓国語ではハングルです。
- ドキュメントが繁体字中国語であってもフォントに注音ブロックがない場合は、注音ブロックを備えたフォントを選択し、意図したスクリプトとして検出されるようにします。
- レンダリングを再実行します。
- 関連項目 例外リファレンス。
エントリ: タグ付きコンテンツから使用可能な構造ツリーが生成されない
「エントリ: タグ付きコンテンツから使用可能な構造ツリーが生成されない」という見出しのセクション- 症状 タグ付きビルドで構造が生成されない、または下流のアクセシビリティチェックで構造ツリーが空または欠落していると報告されます。
- 考えられる原因 コンテンツがタグ付けパスを経由せずに出力されたため、構造要素が作成されていません。構造ツリーは空のままになります。
- 証拠 / 診断
src/Accessibility/StructureTree.phpとsrc/Accessibility/TaggedContentEmitter.phpが、タグ付きコンテンツから構造ツリーを構築します。テストtests/Integration/Accessibility/EmptyTaggedPdfDoesNotAdvertisePdfUa2Test.phpは、空の構造ツリーが PDF/UA-2 を宣言しないことを確認します。 - 解決方法
- 構造要素が作成されるように、コンテンツがタグ付けパスを経由して出力されることを確認します。
- 各マークコンテンツシーケンスが構造要素にマッピングされていることを確認します。
- ビルドを再実行し、構造ツリーを確認します。
- 関連項目 PDF/A および PDF/UA の検証。
エントリ: 構造要素の言語タグが拒否される
「エントリ: 構造要素の言語タグが拒否される」という見出しのセクション- 症状 構造要素またはドキュメントの言語値が有効なタグではないため、ビルドが失敗します。
- 考えられる原因 指定された言語が有効な BCP-47 タグではありません。バリデーターは、不正な形式のタグを出力するのではなく、拒否します。
- 証拠 / 診断
src/Accessibility/Bcp47Validator.phpがタグを検証します。無効なタグではsrc/Accessibility/InvalidBcp47TagException.phpが発生します。PDF/UA-2 の厳格な言語要件はtests/Unit/Conformance/PdfUa2Section844LangStrictTest.phpで検証されます。 - 解決方法
- 言語値を有効な BCP-47 タグに置き換えます。たとえば
en-US、de-DE、zh-Hant-TWです。 - 一部の箇所がドキュメントの言語と異なる場合は、その特定の構造要素に言語を設定します。
- ビルドを再実行します。
- 言語値を有効な BCP-47 タグに置き換えます。たとえば
- 関連項目 PDF/A および PDF/UA の検証。
エッジケースと注意点
「エッジケースと注意点」という見出しのセクションFontNotFoundExceptionとFontParsingExceptionは別の例外です。「見つからない」は、ファイルに到達できなかったことを意味します。「パース」は、ファイルには到達したものの、そのバイト列が使用できないことを意味します。どちらかを判断するには、クラスを確認してください。- 値
font-subsetは、font_fileでは実際のパスではなく、サブセット化の段階を示す意図的なマーカーです。font-subsetという名前のファイルを探さないでください。 CjkFontValidatorは、すべてのコードポイントを検査せずにサンプリングするため、カバレッジの数値はバイト単位で厳密な監査結果ではなく、フォント選択には十分な推定値です。- 空の構造ツリーは、仕様上、PDF/UA-2 ではないと報告されます。これは、エンジンの文書化された動作であり、欠陥ではありません。
用語集: フォントサブセット化 · CJK カバレッジ · 構造ツリー