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 ファイルを解析し、目的の形式に書き換えます。
62 glyph -- FontForge のもつグリフオブジェクト
63 file -- FontForge の書き出した SVG ファイルのファイル名。文字列
65 Parses the SVG file that is output by FontForge, and outputs a new
66 SVG file that can be displayed by a web browser.
74 c = self.get_contents(file)
75 self.out = open(file, 'w')
76 self.parser.Parse(c, 1)
78 print sys.exc_info()[0]
81 def setup(self, glyph):
82 '''内部にもつ XML パーサーのセットアップを行います。'''
84 self.parser = xml.parsers.expat.ParserCreate()
85 self.parser.XmlDeclHandler = self.start_xml_declaration
86 self.parser.StartDoctypeDeclHandler = self.start_doctype_declaration
87 self.parser.StartElementHandler = self.start_element
88 self.parser.EndElementHandler = self.end_element
90 def get_contents(self, file):
91 '''指定したファイルの内容を読み込んで返します。'''
97 def start_xml_declaration(self, version, encoding, standalone):
98 '''XML 宣言部分のパースと書き出しを行います。'''
99 self.out.write('<?xml')
101 self.out.write(' version="%s"' % version)
103 self.out.write(' encoding="%s"' % encoding)
105 val = 'yes' if standalone == 1 else 'no'
106 self.out.write(' standalone="%s"' % val)
109 def start_doctype_declaration(self, doctype, sys_id, pub_id, has_subset):
110 '''DOCTYPE 部分のパースと書き出しを行います。'''
111 self.out.write('<!DOCTYPE %s' % doctype)
113 self.out.write(' PUBLIC "%s"' % pub_id)
115 self.out.write(' "%s"' % sys_id)
117 if self.with_comment:
118 self.out.write('<!-- %s -->' % COPYRIGHT)
120 def start_element(self, name, attrs):
121 '''各要素の開始部分を読み込み、その部分の書き出しを行います。'''
122 self.out.write('<%s' % name)
123 is_svg = name == 'svg'
124 is_path = name == 'path'
126 self.out.write(' xmlns="http://www.w3.org/2000/svg"')
127 for k in attrs.keys():
128 if is_svg and k == 'viewBox':
129 org = attrs[k].split()
130 w = self.glyph.width - int(org[0])
131 # here, using magic numbers at the values of top and height.
132 # if using this script for some other fonts,
133 # you might have to change these values.
134 val = '%s -100 %d 1200' % (org[0], w)
135 self.out.write(' %s="%s"' % (k, val))
136 elif is_path and k == 'fill':
137 self.out.write(' %s="%s"' % (k, self.fill_color))
139 self.out.write(' %s="%s"' % (k, attrs[k]))
142 def end_element(self, name):
143 '''各要素の終了部分を読み込み、その部分の書き出しを行います。'''
144 self.out.write('</%s>' % name)
147 if __name__ == '__main__':
149 class InvalidArgumentError(Exception):
150 '''コマンドライン引数が正しくない場合に生成される例外です。'''
151 def __init__(self, value):
157 第一引数はフォントファイル、第二引数は保存先のディレクトリです。
161 SVG のパスを塗りつぶす色を指定します。
162 省略すると、black が指定されたことになります。
164 コピーライトコメントを付ける場合に指定します。
166 Processes the arguments of command line.
167 The first of them is font file path, and the second of them is path of
168 directory in which the svg files will be stored.
169 The options are like this:
172 The color name with which fill the svg pathes.
175 When this option is specified, the copyright is written as comment
178 usage = 'usage: %prog [-f color] [-c] fontfile directory'
179 p = optparse.OptionParser(usage=usage)
180 p.add_option('-f', '--fill', dest='color', default='black',
181 help='name of color that is used when filling the svg pathes')
182 p.add_option('-c', '--comment', dest='comment',
183 action='store_true', default=False,
184 help="write mshio's copyright as comment in each output files")
185 (opt, args) = p.parse_args()
188 p.error('incorrect number of arguments')
189 raise InvalidArgumentError
191 return (args[0], args[1], opt.color, opt.comment)
195 (font_path, output_dir, color_name, comment) = parse_args()
196 except InvalidArgumentError:
199 customizer = SvgCustomizer(color_name, comment)
200 font = fontforge.open(font_path)
204 if glyph.unicode > 0:
205 path = '%s/%04x.svg' % (output_dir, glyph.unicode)
207 glyph.export(path, 1)
208 customizer.execute(glyph, path)