2 # -*- coding: utf-8 -*-
4 # Copyright (C) 2009, mshio <mshio@users.sourceforge.jp>
6 # This program is free software: you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import xml.parsers.expat
25 COPYRIGHT = 'copyright (c) 2008-2009 mshio (mshio@users.sourceforge.jp)'
29 FontForge が書き出した SVG ファイルの内容を書き換え、
30 ウェブブラウザで表示できるようにするためのクラスです。
32 インスタンスを生成した後、execute メソッドを呼び出してください。
34 This class is for converting SVG files that are generated by FontForge
35 to ones that can be displayed by a web browser.
37 After getting an instance, call its execute method.
40 def __init__(self, fill_color, comment):
45 fill_color -- SVG のパスを塗りつぶすための色。文字列
46 comment -- コピーライトコメントを付けるかどうか。True/False
51 fill_color -- color name for filling svg pathes.
52 comment -- True if adding copyright comment.
54 self.fill_color = fill_color
55 self.with_comment = comment
57 def execute(self, glyph, file):
59 FontForge が書き出した SVG ファイルを解析し、目的の形式に書き換えます。
60 書き換えたファイルのファイル名は、元の SVG ファイルの
64 glyph -- FontForge のもつグリフオブジェクト
65 file -- FontForge の書き出した SVG ファイルのファイル名。文字列
69 self.out = open(file + '~', 'w')
71 self.parser.ParseFile(fh)
73 print sys.exc_info()[0]
77 def setup(self, glyph):
79 self.parser = xml.parsers.expat.ParserCreate()
80 self.parser.XmlDeclHandler = self.startXmlDeclaration
81 self.parser.StartDoctypeDeclHandler = self.startDoctypeDeclaration
82 self.parser.StartElementHandler = self.startElement
83 self.parser.EndElementHandler = self.endElement
85 def startXmlDeclaration(self, version, encoding, standalone):
86 self.out.write('<?xml')
88 self.out.write(' version="%s"' % version)
90 self.out.write(' encoding="%s"' % encoding)
92 val = 'yes' if standalone == 1 else 'no'
93 self.out.write(' standalone="%s"' % val)
96 def startDoctypeDeclaration(self, doctype, sysId, pubId, hasSubset):
97 self.out.write('<!DOCTYPE %s' % doctype)
99 self.out.write(' PUBLIC "%s"' % pubId)
101 self.out.write(' "%s"' % sysId)
103 if self.with_comment:
104 self.out.write('<!-- %s -->' % COPYRIGHT)
106 def startElement(self, name, attrs):
107 self.out.write('<%s' % name)
108 isSvg = name == 'svg'
109 isPath = name == 'path'
111 self.out.write(' xmlns="http://www.w3.org/2000/svg"')
112 for k in attrs.keys():
113 if isSvg and k == 'viewBox':
114 org = attrs[k].split()
115 w = self.glyph.width - int(org[0])
116 val = '%s -100 %d 1200' % (org[0], w)
117 self.out.write(' %s="%s"' % (k, val))
118 elif isPath and k == 'fill':
119 self.out.write(' %s="%s"' % (k, self.fill_color))
121 self.out.write(' %s="%s"' % (k, attrs[k]))
124 def endElement(self, name):
125 self.out.write('</%s>' % name)
127 # --------------------------------------------
129 # --------------------------------------------
131 def make_svg(glyph, filename, customizer):
133 SVG ファイルの生成と書き換えを行います。
135 まず FontForge の export 機能で SVG ファイルを生成し、
136 次いで SvgCustomizer でその内容を書き換えます。
137 SVGCustomizer は末尾に '~' の付いたファイルを出力するので、
140 glyph.export(filename, 1)
141 customizer.execute(glyph, filename)
144 os.rename('%s~' % filename, filename)
146 if __name__ == '__main__':
148 class InvalidArgumentError(Exception):
149 '''コマンドライン引数が正しくない場合に生成される例外です。'''
150 def __init__(self, value):
156 第一引数はフォントファイル、第二引数は保存先のディレクトリです。
160 SVG のパスを塗りつぶす色を指定します。
161 省略すると、black が指定されたことになります。
163 コピーライトコメントを付ける場合に指定します。
165 usage = 'usage: %prog [-f color] [-c] fontfile directory'
166 p = optparse.OptionParser(usage=usage)
167 p.add_option('-f', '--fill', dest='color', default='black',
168 help='name of color that is used when filling the svg pathes')
169 p.add_option('-c', '--comment', dest='comment',
170 action='store_true', default=False,
171 help='write mshio\'s copyright as comment in each output file')
172 (opt, args) = p.parse_args()
175 p.error("incorrect number of arguments")
176 raise InvalidArgumentError, "incorrect number of arguments"
178 return (args[0], args[1], opt.color, opt.comment)
182 (font_path, output_dir, color_name, comment) = parse_args()
183 except InvalidArgumentError:
186 customizer = SvgCustomizer(color_name, comment)
187 font = fontforge.open(font_path)
191 if glyph.unicode > 0:
192 path = '%s/%04x.svg' % (output_dir, glyph.unicode)
194 make_svg(glyph, path, customizer)