Рисование векторной графики — фигуры, цвета и стили линий
Краткий обзор
Заголовок раздела «Краткий обзор»Этот рецепт позволяет рисовать примитивы с заливкой и обводкой: прямоугольники, прямоугольники со скруглёнными углами, окружности, эллипсы и линии. Для каждой фигуры вы задаёте цвет заливки, цвет обводки и толщину линии. Рецепт соответствует examples/06-colors-and-drawing.php.
Каждый примитив сопоставляется с объектом пути ISO 32000-2. Объект пути — это фигура, построенная из отрезков и кривых. Он завершается оператором отрисовки, который указывает программе просмотра выполнить обводку, заливку или то и другое.
Установка
Заголовок раздела «Установка»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' — и то и другое. На уровне PDF залитый прямоугольник — это оператор построения пути 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. Вызов 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, где начало координат находится в нижнем левом углу.
Производительность
Заголовок раздела «Производительность»Каждый примитив порождает несколько операторов потока содержимого. Тысячи фигур на странице с запасом укладываются в бюджет 2000 мс / 64 МБ. Затраты растут линейно с числом примитивов. Растеризация не выполняется, поэтому результат остаётся векторным.
Примечания по безопасности
Заголовок раздела «Примечания по безопасности»Этот рецепт рисует только ту геометрию, которую задаёт ваш код. Он не разбирает входные данные и не обращается к сети. Проверяйте диапазоны любых координат, поступающих из недоверенных данных. Такая проверка не даст вредоносному значению вывести элементы далеко за пределы страницы.
Соответствие стандарту
Заголовок раздела «Соответствие стандарту»| Утверждение | Спецификация | Раздел | 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.