Pular para o conteúdo

Desenhe gráficos vetoriais — formas, cores e estilos de linha

Use esta receita para desenhar primitivas preenchidas e contornadas: retângulos, retângulos arredondados, círculos, elipses e linhas. Para cada forma, você define a cor de preenchimento, a cor de traço e a largura da linha. A receita acompanha examples/06-colors-and-drawing.php.

Cada primitiva corresponde a um objeto de caminho (path object) da ISO 32000-2. Um objeto de caminho é uma forma construída a partir de segmentos de linha e de curva. Ele termina com um operador de pintura, que orienta o visualizador a traçar, preencher ou fazer ambos.

Terminal window
composer require nextpdf/core:^3

Você não precisa instalar nenhuma extensão opcional. A API de desenho e cor está estável desde a versão 1.0.0 e roda na matriz de backport 8.1–8.4.

Defina o estado e depois desenhe. setFillColor(), setDrawColor() e setLineWidth() atualizam o estado gráfico. A próxima chamada de rect(), circle(), ellipse(), roundedRect() ou line() usa esse estado. Os métodos de forma recebem um argumento de estilo: 'F' preenche, 'S' traça (o padrão) e 'DF'/'FD' fazem ambos. Internamente, um retângulo preenchido é representado pelo operador de construção de caminho re, seguido pelo operador de pintura de preenchimento. A ISO 32000-2 §8.5.3 especifica S para traçar e f para preencher como os principais operadores de pintura de caminho.

As cores são cores de dispositivo. setFillColor(r, g, b) seleciona DeviceRGB. A ISO 32000-2 §8.6.4.3 define rg como o operador DeviceRGB para cor de não traço e g como o equivalente DeviceGray. Com um único argumento, setFillColor($v) define um nível de cinza. A largura da linha tem padrão 1.0, e o padrão de traço é uma linha sólida (§8.4.3.6).

A superfície da API é gerada a partir do PHPDoc. Esta receita usa estes métodos:

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

Este exemplo completo, pronto para o harness, respeita NEXTPDF_COOKBOOK_OUTPUT e não introduz entropia própria.

<?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";
  • O estilo tem como padrão o traço. Se você omitir o argumento de estilo, a forma é traçada ('S'). Uma forma que parece invisível normalmente foi desenhada sem uma cor de traço definida ou preenchida com a cor de fundo da página. Passe 'F' para preenchê-la.
  • O estado de cor persiste. setFillColor() permanece em vigor até você alterá-lo. Redefina-o, por exemplo, com setFillColor(255), antes do próximo bloco não relacionado; caso contrário, a cor seguirá adiante.
  • Cinza versus a sobrecarga RGB. setFillColor(128) é um nível de cinza. setFillColor(128, 0, 0) é RGB. A forma de um argumento não é “vermelho 128”.
  • O eixo Y vai de cima para baixo na API. Os auxiliares de desenho usam a origem no canto superior esquerdo do documento. O motor mapeia isso para o espaço de usuário PDF no canto inferior esquerdo para você.

Cada primitiva produz um pequeno conjunto de operadores de fluxo de conteúdo. Milhares de formas por página ficam bem dentro do orçamento de 2000 ms / 64 MB. O custo cresce linearmente com a contagem de primitivas. Não há rasterização, então a saída permanece vetorial.

Esta receita desenha apenas a geometria que o código especifica. Ela não analisa nenhuma entrada e não faz nenhum acesso à rede. Valide a faixa de quaisquer coordenadas que venham de dados não confiáveis. Essa verificação impede que um valor hostil empurre marcas para muito fora da página.

AfirmaçãoEspecificaçãoCláusulareference_id
Um objeto de caminho é composto por linhas, retângulos e curvas de Bézier e termina em um operador de pintura.ISO 32000-2§8.5
S traça e f preenche um caminho.ISO 32000-2§8.5.3
rg define a cor de não traço DeviceRGB; g define DeviceGray.ISO 32000-2§8.6.4.3
O valor inicial do padrão de traço é [] 0, uma linha sólida.ISO 32000-2§8.4.3.6

Perfil de reprodutibilidade — estrutural. O desenho vetorial não tem entropia própria. Ainda assim, todo documento salvo carrega um /ID no trailer e átomos de data. A ISO 32000-2 §8.3.4 também afirma que a disposição exata dos operadores de estado gráfico não tem significado semântico; portanto, um normalizador pode reordenar estados equivalentes. A afirmação suportada é a igualdade estrutural após a normalização do qpdf. Esta receita descreve como o NextPDF produz a estrutura. Ela não afirma conformidade com a ISO 32000-2 como uma alegação genérica.

Não se aplica. O desenho vetorial é um recurso do Core sem barreira Premium.