--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2009, mshio <mshio@users.sourceforge.jp>
+#
+# 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 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, see <http://www.gnu.org/licenses/>.
+
+import fontforge
+import optparse
+import os
+import sys
+import xml.parsers.expat
+
+COPYRIGHT = 'copyright (c) 2008-2009 mshio (mshio@users.sourceforge.jp)'
+
+class SvgCustomizer:
+ '''
+ FontForge が書き出した SVG ファイルの内容を書き換え、
+ ウェブブラウザで表示できるようにするためのクラスです。
+
+ インスタンスを生成した後、execute メソッドを呼び出してください。
+
+ This class is for converting SVG files that are generated by FontForge
+ to ones that can be displayed by a web browser.
+
+ After getting an instance, call its execute method.
+ '''
+
+ def __init__(self, fill_color, comment):
+ '''
+ コンストラクタ
+
+ 引数:
+ fill_color -- SVG のパスを塗りつぶすための色。文字列
+ comment -- コピーライトコメントを付けるかどうか。True/False
+
+ Constructor
+
+ Arguments:
+ fill_color -- color name for filling svg pathes.
+ comment -- True if adding copyright comment.
+ '''
+ self.fill_color = fill_color
+ self.with_comment = comment
+
+ def execute(self, glyph, file):
+ '''
+ FontForge が書き出した SVG ファイルを解析し、目的の形式に書き換えます。
+ 書き換えたファイルのファイル名は、元の SVG ファイルの
+ 末尾に '~' をつけたものになります。
+
+ 引数:
+ glyph -- FontForge のもつグリフオブジェクト
+ file -- FontForge の書き出した SVG ファイルのファイル名。文字列
+ '''
+ self.setup(glyph)
+ try:
+ self.out = open(file + '~', 'w')
+ fh = open(file, 'r')
+ self.parser.ParseFile(fh)
+ except:
+ print sys.exc_info()[0]
+ fh.close()
+ self.out.close()
+
+ def setup(self, glyph):
+ self.glyph = glyph
+ self.parser = xml.parsers.expat.ParserCreate()
+ self.parser.XmlDeclHandler = self.startXmlDeclaration
+ self.parser.StartDoctypeDeclHandler = self.startDoctypeDeclaration
+ self.parser.StartElementHandler = self.startElement
+ self.parser.EndElementHandler = self.endElement
+
+ def startXmlDeclaration(self, version, encoding, standalone):
+ self.out.write('<?xml')
+ if version:
+ self.out.write(' version="%s"' % version)
+ if encoding:
+ self.out.write(' encoding="%s"' % encoding)
+ if standalone != -1:
+ val = 'yes' if standalone == 1 else 'no'
+ self.out.write(' standalone="%s"' % val)
+ self.out.write('?>')
+
+ def startDoctypeDeclaration(self, doctype, sysId, pubId, hasSubset):
+ self.out.write('<!DOCTYPE %s' % doctype)
+ if pubId:
+ self.out.write(' PUBLIC "%s"' % pubId)
+ if sysId:
+ self.out.write(' "%s"' % sysId)
+ self.out.write('>')
+ if self.with_comment:
+ self.out.write('<!-- %s -->' % COPYRIGHT)
+
+ def startElement(self, name, attrs):
+ self.out.write('<%s' % name)
+ isSvg = name == 'svg'
+ isPath = name == 'path'
+ if isSvg:
+ self.out.write(' xmlns="http://www.w3.org/2000/svg"')
+ for k in attrs.keys():
+ if isSvg and k == 'viewBox':
+ org = attrs[k].split()
+ w = self.glyph.width - int(org[0])
+ val = '%s -100 %d 1200' % (org[0], w)
+ self.out.write(' %s="%s"' % (k, val))
+ elif isPath and k == 'fill':
+ self.out.write(' %s="%s"' % (k, self.fill_color))
+ else:
+ self.out.write(' %s="%s"' % (k, attrs[k]))
+ self.out.write('>')
+
+ def endElement(self, name):
+ self.out.write('</%s>' % name)
+
+# --------------------------------------------
+# function
+# --------------------------------------------
+
+def make_svg(glyph, filename, customizer):
+ '''
+ SVG ファイルの生成と書き換えを行います。
+
+ まず FontForge の export 機能で SVG ファイルを生成し、
+ 次いで SvgCustomizer でその内容を書き換えます。
+ SVGCustomizer は末尾に '~' の付いたファイルを出力するので、
+ 最後にファイル名を書き換えます。
+ '''
+ glyph.export(filename, 1)
+ customizer.execute(glyph, filename)
+
+ os.remove(filename)
+ os.rename('%s~' % filename, filename)
+
+if __name__ == '__main__':
+
+ class InvalidArgumentError(Exception):
+ '''コマンドライン引数が正しくない場合に生成される例外です。'''
+ def __init__(self, value):
+ self.value = value
+
+ def parse_args():
+ '''
+ コマンドライン引数の処理をします。
+ 第一引数はフォントファイル、第二引数は保存先のディレクトリです。
+ オプションは下記のとおりです。
+
+ -f, --fill :
+ SVG のパスを塗りつぶす色を指定します。
+ 省略すると、black が指定されたことになります。
+ -c, --comment :
+ コピーライトコメントを付ける場合に指定します。
+ '''
+ usage = 'usage: %prog [-f color] [-c] fontfile directory'
+ p = optparse.OptionParser(usage=usage)
+ p.add_option('-f', '--fill', dest='color', default='black',
+ help='name of color that is used when filling the svg pathes')
+ p.add_option('-c', '--comment', dest='comment',
+ action='store_true', default=False,
+ help='write mshio\'s copyright as comment in each output file')
+ (opt, args) = p.parse_args()
+
+ if len(args) != 2:
+ p.error("incorrect number of arguments")
+ raise InvalidArgumentError, "incorrect number of arguments"
+
+ return (args[0], args[1], opt.color, opt.comment)
+
+
+ try:
+ (font_path, output_dir, color_name, comment) = parse_args()
+ except InvalidArgumentError:
+ sys.exit(1)
+
+ customizer = SvgCustomizer(color_name, comment)
+ font = fontforge.open(font_path)
+ for g in font:
+ if g[0] != '.':
+ glyph = font[g]
+ if glyph.unicode > 0:
+ path = '%s/%04x.svg' % (output_dir, glyph.unicode)
+ print path
+ make_svg(glyph, path, customizer)