SVG Глифы в Pyqt - PullRequest
       21

SVG Глифы в Pyqt

1 голос
/ 10 сентября 2010

Как отобразить глифы в pyqt с помощью svggraphicsItem?

1 Ответ

3 голосов
/ 12 сентября 2010

Недавно я обнаружил, что SVG-файлы, сгенерированные Cairo, не отображаются должным образом в pyqt. Ошибка возникает из-за использования глифов, которые, по-видимому, не показаны в pyqt (это может быть неправильно, но я не смог найти способ заставить глифы отображаться).

В итоге я написал набор функций, которые будут конвертировать глифы в пути SVG, чтобы файл отображался нормально.

Они могут все еще использовать некоторые улучшения для рендеринга цвета и других элементов стиля (которые заблокированы в функциях, которые я написал).

Эти функции нужно будет встроить в класс или удалить самостоятельно, чтобы использовать их в другом месте.

Я просто хотел, чтобы люди имели их, чтобы им не приходилось искать высоко и низко, как я делал, чтобы найти способ визуализации глифов в pyqt.

Надежда на лучшее, Кайл

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)
...