Transforme o espaço de coordenadas: gire, escale, distorça e espelhe
Visão geral
Seção intitulada “Visão geral”Transforme o espaço de coordenadas do desenho em torno de um pivô que você escolher. Esta receita cobre rotação, escala, distorção e espelhamento. Cada transformação permanece isolada em um bloco de estado gráfico salvo, de modo que não afeta o conteúdo posterior. Ela acompanha examples/21-transforms.php.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Você não precisa de nenhum pacote Pro ou Enterprise. A interface de programação de aplicações (API) de transformação vem com o Core e funciona no PHP 8.1 até 8.4.
Visão conceitual
Seção intitulada “Visão conceitual”O conteúdo do Portable Document Format (PDF) é desenhado no espaço do usuário. Por padrão, o espaço do usuário tem origem no canto inferior esquerdo da página, e uma unidade equivale a 1/72 de polegada (ISO 32000-2 §8.3.2). Uma transformação multiplica a matriz de transformação atual (CTM) por uma nova matriz por meio do operador cm (§8.3.4). As transformações são compostas por concatenação de matrizes, portanto a ordem importa.
O NextPDF permite que você trabalhe em um sistema de coordenadas de autoria com origem no canto superior esquerdo. Internamente, ele converte esse sistema para o espaço do usuário nativo com origem no canto inferior esquerdo por meio da projeção toY() nos métodos de transformação. As posições são expressas em unidades do espaço do usuário: pontos PDF, em que 1 pt equivale a 1/72 pol. Para manter uma transformação com escopo local, envolva-a entre startTransform() e stopTransform(). Esses métodos emitem os operadores de estado gráfico q (salvar) e Q (restaurar) (§8.4.2). Tudo o que for desenhado entre eles herda a transformação. Tudo o que vier após stopTransform() retorna à CTM anterior. Cada chamada rotate()/scale()/skewX()/mirrorH() recebe um pivô explícito, de modo que a transformação fique ancorada onde você espera, e não na origem da página.
Superfície da API
Seção intitulada “Superfície da API”A superfície da API é gerada a partir do PHPDoc. Os principais pontos de entrada estão no trait \NextPDF\Core\Concerns\HasTransforms:
Document::startTransform(): static— emiteqe abre um bloco de estadoDocument::stopTransform(): static— emiteQe fecha o blocoDocument::rotate(float $angle, float $x = 0, float $y = 0): staticDocument::scale(float $sx, float $sy, float $x = 0, float $y = 0): staticDocument::skewX(float $angle, float $x = 0, float $y = 0): static/skewY(...)Document::mirrorH(float $x = 0): static/mirrorV(float $y = 0): staticDocument::translateCtm(float $dx, float $dy): static
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Coordinate Transforms');$doc->addPage();
$cx = 60.0;$cy = 60.0;
// Rotate 30° around (cx, cy). The transform is scoped to this block.$doc->startTransform();$doc->rotate(30, $cx, $cy);$doc->setFont('helvetica', '', 14);$doc->text($cx, $cy, 'Rotated 30 degrees');$doc->stopTransform();
// Back to the untransformed CTM — this text is upright.$doc->setFont('helvetica', '', 10);$doc->text($cx, $cy + 20, 'Not rotated');
$doc->save(__DIR__ . '/transforms.pdf');
echo "Created: transforms.pdf\n";Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Este programa autocontido é executado no harness do cookbook. Ele segue de perto a seção de escala de examples/21-transforms.php. Cada transformação permanece em um bloco de estado gráfico salvo com um pivô explícito. As cores e a largura de linha são redefinidas no final, de modo que nada vaza para uma página posterior.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Coordinate Transforms');$doc->addPage();
$doc->setFont('helvetica', 'B', 13);$doc->cell(0, 8, 'Scaling a reference square at 0.5x, 1.0x, 1.5x, 2.0x', newLine: true);$doc->ln(6);
$scaleBaseY = $doc->getY();$scaleFactors = [0.5, 1.0, 1.5, 2.0];
$doc->setDrawColor(30, 58, 138);$doc->setLineWidth(0.4);
foreach ($scaleFactors as $idx => $factor) { $cx = 25.0 + $idx * 45; $cy = $scaleBaseY + 5;
$doc->startTransform(); $doc->scale($factor, $factor, $cx, $cy); // scale about (cx, cy)
$doc->setFillColor(220, 230, 241); $doc->rect($cx, $cy, 15, 15, 'DF'); $doc->line($cx, $cy, $cx + 15, $cy + 15);
$doc->stopTransform(); // CTM restored here
// Drawn AFTER the block — at the original scale, untransformed. $doc->setFont('helvetica', '', 8); $doc->setTextColor(0); $doc->text($cx, $scaleBaseY + 38, sprintf('%.1fx', $factor));}
// Explicit state reset so nothing carries into the next section.$doc->setTextColor(0);$doc->setFillColor(255);$doc->setDrawColor(0);
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script twice under// the structural profile (the transform stream itself is deterministic).$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false && $out !== '' ? $out : __DIR__ . '/transforms.pdf');
echo "Wrote transforms.pdf\n";STDOUT esperado:
Wrote transforms.pdfO exemplo completo cobre todas as quatro famílias de transformação: rotação, escala, distorção e espelhamento. Execute-o com php examples/21-transforms.php; ele grava examples/output/21-transforms.pdf.
Casos extremos e armadilhas
Seção intitulada “Casos extremos e armadilhas”- Sempre emparelhe o bloco. Todo
startTransform()deve ter umstopTransform()correspondente. Uma contagem desbalanceada deq/Qcorrompe o estado gráfico no restante da página (ISO 32000-2 §8.4.2). O NextPDF rastreia a profundidade, mas o contrato desta receita continua sendo de um para um. - A ordem não é comutativa. As transformações se compõem por concatenação de matrizes, portanto
rotate()seguido descale()não é o mesmo quescale()seguido derotate(). Aplique-as dentro de um único bloco na ordem que você pretende. - O pivô assume a origem por padrão. Se você omitir o pivô, a transformação gira em torno da origem da página, e não da forma. Em geral, não é isso que você quer, portanto passe o pivô explicitamente.
- O eixo Y é do espaço de autoria. O
ydo pivô é a distância medida a partir do canto superior esquerdo do espaço de autoria, e o NextPDF o projeta para o espaço do usuário nativo. Misturar coordenadas PDF brutas com a API de autoria produz um resultado espelhado. - Vazamento de estado. A cor, a fonte e a largura de linha definidas dentro de um bloco de transformação persistem após
stopTransform(), porque, nesta superfície da API, oQrestaura apenas a CTM. Redefina esses valores explicitamente se uma seção posterior não puder herdá-los, como faz o exemplo de produção.
Desempenho
Seção intitulada “Desempenho”Uma transformação emite um operador cm mais o par q/Q. Cada componente ocupa apenas alguns bytes e não acrescenta custo mensurável em tempo de execução, portanto a receita permanece dentro do orçamento de 1500 ms / 96 MB. O perfil de reprodutibilidade é estrutural. A saída contém um array /ID no trailer e metadados de criação que não são estáveis entre execuções, portanto você deve normalizá-los antes da comparação. O fluxo de transformação em si é determinístico.
Notas de segurança
Seção intitulada “Notas de segurança”- Residência de dados e mitigações de informações de identificação pessoal (PII). Não aplicável. Esta receita desenha primitivas geométricas e rótulos curtos. Ela não processa nenhum dado externo ou pessoal.
- Telemetria segura e higienização de logs. A receita grava uma única linha de progresso fixa. Ela não registra nenhum conteúdo do documento.
- Modelo de ameaças. Não aplicável. Não há análise de entrada, nem criptografia, nem fronteira de confiança. Uma transformação é uma emissão pura de fluxo de conteúdo.
- Comportamento no modo Federal Information Processing Standards (FIPS). Não aplicável. Não há nenhuma operação criptográfica.
Conformidade
Seção intitulada “Conformidade”| Declaração | Especificação | Cláusula | reference_id |
|---|---|---|---|
Uma transformação concatena uma matriz à CTM com o operador cm. | ISO 32000-2 | §8.3.4 | |
| As transformações se compõem por concatenação de matrizes, e a ordem é significativa. | ISO 32000-2 | §8.3.4 | |
q salva e Q restaura o estado gráfico, o que limita o escopo da transformação. | ISO 32000-2 | §8.4.2 | |
| A origem padrão do espaço do usuário é o canto inferior esquerdo; uma unidade é 1/72 de polegada. | ISO 32000-2 | §8.3.2 |
Esta receita segue as cláusulas citadas da ISO 32000-2 sobre estado gráfico e transformação. Ela não afirma conformidade total com a ISO 32000-2; as cláusulas citadas são as únicas que esta receita exercita.