Graphics: primitive di tracciato + sfumature + trasformazioni
In breve
Sezione intitolata “In breve”Il modulo Graphics traduce l’intento di disegno in operatori grafici PDF. Copre tracciati, stili di linea, spazi colore, trasformazioni, sfumature, pattern, retini e caricamento delle immagini.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Panoramica concettuale
Sezione intitolata “Panoramica concettuale”Graphics è il livello dedicato al disegno vettoriale e raster. Produce le sequenze di operatori che i moduli ContentStream e Writer serializzano in un PDF. Un content stream codifica il contenuto della pagina come sequenza ordinata di operatori grafici: ISO 32000-2 §8. Il modulo emette tali operatori. Non scrive il file.
DrawingEngine è la superficie principale. È un builder fluente e con stato. Ogni setter restituisce self, accumula una modifica dello stato grafico o un operatore relativo ai tracciati e accoda tutto a un buffer interno leggibile con getStream(). Il motore modella direttamente lo stato grafico del PDF: spessore della linea, stile della linea, colore di traccia e di riempimento, alfa e modalità di fusione, limite di smussatura, maschera morbida, ritaglio, sovrastampa, planarità, levigatezza, intento di rendering, generazione del nero e rimozione del sottocolore corrispondono ciascuno a un operatore documentato. I setter relativi al colore accettano un value object Color o un ColorSpace esplicito, così gli spazi device e quelli basati su CIE condividono un’unica forma di chiamata.
Tre famiglie di componenti affiancano il motore. La prima gestisce l’input delle immagini. ImageLoader decodifica un file o un blob in memoria e restituisce un ImageLoadResult. ImageRegistry deduplica le immagini decodificate e ne tiene traccia con un MemoryReport, così i documenti di grandi dimensioni restano entro il budget di memoria. La seconda famiglia riguarda l’importazione vettoriale. SvgParser ed EpsParser traducono formati vettoriali esterni nello stesso flusso di operatori, esponendo getBoundingBox() per l’impaginazione. La terza famiglia riguarda la fedeltà del device-color: sfumature (ShadingManager, le famiglie Type2/Type3 e mesh), pattern (PatternFill), retini (Type1/Type5/Type6/ Type10/Type16), funzioni di trasferimento e spazi colore basati su ICC.
TransformEngine è un complemento mirato per le trasformazioni di coordinate. Delimita una trasformazione tra startTransform() e stopTransform(), che emettono la coppia save/restore q e Q. Offre helper per trasformazioni affini con nome — scale, translate, rotate, skew, mirrorH, mirrorV — ciascuno con un pivot opzionale. La matrice di trasformazione mappa uno spazio di coordinate interno nello spazio di coordinate di destinazione. È lo stesso modello che ISO 32000-2 applica ai domini delle sfumature — §8.7.4.
La gestione del colore segue l’ADR-012: gli spazi colore ICCBased e quelli basati su CIE emettono operatori di content stream cs/CS espliciti, invece di affidarsi al fallback su device-color. I profili ICC vengono incapsulati in un flusso ICCBased con il numero di componenti corretto, secondo ISO 32000-2 §8.6.5.5.
Superficie API
Sezione intitolata “Superficie API”| Classe | Metodi principali | Ruolo |
|---|---|---|
DrawingEngine | getStream(), reset(), setLineWidth(), setLineStyle(), setDrawColor(), setFillColor(), setAlpha(), setSoftMask(), clip(), setOverprint(), setRenderingIntent(), line(), rect(), circle(), ellipse(), polygon(), linearGradient() | Builder con stato per operatori di tracciato + stato grafico |
TransformEngine | startTransform(), stopTransform(), scale(), translate(), rotate(), skew(), mirrorH(), mirrorV(), getStream() | Trasformazioni di coordinate affini |
ImageLoader | load(string $filePath), loadFromString(string $data, string $mimeType) | Decodifica le immagini in ImageLoadResult |
ImageRegistry | load(), loadFromString(), getMetadata(), memoryUsage(), reset() | Cache di immagini con deduplica e reportistica della memoria |
SvgParser | parse(), parseFile() | Traduce SVG nel flusso di operatori |
EpsParser | parse(), parseFile(), getBoundingBox() | Traduce EPS nel flusso di operatori |
ShadingManager | registrazione delle sfumature + emissione del dizionario | Sfumature assiali, radiali e mesh |
Halftone (astratta) | halftoneType(), toDict(), hasStream(), getStream() | Retini di mezzatinta di tipo 1/5/6/10/16 |
Eseguire composer docs:generate-api-php -- --module=Graphics per ottenere la tabella PHPDoc completa.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”Sorgente: examples/06-colors-and-drawing.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Graphics\Color;use NextPDF\Graphics\DrawingEngine;use NextPDF\Graphics\LineStyle;
$engine = new DrawingEngine();
$engine ->setLineWidth(1.5) ->setDrawColor(Color::rgb(0, 51, 102)) ->setFillColor(Color::rgb(230, 240, 250)) ->rect(20.0, 20.0, 160.0, 80.0) ->line(20.0, 110.0, 180.0, 110.0, new LineStyle(dash: [3.0, 2.0]));
$contentStreamBytes = $engine->getStream();Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo esempio collega un registro di immagini con reportistica della memoria e un blocco di trasformazione. Rispecchia la struttura usata in examples/07-images.php ed examples/21-transforms.php.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Graphics\DrawingEngine;use NextPDF\Graphics\ImageRegistry;use NextPDF\Graphics\TransformEngine;
$registry = new ImageRegistry();$image = $registry->load('/srv/assets/logo.png');
$report = $registry->memoryUsage();if ($report->bytes > 32 * 1024 * 1024) { // Decoded image cache exceeded the budget — reset before the next page. $registry->reset();}
$transform = new TransformEngine();$transform ->startTransform() ->translate(40.0, 700.0) ->scale(0.5, 0.5) ->stopTransform();
$engine = new DrawingEngine();$engine->reset();$page = $transform->getStream() . $engine->getStream();Casi limite e insidie
Sezione intitolata “Casi limite e insidie”DrawingEnginemantiene stato. Chiamarereset()tra pagine indipendenti, altrimenti lo stato grafico precedente si propaga nel flusso successivo.TransformEnginerichiede una coppiastartTransform()/stopTransform()corrispondente. Un blocco non bilanciato lascia unqpendente e corrompe lo stack save/restore a valle nel Writer.setSoftMask(),setOverprint(),setBlackGeneration()esetUnderColorRemoval()scrivono marcatori di stato grafico esteso. Restano inerti con un profilo che rifiuta la funzionalità. Verificare il guard del profilo prima di fare affidamento sul risultato visivo.ImageRegistrydeduplica in base al contenuto. Due percorsi con byte identici condividono un unico oggetto. Non presumere un’unica immagine PDF per ogni chiamata aload().EpsParser::getBoundingBox()restituisce il bounding box analizzato, non il box di pagina. Applicare un proprio ritaglio se l’EPS deborda dal rettangolo di destinazione.- La compensazione del punto di nero ha valore advisory ed è basata su marcatori. Da sola non trasforma i pixel.
Convalida e gestione degli errori
Sezione intitolata “Convalida e gestione degli errori”Due modifiche lato producer sono breaking. Entrambe trasformano una corruzione prima silenziosa in un errore esplicito nel punto di chiamata.
La convalida dell’input ora solleva un’eccezione (nota di migrazione). L’input di disegno viene convalidato prima di raggiungere il flusso di operatori; i valori malformati vengono rifiutati con InvalidArgumentException. I chiamanti che in precedenza passavano NaN, Infinity o valori fuori intervallo producevano silenziosamente operatori corrotti; lo stesso input ora solleva un’eccezione. I vincoli verificati sono:
- L’alfa del colore deve essere un valore finito e compreso in
[0, 1]. - Gli operandi della CTM, le dimensioni dei template, le coordinate dei vertici delle sfumature e le coordinate delle mesh-patch devono essere finiti — senza
NaNnéInfinity. - Il flag di bordo di una gradient-patch deve essere uno tra
{0, 1, 2, 3}. - I parametri delle funzioni di tipo 2/3/4 e i parametri dei retini sono soggetti a controlli sui limiti.
- I nomi dei coloranti sono sottoposti a escape.
- Il nome di un layer OCG (contenuto opzionale) non deve essere vuoto.
Verificare prima dell’aggiornamento i punti di chiamata che calcolano coordinate o alfa a partire da dati a monte: un valore che prima veniva accettato è ora un errore irreversibile.
ICCBased /N è fail-closed per impostazione predefinita. L’output Plain-PDF rifiuta uno spazio colore ICCBased il cui numero di componenti /N è al di fuori di {1, 3, 4} e riconcilia il /N dichiarato con il profilo incorporato e lo spazio /Alternate. Ciò segue la regola di ISO 32000-2 §8.6.5.5 per il flusso ICCBased, che include /N insieme a uno spazio /Alternate. Un profilo ICC a N canali (per esempio un profilo hexachrome con N = 6) viene mantenuto solo quando è attivo un profilo PDF/A o PDF/X, con opt-in tramite IccConformancePolicy::ProfileGated. Questo è un gate strutturale sul numero di componenti, non una dichiarazione di certificazione PDF/A o PDF/X.
Prestazioni
Sezione intitolata “Prestazioni”L’emissione degli operatori è lineare rispetto al numero di chiamate di disegno — O(n) accodamenti a un buffer, senza reflow. Il costo di decodifica delle immagini è dominato dal codec e dal numero di pixel, non dal registro. La deduplica basata su content-hash del registro è la leva principale per i documenti di grandi dimensioni: gli asset riutilizzati costano una sola decodifica e un solo oggetto PDF. Il performance_budget per il carico di lavoro di riferimento di questo modulo è di 1500 ms di tempo reale e 64 MB di picco. Usare ImageRegistry::memoryUsage() per osservare l’impronta delle immagini decodificate e reset() per rilasciarla tra gruppi di pagine.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”SvgParser ed EpsParser elaborano input vettoriale non attendibile. Trattare entrambi come parser esposti a dati ostili. Applicare limiti alla dimensione dell’input prima di chiamare parse(). Eseguire l’estrazione in un worker vincolato quando la sorgente è fornita dall’utente. EPS è un dialetto PostScript. Il parser traduce un sottoinsieme vincolato e non esegue un interprete generico, ma occorre comunque limitare la dimensione dell’input e il tempo di analisi. I loader di immagini decodificano codec di terze parti. Mantenere aggiornate le estensioni per immagini del runtime e limitare le dimensioni decodificate. Consultare il modello di minaccia del motore in /modules/core/security/ per il confine di fiducia e le indicazioni sull’isolamento dei worker.
Conformità
Sezione intitolata “Conformità”Il modulo emette strutture di operatori grafici PDF coerenti con ISO 32000-2 §8, dizionari di spazio colore ICCBased secondo §8.6.5.5 e dizionari di sfumatura il cui Domain, Function, Matrix e BBox seguono §8.7.4. Si tratta di proprietà dell’implementazione: le forme degli operatori e dei dizionari sono prodotte da src/Graphics/ e verificate da tests/Unit/Graphics/ oltre che dalle baseline tests/Golden/PdfWriter/PdfWriterShadingGoldenBaselineSmokeTest e PdfWriterExtGStateGoldenSmokeTest. Non costituiscono una dichiarazione di conformità end-to-end a PDF 2.0 o PDF/X. La conformità dell’intero documento è convalidata separatamente dalle suite oracle e golden descritte in /modules/core/conformance/. Il comportamento del profilo per gli OutputIntent ICC è deciso dall’ADR-011 e dall’ADR-012, non dal solo modulo.