사용자 지정 글꼴: FontRegistry 확장 계약
한눈에 보기
섹션 제목: “한눈에 보기”FontRegistryInterface는 글꼴 등록과 조회를 위한, 프로세스 수명 동안 유지되는 계약입니다. 파일 경로, 디렉터리 또는 원시 바이너리 데이터에서 글꼴을 등록한 다음, 레지스트리를 잠가 프로덕션 워커가 이를 변경할 수 없도록 합니다.
composer require nextpdf/core:^3개념 개요
섹션 제목: “개념 개요”글꼴 레지스트리는 개별 Document 인스턴스보다 생명 주기가 긴 싱글턴입니다. 리소스 핸들이나 확장 객체는 보유하지 않고 순수한 PHP 데이터만 보유합니다. 따라서 장기 실행 워커에서 여러 요청에 걸쳐 안전하게 공유할 수 있습니다.
이 계약은 세 가지 등록 경로를 지원합니다.
- 파일에서.
register()는.ttf,.otf,.ttc또는.pfb파일을 구문 분석하고 분석된 메타데이터를 반환합니다. TrueType Collection의 경우 하위 글꼴 인덱스를 전달합니다. - 디렉터리에서.
addFontDirectory()는 엔진이 이름으로 패밀리를 확인할 때 스캔할 검색 경로를 추가합니다. - 바이너리 데이터에서.
registerFromBinary()는 원시 TrueType 또는 OpenType 바이트를 구문 분석합니다. 이 경로는@font-face브리지가data:URI 또는 원격 소스에서 가져온 글꼴에 사용합니다.
첫 요청에 몰리는 지연 시간을 줄이려면 워커 부팅 시 warmup()을 호출하여 글꼴 배치를 미리 구문 분석합니다. 그런 다음 lock()을 호출합니다. lock() 이후에는 모든 변경 메서드가 LogicException을 발생시킵니다. 여기에는 register(), addFontDirectory(), warmup(), registerBase14() 및 registerFromBinary()가 포함됩니다. 조회 메서드인 get(), has(), all() 및 getSearchDirectories()는 계속 사용할 수 있습니다. 이 잠금은 프로덕션 안전 메커니즘이며, 어떤 요청도 공유 글꼴 집합을 변경할 수 없도록 보장합니다.
대부분의 경우 FontRegistryInterface를 직접 구현하지 않습니다. 엔진이 구현을 제공하므로 그 구현을 호출하면 됩니다. 예를 들어 콘텐츠 주소 지정 저장소를 기반으로 하는 사용자 지정 글꼴 해석 전략이 필요한 경우에는 직접 구현합니다. 어느 경우든 이 계약이 경계를 정의합니다.
API 표면
섹션 제목: “API 표면”NextPDF\Contracts\FontRegistryInterface (stable, 1.7.0 이후):
| 메서드 | 반환값 | 용도 |
|---|---|---|
register(string $fontFile, string $alias, int $fontIndex) | FontInfo | 글꼴 파일을 구문 분석해 등록합니다. 레지스트리가 잠겨 있거나 파일을 구문 분석할 수 없는 경우 예외를 발생시킵니다. |
registerFromBinary(string $fontData, string $alias) | FontInfo | 원시 TrueType 또는 OpenType 바이트에서 글꼴을 등록합니다. |
registerBase14(string $key, FontInfo $font) | void | 미리 빌드된 Base 14 표준 글꼴을 등록합니다. |
addFontDirectory(string $directory) | void | 글꼴 검색 디렉터리를 추가합니다. |
warmup(array $fontFiles) | void | 워커 부팅 시 글꼴 배치를 미리 구문 분석합니다. |
lock() | void | 추가 변경을 막기 위해 레지스트리를 동결합니다. |
isLocked() | bool | 레지스트리가 잠겨 있는지 여부를 보고합니다. |
get(string $family, string $style) | FontInfo | null | 패밀리와 스타일로 글꼴을 조회합니다. |
has(string $key) | bool | 등록 키가 존재하는지 확인합니다. |
all() | array<string, FontInfo> | 등록된 모든 글꼴을 반환합니다. |
getSearchDirectories() | list<string> | 검색 디렉터리를 순서대로 반환합니다. |
memoryUsage() | MemoryReport | 현재 레지스트리 메모리 사용량을 보고합니다. |
코드 샘플 — 빠른 시작
섹션 제목: “코드 샘플 — 빠른 시작”<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;
/** @var FontRegistryInterface $fonts */$info = $fonts->register('/srv/fonts/Inter-Regular.ttf', 'Inter');
if (!$fonts->has('inter')) { throw new RuntimeException('Inter failed to register');}코드 샘플 — 프로덕션
섹션 제목: “코드 샘플 — 프로덕션”이 워커 부팅 루틴은 글꼴 집합을 미리 준비하고, 레지스트리를 잠그며, 라이선스 추적을 위해 각 로드를 관찰합니다. 여기서 사용하는 모든 타입은 공개 API입니다.
<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;use NextPDF\Event\Content\FontLoadedEvent;use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;use Psr\Log\LoggerInterface;
final class FontWarmup{ /** @param list<string> $fontFiles */ public function __construct( private readonly FontRegistryInterface $fonts, private readonly LoggerInterface $logger, private readonly array $fontFiles, ) {}
public function boot(): EventDispatcher { $listeners = new ListenerProvider(); $listeners->addListener( FontLoadedEvent::class, function (FontLoadedEvent $event): void { $this->logger->info('font.loaded', [ 'family' => $event->family, 'style' => $event->style, 'type' => $event->fontType->name, ]); }, );
if (!$this->fonts->isLocked()) { $this->fonts->warmup($this->fontFiles); $this->fonts->lock(); }
return new EventDispatcher($listeners); }}엣지 케이스 및 주의 사항
섹션 제목: “엣지 케이스 및 주의 사항”- 잠긴 레지스트리.
lock()이후의 모든 변경은LogicException을 발생시킵니다. 재사용되는 워커에서 조건부 워밍을 수행하기 전에 항상isLocked()를 확인합니다. - 바이너리 등록은 키로 캐시되지 않습니다.
registerFromBinary()는 임시 파일에 기록한 다음 이를 구문 분석합니다. 반환된FontInfo를 핸들로 취급합니다. - TTC 인덱스. TrueType Collection의 경우,
register()의 세 번째 인수가 하위 글꼴을 선택합니다. 기본값0은 첫 번째 페이스를 선택합니다. - 패밀리 해석.
get()은 알 수 없는 패밀리-스타일 쌍에 대해null을 반환합니다. 결과가 non-null이라고 절대 가정하지 마십시오.
warmup()은 구문 분석 비용을 첫 요청에서 부팅 시점으로 이동시킵니다. 레지스트리 메서드는 순수 PHP 데이터에 대해 작동합니다. 조회는 상수 시간의 맵 읽기입니다. 메모리 예산에 맞춰 워커의 상주 글꼴 집합 크기를 산정하려면 memoryUsage()를 호출합니다.
보안 참고 사항
섹션 제목: “보안 참고 사항”등록된 글꼴은 PDF에 임베드할 수 있는 콘텐츠가 됩니다. 등록하기 전에 글꼴의 출처를 검증합니다. 크기 및 형식 검사 없이 공격자가 제어하는 바이너리 데이터를 등록하지 마십시오. FontLoadedEvent 후크는 글꼴 라이선스 준수를 강제하고 문서가 임베드하는 페이스를 기록하기 위해 제공되는 지점입니다.
적합성
섹션 제목: “적합성”서명 또는 아카이브 관련 규범적 주장은 적용되지 않습니다. 글꼴 임베딩 및 서브셋 처리는 PDF 2.0 글꼴 모델을 준수합니다. 해당 적합성은 이 계약이 아니라 내부 서브셋터가 담당합니다.
상업적 맥락
섹션 제목: “상업적 맥락”NextPDF Enterprise는 동일한 FontRegistryInterface 위에 글꼴 라이선스 증명과 감사된 서브셋 정책을 계층화합니다. 계약이 경계를 정의하므로 등록 코드는 에디션 전반에 걸쳐 변경되지 않습니다.
참고 항목
섹션 제목: “참고 항목”관련 계약 및 모듈
섹션 제목: “관련 계약 및 모듈”- 글꼴 모듈 참조 — 레지스트리 구현, 구문 분석, 서브셋 처리 내부 구조.
- 타이포그래피 계약 참조 —
FontRegistryInterface가 카탈로그에 등록되는 위치. - 액션 트리거 및 이벤트 리스너 —
FontLoadedEvent및 디스패처. - 사용자 지정 레이아웃 및 텍스트 가로채기 — 렌더링 시점 전략 계약의 형제 항목.
- SPI 안정성 규칙 —
FontRegistryInterface의 기반이 되는 인터페이스 약속.
용어집은 font registry, image registry 및 event listener를 정의합니다. 각 표준화된 정의는 게시된 용어집을 참조하십시오.