パターンと
シェーディング
PDFの色は、RGBの数値だけではありません。小さな絵を敷き詰める定義も、場所ごとに色が変わる定義も、リソース名を通して選択できます。
コードは名前=緑、数値=黄、参照・構文=青、命令=紫、コメント=灰で色分けしています。
1. パターンとシェーディングの違い
+パターン(Pattern)
図形を塗るときの「色」として選択する仕組みです。/Pattern 色空間を選び、scn または SCN でパターン名を渡します。
種別1はタイル、種別2はシェーディングを使うパターンです。
シェーディング(Shading)
場所によって色がどう変わるかを記述する定義です。軸方向・放射状・メッシュなど7種類があり、パターンの内部からも参照されます。
/S1 sh は現在の /Shading 辞書から定義を選択する命令です。
2. タイリングパターンと基底色
+タイリング(tiling)は、一つのセルを一定間隔で繰り返す仕組みです。セルの命令列はPDFストリームにあり、/BBox がセルの境界、/XStep と /YStep が繰り返し間隔を表します。
次は構造を示す抜粋です。セルは8×8、繰り返し間隔は10です。ストリーム長とページ全体の構造は省略しています。
+/Resources << /Pattern << /P1 10 0 R >> >>
+10 0 obj
+<< /Type /Pattern /PatternType 1
+ /PaintType 1 /TilingType 1
+ /BBox [0 0 8 8] /XStep 10 /YStep 10
+ /Resources << >> >>
+stream
+.2 .5 .8 rg
+0 0 8 8 re f
+endstream
+endobj
+ | 属性 | 意味 | 今回の保持方法 |
|---|---|---|
| PatternType | 1=タイリング、2=シェーディングパターン | 種別番号を判別子にした型 |
| PaintType | 1=セル内で色を指定、2=呼び出し側から色を渡す | 1または2に限定 |
| TilingType | 1=間隔一定、2=形状の歪みを避ける、3=高速化を許す間隔一定 | 1〜3に限定 |
| BBox / XStep / YStep | 境界と間隔。間隔は0以外で、負の値も指定可能 | 4個の有限座標と有限な間隔 |
| Resources | セル自身が使うローカルリソース | 辞書を取得して保持。内部の再帰実行は後段 |
| Matrix | パターン座標から既定のユーザー座標への変換 | 6要素。省略時は単位行列 |
着色パターン
PaintType 1 はセルが色を持ちます。基底色空間を伴わない /Pattern を選択し、数値成分を渡さず名前だけを指定します。次の /P1 は種別1・着色として定義済みとします。
/Pattern cs % 塗りの色空間を選択
+/P1 scn % 数値成分は不要、最後にパターン名
+ 非着色パターン
PaintType 2 はセルが形状を持ち、色は呼び出し側が渡します。例えば [/Pattern /DeviceRGB] はRGBの3成分と名前を受け取ります。/P2 は非着色として定義済みとします。
% /Resources内の色空間定義
+/ColorSpace << /Pat [/Pattern /DeviceRGB] >>
+% コンテンツストリーム
+/Pat cs
+.1 .2 .3 /P2 scn
+ 小文字の cs / scn は塗り、大文字の CS / SCN は輪郭に作用します。sc / SC はPatternには使用できません。基底色の有無と着色方式が食い違う組み合わせもエラーになります。
3. シェーディングの7種類
+シェーディングは色変化の計算方法を /ShadingType で選びます。型1〜3は関数で色を定義し、型4〜7はストリーム内のメッシュを使います。
| 番号 | 種類 | 考え方 |
|---|---|---|
| 1 | 関数ベース | 2次元の位置から色を求める |
| 2 | 軸方向 | 2点を結ぶ軸に沿って色が変わる |
| 3 | 放射状 | 二つの円を基に色が変わる |
| 4 | フリーフォーム | 自由に連結した三角形メッシュ |
| 5 | ラティス | 格子状の三角形メッシュ |
| 6 | クーンズパッチ | 曲線の境界でパッチを定義 |
| 7 | テンソル積パッチ | 内部制御点も使うパッチ |
次は軸方向の定義を二つの経路から使う抜粋です。20 0 R と 21 0 R は間接参照で、オブジェクト番号・世代番号・参照記号の順です。/Function のオブジェクト本体は省略しています。
/Resources <<
+ /Pattern << /P3 << /PatternType 2 /Shading 20 0 R >> >>
+ /Shading << /S1 20 0 R >>
+>>
+20 0 obj
+<< /ShadingType 2 /ColorSpace /DeviceRGB
+ /Background [.1 .2 .3] /BBox [0 0 200 100]
+ /Coords [0 0 200 0] /Function 21 0 R >>
+endobj
+% パターン経由の選択
+/Pattern cs /P3 scn
+% シェーディングの直接指定
+/S1 sh
+ /ColorSpace は色の表現、任意の /Background は背景の成分、任意の /BBox はシェーディングの境界です。この段階では色空間の名前または配列を取得して保持し、背景の成分数や関数固有の値域の検証は後段に残します。
/Function 21 0 R を見つけてもオブジェクト21を読みません。直接の関数辞書・関数配列も元の値として保持します。関数評価とメッシュの展開をここへ混ぜないためです。4. 名前から定義に到達する
+同じ /P1 という名前でも、ページやフォームが違えば別の定義を指せます。現在のスコープだけを引き、別ページの定義へフォールバックしません。
- ページのリソースを準備する。
継承とResources自体の解決は既存のページ処理が担当します。
- 非同期で定義を取得する。
PaintResourcesがカテゴリ・各定義・主要属性の間接参照を解決します。座標と背景色では配列の各要素も解決します。
- 同期の命令に渡す。
scn / SCNが名前を引いて着色方式を検証し、shがShadingの名前を引きます。命令のたびに非同期I/Oは行いません。
- 状態と警告を返す。
パターン名と数値成分は色状態に保存されq/Qの対象です。shは色・色空間・パス・クリップを変更しません。
5. 不正入力・未知の種別・参照エラー
+| 入力 | 今回の結果 |
|---|---|
| Pattern以外で名前の色オペランド | 数値として受理せず型・個数エラー |
| 基底RGBで数値2個+パターン名 | 必要な数値3個に足りず個数エラー |
| 存在しないパターン / シェーディング | PATTERN_NOT_FOUND / SHADING_NOT_FOUNDの警告 |
| 未知・欠落の種別番号 | 元オブジェクトをUnknownとして保持し、使用位置でUNSUPPORTEDの警告 |
| セル間隔0・座標の個数不足・メッシュがストリーム以外 | INVALIDの警告。既定値で正しい定義に見せない |
| カテゴリの参照解決エラー | 準備時に元のエラーを返す |
| 個別定義や主要属性の参照解決エラー | その名前を使用する命令までエラーを保持 |
警告による回復はpdfmodの方針です。未知の定義を描画できると判断した意味ではありません。関数評価前のため、すべてのシェーディング固有の必須キーまで検証する段階でもありません。
+名前が見つからないパターンでも指定名と数値成分は色状態へ保持し、後続命令を処理します。shの定義が不正でも、警告のあとに来る命令を処理できます。
+6. 実装の入口と対応範囲
+呼び出し側は同じResourcesから色空間と描画定義を準備し、結果を確認してからレジストリへ渡します。次は成功経路に絞ったTypeScriptの抜粋です。
+const spaces = await ColorSpaceResources.fromResources(resources, resolveRef);
+if (!spaces.ok) {
+ return spaces;
+}
+
+const paints = await PaintResources.fromResources(resources, resolveRef);
+if (!paints.ok) {
+ return paints;
+}
+
+const registry = OperatorRegistry.createDefault(undefined, spaces.value, paints.value);
+ paints.value.patterns と shadings の名前別結果から、型付き定義を参照できます。パターンの結果は1・2・Unknown、シェーディングの結果は1〜7・Unknownで判別します。成功・エラーと値の有無はそれぞれ別に確認してください。
対応した範囲
間接参照の解決、種別と主要属性の保持、オペランド検証、警告、shの登録です。メッシュのバイト列は未復号で保持します。
後段の処理
Functionの評価、実際の塗り、セルの再帰実行、メッシュ復号、色変換、シェーディング固有のすべての属性の検証です。Rust側には対応する命令実行層がまだないため、今回の変更はTypeScript側です。