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
- Geometry includes paths with elliptical arcs, rectangles, rounded rectangles, circles, ellipses, lines, polylines, polygons, transforms, groups, symbols, and fragment-only
usereferences - Paint includes solid RGB colours, fill and stroke opacity, fill rules, line caps and joins, inherited dash arrays and offsets, miter limits, linear and radial gradient vector bands, gradient strokes backed by coloured tiling patterns, and clip paths
- Object and group opacity use isolated vector transparency Forms, so overlapping descendants composite before their enclosing opacity is applied
- Masks become transparency-group Form resources with PDF Alpha or Luminosity soft masks, including mask-region clipping,
maskUnits,maskContentUnits, and bounded nested mask references - CSS includes embedded type, class, ID, and compound selectors, presentation attributes, inline styles, specificity, source order, and
!important - Document imports embed Unicode font subsets and
ToUnicodemaps through the native authoring engine, use the configured font fallback chains, align fallback runs to a common alphabetic baseline, and calculate text anchoring from actual glyph advances - Embedded PNG and JPEG images become reusable Image XObjects, retain PNG alpha as a soft mask, and support
preserveAspectRatio="none", centredmeet, and centredslice - HTTP, HTTPS, and mail links are retained as placement-aware PDF link annotations without becoming part of the reusable Form stream
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