-
Notifications
You must be signed in to change notification settings - Fork 0
SVG Support
Dragon edited this page Jun 4, 2026
·
2 revisions
PhpPdf includes a built-in SVG renderer that converts SVG markup into native PDF drawing operations. You embed an SVG the same way you embed a raster image - via the Images API - and the renderer handles the rest. The SVG fills its placement rectangle; if you pass only w or only h to $page->image(), the other dimension is derived from the viewBox aspect ratio so the output is undistorted.
use DragonOfMercy\PhpPdf\Image;
// Inline SVG string.
$icon = Image::fromSvgString(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">'
. '<path d="M12 2L2 22h20z" fill="currentColor"/>'
. '</svg>',
);
$page->image($icon, x: 80, y: 20, w: 20);
// Base64 data URI (e.g. from a JS export).
$brand = Image::fromBase64('data:image/svg+xml;base64,...');
$page->image($brand, x: 20, y: 80, w: 60);- All path commands:
M,L,H,V,C,S,Q,T,A,Zand their lowercase relative variants. - Basic shapes:
<rect>(with optionalrx/ryrounded corners),<circle>,<ellipse>,<line>,<polyline>,<polygon>.
- Transforms:
matrix(),translate(),scale(),rotate()(with optional center point),skewX(),skewY(); composition is left-to-right. -
viewBoxon the root<svg>element: the SVG fills its placement rectangle. Passing onlywor onlyhto$page->image()derives the other side from the viewBox aspect. - Groups (
<g>),<defs>+<use>references with cycle detection.
- Solid fill and stroke: 147 named CSS colors,
#abc/#aabbcchex,rgb(),rgba(),currentColor. -
stroke-width,stroke-linecap,stroke-linejoin,stroke-miterlimit. -
stroke-dasharray+stroke-dashoffset. -
fill-rule(nonzero|evenodd). -
fill-opacity,stroke-opacity,opacity(multiplicative).
-
<linearGradient>and<radialGradient>:objectBoundingBoxanduserSpaceOnUseunits,gradientTransform,hrefstop inheritance. - Multi-stop gradients on fill and stroke.
-
spreadMethodpad(default),reflect, andrepeat- all honored by rewriting non-pad gradients into an equivalent pad-mode gradient with extended coordinates and replicated stops. - Per-stop
stop-opacity(including fade-to-transparent): rendered as a coupled grayscale alpha shading wrapped in a PDF/SMask /S /Luminositysoft mask Form. Works for linear, radial, fill, and stroke.
- Presentation attributes AND inline
style="..."(inline > direct > inherited precedence). - CSS: internal
<style>stylesheets with type, class, id, universal, and compound selectors (comma-separated groups), cascaded by specificity then source order.
- Embedded raster
<image>via PNG or JPEG data URI:x/y/width/height,preserveAspectRatio(meet/slice/none),transform,opacity, and intra-SVG dedup of identical data URIs.
-
<text>and<tspan>rendered as real, selectable PDF text using the 14 standard fonts. -
font-family(generic familiesserif/sans-serif/monospaceand the standard family names),font-weight(bold),font-style(italic). -
font-size(unitless / px / pt / em / %). -
text-anchor(start/middle/end). -
x/y/dx/dypositioning. - Fill and stroke (solid colors), opacity, transforms.
- Font property inheritance through
<g>. - Custom TTF/OTF fonts registered in the document via
Document::registerFontFamily()are resolved byfont-familyname and automatically subsetted.
-
clip-path="url(#id)"referencing a<clipPath>withclipPathUnitsuserSpaceOnUseorobjectBoundingBox. - Applies to any element (shape, group, image, text).
- Clip content: basic shapes plus
<use>, withclip-rulenonzero/evenodd. - The clip is the union of the clip children, emitted via the native PDF clip (
W/W*).
-
fill="url(#pat)"/stroke="url(#pat)"rendered via PDF native/PatternType 1tiling. -
patternUnitsuserSpaceOnUseorobjectBoundingBox(default),patternTransform,hrefattribute inheritance, optionalviewBox. - Pattern children: basic shapes,
<g>, and<use>references.
-
<symbol viewBox="..." preserveAspectRatio="...">referenced via<use href="#id" x y width height>. - Use's
width/height(defaulting to the symbol'sviewBoxdimensions) andpreserveAspectRatio(meet/slice/ align) determine the viewBox-to-use-box matrix. - Symbol elements never render directly (defs-only).
-
marker-start/marker-mid/marker-endand themarkershorthand on<line>,<polyline>,<polygon>,<path>. -
<marker viewBox markerWidth markerHeight refX refY markerUnits orient>withmarkerUnitsstrokeWidth(default) oruserSpaceOnUse. -
orient: numeric angle,auto, orauto-start-reverse. - Tangents computed per shape: line endpoints, polyline/polygon bisectors at vertices, path with bezier endpoint tangents.
-
mask="url(#id)"rendered as a PDF luminance soft mask (/SMaskwith/S /Luminosity). -
maskUnitsandmaskContentUnitsuserSpaceOnUseorobjectBoundingBox(defaults per SVG spec). - Mask region
x/y/width/heighthonored. - Mask children: basic shapes,
<g>,<use>,<image>,<text>.
-
filter="url(#id)"rendered via a hybrid raster approach: the filtered region is rasterized to an embedded DeviceRGB image (+ DeviceGray/SMaskalpha channel); the rest of the document stays vector. -
filterUnitsobjectBoundingBox(default) anduserSpaceOnUse. - Supported primitives:
feGaussianBlur,feOffset,feFlood,feMerge,feBlend(normal/multiply/screen/darken/lighten),feComposite(over/in/out/atop/xor/arithmetic),feColorMatrix(matrix/saturate/hueRotate/luminanceToAlpha),feDropShadow. -
SourceGraphic/SourceAlphainputs and namedresultchaining. - Rasterized content inside a filter: shapes, paths, solid fills, opacity, groups /
<use>, linear / radial gradients, and PNG<image>. -
<text>inside a filtered element is drawn as sharp, unfiltered vector text on top (a documented approximation). - Resolution defaults to ~300 DPI relative to the SVG
viewBoxunits, capped at 2000 px per side. Tune it viaDocument::setSvgFilterResolution(int $dpi).
- Per-character positioning (
x="10 20 30"lists),letter-spacing/word-spacing,dominant-baseline/baseline-shift,xml:space="preserve". Characters outside WinAnsi encoding render as?. - Mesh gradients.
-
<text>/<image>inside a<pattern>,patternContentUnits=objectBoundingBox,preserveAspectRatioon a pattern'sviewBox, nested paint-server fills inside pattern children, and uncolored (PaintType 2) tiling. -
fill="url(#x)"referencing an unsupported paint server falls back to black per spec. - Filter primitives not yet implemented:
feTile,feImage,feMorphology,feConvolveMatrix,feTurbulence,feDisplacementMap,feDiffuseLighting,feSpecularLighting. NestedclipPath/mask/pattern/filterinside a filtered element are ignored. -
color-interpolation-filters="sRGB"is not honored (filters always run in linearRGB). -
BackgroundImage/BackgroundAlpha/FillPaint/StrokePaintfilter inputs (treated as transparent). - JPEG
<image>inside a filter requiresext-gd; without it that image is skipped. -
<text>as clip content; nestedclip-pathon children of a<clipPath>. -
transformon the same element that also carriesclip-path: the transform applies to content but not to the clip region (resolved in the parent user space). CSSclip-pathshape functions (inset(),circle(),polygon()); onlyurl(#id)references are honored. - Nested markers (inner markers stripped). Markers on
<rect>/<circle>/<ellipse>. Markers inside a<symbol>. -
preserveAspectRatio(meet / slice / align) on the root<svg>element: the SVG always fills its placement rectangle. (preserveAspectRatioon<image>elements is supported.) - CSS combinators (
g rect,g > rect), pseudo-classes / elements, and attribute selectors in<style>. - CSS
!important, the CSStransformproperty (use the SVGtransformattribute), at-rules (@media,@import,@font-face), and external stylesheets. - Symbol's intrinsic
width/heightattributes (use'swidth/heightis required to size the symbol). - Scripts, animations,
<foreignObject>. -
<image>supports only PNG / JPEG data URIs. Externalhref(file paths or URLs) is ignored. Other data URI formats (GIF, WebP, nested SVG) are ignored. Images with non-positive width or height are ignored.
| Limit | Value |
|---|---|
| SVG document size | 5 MiB raw |
| Nesting depth | 32 levels |
| Element count | 50 000 elements |
<use> cycle |
Any cycle raises immediately |
Missing viewBox
|
When both width and height are also absent |
| Malformed XML | Root must be <svg> in the SVG namespace |
-
Examples - see
example-svg-poster.php - Images
- Internals: Images and SVG
- Barcodes and QR Codes
- Standalone SVG Barcode Export
MIT licensed. Source on GitHub - if phppdf helps you, you can buy me a coffee.