A pure-Python library for reading and converting SVG files to ReportLab Graphics drawings
Core functionality for converting SVG files and streams to ReportLab Drawing objects. This module handles SVG parsing, processing, and conversion to ReportLab's graphics format.
Converts SVG files to ReportLab Drawing objects with support for various input formats including compressed SVG files.
def svg2rlg(path, resolve_entities=False, **kwargs):
"""
Convert an SVG file to an RLG Drawing object.
Parameters:
- path: str, pathlib.Path, or file-like object - SVG file path or stream
- resolve_entities: bool - Enable XML entity resolution for external entities
- **kwargs: Additional arguments passed to SvgRenderer
Returns:
Drawing: ReportLab Drawing object or None if conversion fails
"""Usage Examples:
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
import io
# Convert from file path
drawing = svg2rlg("diagram.svg")
# Convert from pathlib.Path
from pathlib import Path
svg_path = Path("graphics/chart.svg")
drawing = svg2rlg(svg_path)
# Convert from compressed SVG
drawing = svg2rlg("compressed_graphic.svgz") # Automatically decompressed
# Convert from file-like object
svg_content = '<svg>...</svg>'
drawing = svg2rlg(io.StringIO(svg_content))
# Enable entity resolution for SVGs with external references
drawing = svg2rlg("complex.svg", resolve_entities=True)
# Use converted drawing
if drawing:
renderPDF.drawToFile(drawing, "output.pdf")Low-level function for loading and parsing SVG files using lxml.
def load_svg_file(path, resolve_entities=False):
"""
Load and parse an SVG file using lxml.
Parameters:
- path: str or file-like object - SVG file path or stream
- resolve_entities: bool - Enable XML entity resolution
Returns:
Element: Parsed SVG root element or None if parsing fails
"""Main renderer class that converts SVG DOM to ReportLab Drawing objects.
class SvgRenderer:
"""
Renderer that renders an SVG file on a ReportLab Drawing instance.
"""
def __init__(self, path, color_converter=None, parent_svgs=None, font_map=None):
"""
Initialize SVG renderer.
Parameters:
- path: str - Source SVG file path
- color_converter: callable, optional - Custom color conversion function
- parent_svgs: list, optional - Parent SVG chain for circular reference detection
- font_map: FontMap, optional - Custom font mapping instance
"""
def render(self, svg_root):
"""
Render SVG root element to ReportLab Drawing.
Parameters:
- svg_root: Element - Parsed SVG root element
Returns:
Drawing: ReportLab Drawing object
"""Converts SVG attributes to ReportLab format.
class Svg2RlgAttributeConverter:
"""A concrete SVG to RLG attribute converter."""
def __init__(self, color_converter=None, font_map=None):
"""
Initialize attribute converter.
Parameters:
- color_converter: callable, optional - Custom color conversion function
- font_map: FontMap, optional - Font mapping instance
"""
def convertLength(self, svgAttr, em_base=12, attr_name=None, default=0.0):
"""
Convert SVG length to points.
Parameters:
- svgAttr: str - SVG length attribute value
- em_base: float - Base size for 'em' units
- attr_name: str, optional - Attribute name for context
- default: float - Default value if conversion fails
Returns:
float: Length in points
"""Converts SVG shape elements to ReportLab shapes.
class Svg2RlgShapeConverter:
"""Converts SVG shape elements to ReportLab shapes."""
def __init__(self, path, attrConverter):
"""
Initialize shape converter.
Parameters:
- path: str - Source SVG file path
- attrConverter: Svg2RlgAttributeConverter - Attribute converter instance
"""
def get_handled_shapes(self):
"""
Get list of SVG element names this converter can handle.
Returns:
list: SVG element names
"""Path object that never receives stroke width regardless of style properties.
class NoStrokePath(Path):
"""
Path object that never gets stroke width.
Useful for workaround of ReportLab rendering issues.
"""
def __init__(self, *args, copy_from=None, **kwargs):
"""
Initialize NoStrokePath.
Parameters:
- *args: Path constructor arguments
- copy_from: Path, optional - Path to copy properties from
- **kwargs: Additional keyword arguments
"""Path object for SVG clipping operations.
class ClippingPath(Path):
"""Path object for SVG clipping operations."""
def __init__(self, *args, **kwargs):
"""Initialize ClippingPath with standard Path arguments."""Exception raised when circular references are detected in SVG files.
class CircularRefError(Exception):
"""Exception for circular reference detection in SVG processing."""Adjusts coordinate points to work around ReportLab's handling of zero-size shapes.
def nudge_points(points):
"""
Nudge first coordinate if all coordinate pairs are identical.
Works around ReportLab's decision to hide shapes of size zero.
Parameters:
- points: list - List of coordinate values [x1, y1, x2, y2, ...]
"""Copies properties from one ReportLab shape to another.
def copy_shape_properties(source_shape, dest_shape):
"""
Copy properties from source shape to destination shape.
Parameters:
- source_shape: Shape - Source ReportLab shape
- dest_shape: Shape - Destination ReportLab shape
"""Applies patches to ReportLab for better SVG compatibility.
def monkeypatch_reportlab():
"""Apply patches to ReportLab for better SVG compatibility."""Named tuple for bounding box representation.
Box = namedtuple('Box', ['x', 'y', 'width', 'height'])Usage:
from svglib.svglib import Box
# Create bounding box
bbox = Box(x=10, y=20, width=100, height=50)
print(f"Box: {bbox.x}, {bbox.y}, {bbox.width}x{bbox.height}")Install with Tessl CLI
npx tessl i tessl/pypi-svglib