Optional Document Handlers
THPDFDocumentHandlerRegistry는 약한 확장자나 MIME 힌트보다 검사한 콘텐츠로 교체 가능한 핸들러를 고른 뒤, 선택된 소스를 내보내기와 렌더링이 공유하는 하나의 불변 PDF 캐시로 변환합니다
내장 선택 핸들러
- XPS/OpenXPS는 fixed-page 차원과 시각 순서를 유지하고, self-closing 또는 속성을 지닌 축약
Path지오메트리를 네이티브 PDF 벡터로 변환하며, 속성/property-element solid brush, multi-stopLinearGradientBrush, 타원RadialGradientBrushshading pattern을 보존하고,TileMode=None인 패키지 JPEG/PNG/TIFF/JPEG XRImageBrush리소스로 path를 채웁니다 - XPS 이미지 채움은 절대 또는
RelativeToBoundingBoxViewbox/Viewport매핑,None/Tile/FlipX/FlipY/FlipXYtile 모드, 네이티브 path·배치 클리핑, 유한 6파라미터Transform속성 또는ImageBrush.TransformMatrixTransform요소, brush/path opacity, PNG soft-mask alpha, 이미지 DPI, 패키지 리소스 캐싱을 지원합니다 - XPS
Path.OpacityMask는 solid, multi-stop linear 또는 타원 radial gradient, 반복/반사 이미지 셀을 포함한 PNGImageBrushmask를 지원합니다. 균일 alpha는 기존 그래픽 상태로 병합되고, 가변 alpha는 shading pattern과 이미지 soft-mask stream을 공유하는 상한 네이티브 DeviceGray transparency group을 씁니다 - XPS Canvas
Opacity와Canvas.OpacityMask는 각 자식을 독립적으로 감쇠하는 대신 겹치는 자손을 격리 DeviceRGB Form XObject로 한 번 합성합니다. 균일 mask alpha는 group 상태로 병합되고, 가변 gradient/PNG 이미지 alpha는 네이티브 soft-mask 리소스를 재사용하며, 중첩 group은 그룹당 4,096개와 캡처 콘텐츠 16MiB 한도 안에서 변환된 클립, 리소스 소유권, 상한 링크 주석을 유지합니다 - XPS
VisualBrush는 inline/리소스 기반Canvas,Path,Glyphsvisual을 재귀 변환하고, 중첩/원격ResourceDictionaryscope를 해석하며, 절대Viewbox를 절대/상대Viewport로 매핑하고, 직접/타일/반사 배치에 걸쳐 하나의 상한 PDF Form XObject를 재사용합니다 - XPS
Canvas.Clip은 상한 축약 지오메트리, 로컬/원격StaticResourcePathGeometry값, 구조화된 line/Bézier/quadratic/arc figure, 지오메트리 transform, 빈 지오메트리,EvenOdd/NonZero채움 규칙이 있는 직접 property element를 받습니다. 중첩 클립은 네이티브 PDFW*/Wpath가 되고, 내비게이션 사각형은 활성 변환 클립 바운드와 교차하며, 파싱은 100,000 수치로 제한되고, malformed/특이 클립은 자식 visual이 그려지기 전에 fail-closed 됩니다 - XPS
Glyphs는 최대 65,536개 엄격Indices매핑을 받고, 일대다/다대일 cluster 진행, 명시적 em 백분위 advance, 가로/세로 오프셋, 홀수BidiLevel역방향 진행, solid 속성/property-element 채움, opacity, Unicode 추출, fail-closed malformed 입력 진단을 유지합니다. 단순 run은 네이티브 PDFTJ배열을 쓰고 큰 매핑 버퍼는 상환 선형 비용으로 늘어납니다 - 패키지
FontUri리소스는 TrueType/OpenType 프로그램, TTC 멤버 조각, XPS GUID 난독화 폰트를 지원합니다. 정확한 glyph ID, cmap 유도 run, cluster, advance, 오프셋, RTL 원점, 폰트 리소스 재사용, 내장 권한, 선택적 subsetting,ToUnicode추출 맵이 GDI 치환 없이 네이티브 PDF 폰트 데이터로 유지됩니다 - 변환된
Path/Glyphsvisual의 XPSFixedPage.NavigateUri는 지오메트리/메트릭 유도 바운드를 가진 네이티브 PDF 링크 주석이 됩니다. HTTP/HTTPS/mail 링크는 URI action으로 남고, 패키지 상대 페이지와 percent 디코딩된LinkTarget조각은 모든 페이지가 준비된 뒤 순방향/역방향 GoTo action이 됩니다 - Canvas
FixedPage.NavigateUri는 자손이 자체 URI를 공급할 때까지 모든 자손Path,Glyphs, 중첩 Canvas visual의 상속 대상이 됩니다. 범위 지정 대상은 중첩 재정의 뒤 복원되고, 각 visual의 지오메트리와 transform을 따르며, 활성 Canvas 클립에 계속 구속되고, 격리 opacity-group 캡처를 넘어 살아남고, 재사용VisualBrushForm 안에서는 억제된 채 유지됩니다 - 내비게이션은 링크 65,536개, URI당 8,192자로 제한되고, 공개 중 취소를 검사하며, 재사용
VisualBrush캡처 중 억제되고, 제어 문자, 안전하지 않은 scheme, 없는 대상, path/조각 불일치에서 거부됩니다 - 비표준
RelativeTransform, 미해석 행렬 리소스, Repeat/Reflect gradient spread, non-sRGB 보간, 가변 alpha 도색 brush, 색 변환, 이미지 선, 상대VisualBrushviewbox, 스타일 시뮬레이션, 옆으로 누운 glyph, 고급 stroke 속성은 명시적 진단으로 남습니다 - EPUB은
container.xml, manifest, spine 순서를 해석한 뒤 콜백 전용 패키지 리소스로 상한 HTML5 paged-media importer를 씁니다 - CBZ는 지원 이미지 항목을 인식하고, 결정론적 자연 파일명 순서를 적용하고, 설정된 이미지 DPI로 이미지당 한 페이지를 만듭니다
예산과 실패 격리
검증된 ZIP central-directory 스캔 한 번이 변환 전에 항목 수, 압축 바이트, 확장 바이트, 항목별, 중복 경로, 안전하지 않은 경로, 압축률 한도를 강제합니다
클래식 PKZIP ZipCrypto 항목은 ArchivePasswordCallback으로 자격 증명을 요청할 수 있습니다. 콜백은 소스 이름, 항목 이름, 1 기반 시도 번호를 받고, MaxPasswordAttempts는 재시도를 1~16으로 제한합니다
자격 증명과 부분 디코딩된 항목 바이트는 메모리에 머물다 시도 사이에 지워지고, 취소는 모든 콜백 전후로 검사되며, 콜백 누락, 자격 거부, 재시도 소진, 미지원 암호화는 fail-closed 됩니다
ZipCrypto는 현대의 authenticated encryption이 아니라 구식 암호 보호이며, non-ASCII 암호 바이트 관례는 ZIP 생산자마다 다를 수 있습니다
암호로 보호된 항목에는 Delphi 12 이상이 필요합니다. 이 버전의 System.Zip이 복호화 훅을 노출합니다. 더 오래된 Delphi 버전으로 빌드하면 핸들러는 암호화되지 않은 항목은 여전히 읽지만, 암호화된 항목은 ArchivePasswordCallback이 호출되기 전에 미지원으로 거부합니다
크기나 오프셋에 ZIP64 필드가 필요한 항목에는 Delphi 11 이상이 필요합니다. 그 이전 Delphi 버전은 이를 미지원으로 거부합니다
리소스, reflow, 페이지, 픽셀, DPI, 출력, 취소 한도는 변환·렌더링 내내 활성 상태를 유지하고, 출력 공개가 실패하면 seekable destination stream을 복원합니다
등록과 사용
var
Registry: THPDFDocumentHandlerRegistry;
Options: THPDFDocumentHandlerOptions;
Handled: IHPDFHandledDocument;
Info: THPDFDocumentHandlerInfo;
begin
Registry:= THPDFDocumentHandlerRegistry.Create;
try
Registry.RegisterStandardHandlers;
Options:= THPDFDocumentHandlerOptions.Default;
Options.ArchivePasswordCallback:= SupplyArchivePassword;
if Registry.OpenFromFile('book.epub', '', Options, Handled, Info) then
Handled.WritePDF(OutputStream, Options, Info);
finally
Registry.Free;
end;
end;