Menu

Tree [bc49e9] master /
 History

HTTPS access


File Date Author Commit
 README.md 2012-12-12 Andrew Danger Lyon Andrew Danger Lyon [776bab] 755 -> 644
 cl-svg-polygon.asd 2019-11-22 Arseny Arseny [495fa2] Tweaked for compilation on my system
 matrix.lisp 2019-11-22 Arseny Arseny [495fa2] Tweaked for compilation on my system
 package.lisp 2012-12-12 Andrew Danger Lyon Andrew Danger Lyon [776bab] 755 -> 644
 paths.lisp 2019-11-23 Arseny Slobodyuk Arseny Slobodyuk [a5a203] Light arc fix
 svg.lisp 2021-01-24 Arseniy Slobodyuk Arseniy Slobodyuk [bc49e9] Added label to the list of saved parameters
 transformations.lisp 2012-12-12 Andrew Danger Lyon Andrew Danger Lyon [776bab] 755 -> 644
 vector.lisp 2012-12-12 Andrew Danger Lyon Andrew Danger Lyon [776bab] 755 -> 644

Read Me

cl-svg-polygon

(Or svgp for short). This is a pure-lisp library that takes an SVG file and generates, for each SVG object, a
set of points that outline the object. It approximates curves based on a given resolution: the
higher the resolution, the more accurate the curve is (this works for paths, circles, ellipses).
This package relies on xmls to parse the SVG file's XML.

cl-svg-polygon also calculates transformations within the groups and objects in the file to the
final points/holes returned for each polygon.

Usage

Parse the contents of an SVG string:

(svgp:parse-svg-string "...")

Parse the contents of an SVG file:

(svgp:parse-svg-file "drawing.svg")   ; wraps around parse-svg-string

Both these functions return a flat list of SVG objects (plists):

'((:type "path"
   :group ("layer1" "ghostie" "g221")
   :d "m -397.936,580.106 c -0.294,-1.122 -1.382,-2.535 -2.729,-2.046 -1.52,0.551 -2.286,1.984 ..."
   :style "fill:#ffffff"
   :point-data #((400.94077 477.2889) (400.82928 476.94577) (400.67334 476.5983) (400.4762 476.25974) ...)
   :holes (#((400.94077 477.2889) (400.82928 476.94577) (400.67334 476.5983) (400.4762 476.25974) ...))
   :meta (:disconnected nil)) ...)

Call parameters

Here are the keyword parameters you can give the the (parse-svg-* ...) functions:

:curve-resolution         ; (integer) How many points each curve will use. Higher == more accurate
:scale                    ; (list) Apply a scale vector '(x y) to ALL points/holes in all
                          ; objects returned. Can be used with a negative value to invert the y axis.
:save-attributes          ; (list) This list is appended to the list of attributes to save
                          ; from each object, allowing you to grab custom data for each object.
:group-id-attribute-name  ; (string, default "id") Which parameter in the <g> tag to pull
                          ; the group id from. This is useful for programs like Inkscape
                          ; that use "label" instead of "id." If no data is available for the
                          ; given field, falls back on the "id" field.

Grouping

Even though the objects in the file may be in group hierarchies, they are returned as a flat list.
The :group key contains each group the object is a member of, ordered from the top down. This
can be used to create hierarchies among the objects later on if needed.

Polygon data

The :point-data key contains the outline of the polygon as a vector of points #((x1 y1) (x2 y2) ...)
and :holes contains holes that are cut out of the polygon.

Object meta information

Objects can return meta information in the final result under the :meta key. Currently, this is
only used for paths, which return whether or not the path is "disconnected," meaning it's a set of
line segments such that the end does not join up with the beginning (if :disconnected t).
This can be useful in determining whether or not to bother with triangulation.

More object types may use meta later on.

Philosophy

The idea behind this library is that SVG files can be used to describe objects that will be sent
to OpenGL (or any other display system). With something like Illustrator or Inkscape, you could
have an instant level editor for a game.

In addition to polygons/holes, it tries to return as much relevant data about each object as
possible (groups, styles, meta info) so you can make decisions about the object later on in your
application.

Triangulation

In the spirit of doing one thing well, this library focuses no attention on turning the polygons
it churns out into triangles. Please see glu-tessellate
for a triangulation library that wraps around GLU's tessellation system.
glu-tessellate triangulates (with holes) and
supports a number of winding methods.

Limitations

There are a few limitations with this library:

  • Line/polyline types are ignored when parsing. This fix is coming soon.
  • Strokes are not honored. So the point list returned for a path with two points and a stroke
    will just be two points (with :disconnected t) instead of a connected polygon shape representing
    what the real object looks like. Since stroking is technically up to the drawer, it's unlikely that
    I'll add in default support for this, however I'll probably add an option in the future to render
    strokes as part of the polygon in case you don't want to deal with it in the app =]. The meta info
    for the polygon would then specify whether or not it was a stroked polygon vs an actual polygon.
    This change would go hand in hand with supporting lines as well.
  • Clipping/masking are not supported. Fix also coming soon, especially since masks appear in many
    of the files I'm parsing. For now, they are just ignored.

Notes

I do my best to keep cl-svg-polygon up to date with the SVG spec.
I do plan on fixing the limitations in a timely manner. If you see any bugs or
problems with this library, please feel free to contact me or fix it and issue
a pull request.

Thanks!

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.