layers2svgfont.py revision 61dabf2c373983408b3a24c044294d6e64559764
'''
Copyright (C) 2011 Felipe Correa da Silva Sanches <juca@members.fsf.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import inkex
import sys
from PathData import PathData
class Layers2SVGFont(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
def guideline_value(self, label, index):
namedview = self.svg.find(inkex.addNS('namedview', 'sodipodi'))
guides = namedview.findall(inkex.addNS('guide', 'sodipodi'))
for guide in guides:
l=guide.get(inkex.addNS('label', 'inkscape'))
if l==label:
return int(guide.get("position").split(",")[index])
return 0
def get_or_create(self, parentnode, nodetype):
node = parentnode.find(nodetype)
if node is None:
node = inkex.etree.SubElement(parentnode, nodetype)
return node
def get_or_create_glyph(self, font, unicode_char):
glyphs = font.findall(inkex.addNS('glyph', 'svg'))
for glyph in glyphs:
if unicode_char == glyph.get("unicode"):
return glyph
return inkex.etree.SubElement(font, inkex.addNS('glyph', 'svg'))
def flip_cordinate_system(self, d, units_per_em, baseline):
pathdata = PathData(d)
def flip_cordinates(coordinates, units_per_em, baseline, relative):
x, y = coordinates
if relative:
return (x, -y)
else:
return (x, units_per_em - baseline - y)
return pathdata.transform_coordinate_values(flip_cordinates, units_per_em, baseline)
def effect(self):
# Get access to main SVG document element
self.svg = self.document.getroot()
self.defs = self.get_or_create(self.svg, inkex.addNS('defs', 'svg'))
setwidth = int(self.svg.get("width"))
units_per_em = setwidth #TODO: ask the user for this value?
baseline = self.guideline_value("baseline", 1)
ascender = self.guideline_value("ascender", 1) - baseline
caps = self.guideline_value("caps", 1) - baseline
xheight = self.guideline_value("xheight", 1) - baseline
descender = baseline - self.guideline_value("descender", 1)
lbearing = self.guideline_value("lbearing", 0)
rbearing = setwidth - self.guideline_value("rbearing", 0)
font = self.get_or_create(self.defs, inkex.addNS('font', 'svg'))
font.set("horiz-adv-x", str(setwidth))
font.set("horiz-origin-y", str(baseline))
fontface = self.get_or_create(font, inkex.addNS('font-face', 'svg'))
fontface.set("units-per-em", str(setwidth))
fontface.set("cap-height", str(caps))
fontface.set("x-height", str(xheight))
fontface.set("ascent", str(ascender))
fontface.set("descent", str(descender))
#TODO: should we somehow store sidebearing values?
groups = self.svg.findall(inkex.addNS('g', 'svg'))
for group in groups:
label = group.get(inkex.addNS('label', 'inkscape'))
if "GlyphLayer-" in label:
unicode_char = label.split("GlyphLayer-")[1]
glyph = self.get_or_create_glyph(font, unicode_char)
glyph.set("unicode", unicode_char)
#use = self.get_or_create(glyph, inkex.addNS('use', 'svg'))
#use.set(inkex.addNS('href', 'xlink'), "#"+group.get("id"))
#TODO: This code creates <use> nodes but they do not render on svg fonts dialog. why?
paths = group.findall(inkex.addNS('path', 'svg'))
for p in paths:
path = inkex.etree.SubElement(glyph, inkex.addNS('path', 'svg'))
d = p.get("d")
d = self.flip_cordinate_system(d, units_per_em, baseline)
path.set("d", d)
if __name__ == '__main__':
e = Layers2SVGFont()
e.affect()