Aller au contenu

ValueObjects : primitives de domaine + unités

Le module ValueObjects regroupe les primitives géométriques immuables que le moteur manipule : PageSize, Dimension, Position, Margin, et l’énumération Unit. Chacune est une classe final readonly, ce qui permet de partager librement une instance ; toute transformation renvoie une nouvelle instance.

Fenêtre de terminal
composer require nextpdf/core:^3

Les quatre objets-valeurs sont tous final readonly. Ils contiennent des coordonnées float et n’exposent aucun mutateur — les méthodes de transformation reconstruisent une nouvelle instance avec des arguments nommés. Tu peux donc les mettre en cache, les transmettre d’un document à l’autre et les partager entre workers en toute sécurité, sans copie défensive.

PageSize stocke une largeur, une hauteur (en points ; 1 pt = 1/72 pouce) et un nom. Des fabriques statiques couvrent la série A de l’ISO 216 (A0A6), la série B de l’ISO 216 (B0B5), ainsi que les formats nord-américains (Letter, Legal, Tabloid). Les dimensions A/B suivent la série de formats de papier rognés définie par l’ISO 216. fromName() résout un nom sans tenir compte de la casse et lève PageLayoutException pour un nom inconnu. landscape() et portrait() renvoient la variante d’orientation (et renvoient self inchangé lorsque l’orientation correspond déjà). toDimension() convertit en Dimension en points.

Dimension stocke une largeur, une hauteur et une Unit. Les fabriques (fromMillimeters(), fromPoints(), fromInches()) créent une instance dans une unité donnée. toPoints() et toMillimeters() convertissent (en renvoyant self lorsque la valeur est déjà en points). withWidth() et withHeight() renvoient une copie redimensionnée. La conversion utilise des facteurs exacts : 72/25.4 points par millimètre, 72/2.54 par centimètre, 72 par pouce.

Position est un point 2D dans l’espace utilisateur PDF (x, y). origin() renvoie (0, 0). translate(dx, dy) renvoie une copie décalée. withX() / withY() renvoient une copie dont un seul axe est remplacé.

Margin contient top, right, bottom, left. Les fabriques sont : uniform() (même valeur sur tous les côtés), symmetric(vertical, horizontal), et zero().

Unit est une énumération adossée à une chaîne — Point (pt), Millimeter (mm), Centimeter (cm), Inch (in) — avec toPointFactor() qui renvoie le multiplicateur vers les points.

SymboleNatureMembres clés
NextPDF\ValueObjects\PageSizeclasse final readonly$width, $height, $name ; fabriques A0A6, B0B5, Letter, Legal, Tabloid ; fromName(), landscape(), portrait(), toDimension()
NextPDF\ValueObjects\Dimensionclasse final readonly$width, $height, $unit ; fromMillimeters(), fromPoints(), fromInches(), toPoints(), toMillimeters(), withWidth(), withHeight()
NextPDF\ValueObjects\Positionclasse final readonly$x, $y ; origin(), translate(), withX(), withY()
NextPDF\ValueObjects\Marginclasse final readonly$top, $right, $bottom, $left ; uniform(), symmetric(), zero()
NextPDF\ValueObjects\Uniténumération de chaînePoint, Millimeter, Centimeter, Inch ; toPointFactor()

Construis des primitives géométriques à l’aide des fabriques.

<?php
declare(strict_types=1);
use NextPDF\ValueObjects\Margin;
use NextPDF\ValueObjects\PageSize;
use NextPDF\ValueObjects\Position;
$page = PageSize::A4(); // 595.276 x 841.890 pt
$margin = Margin::uniform(18.0); // 18 pt all sides
$origin = Position::origin()->translate(72.0, 72.0); // 1 inch in from corner

Convertis les unités, déduis l’orientation et transmets les marges à une configuration.

<?php
declare(strict_types=1);
use NextPDF\Core\Config;
use NextPDF\ValueObjects\Dimension;
use NextPDF\ValueObjects\Margin;
use NextPDF\ValueObjects\PageSize;
// A label sized in millimeters, resolved to points for the engine.
$label = Dimension::fromMillimeters(width: 100.0, height: 150.0)->toPoints();
$page = PageSize::A4()->landscape(); // swap to width >= height
$margin = Margin::symmetric(vertical: 20.0, horizontal: 15.0);
$config = (new Config())
->withPageSize($page)
->withMargins($margin);
// $label->width / $label->height are now in points for downstream layout.
  • Toutes les dimensions sont en points, sauf lorsqu’elles sont encapsulées dans une Dimension avec une Unit explicite. Les marges de Config sont en points par défaut.
  • PageSize::landscape() / portrait() renvoient la même instance lorsque l’orientation correspond déjà : aucune allocation, l’identité est préservée.
  • PageSize::fromName() est insensible à la casse mais ne résout que les fabriques nommées. Un nom inconnu lève PageLayoutException, et non une taille par défaut.
  • Dimension::toPoints() renvoie self lorsque l’unité est déjà Point ; ne présume pas qu’un nouvel objet a été créé.
  • Ces objets contiennent des valeurs float brutes et n’appliquent aucune validation de plage. Des dimensions négatives ou nulles sont acceptées à la construction. La validité géométrique est imposée par les couches de mise en page et d’écriture, pas ici.
  • La conversion en flottant utilise des facteurs rationnels exacts (72/25.4, 72/2.54) ; n’arrondis qu’à la frontière de présentation pour conserver une sortie reproductible et stable.

Chaque objet-valeur est une structure plate readonly de flottants. La construction et chaque transformation se limitent à une allocation unique en O(1), sans copie profonde, puisqu’il n’y a aucun état mutable imbriqué. Partager une instance entre documents n’a pas de coût supplémentaire. Le performance_budget par défaut de cette page de référence est wall_ms: 1500, peak_mb: 64.

Ces objets-valeurs ne gèrent aucune E/S, aucune chaîne fournie par l’utilisateur hormis un nom de taille de page, et aucun handle de ressource externe ; ils ne présentent donc aucune surface d’attaque directe. PageSize::fromName() rejette une entrée inconnue par une exception au lieu de se rabattre silencieusement, ce qui fait échouer explicitement une configuration mal formée plutôt que de produire une géométrie de page inattendue.

SpécificationClauseSujet
ISO 216:2007Séries A / BDimensions de formats de papier rognés pour les fabriques A* / B* (paraphrasé ; prose ISO non citée, aucun chunk épinglé)

Les dimensions des fabriques A et B correspondent aux formats rognés de l’ISO 216 exprimés en points. Les formats nord-américains (Letter, Legal, Tabloid) sont des formats de facto du secteur, sans fondement ISO. La référence ISO est paraphrasée conformément à la politique de citation du site. Aucun chunk verbatim n’est épinglé.

  • /modules/core/config/Config utilise PageSize et Margin
  • /modules/core/layout/ — les composants géométriques qui consomment ces primitives
  • /modules/core/graphics/Position dans l’espace de coordonnées de dessin
  • /modules/core/contracts/Orientation associée à PageSize
  • /modules/core/exception/PageLayoutException émise par fromName()