SVG Form XObject 가져오기

THotPDF.ImportSVGFormXObject는 SVG를 한 번 구문 분석하여 하나의 재사용 가능한 PDF Form XObject를 등록하고, THPDFPage.DrawSVGFormXObject는 이를 임의의 크기로 배치하며 선택적으로 페이지 링크 주석을 생성합니다

선언

function ImportSVGFormXObject(const Input: TBytes): AnsiString; overload;
function ImportSVGFormXObject(
  const Input: TBytes;
  out Statistics: THPDFSVGImportStatistics
): AnsiString; overload;

procedure DrawSVGFormXObject(
  const FormName: AnsiString;
  X, Y, W, H: Single;
  AddLinks: Boolean = True
);

벡터 프로파일

텍스트와 페인트 경계

텍스트는 단색 fill, bold 및 italic 변형, 글꼴 크기, 변환, 앵커링, 불투명도, 기하 클리핑을 지원합니다. gradient 텍스트 페인트는 fail closed이며, 각 text 또는 tspan 노드는 완전한 SVG 텍스트 흐름 레이아웃 엔진이 아니라 독립적으로 배치되는 run으로 남습니다

문서 텍스트 가져오기는 스타일 인식 glyph 검사와 폴백 레이아웃을 거치면서 선택된 bold 및 italic 서체를 유지하고, 측정된 잉크 bounds를 보존하며, 진짜 미해결 glyph은 거부합니다

UTF-8 텍스트와 16진 또는 10진 XML 문자 참조는 UTF-16 surrogate pair로 표현되는 보충 scalar를 포함해 Delphi와 FPC에서 같은 Unicode scalar를 보존합니다

텍스트 빌더가 없는 독립형 HPDFBuildSVGFormData overload는 측정된 Helvetica, Times, Courier Base 14 advance를 쓰고, 물음표로 대체하는 대신 WinAnsi 밖의 문자를 거부합니다. THPDFSVGTextRunBuilder가 있는 overload는 호출자가 제공한 내장 텍스트 form과 메트릭을 받습니다

gradient는 한도가 있는 벡터 밴드 근사를 유지합니다. 투명 리소스는 PDF 1.4가 필요하고 PDF/A-1 strict 프로파일에서는 거부됩니다

stroke 스타일

stroke-dasharray, stroke-dashoffset, stroke-miterlimit은 그룹과 조각 전용 use 인스턴스를 포함해 프레젠테이션 속성, 내장 CSS, 인라인 스타일, 상속을 통해 동작합니다

dash 배열은 쉼표나 공백으로 구분된 숫자와 지원되는 길이를 받습니다. 백분율은 sqrt((viewWidth * viewWidth + viewHeight * viewHeight) / 2)로 계산되는 정규화된 viewport 대각선을 사용합니다

홀수 길이 배열은 반복되어 짝수 길이 패턴을 만들고, 각 subpath는 패턴을 다시 시작하며, 양수나 음수 오프셋은 전체 패턴을 순환합니다. none과 전부 0인 배열은 단색 stroke가 됩니다

길이 0의 그려지는 dash는 round 또는 square cap 자국을 유지합니다. 평범한 단색 stroke, gradient stroke pattern, 클립, 마스크, isolated opacity group은 선택된 stroke 설정을 공유합니다

기본 miter limit은 4입니다. SVG 2의 0과 1 사이 값도 받아들이며 miter가 한도를 넘는 곳은 bevel join을 쓰고, gradient 및 transparency 리소스 bounds는 선택된 한도 안에서 날카로운 join을 유지합니다

네이티브 렌더링은 한도가 있는 dash 지오메트리로 오프셋, 소수 길이, GDI pen 한도보다 긴 배열을 유지하며, 적응형 곡선 평탄화와 세그먼트 경계를 넘는 연속 그려짐 join을 제공합니다

pathLength로 dash를 보정하는 것은 이 프로파일의 범위 밖입니다. 단색이 아닌 dash 배열과 pathLength를 함께 쓰는 도형은 보정되지 않은 길이를 조용히 쓰는 대신 fail closed합니다

stroke 의미론은 아래에서 설명하는 파서 및 렌더러 예산 안에서 SVG 2 stroke 모델을 따릅니다

텍스트 shaping 설정

내장 SVG 텍스트는 가져오는 문서의 ShapingFeatures, AutoShapeArabic, AutoShapeSyriac, AutoShapeNko, AutoShapeAdlam, AutoShapeHanifiRohingya 설정과 GSUB script·언어 선택, 폰트 폴백 체인을 함께 사용합니다

이 설정들은 호출자의 구성을 바꾸지 않으면서 측정된 advance와 생성된 텍스트 appearance 양쪽에 적용됩니다. shaping은 여전히 opt-in이며 요청된 glyph과 OpenType 테이블을 공급하는 폰트가 필요합니다

생성된 텍스트 appearance 하나는 최대 256개의 서로 다른 shaping 폰트 선택과 64MiB의 누적 raw 폰트 데이터를 받습니다. 지원되지 않는 폰트 데이터나 한도 초과는 가져오기를 원자적으로 실패시킵니다

객체 및 그룹 opacity

opacity는 자신 노드의 그려진 결과 전체에 한 번 적용되며 자손에 상속되지 않습니다. fill-opacity와 stroke-opacity는 각자 상속되는 페인트 값을 유지합니다

<g opacity="0.5"> 안에서 겹치는 두 개의 불투명 빨간 직사각형은 겹친 영역에서 똑같이 반투명하게 남고, 각자 반투명한 두 직사각형은 겹치는 곳이 더 어두워집니다

중첩 그룹은 순서대로 합성됩니다. 0.5인 바깥 opacity 두 겹은 불투명한 자손 위에서 실효 0.25가 되고, 자손의 명시적 opacity 1은 바깥 그룹을 무시하지 못합니다

루트 SVG 노드, 컨테이너, 링크, 조각 참조, 텍스트, 이미지, 도형은 같은 객체 opacity 경로를 씁니다. 조각 전용 use 참조는 인스턴스와 참조된 노드 양쪽 스타일을 유지합니다

fill과 stroke alpha는 반투명 객체 안에서 겹치는 지점까지 서로 독립이고, gradient stop alpha는 객체 합성 전에 해당 페인트 alpha와 결합합니다

클립과 mask 효과는 자손 페인트 설정으로 상속되지 않고 자신 노드에 속합니다. 링크 지오메트리는 배치 인식형으로 남고, isolated Form bounds는 변환된 stroke와 cap을 보수적으로 유지합니다

가져오기는 vector 연산자, 내장 텍스트 Form, 이미지 리소스, pattern, mask를 isolated group 안에 유지합니다. SVG 전체를 bitmap으로 평탄화하지는 않습니다

지원되는 동작은 SVG 객체 및 그룹 opacity 모델을 따릅니다. 이 페이지의 다른 텍스트·gradient·기하 한도도 그대로 적용됩니다

보안 및 예산

가져오기는 최대 8 MiB의 일반 또는 gzip 압축 SVG를 수용하고, 확장 입력을 32 MiB, main·pattern·mask·group 연산자를 합쳐 16 MiB, 노드를 4,096개, 중첩을 64단계, CSS 규칙을 256개, 경로 값을 100,000개로 제한합니다

내장 이미지는 엄격한 Base64 data:image/png;base64,와 data:image/jpeg;base64, 페이로드만 받으며, 최대 128개 이미지, 차원당 16,384픽셀, 모든 이미지를 합쳐 16,777,216 디코딩 픽셀로 제한됩니다. 차원은 네이티브 디코딩 전에 검사합니다

텍스트는 128개 run, run당 65,536 UTF-16 unit으로 제한되고, gradient stroke pattern, 마스크, isolated opacity group은 각각 128개 리소스로 제한됩니다. 재귀 mask 참조는 fail closed합니다

dash 배열은 홀수 배열 확장 전에 소스 항목 최대 64개를 가집니다. 양수 항목은 0.000001 사용자 unit 이상이어야 하고, 개별 길이와 정규화된 주기는 1,000,000,000을 넘을 수 없으며, 절대 오프셋은 1,000,000,000을 넘을 수 없고, miter limit은 0에서 1,000,000 사이여야 합니다

실제 중첩 transparency 효과는 네이티브 렌더러에 맞춰 SVG 트리 깊이 한도와 별개로 여덟 단계로 제한됩니다. transparency 효과 없는 평범한 중첩 컨테이너는 이 허용치를 소비하지 않습니다

transparency 효과 bounds는 유한해야 하고 각 좌표는 절댓값 1,000,000,000 안에 있어야 합니다. 이 좌표 프로파일을 벗어나는 가져오기는 group이나 mask 등록 전에 실패합니다

실패한 가져오기는 생성된 객체, 내장 텍스트 Form, registry 항목, 버전 및 device-color 상태를 롤백하므로, 호출자는 같은 문서를 재사용하고 바깥 graph transaction을 유지할 수 있습니다

스크립트, 이벤트 핸들러, DTD, foreignObject, 지원되지 않는 data 미디어 타입, JavaScript URL, 외부 페인트 또는 이미지 리소스 URL은 안전하게 실패(fail closed)합니다

url(#gradient), url(#clip) 및 href="#symbol"과 같은 조각 참조는 구문 분석된 문서 내에 유지되며 파일 또는 네트워크 접근을 절대 트리거하지 않습니다

통계

THPDFSVGImportStatistics는 노드, CSS 규칙, 그래디언트, gradient stroke, 마스크, 이미지, 링크, 텍스트 런, GroupCount로 세는 isolated opacity group, 생성된 main·pattern·mask·group 연산자 바이트를 합친 양을 보고합니다

HPDFBuildSVGFormData는 등록 전에 Form 콘텐츠, 고유 치수, 불투명도 리소스, 이미지 페이로드, pattern·mask 스트림, 텍스트 리소스 이름 또는 링크 메타데이터가 필요한 호출자를 위해 경계 파서를 THPDFSVGFormData 및 THPDFSVGLinkInfo를 통해 별도로 노출합니다. Groups는 isolated group 연산자 스트림과 보수적인 Form bounds를 제공합니다

예제

Document.BeginDoc;
FormName := Document.ImportSVGFormXObject(SVGBytes, Statistics);
if FormName = '' then
  raise Exception.Create('SVG import failed');

Document.CurrentPage.DrawSVGFormXObject(
  FormName,
  36,
  72,
  240,
  120,
  True
);

Document.CurrentPage.DrawSVGFormXObject(
  FormName,
  320,
  72,
  120,
  60,
  False
);

참조: THotPDF.ImportSVGFormXObject, THPDFPage.DrawSVGFormXObject, HTML5 Paged-Media 가져오기