Text: ขอบเขตการ shaping, CJK และการจัดการ run
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”โมดูล text กำหนดขอบเขตของการ shaping โดยเปิดเผยอินเทอร์เฟซขนาดเล็กที่แปลง run แบบ 8-bit Unicode Transformation Format (UTF-8) ให้เป็นกลิฟที่กำหนดตำแหน่งแล้ว เลือกใช้แบ็กเอนด์ OpenType จริงเมื่อพร้อมใช้งาน ถอยกลับด้วยพฤติกรรมที่กำหนดผลได้เมื่อไม่มี และจัดเตรียมรีจิสทรีสำหรับ shaper เฉพาะ script
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”ShaperInterface เชื่อมไปป์ไลน์ text-layout เข้ากับเอนจิน shaping แบบ OpenType อินเทอร์เฟซนี้ตั้งใจให้มีขนาดเล็ก เมท็อด shape() เพียงหนึ่งเดียวรับ ShaperInput แล้วคืนค่าเป็น ShapingResult ชนิดค่าคืนนี้เป็นผลลัพธ์เดียวที่ผู้ใช้งานมองเห็น การนำไปใช้งานต้องไม่ทำให้รายละเอียดภายในของเอนจิน shaping รั่วไหล และค่าคืนที่กำหนดชนิดไว้จะบังคับขอบเขตดังกล่าว ShapingResult บรรจุรายการเรกคอร์ด GlyphRun ข้อความต้นฉบับที่สะท้อนกลับมา script และทิศทาง รวมถึงแท็ก shaperImpl ที่ระบุแบ็กเอนด์ซึ่งสร้างผลลัพธ์นี้
การเลือกแบ็กเอนด์ทำอย่างชัดเจนและรายงานความสามารถโดยไม่ต้องคาดเดา ShaperFactory ตรวจสอบความสามารถหนึ่งครั้ง หากโฮสต์มี binding ของ HarfBuzz ที่ทำงานได้ create() จะคืน shaper ที่ใช้ HarfBuzz เป็นแบ็กเอนด์ มิฉะนั้นจะคืน NullShaper NullShaper เป็น fallback แบบส่งผ่าน fallback นี้ปล่อยกลิฟสังเคราะห์หนึ่งตัวต่อหนึ่ง Unicode codepoint โดยมี advance เป็นศูนย์และ offset เป็นศูนย์ พร้อมติดแท็กผลลัพธ์เพื่อให้ระบบ observability ตรวจพบการถอยกลับได้ และมอบการปรับค่า advance ให้กับโมดูล font-metrics เส้นทางนี้คือการลดทอนคุณภาพที่บันทึกไว้เป็นเอกสาร ไม่ใช่การ shaping แบบเต็มรูปแบบ การแทนที่ ลิเกเจอร์ การจัดตำแหน่ง mark และรูปแบบตามบริบทจำเป็นต้องใช้แบ็กเอนด์จริง wouldUseRealShaper() เป็นเพรดิเคตสำหรับการวินิจฉัย โค้ดในระบบจริงควรแยกสาขาตามแท็ก shaperImpl ของผลลัพธ์แทน
การ shaping เฉพาะ script เป็น service provider interface (SPI) ไม่ใช่การนำไปใช้งานที่มาพร้อมในแพ็กเกจ ScriptShaperRegistry เป็นรีจิสทรีสไตล์ PHP Standards Recommendation 11 (PSR-11) ที่ resolve MongolianShaperInterface หรือ TibetanShaperInterface ตามแท็ก script ของ International Organization for Standardization (ISO) 15924 รีจิสทรีจัดเก็บคีย์แบบไม่สนใจตัวพิมพ์ใหญ่เล็ก และอาศัยแหล่งข้อมูลอ้างอิงหลักเพียงแหล่งเดียวสำหรับความถูกต้องของ script-code รีจิสทรีและอินเทอร์เฟซของ script-shaper เป็นสัญญาที่ถูกตรึงไว้ ดังนั้นส่วนขยายจึงลงทะเบียน provider แบบ Phase-12 ได้โดยไม่ต้องแตะ call site เอนจินจัดส่งขอบเขตมาให้ ผู้ใช้งานเป็นผู้จัดหา provider สำหรับ complex-script
การจัดการ run ภาษาจีน ญี่ปุ่น และเกาหลี (CJK) อยู่ในขอบเขตการเข้ารหัสด้าน typography หน้าฟอนต์ CJK TrueType ที่ฝังตัวจะถูกปล่อยออกมาเป็นฟอนต์ Type 0 ที่มี CMap แบบ Identity-H และ descendant แบบ CIDFontType2 ตามที่ครอบคลุมใน ISO 32000-2 §9.7.4 (ไดเจสต์ retrieval-augmented generation (RAG) ถูกตัดทอนโดยข้อจำกัดสิทธิ์การใช้งาน บันทึกไว้ใน _downgraded-claims-o3.md) เมื่อมีการฝังโปรแกรม TrueType แล้ว CIDFont แบบ Type 2 จะแมป character identifier ไปยังดัชนีกลิฟผ่านรายการ CIDToGIDMap ตามที่ครอบคลุมใน ISO 32000-2 §9 (ไดเจสต์ที่ตรึงไว้โดยหน้าสัญญา B1) ตัว subsetter รักษาหมายเลขกลิฟเดิมไว้ เพื่อให้ /CIDToGIDMap /Identity ยังคงใช้ได้กับ subset CjkFontValidator ตรวจสอบว่าฟอนต์ตัวเลือกครอบคลุมบล็อก Unicode ที่ script ต้องการหรือไม่ ก่อนเลือกฟอนต์นั้น
ส่วนต่อประสาน API
หัวข้อที่มีชื่อว่า “ส่วนต่อประสาน API”| ชนิด | ประเภท | สมาชิกหลัก | ความเสถียร | ตั้งแต่ |
|---|---|---|---|---|
ShaperInterface | interface | shape(ShaperInput): ShapingResult | stable | 3.2.0 |
ShaperFactory | final class | default(), create(), wouldUseRealShaper() | stable | 3.2.0 |
NullShaper | final readonly class | shaper สำรองแบบส่งผ่าน | stable | 3.2.0 |
ShapingResult | final readonly class | $glyphRuns, $originalText, $script, $direction, $shaperImpl | stable | 3.2.0 |
ScriptShaperRegistry | final class | registerMongolian(), getMongolian(), hasMongolian() และส่วนเทียบเท่าของภาษาทิเบต | stable | 3.1.0 |
CjkFontValidator | final class | validateCoverage(), detectScript(), isCjkCodepoint() | stable | 1.0.0 |
รูปแบบเมท็อด register*, get* และ has* ของ ScriptShaperRegistry รวมถึงอินเทอร์เฟซของ script-shaper เป็นสัญญาที่ถูกตรึงไว้ ตามการออกแบบ ShapingResult คือผลลัพธ์เดียวของ shaper ที่ผู้ใช้งานมองเห็นได้
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Font\Shaper\ShaperFactory;use NextPDF\Font\Shaper\ShaperImpl;
$factory = ShaperFactory::default();$shaper = $factory->create();
// Branch on the result tag, not on the concrete class.$wouldShape = $factory->wouldUseRealShaper() ? 'HarfBuzz backend available' : 'NullShaper fallback (degraded — no substitution or positioning)';
echo $wouldShape, "\n";ShaperFactory::default() เชื่อมต่อตัวตรวจสอบความสามารถสำหรับระบบจริง create() จดจำแบ็กเอนด์ที่เลือกไว้ตลอดอายุของ factory ใช้ wouldUseRealShaper() และแท็ก shaperImpl ในแต่ละผลลัพธ์เพื่อตรวจสอบความสามารถ
ตัวอย่างโค้ด — ระบบจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — ระบบจริง”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Text\Shaping\MongolianShaperInterface;use NextPDF\Text\Shaping\ScriptShaperRegistry;
final readonly class ComplexScriptBootstrap{ public function __construct(private ScriptShaperRegistry $registry) {}
/** * Register a consumer-supplied Mongolian shaper provider at boot so * the layout pipeline can resolve it by ISO 15924 script tag. */ public function register(MongolianShaperInterface $mongolian): void { $this->registry->registerMongolian($mongolian); }
public function hasMongolian(): bool { return $this->registry->hasMongolian(); }}รีจิสทรีคือจุดเชื่อมต่อสำหรับ provider แบบ complex-script เอนจินจัดส่งขอบเขตและรูปแบบ accessor ที่ถูกตรึงไว้ ผู้ใช้งานเป็นผู้จัดหาการนำไปใช้งานสำหรับภาษามองโกเลียและภาษาทิเบต
กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”- ผลลัพธ์ของ
NullShaperมี advance เป็นศูนย์และ offset เป็นศูนย์ อย่าป้อนตำแหน่งเหล่านั้นเข้าสู่ text layout โดยตรง ให้ปรับค่า advance จากโมดูล font-metrics และตรวจจับการถอยกลับผ่านshaperImpltag - อินพุตว่างจะให้รายการ
glyphRunsที่ว่างเปล่า ไม่ใช่ run ว่าง โค้ดวนซ้ำของผู้ใช้งานไม่จำเป็นต้องมีกรณีพิเศษสำหรับ run ที่มีความยาวเป็นศูนย์ ScriptShaperRegistryไม่ได้นำPsr\Container\ContainerInterfaceไปใช้งานโดยตรง ดังนั้น accessor ที่กำหนดชนิดแล้วจึงรักษาชนิดค่าคืนที่แคบไว้ภายใต้การวิเคราะห์แบบสถิต ใช้getMongolian()และgetTibetan()ไม่ใช่get()แบบทั่วไป- แท็ก script จะถูกจับคู่ตามค่ามาตรฐาน alpha-4 ของ ISO 15924 และจัดเก็บแบบไม่สนใจตัวพิมพ์ใหญ่เล็ก หากส่งค่า
MongหรือTibtตัวพิมพ์ใหญ่เล็กจะไม่มีผลต่อการค้นหา - อักขระ CJK Extension B อยู่ใน Unicode plane 2 และบังคับให้ใช้ subtable แบบ cmap Format 12 ใน subset เส้นทางการเข้ารหัสจัดการกรณีนี้ให้แล้ว อย่าสมมติว่า basic multilingual plane ครอบคลุมข้อความ CJK ทั้งหมด
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”ตัวตรวจสอบความสามารถจะทำงานหนึ่งครั้งต่อหนึ่งอินสแตนซ์ของ ShaperFactory และแบ็กเอนด์จะถูกจดจำไว้ ดังนั้นการเรียก create() ซ้ำจึงไม่มีค่าใช้จ่ายเพิ่ม NullShaper มีความซับซ้อนเชิงเส้นตามจำนวน codepoint ของ run อินพุต และไม่ทำ input/output (I/O) ScriptShaperRegistry resolve ด้วยการค้นหาตามคีย์ในเวลาคงที่ CjkFontValidator สุ่มตัวอย่าง codepoint เป็นช่วงก้าวแทนการทดสอบทุกตัว ซึ่งทำให้การตรวจสอบความครอบคลุมมีต้นทุนต่ำแม้กับฟอนต์ CJK ขนาด 20,000 กลิฟ performance_budget ที่ 1500 ms wall และ 64 MB peak ครอบคลุมการทำงานทั่วไป ในการ shaping จริง ต้นทุนหลักคือแบ็กเอนด์ OpenType ต้นทุนนั้นอยู่นอกขอบเขตของโมดูลนี้เมื่อ fallback ทำงานอยู่
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”ขอบเขตของ shaper รับสตริง UTF-8 NullShaper รองรับ UTF-8 ที่ผิดรูปแบบด้วยการแบ่งแบบ best-effort แทนการยกข้อผิดพลาด เพราะสัญญา fallback ที่ระบุไว้คือ “ไม่มีการ shaping จริง” อยู่แล้ว ผู้เรียกจึงต้องพร้อมรับเอาต์พุตคุณภาพต่ำ สัญญา byte-offset cluster ใช้ความยาวแบบอิงไบต์ ซึ่งถูกต้องสำหรับอินพุตหลายไบต์ และหลีกเลี่ยงข้อบกพร่องการแมป cluster ที่คลาดเคลื่อนไปหนึ่ง codepoint เมื่อมีอยู่ แบ็กเอนด์จริงคือไลบรารี native ของบุคคลที่สาม จงปฏิบัติต่ออินพุตของแบ็กเอนด์นั้นเสมือนว่าไม่น่าเชื่อถือ และจำกัดความยาวของ run ที่ต้นทาง รีจิสทรีของ script-shaper จัดเก็บ provider ที่ผู้ใช้งานจัดหามา การนำไปใช้งานเหล่านั้นอยู่ภายในขอบเขตความเชื่อถือของผู้ใช้งาน ไม่ใช่ของเอนจิน
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”| ข้อกล่าวอ้าง | มาตรฐาน | ข้อกำหนด | หลักฐาน |
|---|---|---|---|
หน้าฟอนต์ CJK TrueType ที่ฝังตัวจะถูกปล่อยออกมาเป็นฟอนต์ Type 0 ที่มี CMap แบบ Identity-H และมี CIDFontType2 เป็น descendant | ISO 32000-2 | §9.7.4 | ไดเจสต์ retrieval-augmented generation (RAG) ถูกตัดทอนโดยข้อจำกัดสิทธิ์การใช้งาน prefix 7a5258772f508e3b ดู _downgraded-claims-o3.md |
CIDFont แบบ Type 2 ที่ฝังตัวจะแมป character identifier ผ่าน CIDToGIDMap ไปยังดัชนีกลิฟ | ISO 32000-2 | §9 |
ทั้งสองข้อกำหนดเป็นการถอดความ ข้อที่สองถูกตรึงด้วยไดเจสต์ (นำกลับมาใช้จากหน้าสัญญา B1) และข้อแรกได้รับการยืนยันโดย ADR-013 และภาพรวมสำหรับนักพัฒนาของ cmap-encoder NextPDF ไม่ทำซ้ำข้อความเชิงบรรทัดฐาน แบ็กเอนด์ของ shaper เป็นอิสระจากความสอดคล้องของ Portable Document Format (PDF) ข้อกล่าวอ้างด้านความสอดคล้องในที่นี้เกี่ยวข้องกับการปล่อย font-dictionary ของ CJK ที่สร้างโดยขอบเขตการเข้ารหัส ADR-013 และภาพรวมสำหรับนักพัฒนาของ cmap-encoder บันทึกรายละเอียดเส้นทางนั้นไว้เพิ่มเติม
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”ไปป์ไลน์ text-preprocessing ขั้นสูงและบริการการแยกข้อมูลต่อยอดจากขอบเขตของ shaper ใน Core และชนิดค่าของการจัดการ run โมดูล text ใน Core จัดส่งขอบเขต fallback และรีจิสทรีของ script-shaper มาให้โดยไม่ต้องมีสิทธิ์การใช้งาน การไม่มีลิงก์การแปลงเป็นการตั้งใจ
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- Typography: registry, subsetting, CMap, encoding, BiDi — ขอบเขตการเข้ารหัสและเอนจินข้อความแบบสองทิศทาง
- Font: value types, embedding, fallback — ค่า
FontInfoที่ shaper input อ้างถึง - Contracts / Typography — สัญญา text-preprocessor ที่อยู่เหนือกระบวนการ shaping