Skip to content

Commit

Permalink
Refactor SVG rendering API
Browse files Browse the repository at this point in the history
  • Loading branch information
kklemon committed May 27, 2024
1 parent 9f58a8c commit aea62ad
Showing 1 changed file with 46 additions and 16 deletions.
62 changes: 46 additions & 16 deletions src/penai/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,25 @@


class BaseSVGRenderer(abc.ABC):
"""Base class for SVG renderers.
We distinguish between the representation of SVGs given by their content and as a file,
since SVG engines could inherently work with either representation.
"""

@abc.abstractmethod
def render(
def render_svg(
self,
svg: str | PathLike,
svg_string: str,
width: int | None = None,
height: int | None = None,
) -> Image.Image:
pass

@abc.abstractmethod
def render_svg_file(
self,
svg_path: PathLike,
width: int | None = None,
height: int | None = None,
) -> Image.Image:
Expand Down Expand Up @@ -105,16 +120,15 @@ def _render_svg(self, svg_path: str) -> Image.Image:

return Image.open(buffer).convert("RGB")

def render(
def render_svg(
self,
svg: str | Path,
svg_string: str,
width: int | None = None,
height: int | None = None,
) -> Image.Image:
"""Render an SVG file or string to an image.
"""Render the content of an SVG file to an image.
:param svg: The SVG file or string to render. If an instance of `Path` is passed, the file is read and rendered.
Otherwise, the input is treated as an SVG string.
:param svg: The content of the SVG file to render.
:param width: The width of the rendered image. Currently not supported.
:param height: The height of the rendered image. Currently not supported.
"""
Expand All @@ -123,15 +137,31 @@ def render(
"Specifying width or height is currently not supported by ChromeSVGRenderer",
)

if isinstance(svg, Path):
path = svg.absolute()
with NamedTemporaryFile(prefix="penpy_", suffix=".svg", mode="w") as file:
file.write(svg_string)
return self._render_svg(Path(file.name).as_uri())

def render_svg_file(
self,
svg_path: PathLike,
width: int | None = None,
height: int | None = None,
) -> Image.Image:
"""Render an SVG file to an image.
:param svg_path: Path to the SVG file to render.
:param width: The width of the rendered image. Currently not supported.
:param height: The height of the rendered image. Currently not supported.
"""
if width or height:
raise NotImplementedError(
"Specifying width or height is currently not supported by ChromeSVGRenderer",
)

if not path.exists():
raise FileNotFoundError(f"{path} does not exist")
svg_path = Path(svg_path)
path = svg_path.absolute()

return self._render_svg(path.as_uri())
else:
with NamedTemporaryFile(prefix="penpy_", suffix=".svg", mode="w") as file:
file.write(svg)
if not path.exists():
raise FileNotFoundError(f"{path} does not exist")

return self._render_svg(Path(file.name).as_uri())
return self._render_svg(path.as_uri())

0 comments on commit aea62ad

Please sign in to comment.