绘制矢量图形——形状、颜色与线条样式
本示例会绘制带填充或描边的基本图元:矩形、圆角矩形、圆形、椭圆和线条。 每一种图元都可以设置填充颜色、描边颜色(绘制颜色)以及线宽。 本示例遵循 examples/06-colors-and-drawing.php。
每个图元都会映射到一个 ISO 32000-2 路径对象。 路径对象是由线段和曲线段组成的形状。 它以一个绘图运算符结束,由该运算符决定这个形状是描边、填充,还是两者都执行。
composer require nextpdf/core:^3不需要任何可选扩展。 绘图与颜色 API 自 1.0.0 起即为稳定版,并可在 8.1–8.4 的 backport 兼容矩阵上运行。
概念说明
标题为“概念说明”的章节先设置状态,再执行绘制。 setFillColor()、setDrawColor() 与 setLineWidth() 会更新绘图状态。 随后的 rect()、circle()、ellipse()、roundedRect() 或 line() 会使用该状态。 这些形状方法都接受一个样式参数:'F' 表示填充,'S' 表示描边(默认值),'DF'/'FD' 则表示两者都执行。 在内部,一个填充矩形就是路径构造运算符 re 后接填充绘图运算符。 ISO 32000-2 §8.5.3 将 S 指定为描边、f 指定为填充,作为主要的路径绘图运算符。
颜色属于设备颜色(device colour)。 setFillColor(r, g, b) 会选用 DeviceRGB。 ISO 32000-2 §8.6.4.3 将 rg 定义为 DeviceRGB 的非描边颜色运算符,并将 g 定义为对应的 DeviceGray 运算符。 单参数形式的 setFillColor($v) 表示一个灰度值。 线宽默认为 1.0,虚线样式默认为实线(§8.4.3.6)。
API 接口
标题为“API 接口”的章节此 API 接口从 PHPDoc 自动生成。 本示例会用到以下方法:
rect(float $x, float $y, float $w, float $h, string $style = 'S'): staticroundedRect(float $x, float $y, float $w, float $h, float $r, string $style = 'S'): staticcircle(float $x, float $y, float $r, string $style = 'S'): staticellipse(float $x, float $y, float $rx, float $ry, string $style = 'S'): staticline(float $x1, float $y1, float $x2, float $y2): staticsetFillColor(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。 单参数形式并不是“红色 128”的意思。 - 在 API 中 Y 轴从上到下递增。 这些绘图辅助方法使用文档左上角作为原点。 引擎会替你把它映射到 PDF 以左下角为原点的用户空间。
每个图元只会生成少量内容流(content stream)运算符。 每页数千个形状仍能轻松落在 2000 ms / 64 MB 的预算之内。 成本会随图元数量线性增长。 过程中不会进行栅格化,因此输出会保持为矢量。
安全注意事项
标题为“安全注意事项”的章节此示例只会绘制你的代码所指定的几何图形。 它不会解析任何输入,也不会进行任何网络访问。 对任何来自不可信数据的坐标,都要做范围检查。 范围检查可以阻止恶意值把标记推到远离页面之外的位置。
符合性
标题为“符合性”的章节| 陈述 | 规范 | 条款 | 参考 ID |
|---|---|---|---|
| 路径对象由线段、矩形和贝塞尔(Bézier)曲线组成,并以一个绘图运算符结束。 | 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 |
可复现性配置文件 —— 结构性。 矢量绘图本身不带任何熵。 即便如此,每份保存的文档都会带有一个 trailer /ID 与日期原子(atom)。 ISO 32000-2 §8.3.4 也指出,绘图状态运算符的确切排列顺序并无语义上的意义,因此规范化器可以重新排列等价的状态。 严格来说,这里能成立的主张是经过 qpdf 规范化之后的结构相等。 此示例说明 NextPDF 如何生成这样的结构。 它并未主张全面符合 ISO 32000-2。
商业情境
标题为“商业情境”的章节不适用。 矢量绘图是核心(Core)功能,没有 Premium 限制。