Back to cookbook
Normally it's easier to use librsvg Python bindings from PyGTK, so you can import rsvg. When that's not an option, you may be able to bind just enough of it using the ctypes module to use it. Example for win32 follows.
# Very primitive librsvg bindings for win32
# no error checking, etc.
# but hey it works!
from ctypes import *
import cairo
l=CDLL('librsvg-2-2.dll')
g=CDLL('libgobject-2.0-0.dll')
g.g_type_init()
class PycairoContext(Structure):
_fields_ = [("PyObject_HEAD", c_byte * object.__basicsize__),
("ctx", c_void_p),
("base", c_void_p)]
class RsvgDimensionData(Structure):
_fields_ = [("width", c_int),
("height", c_int),
("em",c_double),
("ex",c_double)]
svghandlecache = {}
def renderSVG(ctx,filename,x,y):
if not filename in svghandlecache:
error=''
handle1 = l.rsvg_handle_new_from_file(filename,error)
svghandlecache[filename] = handle1
else:
handle1 = svghandlecache[filename]
#print error
#print handle1
#svgDim = RsvgDimensionData()
#l.rsvg_handle_get_dimensions(handle1,byref(svgDim))
#print 'SVG Dimensions: ',svgDim.width,'x',svgDim.height
#scaleX = float(WIDTH) / float(svgDim.width)
#scaleY = float(HEIGHT) / float(svgDim.height)
#scaleY = scaleX
#scaleX = 1
#scaleY = 1
#print scaleY
ctx.save()
#ctx.scale(scaleX, scaleY)
ctx.translate(x,y)
z = PycairoContext.from_address(id(ctx))
#print z.ctx
#print '>>',l.rsvg_handle_render_cairo(handle1, z.ctx)
l.rsvg_handle_render_cairo(handle1, z.ctx)
ctx.restore()
WIDTH, HEIGHT = 400, 400
# Setup Cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
#bg
bg = WebColour('#FFFFFF')
ctx.set_source_rgb(bg[0],bg[1],bg[2])
ctx.paint()
renderSVG(ctx,'ball.svg',0,0)
surface.write_to_png("test.png")
An extremely minimal wrapper for rsvg that can be used in windows as a drop-in replacement for rsvg might go as follows:
#some code to give rsvg.render_cairo(ctx) ability
#on windows.
import os
try:
import rsvg
WINDOWS=False
except ImportError:
print"Warning, could not import 'rsvg'"
if os.name == 'nt':
print "Detected windows, creating rsvg."
#some workarounds for windows
from ctypes import *
l=CDLL('librsvg-2-2.dll')
g=CDLL('libgobject-2.0-0.dll')
g.g_type_init()
class rsvgHandle():
class RsvgDimensionData(Structure):
_fields_ = [("width", c_int),
("height", c_int),
("em",c_double),
("ex",c_double)]
class PycairoContext(Structure):
_fields_ = [("PyObject_HEAD", c_byte * object.__basicsize__),
("ctx", c_void_p),
("base", c_void_p)]
def __init__(self, path):
self.path = path
error = ''
self.handle = l.rsvg_handle_new_from_file(self.path,error)
def get_dimension_data(self):
svgDim = self.RsvgDimensionData()
l.rsvg_handle_get_dimensions(self.handle,byref(svgDim))
return (svgDim.width,svgDim.height)
def render_cairo(self, ctx):
ctx.save()
z = self.PycairoContext.from_address(id(ctx))
l.rsvg_handle_render_cairo(self.handle, z.ctx)
ctx.restore()
class rsvgClass():
def Handle(self,file):
return rsvgHandle(file)
rsvg = rsvgClass()
This wrapper may be used to render svg's with the same syntax as rsvg. i.e.:
h = rsvg.Handle("box.svg")
s = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
ctx = cairo.Context(s)
h.render_cairo(ctx)