SVG Form XObject Import

THotPDF.ImportSVGFormXObject parses SVG once and registers one reusable PDF Form XObject, whilst THPDFPage.DrawSVGFormXObject places it at any size and optionally creates page link annotations

Declaration

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
);

Vector profile

Text and paint boundaries

Text supports solid fill, bold and italic variants, font size, transforms, anchoring, opacity, and geometric clipping; gradient text paint fails closed, and each text or tspan node remains an independently positioned run rather than a complete SVG text-flow layout engine

Document text imports retain the selected bold and italic face through style-aware glyph checks and fallback layout, preserve measured ink bounds, and reject genuinely unresolved glyphs

UTF-8 text and hexadecimal or decimal XML character references preserve the same Unicode scalars on Delphi and FPC, including supplementary scalars represented by UTF-16 surrogate pairs

The standalone HPDFBuildSVGFormData overload without a text builder uses measured Helvetica, Times, and Courier Base 14 advances and rejects characters outside WinAnsi instead of substituting question marks; the overload with THPDFSVGTextRunBuilder accepts caller-provided embedded text forms and metrics

Gradients retain the bounded vector-band approximation; transparent resources require PDF 1.4 and are rejected by the PDF/A-1 strict profile

Stroke styles

stroke-dasharray, stroke-dashoffset, and stroke-miterlimit work through presentation attributes, embedded CSS, inline styles, and inheritance, including groups and fragment-only use instances

Dash arrays accept comma or whitespace-separated numbers and supported lengths; percentages use the normalised viewport diagonal, calculated as sqrt((viewWidth * viewWidth + viewHeight * viewHeight) / 2)

Odd-length arrays repeat to form an even-length pattern, each subpath restarts the pattern, and positive or negative offsets wrap around the complete pattern; none and all-zero arrays produce solid strokes

Zero-length painted dashes retain round or square cap marks; ordinary solid strokes, gradient stroke patterns, clips, masks, and isolated opacity groups share the selected stroke settings

The default miter limit is 4; SVG 2 values between 0 and 1 are accepted and use bevel joins where a miter would exceed the limit, whilst gradient and transparency resource bounds retain sharp joins within the selected limit

Native rendering uses bounded dash geometry to retain offsets, fractional lengths, and arrays longer than the GDI pen limit, with adaptive curve flattening and continuous painted joins across segment boundaries

Calibrating dashes with pathLength remains outside this profile; shapes combining a non-solid dash array with pathLength fail closed rather than silently using uncalibrated lengths

The stroke semantics follow the SVG 2 stroke model within the parser and renderer budgets described below

Text shaping configuration

Embedded SVG text uses the importing document's ShapingFeatures, AutoShapeArabic, AutoShapeSyriac, AutoShapeNko, AutoShapeAdlam, and AutoShapeHanifiRohingya settings, together with its GSUB script and language selections and font fallback chains

These settings apply during both measured advances and generated text appearances without changing the caller's configuration; shaping remains opt-in and requires a font that supplies the requested glyphs and OpenType tables

Each generated text appearance accepts at most 256 distinct shaping font selections and 64 MiB of cumulative raw font data; unsupported font data or an exceeded limit fails the import atomically

Object and group opacity

opacity applies once to the complete painted result of its node and is not inherited by descendants; fill-opacity and stroke-opacity retain their separate inherited paint values

Two overlapping opaque red rectangles inside <g opacity="0.5"> remain equally translucent in their overlap, whilst two independently translucent rectangles become darker where they overlap

Nested groups composite in order: two enclosing opacities of 0.5 yield an effective 0.25 over an opaque descendant, and a descendant's explicit opacity of 1 does not override its enclosing group

Root SVG nodes, containers, links, fragment references, text, images, and shapes use the same object-opacity path; fragment-only use references preserve both the instance and referenced node's styles

Fill and stroke alpha remain independent, including at their overlap inside a translucent object, and gradient stop alpha combines with the relevant paint alpha before object compositing

Clip and mask effects belong to their node rather than inheriting as descendant paint settings; link geometry remains placement-aware, and isolated Form bounds conservatively retain transformed strokes and caps

The importer retains vector operators, embedded text Forms, image resources, patterns, and masks inside isolated groups; it does not flatten the entire SVG into a bitmap

The supported behaviour follows the SVG object and group opacity model; the other bounded text, gradient, and geometry restrictions on this page still apply

Security and budgets

The importer accepts plain or gzip-compressed SVG up to 8 MiB, bounds expanded input to 32 MiB, combined main, pattern, mask, and group operators to 16 MiB, nodes to 4,096, nesting to 64 levels, CSS rules to 256, and path values to 100,000

Embedded images accept only strict Base64 data:image/png;base64, and data:image/jpeg;base64, payloads, with at most 128 images, 16,384 pixels per dimension, and 16,777,216 decoded pixels across all images; dimensions are checked before native decoding

Text is bounded to 128 runs and 65,536 UTF-16 units per run, and gradient stroke patterns, masks, and isolated opacity groups to 128 resources each; recursive mask references fail closed

Dash arrays contain at most 64 source entries before odd-array expansion; positive entries must be at least 0.000001 user units, individual lengths and the normalised cycle must not exceed 1,000,000,000, absolute offsets must not exceed 1,000,000,000, and miter limits must remain between 0 and 1,000,000

Actual nested transparency effects are limited to eight levels to match the native renderer, independently of the SVG tree-depth limit; ordinary nested containers without transparency effects do not consume this allowance

Transparency-effect bounds must be finite and each coordinate must remain within an absolute value of 1,000,000,000; imports outside this bounded coordinate profile fail before group or mask registration

Failed imports roll back generated objects, embedded text Forms, registry entries, and version and device-colour state, so callers can reuse the same document and preserve an enclosing graph transaction

Scripts, event handlers, DTDs, foreignObject, unsupported data media types, JavaScript URLs, and external paint or image resource URLs fail closed

Fragment references such as url(#gradient), url(#clip), and href="#symbol" remain inside the parsed document and never trigger file or network access

Statistics

THPDFSVGImportStatistics reports nodes, CSS rules, gradients, gradient strokes, masks, images, links, text runs, isolated opacity groups through GroupCount, and combined generated main, pattern, mask, and group operator bytes

HPDFBuildSVGFormData exposes the bounded parser separately through THPDFSVGFormData and THPDFSVGLinkInfo for callers that need Form content, intrinsic dimensions, opacity resources, image payloads, pattern and mask streams, text resource names, or link metadata before registration; Groups provides the isolated group operator streams and conservative Form bounds

Example

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
);

See also: THotPDF.ImportSVGFormXObject, THPDFPage.DrawSVGFormXObject, HTML5 Paged-Media Import