<span class="Apple-style-span" style="font-family: verdana, geneva, helvetica, arial, sans-serif; font-size: 13px; border-collapse: collapse; ">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). <br>
<br>I ended up writing a set of functions that will convert the glyphs to svg paths so the file will render normally. <br><br>These could still use some improvements for rendering color and other style elements (which are locked in the functions that I wrote). <br>
<br>These functions will need to be embedded in a class or have self removed to be used elsewhere. <br><br>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. <br>
<br>Hope for the best, <br>Kyle <br><br> def convertSVG(self, file): <br> dom = self._getsvgdom(file) <br> print dom <br> self._switchGlyphsForPaths(dom) <br> self._commitSVG(file, dom) <br>
def _commitSVG(self, file, dom): <br> f = open(file, 'w') <br> dom.writexml(f) <br> f.close() <br> def _getsvgdom(self, file): <br> print 'getting DOM model' <br> import xml.dom <br>
import xml.dom.minidom as mini <br> f = open(file, 'r') <br> svg = f.read() <br> f.close() <br> dom = mini.parseString(svg) <br> return dom <br> def _getGlyphPaths(self, dom): <br>
symbols = dom.getElementsByTagName('symbol') <br> glyphPaths = {} <br> for s in symbols: <br> pathNode = [p for p in s.childNodes if 'tagName' in dir(p) and p.tagName == 'path'] <br>
glyphPaths[s.getAttribute('id')] = pathNode[0].getAttribute('d') <br> return glyphPaths <br> def _switchGlyphsForPaths(self, dom): <br> glyphs = self._getGlyphPaths(dom) <br> use = self._getUseTags(dom) <br>
for glyph in glyphs.keys(): <br> print glyph <br> nl = self.makeNewList(glyphs[glyph].split(' ')) <br> u = self._matchUseGlyphs(use, glyph) <br> for u2 in u: <br>
print u2, 'brefore' <br> self._convertUseToPath(u2, nl) <br> print u2, 'after' <br> <br> def _getUseTags(self, dom): <br> return dom.getElementsByTagName('use') <br>
def _matchUseGlyphs(self, use, glyph): <br> matches = [] <br> for i in use: <br> print i.getAttribute('xlink:href') <br> if i.getAttribute('xlink:href') == '#'+glyph: <br>
matches.append(i) <br> print matches <br> return matches <br> def _convertUseToPath(self, use, strokeD): <br> ## strokeD is a list of lists of strokes to make the glyph <br> newD = self.nltostring(self.resetStrokeD(strokeD, use.getAttribute('x'), use.getAttribute('y'))) <br>
use.tagName = 'path' <br> use.removeAttribute('xlink:href') <br> use.removeAttribute('x') <br> use.removeAttribute('y') <br> 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; ') <br>
use.setAttribute('d', newD) <br> def makeNewList(self, inList): <br> i = 0 <br> nt = [] <br> while i < len(inList): <br> start = i + self.listFind(inList[i:], ['M', 'L', 'C', 'Z']) <br>
end = start + self.listFind(inList[start+1:], ['M', 'L', 'C', 'Z', '', ' ']) <br> nt.append(inList[start:end+1]) <br> i = end + 1 <br> return nt <br>
def listFind(self, x, query): <br> for i in range(len(x)): <br> if x[i] in query: <br> return i <br> return len(x) <br> def resetStrokeD(self, strokeD, x, y): <br> nsd = [] <br>
for i in strokeD: <br> nsd.append(self.resetXY(i, x, y)) <br> return nsd <br> def resetXY(self, nl, x, y): # convert a list of strokes to xy coords <br> nl2 = [] <br> for i in range(len(nl)): <br>
if i == 0: <br> nl2.append(nl[i]) <br> elif i%2: # it's odd <br> nl2.append(float(nl[i]) + float(x)) <br> elif not i%2: # it's even <br> nl2.append(float(nl[i]) + float(y)) <br>
else: <br> print i, nl[i], 'error' <br> return nl2 <br> def nltostring(self, nl): # convert a colection of nl's to a string <br> col = [] <br> for l in nl: <br>
templ = [] <br> for c in l: <br> templ.append(str(c)) <br> templ = ' '.join(templ) <br> col.append(templ) <br> return ' '.join(col)</span>