ข้ามไปยังเนื้อหา

ValueObjects: พรีมิทีฟของโดเมน + หน่วย

โมดูล ValueObjects ให้พรีมิทีฟทางเรขาคณิตแบบเปลี่ยนแปลงไม่ได้ที่ใช้ทั่วทั้งเอนจิน ได้แก่ PageSize, Dimension, Position, Margin และ enum Unit แต่ละตัวเป็นคลาส final readonly จึงแชร์อินสแตนซ์ได้อย่างอิสระ และการแปลงค่าแต่ละครั้งจะคืนอินสแตนซ์ใหม่

Terminal window
composer require nextpdf/core:^3

value object ทั้งสี่ตัวเป็น final readonly แต่ละตัวเก็บพิกัดเป็น float และไม่เปิดเผยเมธอดสำหรับแก้ไขค่า เมธอดการแปลงค่าจะสร้างอินสแตนซ์ใหม่ด้วยอาร์กิวเมนต์แบบมีชื่อ สามารถแคชค่าเหล่านี้ ส่งผ่านระหว่างเอกสาร และแชร์ข้ามเวิร์กเกอร์ได้โดยไม่ต้องคัดลอกเพื่อป้องกันการเปลี่ยนแปลง

PageSize เก็บความกว้าง ความสูง (เป็นพอยต์ 1 pt = 1/72 นิ้ว) และชื่อ แฟกทอรีแบบสแตติกครอบคลุมซีรีส์ A ของ International Organization for Standardization (ISO) 216 (A0A6) ซีรีส์ B ของ ISO 216 (B0B5) และขนาดของอเมริกาเหนือ (Letter, Legal, Tabloid) มิติ A/B เป็นไปตามซีรีส์ขนาดกระดาษหลังตัดขอบที่กำหนดโดย ISO 216 fromName() แปลงชื่อโดยไม่คำนึงถึงตัวพิมพ์เล็กพิมพ์ใหญ่ และโยน PageLayoutException เมื่อพบชื่อที่ไม่รู้จัก landscape() และ portrait() คืนค่าขนาดหน้าตามการวางแนว หรือ self เมื่อหน้านั้นอยู่ในแนวดังกล่าวอยู่แล้ว toDimension() แปลงขนาดหน้าเป็น Dimension ในหน่วยพอยต์

Dimension เก็บความกว้าง ความสูง และ Unit แฟกทอรี (fromMillimeters(), fromPoints(), fromInches()) สร้างมิติในหน่วยที่เลือก toPoints() และ toMillimeters() ใช้แปลงหน่วย toPoints() คืนค่า self เมื่อมิติอยู่ในหน่วยพอยต์อยู่แล้ว withWidth() และ withHeight() คืนสำเนาที่ปรับขนาดแล้ว การแปลงค่าใช้แฟกเตอร์ที่แม่นยำ: 72/25.4 พอยต์ต่อมิลลิเมตร 72/2.54 ต่อเซนติเมตร และ 72 ต่อนิ้ว

Position เป็นจุดสองมิติในพื้นที่ผู้ใช้ของ Portable Document Format (PDF) (x, y) origin() คืนค่า (0, 0) translate(dx, dy) คืนสำเนาที่เลื่อนตำแหน่งแล้ว withX() / withY() คืนสำเนาที่แทนที่ค่าในแกนใดแกนหนึ่ง

Margin เก็บ top, right, bottom และ left แฟกทอรีได้แก่ uniform() (ค่าเดียวกันทุกด้าน) symmetric(vertical, horizontal) และ zero()

Unit เป็น enum แบบอิงค่าสตริง: Point (pt), Millimeter (mm), Centimeter (cm) และ Inch (in) toPointFactor() คืนค่าตัวคูณสำหรับแปลงเป็นพอยต์

สัญลักษณ์ชนิดสมาชิกสำคัญ
NextPDF\ValueObjects\PageSizeคลาส final readonly$width, $height, $name; แฟกทอรี A0A6, B0B5, Letter, Legal, Tabloid; fromName(), landscape(), portrait(), toDimension()
NextPDF\ValueObjects\Dimensionคลาส final readonly$width, $height, $unit; fromMillimeters(), fromPoints(), fromInches(), toPoints(), toMillimeters(), withWidth(), withHeight()
NextPDF\ValueObjects\Positionคลาส final readonly$x, $y; origin(), translate(), withX(), withY()
NextPDF\ValueObjects\Marginคลาส final readonly$top, $right, $bottom, $left; uniform(), symmetric(), zero()
NextPDF\ValueObjects\Unitstring enumPoint, Millimeter, Centimeter, Inch; toPointFactor()

ใช้แฟกทอรีในการสร้างพรีมิทีฟทางเรขาคณิต

<?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

แปลงหน่วย กำหนดการวางแนว และส่งระยะขอบเข้าสู่การกำหนดค่า

<?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.
  • มิติทั้งหมดใช้พอยต์ เว้นแต่จะระบุ Dimension พร้อม Unit อย่างชัดเจน ระยะขอบของ Config ใช้พอยต์เป็นค่าเริ่มต้น
  • PageSize::landscape() / portrait() คืนอินสแตนซ์เดิมเมื่อการวางแนวตรงกันอยู่แล้ว จึงไม่มีการจัดสรรหน่วยความจำเพิ่ม และยังคงเอกลักษณ์ของออบเจกต์ไว้
  • PageSize::fromName() ไม่คำนึงถึงตัวพิมพ์เล็กพิมพ์ใหญ่ แต่แปลงได้เฉพาะแฟกทอรีที่มีชื่อเท่านั้น ชื่อที่ไม่รู้จักจะโยน PageLayoutException ไม่ใช่คืนขนาดเริ่มต้น
  • Dimension::toPoints() คืนค่า self เมื่อหน่วยเป็น Point อยู่แล้ว อย่าสันนิษฐานว่าได้ออบเจกต์ใหม่
  • ออบเจกต์เหล่านี้เก็บค่า float ดิบ และไม่มีการตรวจสอบช่วงค่า จึงรับมิติที่เป็นค่าลบหรือศูนย์ได้ตั้งแต่ตอนสร้างออบเจกต์ เลเยอร์เค้าโครงและเลเยอร์ writer เป็นผู้บังคับใช้ความถูกต้องทางเรขาคณิต ไม่ใช่ออบเจกต์เหล่านี้
  • การแปลงค่าทศนิยมใช้แฟกเตอร์อัตราส่วนที่แม่นยำ (72/25.4, 72/2.54) ปัดเศษเฉพาะที่ขอบเขตการนำเสนอเท่านั้น เพื่อให้ผลลัพธ์ที่ทำซ้ำได้คงที่

value object แต่ละตัวเป็นโครงสร้างข้อมูลแบบราบที่ประกอบด้วยค่าทศนิยมแบบ readonly การสร้างและการแปลงค่าแต่ละครั้งเป็นการจัดสรรหน่วยความจำครั้งเดียวแบบ O(1) โดยไม่มีการคัดลอกแบบลึก เพราะไม่มีสถานะที่เปลี่ยนแปลงได้ซ้อนอยู่ภายใน สามารถแชร์อินสแตนซ์ข้ามเอกสารได้โดยไม่มีต้นทุนเพิ่มเติม performance_budget เริ่มต้นสำหรับหน้าอ้างอิงนี้คือ wall_ms: 1500, peak_mb: 64

value object เหล่านี้ไม่ทำ input/output (I/O) ไม่รับสตริงที่ผู้ใช้ระบุยกเว้นชื่อขนาดหน้า และไม่เก็บแฮนเดิลของทรัพยากรภายนอก จึงไม่มีพื้นผิวการโจมตีโดยตรง PageSize::fromName() ปฏิเสธข้อมูลที่ไม่รู้จักด้วยข้อยกเว้นแทนที่จะถอยกลับเงียบๆ ดังนั้นการกำหนดค่าที่ผิดรูปจะล้มเหลวอย่างชัดแจ้งแทนที่จะสร้างเรขาคณิตของหน้าที่ไม่คาดคิด

ข้อกำหนดข้อหัวข้อ
ISO 216:2007ซีรีส์ A / Bมิติขนาดกระดาษหลังตัดขอบสำหรับแฟกทอรี A* / B* (เรียบเรียงใหม่ ไม่ได้อ้างถ้อยคำของ ISO และไม่ได้ปักหมุดชังก์)

มิติจากแฟกทอรี A และ B สอดคล้องกับขนาดหลังตัดขอบของ ISO 216 โดยแสดงเป็นพอยต์ ขนาดของอเมริกาเหนือ (Letter, Legal, Tabloid) เป็นขนาดอุตสาหกรรมโดยพฤตินัยที่ไม่มีพื้นฐานจาก ISO การอ้างอิง ISO ได้รับการเรียบเรียงใหม่ภายใต้นโยบายการอ้างอิงของเว็บไซต์ ไม่มีการปักหมุดชังก์แบบคำต่อคำ

  • /modules/core/config/Config ใช้ PageSize และ Margin
  • /modules/core/layout/ — ตัวใช้เค้าโครงสำหรับพรีมิทีฟเหล่านี้
  • /modules/core/graphics/Position ในพื้นที่พิกัดการวาด
  • /modules/core/contracts/Orientation ที่ใช้กับ PageSize
  • /modules/core/exception/PageLayoutException จาก fromName()