[PyQt] SVG Glyphs in PyQt
Kyle Covington
kyle at red-r.org
Mon Sep 13 19:24:29 BST 2010
Recently I found that svg files generated by Cairo do not plot properly in
pyqt. The error comes from the use of glyphs which seem not to be shown in
pyqt (this might be wrong but I couldn't find any way of getting glyphs to
render).
I ended up writing a set of functions that will convert the glyphs to svg
paths so the file will render normally.
These could still use some improvements for rendering color and other style
elements (which are locked in the functions that I wrote).
These functions will need to be embedded in a class or have self removed to
be used elsewhere.
I just wanted people to have these so they wouldn't have to search high and
low like I did to find a way to render glyphs in pyqt.
Hope for the best,
Kyle
def convertSVG(self, file):
dom = self._getsvgdom(file)
print dom
self._switchGlyphsForPaths(dom)
self._commitSVG(file, dom)
def _commitSVG(self, file, dom):
f = open(file, 'w')
dom.writexml(f)
f.close()
def _getsvgdom(self, file):
print 'getting DOM model'
import xml.dom
import xml.dom.minidom as mini
f = open(file, 'r')
svg = f.read()
f.close()
dom = mini.parseString(svg)
return dom
def _getGlyphPaths(self, dom):
symbols = dom.getElementsByTagName('symbol')
glyphPaths = {}
for s in symbols:
pathNode = [p for p in s.childNodes if 'tagName' in dir(p) and
p.tagName == 'path']
glyphPaths[s.getAttribute('id')] =
pathNode[0].getAttribute('d')
return glyphPaths
def _switchGlyphsForPaths(self, dom):
glyphs = self._getGlyphPaths(dom)
use = self._getUseTags(dom)
for glyph in glyphs.keys():
print glyph
nl = self.makeNewList(glyphs[glyph].split(' '))
u = self._matchUseGlyphs(use, glyph)
for u2 in u:
print u2, 'brefore'
self._convertUseToPath(u2, nl)
print u2, 'after'
def _getUseTags(self, dom):
return dom.getElementsByTagName('use')
def _matchUseGlyphs(self, use, glyph):
matches = []
for i in use:
print i.getAttribute('xlink:href')
if i.getAttribute('xlink:href') == '#'+glyph:
matches.append(i)
print matches
return matches
def _convertUseToPath(self, use, strokeD):
## strokeD is a list of lists of strokes to make the glyph
newD = self.nltostring(self.resetStrokeD(strokeD,
use.getAttribute('x'), use.getAttribute('y')))
use.tagName = 'path'
use.removeAttribute('xlink:href')
use.removeAttribute('x')
use.removeAttribute('y')
use.setAttribute('style', 'fill: rgb(0%,0%,0%); stroke-width: 0.5;
stroke-linecap: round; stroke-linejoin: round; stroke: rgb(0%,0%,0%);
stroke-opacity: 1;stroke-miterlimit: 10; ')
use.setAttribute('d', newD)
def makeNewList(self, inList):
i = 0
nt = []
while i < len(inList):
start = i + self.listFind(inList[i:], ['M', 'L', 'C', 'Z'])
end = start + self.listFind(inList[start+1:], ['M', 'L', 'C',
'Z', '', ' '])
nt.append(inList[start:end+1])
i = end + 1
return nt
def listFind(self, x, query):
for i in range(len(x)):
if x[i] in query:
return i
return len(x)
def resetStrokeD(self, strokeD, x, y):
nsd = []
for i in strokeD:
nsd.append(self.resetXY(i, x, y))
return nsd
def resetXY(self, nl, x, y): # convert a list of strokes to xy coords
nl2 = []
for i in range(len(nl)):
if i == 0:
nl2.append(nl[i])
elif i%2: # it's odd
nl2.append(float(nl[i]) + float(x))
elif not i%2: # it's even
nl2.append(float(nl[i]) + float(y))
else:
print i, nl[i], 'error'
return nl2
def nltostring(self, nl): # convert a colection of nl's to a string
col = []
for l in nl:
templ = []
for c in l:
templ.append(str(c))
templ = ' '.join(templ)
col.append(templ)
return ' '.join(col)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20100913/6e43c5df/attachment.html>
More information about the PyQt
mailing list