グラフィック

グラフィックの描画
PDF では、コンテンツストリームで定義された内容が、ページで表示される内容となります。

コンテンツストリームのデータ部分で命令を記述することにより、パスを使った図形や、テキスト、画像などのグラフィックを描画できます。

ただし、SVG ファイルなどを埋め込んで表示したりすることはできないので、ベクター形式のグラフィックは、PDF 構文に変換して描画する必要があります。
座標系
グラフィック要素の座標などは、x, y の2つの実数値のペアで指定します。
各座標系によって、軸の方向や単位は変わります。
デバイス空間
ページの内容は、最終的に、ディスプレイやプリンターなどの出力デバイスに出力されます。
このような各デバイスごとの座標系は、「デバイス空間」と呼ばれます。

デバイス空間は、各デバイスによって、軸の方向や単位の長さが異なります。
ユーザー空間
PDF のページで使われる、出力デバイスに依存しない座標系は、「ユーザー空間」と呼ばれます。
PDF 内では、基本的にこの座標系が使われます。

ユーザー空間は、左下が原点となり、x は右方向、y は上方向が正の値となります。

ページオブジェクト(またはページツリーノード)の MediaBoxCropBox エントリで指定された矩形が、実際に表示される部分の範囲となります。

/MediaBox [ 0 0 612 792 ]

この場合、左下が (0, 0)、右上が (612, 792) の範囲を、ページとして表示するということになります。

ユーザー空間における 1 単位は、「1/72 インチ」です。(1 インチ = 2.54 cm)

ページオブジェクトの UserUnit エントリ [PDF 1.6] を使うと、1 単位を 1/72 インチの倍率で指定することができますが、基本的には 1/72 インチで扱います。
単位をインチ以外にすることはできません。

上記の例である 0 0 612 792 の場合は、ページのサイズが、アメリカのレターサイズ 8.5 x 11 インチとなります。
8.5 x 11 インチを 1/72 インチ単位で表すと、8.5 x 72 = 612, 11 x 72 = 792 となります。

cm 単位でサイズを計算するのであれば、cm * 72 / 2.54 となります。
ページの領域
ページオブジェクトまたはページツリーノードでは、ページの領域をいくつかの種類で指定できます。
各値は、出力環境によって、使用方法が異なってきます。

MediaBox印刷時の物理メディアの領域です。
裁ち落としや印刷マークなどの拡張部分の領域が含まれる場合があります。
ディスプレイへの出力時、CropBox が存在する場合は、無視されます。

この値が一番トップの値となり、以下を省略すると、すべてこの矩形と同じ値になります。
CropBox表示または印刷時に切り取られる領域。
ディスプレイ出力時は、これが実際の表示領域となります。
BleedBox(PDF 1.3) 実際の印刷時に画像化される領域 (裁ち落とし領域)。
印刷マークなどは含まず、裁ち落としの範囲までの領域となります。
TrimBox(PDF 1.3) 印刷における、最終的な完成時の寸法
ArtBox(PDF 1.3) ページ内で意味のあるコンテンツ(空白部分を含む)の範囲。
ページのコンテンツを別のアプリケーションに配置する場合の領域となります。
印刷時は無視されます。
変換行列
ある座標系から別の座標系への変換や、グラフィック要素の移動・拡大・回転などの変換は、3 x 3 の行列を使って行うことが出来ます。

PDF 内では、変換行列は、6つの数値の配列 [a b c d e f] で定義されます。
(グラフィック命令内で指定する場合は、配列ではなく、6つの数値として指定します)

なお、2次元の座標 (x, y) は、[x y 1] のベクトル形式で表現されます。

# 3x3 行列

| a b 0 |
| c d 0 |
| e f 1 |

# 行列の適用
# x , y  = 変換前の位置
# x', y' = 変換後の位置

[x' y' 1] = [x y 1] x (3x3 行列)

x' = x * a + y * c + e
y' = x * b + y * d + f

変換行列の例は、以下のようになります。

# 平行移動
[1 0 0 1 tx ty]

# 拡大
[sx 0 0 sy 0 0]

# 回転
[cosθ sinθ -sinθ cosθ 0 0]

# 傾斜 (x を角度α、y を角度βで)
[1 tanα tanβ 1 0 0]

行列は、複数適用させることができます。

その場合、行列を適用する順番に注意してください。
「回転後に拡大」するのと、「拡大後に回転」するのでは、結果が異なります。
変換行列のセット
コンテンツストリーム内で変換行列をセットする場合は、cm 命令を使います。

# cm の前に行列の6つの数値を指定
a b c d e f cm

この命令以降に記述されたグラフィック要素に、行列が適用されます。
複数の行列が設定された場合は、最後に設定された行列から順に適用されます。
座標系の変換
ユーザー空間の座標系では左下が原点となりますが、左上や右上を原点としたい、という場合もあります。
その場合は、変換行列を使うことで、座標系を変換できます。

例えば、左上を原点としたい場合、
左上原点において (x, y) の位置は、左下原点の座標では (x, H - y) となります。
(H はページの右上 Y 位置)

つまり、左上原点の座標から左下原点の座標へ変換したい場合、以下のような変換式で求められることになるため、

x' = x * 1 + y *  0 + 0
y' = x * 0 + y * -1 + H

変換行列は [ 1 0 0 -1 0 H ] となります。

※この場合、画像などは上下反転されてしまうため、パスの座標などで使用してください。
パスによる描画
PDF での図形描画は、パスを使います。

直線とベジェ曲線によってパスを作成することで、そのパスから、ストローク (パスをなぞる線) を描画したり、パス内の領域を塗りつぶしたり、クリッピングする領域を定義したりできます。

パスは複数のサブパスで構成されます。

「閉じられたパス」というのは、パスの開始点と終点が同じ、つまり、最初から最後までがひと続きになって、囲まれているパスのことです。
塗りつぶしを行う場合、パスは必ず閉じられた状態でなければなりません。

クリッピングパスを設定すると、以降のグラフィック要素に適用され、クリッピングパスの領域外は描画されなくなります。

パス関連の命令は、「パスを構築する命令」「作成したパスを描画する命令」「クリッピングパスを操作する命令」に分かれています。
パス構築命令
座標はすべてユーザー空間単位です。

オペランド命令説明
x ym現在の位置を座標 (x, y) に移動して、新しいサブパスを開始する。
直前の命令も m だった場合は、上書きされます。
x yl現在の位置から (x, y) への直線セグメントを追加し、現在位置を (x, y) に移動する
x1 y1 x2 y2 x3 y3c3次ベジェ曲線を追加し、現在位置を (x3, y3) に移動する。
現在の位置が開始点、(x1, y1) (x2, y2) が制御点、(x3, y3) を終点とする。
x2 y2 x3 y3v3次ベジェ曲線を追加し、現在位置を (x3, y3) に移動する。
1つ目の制御点 (x1, y1) は現在の位置と等しい。
x1 y1 x3 y3y3次ベジェ曲線を追加し、現在位置を (x3, y3) に移動する。
2つ目の制御点 (x2, y2) は (x1, y1) と等しい。
-h現在位置からサブパスの開始点までを直線でつなぎ、サブパスを閉じる。
x y width heightre長方形のサブパスを追加する。
左下位置・幅・高さを指定します。
パス描画命令
※オペランドはありません。

Sパスをストロークで描画
s現在のパスを閉じた後 (開始点までを直線でつなぐ)、ストロークで描画
f非ゼロワインディング規則を使用して、パス内部を塗りつぶす。
(交差している部分の領域も塗りつぶす)
パスは自動的に閉じられる。
Ff と同じ。互換性のために残されている。
f*偶奇規則を使用してパスを塗りつぶす。
(交差している内側の部分は塗りつぶされない)
Bパスを塗りつぶして、ストロークも描画する (非ゼロワインディング規則)
bB と同じだが、描画前にパスを閉じる
B*パスを塗りつぶして、ストロークも描画する (偶奇規則)
b*B* と同じだが、描画前にパスを閉じる
n現在のパスを描画せずに終了する (クリッピングパスの指定)
クリッピングパス命令
W現在作成されているパスから、非ゼロワインディング規則による塗りつぶしで領域を定義して、現在のクリッピングパスに対して適用し、領域の内部を新しいクリッピングパスとして設定する
W*W と同じだが、偶奇規則を使う
>> 10.pdf

% 座標系の変換
.23999999 0 0 -.23999999 0 792.95996 cm
% 拡大と移動
3.0013709 0 0 3.0013709 1.50068545 1.50068545 cm
219 216 m
287.33334 283.20001 355.66666 283.20001 424 216 c
492.33334 148.799988 560.66669 148.799988 629 216 c
629 384 l
560.66669 316.79999 492.33334 316.79999 424 384 c
355.66666 451.20001 287.33334 451.20001 219 384 c
219 216 l
h % 開始点と直線でつなぎ、パスを閉じる
S % ストローク描画