Przejdź do głównej zawartości

Rysowanie grafiki wektorowej — kształty, kolory i style linii

Użyj tego przepisu, aby rysować wypełnione i obrysowane prymitywy: prostokąty, zaokrąglone prostokąty, koła, elipsy i linie. Dla każdego kształtu ustawiasz kolor wypełnienia, kolor obrysu oraz grubość linii. Przepis odpowiada przykładowi examples/06-colors-and-drawing.php.

Każdy prymityw odpowiada obiektowi ścieżki z ISO 32000-2. Obiekt ścieżki to kształt zbudowany z segmentów linii i krzywych. Kończy się operatorem malowania, który wskazuje przeglądarce PDF, że ma obrysować, wypełnić albo wykonać obie operacje.

Okno terminala
composer require nextpdf/core:^3

Nie potrzebujesz żadnego opcjonalnego rozszerzenia. API do rysowania i obsługi kolorów jest stabilne od wersji 1.0.0 i działa w macierzy backportów 8.1–8.4.

Najpierw ustaw stan, potem rysuj. setFillColor(), setDrawColor() i setLineWidth() aktualizują stan grafiki. Następne wywołanie rect(), circle(), ellipse(), roundedRect() lub line() korzysta z tego stanu. Metody rysujące kształty przyjmują argument stylu: 'F' wypełnia, 'S' obrysowuje (wartość domyślna), a 'DF'/'FD' wykonuje obie operacje. Wewnętrznie wypełniony prostokąt to operator konstrukcji ścieżki re, po którym następuje operator malowania wypełnienia. ISO 32000-2 §8.5.3 określa S do obrysowywania oraz f do wypełniania jako podstawowe operatory malowania ścieżki.

Są to kolory urządzenia. setFillColor(r, g, b) wybiera DeviceRGB. ISO 32000-2 §8.6.4.3 definiuje rg jako operator koloru niezwiązanego z obrysem dla DeviceRGB, a g jako odpowiednik dla DeviceGray. Wywołanie setFillColor($v) z jednym argumentem ustawia poziom szarości. Domyślna grubość linii wynosi 1.0, a domyślny wzór kreskowania to linia ciągła (§8.4.3.6).

Powierzchnia API jest generowana na podstawie PHPDoc. Ten przepis korzysta z następujących metod:

  • 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');

Ten kompletny przykład, gotowy do uruchomienia w środowisku testowym, respektuje NEXTPDF_COOKBOOK_OUTPUT i nie dodaje własnej entropii.

<?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";
  • Domyślnym stylem jest obrys. Jeśli pominiesz argument stylu, kształt zostaje obrysowany ('S'). Kształt, który wydaje się niewidoczny, zwykle został narysowany bez ustawionego koloru obrysu albo wypełniony kolorem tła strony. Przekaż 'F', aby go wypełnić.
  • Stan koloru jest trwały. setFillColor() pozostaje aktywne, dopóki go nie zmienisz. Zresetuj kolor, na przykład za pomocą setFillColor(255), przed kolejnym niepowiązanym blokiem; w przeciwnym razie przejdzie na kolejne elementy.
  • Szarość a przeciążenie RGB. setFillColor(128) to poziom szarości. setFillColor(128, 0, 0) to RGB. Forma jednoargumentowa nie oznacza „czerwieni 128”.
  • Oś Y w API biegnie z góry na dół. Pomocnicze funkcje rysowania korzystają z punktu odniesienia w lewym górnym rogu dokumentu. Silnik automatycznie odwzorowuje to na przestrzeń użytkownika PDF z punktem odniesienia w lewym dolnym rogu.

Każdy prymityw generuje kilka operatorów strumienia treści. Tysiące kształtów na stronę bezpiecznie mieszczą się w budżecie 2000 ms / 64 MB. Koszt rośnie liniowo wraz z liczbą prymitywów. Nie zachodzi rasteryzacja, więc wynik pozostaje wektorowy.

Ten przepis rysuje wyłącznie geometrię określoną w kodzie. Nie analizuje żadnych danych wejściowych ani nie uzyskuje dostępu do sieci. Sprawdzaj zakres wszystkich współrzędnych pochodzących z niezaufanych danych. Taka kontrola zapobiega wypychaniu znaków daleko poza stronę przez złośliwą wartość.

StwierdzenieSpecyfikacjaKlauzulareference_id
Obiekt ścieżki to linie, prostokąty i krzywe Béziera zakończone operatorem malowania.ISO 32000-2§8.5
S obrysowuje, a f wypełnia ścieżkę.ISO 32000-2§8.5.3
rg ustawia kolor niezwiązany z obrysem dla DeviceRGB; g ustawia DeviceGray.ISO 32000-2§8.6.4.3
Wartością początkową wzoru kreskowania jest [] 0, czyli linia ciągła.ISO 32000-2§8.4.3.6

Profil odtwarzalności — strukturalny. Rysowanie wektorowe nie wprowadza własnej entropii. Mimo to każdy zapisany dokument zawiera w trailerze /ID oraz atomy daty. ISO 32000-2 §8.3.4 stwierdza również, że dokładne rozmieszczenie operatorów stanu grafiki nie ma znaczenia semantycznego, więc normalizator może zmieniać kolejność równoważnego stanu. Obsługiwane twierdzenie to równość strukturalna po normalizacji qpdf. Ten przepis opisuje, jak NextPDF tworzy tę strukturę. Nie stwierdza zgodności z ISO 32000-2 jako ogólnego twierdzenia.

Nie dotyczy. Rysowanie wektorowe jest funkcją Core bez bramki Premium.