Перейти к содержимому

Рисование векторной графики — фигуры, цвета и стили линий

Этот рецепт позволяет рисовать примитивы с заливкой и обводкой: прямоугольники, прямоугольники со скруглёнными углами, окружности, эллипсы и линии. Для каждой фигуры вы задаёте цвет заливки, цвет обводки и толщину линии. Рецепт соответствует 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 формируется из 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. Форма с одним аргументом — это не “красный 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.