Newer
Older
GB_Printer / Dump / share / extensions / svgfont2layers.py
#!/usr/bin/env python 
'''
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
import simplepath

class SVGFont2Layers(inkex.Effect):
	def __init__(self):
		self.count=0
		inkex.Effect.__init__(self)
		self.OptionParser.add_option("--limitglyphs",
						action="store", type="inkbool",
						dest="limitglyphs", default=True,
						help="Load only the first 30 glyphs from the SVGFont (otherwise the loading process may take a very long time)")

	def create_horiz_guideline(self, label, y):
		namedview = self.svg.find(inkex.addNS('namedview', 'sodipodi'))
		guide = inkex.etree.SubElement(namedview, inkex.addNS('guide', 'sodipodi'))
		guide.set(inkex.addNS('label', 'inkscape'), label)
		guide.set("orientation", "0,1")
		guide.set("position", "0,"+str(y))

	def get_or_create(self, parentnode, nodetype):
		node = parentnode.find(nodetype)
		if node is None:
			node = inkex.etree.SubElement(parentnode, nodetype)
		return node

	def flip_cordinate_system(self, d, emsize, baseline):
		pathdata = simplepath.parsePath(d)
		simplepath.scalePath(pathdata, 1,-1)
		simplepath.translatePath(pathdata, 0, int(emsize) - int(baseline))
		return simplepath.formatPath(pathdata)

	def effect(self):
		# Get access to main SVG document element
		self.svg = self.document.getroot()
		self.defs = self.svg.find(inkex.addNS('defs', 'svg'))

		#TODO: detect files with multiple svg fonts declared. 
		# Current code only reads the first svgfont instance
		font = self.defs.find(inkex.addNS('font', 'svg'))
		setwidth = font.get("horiz-adv-x")
		baseline = font.get("horiz-origin-y")
		if baseline is None:
			baseline = 0

		fontface = font.find(inkex.addNS('font-face', 'svg'))

		#TODO: where should we save the font family name?
		#fontfamily = fontface.get("font-family")
		emsize = fontface.get("units-per-em")

		#TODO: should we guarantee that <svg:font horiz-adv-x> equals <svg:font-face units-per-em> ?
		caps = fontface.get("cap-height")
		xheight = fontface.get("x-height")
		ascender = fontface.get("ascent")
		descender = fontface.get("descent")

		self.svg.set("width", emsize)
		self.create_horiz_guideline("baseline", int(baseline))
		self.create_horiz_guideline("ascender", int(baseline) + int(ascender))
		self.create_horiz_guideline("caps", int(baseline) + int(caps))
		self.create_horiz_guideline("xheight", int(baseline) + int(xheight))
		self.create_horiz_guideline("descender", int(baseline) - int(descender))

		#TODO: missing-glyph
		glyphs = font.findall(inkex.addNS('glyph', 'svg'))
		first_glyph = True
		for glyph in glyphs:
			unicode_char = glyph.get("unicode")
			if unicode_char is None:
				continue

			layer = inkex.etree.SubElement(self.svg, inkex.addNS('g', 'svg'))
			layer.set(inkex.addNS('label', 'inkscape'), "GlyphLayer-" + unicode_char)
			layer.set(inkex.addNS('groupmode', 'inkscape'), "layer")

      #glyph layers (except the first one) are innitially hidden
			if not first_glyph:
				layer.set("style", "display:none")
			first_glyph = False

			#TODO: interpret option 1

			############################
			#Option 1:
			# Using clone (svg:use) as childnode of svg:glyph

			#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? 

			############################
			#Option 2:
			# Using svg:paths as childnodes of svg:glyph

			paths = glyph.findall(inkex.addNS('path', 'svg'))
			for path in paths:
				d = path.get("d")
				if d is None:
					continue
				d = self.flip_cordinate_system(d, emsize, baseline)
				new_path = inkex.etree.SubElement(layer, inkex.addNS('path', 'svg'))
				new_path.set("d", d)

			############################
			#Option 3:
			# Using curve description in d attribute of svg:glyph

			d = glyph.get("d")
			if d is None:
				continue
			d = self.flip_cordinate_system(d, emsize, baseline)
			path = inkex.etree.SubElement(layer, inkex.addNS('path', 'svg'))
			path.set("d", d)

			self.count+=1
			if self.options.limitglyphs and self.count>=30:
				break

if __name__ == '__main__':
	e = SVGFont2Layers()
	e.affect()