Den Koordinatenraum transformieren: drehen, skalieren, scheren und spiegeln
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Transformieren Sie den Zeichenkoordinatenraum um einen gewählten Drehpunkt. Dieses Recipe behandelt Rotation, Skalierung, Scherung und Spiegelung. Jede Transformation bleibt in einem gesicherten Grafikstatusblock isoliert und wirkt sich daher nicht auf spätere Inhalte aus. Es folgt examples/21-transforms.php.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Sie benötigen kein Pro- oder Enterprise-Paket. Die Transformations-API wird mit Core ausgeliefert und läuft unter PHP 8.1 bis 8.4.
Konzeptueller Überblick
Abschnitt betitelt „Konzeptueller Überblick“PDF-Inhalte werden im User Space gezeichnet. Standardmäßig liegt der Ursprung des User Space unten links auf der Seite, und eine Einheit entspricht 1/72 Zoll (ISO 32000-2 §8.3.2). Eine Transformation multipliziert die aktuelle Transformationsmatrix (CTM) über den Operator cm mit einer neuen Matrix (§8.3.4). Transformationen werden durch Matrixmultiplikation verkettet; daher kommt es auf die Reihenfolge an.
NextPDF stellt ein Autorenkoordinatensystem mit Ursprung oben links bereit. Intern wandelt NextPDF es über die in den Transformationsmethoden integrierte Projektion toY() in den nativen User Space mit Ursprung unten links um. Positionsangaben verwenden User-Space-Einheiten, also PDF-Punkte, wobei 1 pt 1/72 in entspricht. Damit eine Transformation lokal bleibt, setzen Sie sie zwischen startTransform() und stopTransform(). Diese Methoden geben die Grafikstatus-Operatoren q (sichern) und Q (wiederherstellen) aus (§8.4.2). Alles, was dazwischen gezeichnet wird, erbt die Transformation. Alles nach stopTransform() kehrt zur vorherigen CTM zurück. Jeder Aufruf von rotate()/scale()/skewX()/mirrorH() nimmt einen expliziten Drehpunkt entgegen, sodass die Transformation dort verankert wird, wo Sie es erwarten, statt am Seitenursprung.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“Die API-Oberfläche wird aus PHPDoc generiert. Die zentralen Einstiegspunkte stammen aus dem Trait \NextPDF\Core\Concerns\HasTransforms:
Document::startTransform(): static— gibtqaus und öffnet einen StatusblockDocument::stopTransform(): static— gibtQaus und schließt den BlockDocument::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
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“<?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";Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Dies ist das eigenständige, vom Harness ausführbare Programm. Es spiegelt den Skalierungsabschnitt von examples/21-transforms.php wider. Jede Transformation ist mit einem expliziten Drehpunkt in einem gesicherten Grafikstatusblock isoliert. Farb- und Linieneinstellungen werden am Ende zurückgesetzt, sodass nichts auf spätere Seiten übergreift.
<?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";Erwartete STDOUT-Ausgabe:
Wrote transforms.pdfDas vollständige Beispiel deckt alle vier Transformationsfamilien ab: Rotation, Skalierung, Scherung und Spiegelung. Führen Sie es mit php examples/21-transforms.php aus; dadurch wird examples/output/21-transforms.pdf geschrieben.
Sonderfälle & Stolperfallen
Abschnitt betitelt „Sonderfälle & Stolperfallen“- Blöcke immer paarweise schließen. Jedes
startTransform()benötigt ein passendesstopTransform(). Eine unausgeglichene Anzahl vonq/Qbeschädigt den Grafikstatus für den Rest der Seite (ISO 32000-2 §8.4.2). NextPDF verfolgt die Tiefe, aber auf Recipe-Ebene gilt eine Eins-zu-eins-Zuordnung. - Die Reihenfolge ist nicht kommutativ. Transformationen werden durch Matrixmultiplikation verkettet; daher ist
rotate()gefolgt vonscale()nicht dasselbe wiescale()gefolgt vonrotate(). Wenden Sie sie innerhalb eines Blocks in der beabsichtigten Reihenfolge an. - Der Drehpunkt liegt standardmäßig im Ursprung. Wenn Sie den Drehpunkt weglassen, dreht die Transformation um den Seitenursprung, nicht um die Form. Das ist meist nicht das gewünschte Ergebnis; geben Sie den Drehpunkt daher explizit an.
- Die Y-Achse ist Autorenraum. Der Drehpunkt-
yist der Abstand von der oberen linken Autorenecke, den NextPDF in den nativen User Space projiziert. Wenn rohe PDF-Koordinaten mit der Autoren-API gemischt werden, entsteht ein gespiegeltes Ergebnis. - Statusleck. Farbe, Schriftart und Linienbreite, die innerhalb eines Transformationsblocks gesetzt werden, bleiben nach
stopTransform()bestehen, weilQin dieser API-Oberfläche nur die CTM wiederherstellt. Setzen Sie diese Werte explizit zurück, wenn ein späterer Abschnitt sie nicht erben darf, wie im Produktionsbeispiel gezeigt.
Performance
Abschnitt betitelt „Performance“Eine Transformation besteht aus einem einzelnen cm-Operator plus dem Paar q/Q. Jeder Teil ist nur wenige Bytes groß und verursacht keinen messbaren Laufzeitaufwand, sodass das Recipe klar innerhalb des Budgets von 1500 ms / 96 MB bleibt. Das Reproduzierbarkeitsprofil ist strukturell. Die Ausgabe enthält ein Trailer-/ID-Array und Erstellungsmetadaten, die zwischen Durchläufen nicht stabil sind; daher müssen Sie sie vor dem Vergleich normalisieren. Der Transformationsstream selbst ist deterministisch.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“- Datenresidenz & PII-Maßnahmen. Nicht zutreffend. Dieses Recipe zeichnet geometrische Grundformen und kurze Beschriftungen. Es verarbeitet weder externe noch personenbezogene Daten.
- Sichere Telemetrie & Log-Bereinigung. Das Recipe schreibt genau eine feste Fortschrittszeile. Dokumentinhalte werden nicht geloggt.
- Bedrohungsmodell. Nicht zutreffend. Es werden keine Eingaben geparst; es gibt keine Kryptografie und keine Vertrauensgrenze. Eine Transformation ist eine reine Content-Stream-Ausgabe.
- FIPS-Modus-Verhalten. Nicht zutreffend. Es gibt keine kryptografische Operation.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Spezifikation | Abschnitt | reference_id |
|---|---|---|---|
Eine Transformation verkettet über den Operator cm eine Matrix mit der CTM. | ISO 32000-2 | §8.3.4 | |
| Transformationen verketten sich durch Matrixmultiplikation; die Reihenfolge ist bedeutsam. | ISO 32000-2 | §8.3.4 | |
q sichert und Q stellt den Grafikstatus wieder her und grenzt damit die Transformation ein. | ISO 32000-2 | §8.4.2 | |
| Der Standard-Ursprung des User Space liegt unten links; eine Einheit ist 1/72 Zoll. | ISO 32000-2 | §8.3.2 |
Dieses Recipe setzt die zitierten Grafikstatus- und Transformationsklauseln von ISO 32000-2 um. Es beansprucht keine pauschale ISO 32000-2-Konformität; die zitierten Klauseln sind nur diejenigen, die dieses Recipe ausübt.