#!/usr/bin/python3 ''' remap-*.py で出力されたファイルの処理 $ ./remap-tool.py [option] ... -u: 変換元のフォントで、マッピングされないグリフのGIDをリストアップ。 $ spot -nc FONTFILE > gid.txt 上記コマンドで、GID と CID のマッピング一覧を出力し、そのファイルを引数に指定。 $ ./remap-tool.py -u map.txt gid.txt > unused.txt fontplot などのコマンドで、出力したファイルを -gf FILE で指定すると、 未使用となるグリフの一覧を PDF で出力できる。 $ fontplot2 -o out.pdf -gf unused.txt -m : mergefonts 用のマッピングファイルを出力。 N は、ROS の Suppliment 番号 (3〜7)。 PostScript_name は、出力フォントの PostScript 名。 (例えば、源ノ明朝 subset JP の Regular であれば、"SourceHanSansJP-Regular") https://github.com/adobe-type-tools/Adobe-Japan1 から "Adobe-Japan1-7_ordering.txt" をダウンロードして、引数に指定する。 (省略で 'Adobe-Japan1-7_ordering.txt') $ ./remap-tool.py -m 7 MySample map.txt [Adobe-Japan1-7_ordering.txt] > map-Generic.txt map-Proportional.txt ... グリフのタイプ別でファイルが出力される。 -o [DIR]: -m 時の出力ディレクトリ ''' import sys import os import re if len(sys.argv) < 2: print("[usage] " + sys.argv[0] + " [option] ...") sys.exit(0) args = [] option = '' outdir = None # オプション i = 1 while i < len(sys.argv): l = sys.argv[i] i += 1 if l[0] != '-': args.append(l) else: l = l[1:] if l == 'u': option = 'unused' elif l == 'm': option = 'map' map_supplement = int(sys.argv[i]) map_postname = sys.argv[i+1] i += 2 elif l == 'o': outdir = sys.argv[i] i += 1 fname_map = args.pop(0) class MapTool: # エラー def err(self,mes): print(mes,file=sys.stderr) sys.exit(1) # src map 読み込み def read_map(self,fname): f = open(fname, 'rt') lines = f.readlines() f.close() self.dat = [] self.dat.append(0) mo = re.compile(r'(\d+)\[(\d+)\]$') for l in lines: l = l.strip() if not l: continue sp = l.split('#') if '[' in sp[0]: m = mo.match(sp[0]) dstid = int(m.group(1)) srcid = int(m.group(2)) else: dstid = int(sp[0]) srcid = None self.dat.append(srcid) self.datlen = len(self.dat) # ソースで未使用のCIDを出力 def unused_src(self,fname): f = open(fname, 'rt') lines = f.readlines() f.close() lines.pop(0) # フォントに含まれるCIDのマップ flags = {} mo = re.compile(r'\[(\d+)\]=<\\(\d+)>') for l in lines: l = l.strip() if not l: continue m = mo.match(l) if m: gid = int(m.group(1)) cid = int(m.group(2)) flags[cid] = gid # 使用されているCIDをクリア flags[0] = -1 for cid in self.dat: if cid: flags[cid] = -1 # 未使用のGIDをリストアップ # [!] 終端に ',' があるとエラーになる num = 0 o = '' for cid,gid in flags.items(): if gid != -1: o += '{0},'.format(gid) num += 1 if num > 10: o += '\n' num = 0 if o and o[-1] == '\n': o = o[0:-1] if o and o[-1] == ',': o = o[0:-1] print(o, end='') # ordering ファイルを読み込み def read_ordering(self,fname): f = open(fname, 'rt') lines = f.readlines() f.close() self.order = [] mo = re.compile(r'(\d+)\s+(.+?)\s+') for l in lines: l = l.strip() if not l: continue m = mo.match(l) if not m: continue cid = int(m.group(1)) kind = m.group(2) self.order.append(kind) # suppliment ごとのグリフ数取得 def get_glyph_num(self,no): if no < 3 or no > 7: self.err('suppliment is 3-7.') else: num = (9354, 15444, 20317, 23058, 23060) return num[no - 3] # マッピングファイルを出力 def output_mapping(self,suppliment,postname,outdir): gnum = self.get_glyph_num(suppliment) if self.datlen < gnum: self.dat.extend([None] * (gnum - self.datlen)) # 種類ごとに分ける dat = {} i = 0 while i < gnum: sid = self.dat[i] kind = self.order[i] if kind not in dat: dat[kind] = 'mergefonts {0}-{1}\n'.format(postname, kind) if sid is None: sid = 0 dat[kind] += "{0:05d} {1:05d}\n".format(i, sid) i += 1 # ファイルに出力 cmd = '\n[mergefonts option]\n' for kind,txt in dat.items(): outname = 'map-' + kind + '.txt' if outdir: outfname = os.path.join(outdir, outname) else: outfname = outname f = open(outfname, 'wt') f.write(txt) f.close() print(outname) cmd += outname + ' FONTNAME ' print(cmd) #---- c = MapTool() c.read_map(fname_map) if option == 'unused': if len(args) == 0: print('need file: $ spot -nc FONTFILE > output') else: c.unused_src(args[0]) elif option == 'map': if args: fname = args[0] else: fname = 'Adobe-Japan1-7_ordering.txt' c.read_ordering(fname) c.output_mapping(map_supplement, map_postname, outdir) else: print('no option')