[rendering] This simple trick didn't work...
[wikipediardware.git] / host-tools / glyphs / spacing / extract_spacing.py
bloba4b33a7b3d0a781a854513291544bb4b5ee14d31
1 #!/usr/bin/env python
2 """
3 Generate a font file to be used on the target device
5 Copyright (C) 2008, 2009 Holger Hans Peter Freyther <zecke@openmoko.org>
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 """
21 import gzip
22 import glob
23 import optparse
24 import os
25 import sys
27 def mkdir(path):
28 try:
29 os.mkdir(path)
30 except:
31 pass
33 def parse():
34 parser = optparse.OptionParser(version = "Extract spacing from a rendertext file",
35 usage = """%prog [options] input_file
36 Two modes are supported. Single conversion and batch mode""")
37 parser.add_option("-b", "--batch", help = "start a batch job",
38 action = "store_true", dest = "batch", default = False)
39 parser.add_option("-e", "--error-file", help = "File where to put errors",
40 action = "store", dest = "error_file", default = "failed_spacing.files")
43 return parser.parse_args(sys.argv)
45 # Load glyphs... share this with render_text.py
46 def load(file):
47 glyphs = []
48 for line in file:
49 split = line.strip().split(',')
52 glyph = { 'x' : int(split[0]),
53 'y' : int(split[1]),
54 'font' : split[2],
55 'glyph' : split[3] }
56 glyphs.append(glyph)
58 return glyphs
60 def extract_spacing(kern_info, last_glyph, glyph):
61 """Extract the spacing between two glyphs and save that"""
62 if not last_glyph:
63 return
65 if not last_glyph['x'] < glyph['x']:
66 print "Something went wrong, overlapping glyphs...", last_glyph, glyph
67 return
69 kern_x = glyph['x'] - last_glyph['x']
70 kern_y = glyph['y'] - last_glyph['y']
71 kern = (kern_x, kern_y)
72 glyph_pair = (last_glyph['glyph'], glyph['glyph'])
73 glyph_font = glyph['font']
74 if not glyph['font'] in kern_info:
75 kern_info[glyph_font] = {}
76 kern_info[glyph_font][glyph_pair] = kern
77 elif not glyph_pair in kern_info[glyph_font]:
78 kern_info[glyph_font][glyph_pair] = kern
79 elif kern != kern_info[glyph_font][glyph_pair]:
80 print "Not matching spacing will need to fixup: new: %s old: %s" % (kern, kern_info[glyph_font][glyph_pair]), last_glyph, glyph
81 assert False
83 def generate_text_runs(kern_info, glyphs):
84 current = None
85 last_glyph = None
86 last_x = -1
87 skip_paragraph = False
89 for glyph in glyphs:
90 if glyph['x'] == 0 and glyph['y'] == 0 and glyph['font'] == '0' and glyph['glyph'] == '0':
91 last_glyph = None
92 skip_paragraph = False
93 continue
94 elif skip_paragraph:
95 continue
96 elif last_x == glyph['x']:
97 print "Skipping overlapping paragraph..."
98 skip_paragraph = True
99 continue
102 extract_spacing(kern_info, last_glyph, glyph)
103 last_x = glyph['x']
104 last_glyph = glyph
108 def write_mappings(kern_info):
109 """Write out the mappings used for this article"""
111 # Write options
112 mkdir("fonts")
114 for font in kern_info.keys():
115 font_index = "%s" % font
116 font_path = os.path.join("fonts", font_index)
117 mkdir(font_path)
118 glyph_path_base = os.path.join(font_path, "spacing")
119 mkdir(glyph_path_base)
120 spacing_file = gzip.open(os.path.join(glyph_path_base, "spacing-file.gz"), "a")
122 for (l_glyph, r_glyph) in kern_info[font].keys():
123 (x,y) = kern_info[font][(l_glyph, r_glyph)]
124 glyph_text = "%s-%s: %d,%d" % (l_glyph, r_glyph, x, y)
125 print >> spacing_file, glyph_text
128 # Import Psyco if available
129 try:
130 import psyco
131 psyco.full()
132 except ImportError:
133 pass
136 opts, args = parse()
138 if not opts.batch:
139 raw_glyphs = load(file(args[1]))
141 kern = {}
142 generate_text_runs(kern, raw_glyphs)
143 write_mappings(kern)
144 else:
145 failed = open(opts.error_file, "a")
147 def convert(base_name, file_name):
149 Convert a single blib
151 file_name = os.path.join(base_name, "articles", file_name[0], file_name[1:3], file_name)
152 file_name = "%s.blib" % file_name
153 raw_glyphs = load(open(file_name, 'rb'))
155 kern = {}
156 generate_text_runs(kern, raw_glyphs)
157 write_mappings(kern)
159 for arg in range(1, len(args)):
160 for work in glob.glob(os.path.join(args[arg], "*.work")):
161 print "Working on %s" % work
162 file = open(work)
163 for line in file:
164 data = line[:-1].split(" ", 1)
165 try:
166 convert(args[arg], data[0])
167 except:
168 print >> failed, "Error: %s from %s" % (data[0], work)