How to use librsvg from Python
It finally took me an entire installation of a new O/S and "locate .py | grep rsvg"(*) on my drive to find what I could not find via google : how to open an SVG file and draw it from PyCairo.
I had to upgrade my O/S (to Gnu/Linux Kubuntu 7.10) in order to get the latest Python-gnome2-* packages for, buried in there, is a Python wrapper for librsvg. I don't know why it's not a stand-alone wrapper like PyCairo, but that's the way it is.
The first demo is directly from the example I found on my drive.
(*) You can find this demo in /usr/share/doc/python-gnome2-desktop/examples/rsvg on *buntu Gutsy 7.10
#!/usr/bin/env python
import sys
import cairo
import rsvg
import gtk
BORDER_WIDTH = 10
def delete_cb(win, event):
gtk.main_quit()
def expose_cairo(win, event, svg):
x, y, w, h = win.allocation
cr = win.window.cairo_create()
cr.set_source_color(win.style.fg[win.state])
cr.rectangle(BORDER_WIDTH, BORDER_WIDTH,
w - 2*BORDER_WIDTH, h - 2*BORDER_WIDTH)
cr.set_line_width(5.0)
cr.set_line_join(cairo.LINE_JOIN_ROUND)
cr.stroke()
if svg != None:
matrix = cairo.Matrix(3,0,0,3,0, 0)
#cairo.Matrix.rotate( matrix, prop.rot )
cr.transform (matrix)
svg.render_cairo(cr)
return True
def main():
win = gtk.Window ()
win.connect("delete-event", delete_cb)
svg = None
if (len (sys.argv) > 1):
svg = rsvg.Handle(file=sys.argv[1])
else:
raise SystemExit("need svg file")
win.connect("expose-event", expose_cairo, svg)
print svg.props.width, svg.props.height, svg.props.em, svg.props.ex
win.show_all()
win.connect("destroy", lambda w: gtk.main_quit())
gtk.main()
if __name__ == '__main__':
main()
Writing an SVG file
I thought I'd see how writing out an SVG file from Cairo works, this is a short example.
import cairo
import rsvg
import math
fo = file('test.svg', 'w')
WIDTH, HEIGHT = 256, 256
## Prepare a destination surface -> out to an SVG file!
surface = cairo.SVGSurface (fo, WIDTH, HEIGHT)
## draw something - this taken from the web.
ctx = cairo.Context (surface)
ctx.scale (WIDTH/1.0, HEIGHT/1.0) # Normalizing the canvas
pat = cairo.LinearGradient (0.0, 0.0, 0.0, 1.0)
pat.add_color_stop_rgba (1, 0.7, 0, 0, 0.5) # First stop, 50% opacity
pat.add_color_stop_rgba (0, 0.9, 0.7, 0.2, 1) # Last stop, 100% opacity
ctx.rectangle (0, 0, 1, 1) # Rectangle(x0, y0, x1, y1)
ctx.set_source (pat)
ctx.fill ()
ctx.translate (0.1, 0.1) # Changing the current transformation matrix
ctx.move_to (0, 0)
ctx.arc (0.2, 0.1, 0.1, -math.pi/2, 0) # Arc(cx, cy, radius, start_angle, stop_angle)
ctx.line_to (0.5, 0.1) # Line to (x,y)
ctx.curve_to (0.5, 0.2, 0.5, 0.4, 0.2, 0.8) # Curve(x1, y1, x2, y2, x3, y3)
ctx.close_path ()
ctx.set_source_rgb (0.3, 0.2, 0.5) # Solid color
ctx.set_line_width (0.02)
ctx.stroke ()
## Do the deed.
surface.finish()
You can use 'svgdisplay' (if you have the binary), Inkscape, Firefox or the first demo app to view test.svg
A feedback loop
What happens when you feed the snake its tail?
import cairo
import rsvg
fo = file('test.svg', 'w')
WIDTH, HEIGHT = 256, 256
surface = cairo.SVGSurface (fo, WIDTH, HEIGHT)
ctx = cairo.Context (surface)
svg = rsvg.Handle(file="test2.svg")
svg.render_cairo(ctx)
surface.finish()
Well, it works! test.svg comes in and comes out as test2.svg. I don't think it proves anything, but it's fun.