Skip to content

Instantly share code, notes, and snippets.

@superlou
Created July 9, 2013 13:06
Show Gist options
  • Save superlou/5957173 to your computer and use it in GitHub Desktop.
Save superlou/5957173 to your computer and use it in GitHub Desktop.
Cairo Inkscape Rendering
import wx
import rsvg
import numpy
try:
import wx.lib.wxcairo
import cairo
haveCairo = True
except ImportError:
haveCairo = False
from lxml import etree as ET
nsmap = {
'sodipodi': 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
'cc': 'http://web.resource.org/cc/',
'svg': 'http://www.w3.org/2000/svg',
'dc': 'http://purl.org/dc/elements/1.1/',
'xlink': 'http://www.w3.org/1999/xlink',
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'inkscape': 'http://www.inkscape.org/namespaces/inkscape'
}
class ComponentFrame(wx.Frame):
def __init__(self, parent, id, title, pos, size):
wx.Frame.__init__(self, parent, id, title, pos, size)
self.panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.HORIZONTAL)
component = SvgComponent(self.panel)
vbox.Add(component, 1, wx.EXPAND | wx.ALL, 10)
self.panel.SetSizer(vbox)
self.Show(True)
class SvgComponent(wx.PyControl):
def __init__(self, parent, label="",
id=wx.ID_ANY,
pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.NO_BORDER, validator=wx.DefaultValidator,
name="CustomMeter"):
wx.PyControl.__init__(self, parent, id, pos, size, style, validator, name)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
if not haveCairo or not wx.GraphicsRenderer.GetCairoRenderer():
print "Cairo unavailable!"
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self)
dc.Clear()
self.Draw(dc)
def Draw(self, dc):
width, height = self.GetClientSize()
if not width or not height:
return
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = wx.lib.wxcairo.ContextFromDC(dc)
ctx.scale(width/300.0, height/300.0)
with open('demo.svg', 'r') as content_file:
xml_data = content_file.read()
xml_data = self.RotateNeedle(xml_data)
svg = rsvg.Handle(data=xml_data)
svg.render_cairo(ctx)
def OnSize(self, event):
self.Refresh(True)
def OnEraseBackground(self, event):
pass
def DoGetBestSize(self):
"""
Overridden base class virtual. Determines the best size of the control
based on the label size, the bitmap size and the current font.
"""
best = wx.Size(400, 400)
self.CacheBestSize(best)
return best
def RotateNeedle(self, xml):
tree = ET.fromstring(xml)
needle = tree.xpath("//svg:path[@id='needle']", namespaces=nsmap)[0]
needle_axis = tree.xpath("//svg:path[@id='needle_axis']", namespaces=nsmap)
#needle.set('transform', 'rotate(90, 161, 885)') manually determined
print ET.tostring(needle)
return ET.tostring(tree)
if __name__ == '__main__':
app = wx.App()
frame = ComponentFrame(None, wx.ID_ANY, 'test rsvg', (200, 200), (400, 400))
app.MainLoop()
Display the source blob
Display the rendered blob
Raw
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="demo.svg">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient3762">
<stop
style="stop-color:#00d2fa;stop-opacity:1"
offset="0"
id="stop3764" />
<stop
style="stop-color:#00546a;stop-opacity:1"
offset="1"
id="stop3766" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3762"
id="linearGradient3768"
x1="122.53993"
y1="122.13509"
x2="195.07774"
y2="122.13509"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3988302,0.91702479,-0.91702479,0.3988302,253.69603,663.49066)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3762-7"
id="linearGradient3768-1"
x1="122.53993"
y1="122.13509"
x2="195.07774"
y2="122.13509"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3988302,0.91702479,-0.91702479,0.3988302,253.69603,663.49066)" />
<linearGradient
inkscape:collect="always"
id="linearGradient3762-7">
<stop
style="stop-color:#00d2fa;stop-opacity:1"
offset="0"
id="stop3764-4" />
<stop
style="stop-color:#00546a;stop-opacity:1"
offset="1"
id="stop3766-0" />
</linearGradient>
<linearGradient
y2="122.13509"
x2="195.07774"
y1="122.13509"
x1="122.53993"
gradientTransform="matrix(0.02444215,0.99970124,-0.99970124,0.02444215,327.14682,719.73364)"
gradientUnits="userSpaceOnUse"
id="linearGradient3006"
xlink:href="#linearGradient3762-7"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="137.03355"
inkscape:cy="162.74557"
inkscape:document-units="px"
inkscape:current-layer="svg2"
showgrid="false"
inkscape:window-width="856"
inkscape:window-height="638"
inkscape:window-x="1294"
inkscape:window-y="21"
inkscape:window-maximized="0"
inkscape:showpageshadow="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-29,-763.36218)">
<path
sodipodi:type="arc"
style="fill:#008000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:10;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path2985"
sodipodi:cx="172"
sodipodi:cy="164"
sodipodi:rx="121"
sodipodi:ry="121"
d="M 293,164 C 293,230.82645 238.82645,285 172,285 105.17355,285 51,230.82645 51,164 51,97.173545 105.17355,43 172,43 c 66.82645,0 121,54.173545 121,121 z"
transform="translate(-8,731.36218)" />
<path
style="fill:#008000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:10;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
d="m 313,986.36218 c 0,36.45082 -29.54921,66.00002 -66,66.00002 -36.45079,0 -66,-29.5492 -66,-66.00002 0,-36.4508 29.54921,-66 66,-66 36.45079,0 66,29.5492 66,66 z"
id="path2987"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 176,792.36218 133,0"
id="path2990"
inkscape:connector-curvature="0" />
<path
style="fill:url(#linearGradient3006);fill-opacity:1;stroke:none"
d="M 256.07998,881.519 C 256.07998,881.519 160.28886,820.46425 161.22055,858.57109 161.22055,858.57109 161.88684,885.82256 162.52234,911.81481 163.15783,937.80703 256.07998,881.519 256.07998,881.519 z"
id="needle"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc"
inkscape:label="#path3760"
inkscape:transform-center-x="-47.433091" />
<path
sodipodi:type="arc"
style="fill:#ffcd29;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="needle_axis"
sodipodi:cx="184"
sodipodi:cy="224"
sodipodi:rx="67"
sodipodi:ry="67"
d="M 251,224 A 67,67 0 1 1 117,224 67,67 0 1 1 251,224 z"
transform="matrix(0.09608209,0,0,0.09608209,144.88339,862.56649)" />
</g>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment