Draw vector graphics — shapes, colours, and line styles
At a glance
Section titled “At a glance”Use this recipe to draw filled and outlined primitives: rectangles, rounded rectangles, circles, ellipses, and lines. For each shape, you set the fill colour, stroke colour, and line width. The recipe follows examples/06-colors-and-drawing.php.
Each primitive maps to an ISO 32000-2 path object. A path object is a shape built from line and curve segments. It ends with a painting operator that tells the viewer to stroke, fill, or do both.
Install
Section titled “Install”composer require nextpdf/core:^3You do not need an optional extension. The drawing and colour application programming interface (API) has been stable since 1.0.0, and it runs on the 8.1–8.4 backport matrix.
Conceptual overview
Section titled “Conceptual overview”Set the state, then draw. setFillColor(), setDrawColor(), and setLineWidth() update the graphics state. The next rect(), circle(), ellipse(), roundedRect(), or line() uses that state. Shape methods take a style argument: 'F' fills, 'S' strokes (the default), and 'DF'/'FD' does both. Internally, a filled rectangle is the path-construction re operator followed by the fill painting operator. ISO 32000-2 §8.5.3 specifies S for stroking and f for filling as the principal path-painting operators.
Colours are device colours. setFillColor(r, g, b) selects DeviceRGB. ISO 32000-2 §8.6.4.3 defines rg as the DeviceRGB non-stroking colour operator and g as the DeviceGray equivalent. A single-argument setFillColor($v) sets a grey level. The line width defaults to 1.0, and the dash pattern defaults to a solid line (§8.4.3.6).
API surface
Section titled “API surface”The API surface is generated from PHPDoc. This recipe uses these methods:
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
Code sample — Quick start
Section titled “Code sample — Quick start”<?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');Code sample — Production
Section titled “Code sample — Production”This complete, harness-ready example honours NEXTPDF_COOKBOOK_OUTPUT and adds no entropy of its own.
<?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";Edge cases & gotchas
Section titled “Edge cases & gotchas”- The style defaults to stroke. If you omit the style argument, the shape is stroked (
'S'). A shape that looks invisible is usually drawn with no draw colour set, or filled with the page-background colour. Pass'F'to fill it. - Colour state persists.
setFillColor()stays in effect until you change it. Reset it, for example withsetFillColor(255), before the next unrelated block, or the colour carries forward. - Grey versus the RGB overload.
setFillColor(128)is a grey level.setFillColor(128, 0, 0)is RGB. The one-argument form is not “red 128”. - The Y axis runs top-down in the API. The drawing helpers use the document’s top-left origin. The engine maps that to the PDF bottom-left user space for you.
Performance
Section titled “Performance”Each primitive produces a handful of content-stream operators. Thousands of shapes per page stay well within the 2000 ms / 64 MB budget. Cost grows linearly with the primitive count. There is no rasterisation, so the output stays vector.
Security notes
Section titled “Security notes”This recipe draws only the geometry your code specifies. It parses no input and makes no network access. Range-check any coordinates that come from untrusted data. This check stops a hostile value from pushing marks far outside the page.
Conformance
Section titled “Conformance”| Statement | Spec | Clause | reference_id |
|---|---|---|---|
| A path object is lines, rectangles, and Bézier curves ending in a painting operator. | ISO 32000-2 | §8.5 | |
S strokes and f fills a path. | ISO 32000-2 | §8.5.3 | |
rg sets the DeviceRGB non-stroking colour; g sets DeviceGray. | ISO 32000-2 | §8.6.4.3 | |
The dash-pattern initial value is [] 0, a solid line. | ISO 32000-2 | §8.4.3.6 |
Reproducibility profile — structural. Vector drawing has no entropy of its own. Even so, every saved document carries a trailer /ID and date atoms. ISO 32000-2 §8.3.4 also states that the exact arrangement of graphics-state operators has no semantic significance, so a normaliser may re-order equivalent state. The supported claim is structural equality after qpdf normalisation. This recipe describes how NextPDF produces the structure. It does not assert ISO 32000-2 conformance as a blanket claim.
Commercial context
Section titled “Commercial context”Not applicable. Vector drawing is a Core capability with no Premium gate.