コンテンツにスキップ

ベクターグラフィックスを描画する — 図形、色、線スタイル

このレシピでは、塗りつぶしと輪郭線を持つプリミティブを描画します。対象は、長方形、角丸長方形、円、楕円、直線です。それぞれについて、塗りつぶし色、ストローク(描画)色、線幅を設定します。このレシピは examples/06-colors-and-drawing.php に対応しています。

各プリミティブは ISO 32000-2 のパスオブジェクトに対応します。パスオブジェクトは、直線セグメントと曲線セグメントから構成される図形です。パスの末尾には、その図形をストローク、塗りつぶし、またはその両方のいずれで描画するかを決めるペイント演算子が置かれます。

Terminal window
composer require nextpdf/core:^3

オプションの拡張機能は不要です。描画と色の API は 1.0.0 以降で安定しており、8.1~8.4 のバックポートマトリックスで動作します。

状態を設定してから描画します。setFillColor()setDrawColor()setLineWidth() はグラフィックス状態を更新します。次に呼び出される rect()circle()ellipse()roundedRect()、または line() が、その状態を使って描画します。図形メソッドはスタイル引数を取ります。'F' は塗りつぶし、'S' はストローク(デフォルト)、'DF'/'FD' はその両方を行います。内部的には、塗りつぶし済みの長方形は、パス構築の re 演算子の後に塗りつぶしのペイント演算子を実行して表現されます。ISO 32000-2 §8.5.3 は、主要なパスペイント演算子として、ストロークに S を、塗りつぶしに f を規定しています。

色はデバイスカラーです。setFillColor(r, g, b) は DeviceRGB を選択します。ISO 32000-2 §8.6.4.3 は、rg を DeviceRGB の非ストローク色演算子として、g を DeviceGray に対応する演算子として定義しています。引数が 1 つの setFillColor($v) はグレーレベルです。線幅のデフォルトは 1.0 で、破線パターンのデフォルトは実線です(§8.4.3.6)。

API サーフェスは PHPDoc から自動生成されます。このレシピでは、次のメソッドを使用します。

  • rect(float $x, float $y, float $w, float $h, string $style = 'S'): static
  • roundedRect(float $x, float $y, float $w, float $h, float $r, string $style = 'S'): static
  • circle(float $x, float $y, float $r, string $style = 'S'): static
  • ellipse(float $x, float $y, float $rx, float $ry, string $style = 'S'): static
  • line(float $x1, float $y1, float $x2, float $y2): static
  • setFillColor(int $r, int $g = -1, int $b = -1): static / setDrawColor(...)
  • setLineWidth(float $width): static
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->setFillColor(30, 58, 138);
$doc->rect(20, 30, 60, 40, 'F'); // filled rectangle
$doc->setDrawColor(217, 119, 6);
$doc->setLineWidth(1.0);
$doc->circle(140, 50, 20, 'S'); // stroked circle
$doc->setLineWidth(0.3);
$doc->line(20, 90, 190, 90); // thin rule
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/vector.pdf');

これは、ハーネスでそのまま使える完全な例です。NEXTPDF_COOKBOOK_OUTPUT を尊重し、例自体はエントロピーを一切追加しません。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Colors and Drawing');
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Colors and Drawing', newLine: true);
$doc->ln(5);
// --- Filled rectangles: set fill colour, then draw with style 'F' ---
$palette = [
[30, 58, 138], [217, 119, 6], [30, 27, 75],
[239, 66, 35], [21, 128, 61],
];
$x = 15.0;
$rowY = $doc->getY();
foreach ($palette as [$r, $g, $b]) {
$doc->setFillColor($r, $g, $b);
$doc->rect($x, $rowY, 30, 20, 'F');
$x += 35.0;
}
$doc->ln(28);
// --- Outlined shapes: set draw colour + line width, draw with 'S' ---
$doc->setDrawColor(30, 58, 138);
$doc->setLineWidth(0.5);
$y = $doc->getY();
$doc->rect(15, $y, 30, 25, 'S');
$doc->roundedRect(55, $y, 30, 25, 5, 'S');
$doc->circle(110, $y + 12.5, 12.5, 'S');
$doc->ellipse(150, $y + 12.5, 18, 10, 'S');
$doc->ln(33);
// --- Lines at three widths ---
$y = $doc->getY();
$doc->setDrawColor(0);
$doc->setLineWidth(0.2);
$doc->line(15, $y, 195, $y);
$doc->setLineWidth(0.8);
$doc->line(15, $y + 5, 195, $y + 5);
$doc->setLineWidth(1.5);
$doc->line(15, $y + 12, 195, $y + 12);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/vector.pdf';
$doc->save($out);
echo "Created vector.pdf\n";
  • スタイルのデフォルトはストロークです。 スタイル引数を省略すると、図形はストローク('S')で描画されます。表示されていないように見える図形は、たいてい描画色が設定されていないまま描画されているか、ページの背景色で塗りつぶされています。塗りつぶすには 'F' を渡します。
  • 色の状態は保持されます。 setFillColor() は、変更するまで有効なままです。後続の無関係なブロックの前にリセットしない(たとえば setFillColor(255))と、色がそのまま引き継がれます。
  • グレーと RGB オーバーロードの違い。 setFillColor(128) はグレーレベルです。setFillColor(128, 0, 0) は RGB です。引数が 1 つの形式は「赤 128」ではありません。
  • API では Y 軸は上から下に向かいます。 描画ヘルパーは、ドキュメントの左上を原点として扱います。エンジンが、それを PDF の左下を原点とするユーザー空間へ自動的にマッピングします。

各プリミティブは、ごく少数のコンテンツストリーム演算子で表現されます。1 ページあたり数千個の図形でも、2000 ms / 64 MB のバジェットに十分収まります。コストはプリミティブ数に比例して線形に増加します。ラスタライズは行われないため、出力はベクターのまま保たれます。

このレシピは、コードで指定したジオメトリのみを描画します。入力を解析せず、ネットワークアクセスも行いません。信頼できないデータに由来する座標は、すべて範囲チェックを行ってください。範囲チェックを行えば、悪意のある値によって描画マークがページのはるか外側へ押し出されるのを防げます。

記述仕様箇条reference_id
パスオブジェクトは、直線、長方形、ベジエ曲線をペイント演算子で終端したものです。ISO 32000-2§8.5
S はパスをストロークし、f はパスを塗りつぶします。ISO 32000-2§8.5.3
rg は DeviceRGB の非ストローク色を設定し、g は DeviceGray を設定します。ISO 32000-2§8.6.4.3
破線パターンの初期値は [] 0 で、実線です。ISO 32000-2§8.4.3.6

再現性プロファイル — 構造的。 ベクター描画はそれ自体にエントロピーを持ちません。それでも、保存される各ドキュメントにはトレーラーの /ID と日付アトムが含まれます。ISO 32000-2 §8.3.4 はまた、グラフィックス状態演算子の正確な並び順には意味上の重要性がないと述べているため、ノーマライザーは等価な状態を並べ替える場合があります。厳密に主張できるのは、qpdf による正規化後の構造的同一性です。このレシピは、NextPDF がその構造をどのように生成するかを説明します。ISO 32000-2 への包括的な準拠を主張するものではありません。

該当しません。ベクター描画は Core の機能であり、Premium のゲートはありません。