#!/usr/bin/python3 ''' remap-unicode.py で出力したマッピングファイルに、GSUB での置き換えグリフを適用。 (1) 変換元のフォントの GSUB 情報を取得 $ spot -t GSUB=7 [FONTFILE] > gsub.txt (2) https://github.com/adobe-type-tools/Adobe-Japan1 から、以下のファイルをダウンロード。 - GSUB/aj17-gsub-jp04.fea (3) 適用 $ ./remap-gsub.py src.txt gsub.txt [aj17-gsub-jp04.fea] > out.txt ''' import sys import re if len(sys.argv) < 3: print("[usage] " + sys.argv[0] + " []") sys.exit(0) fname_map = sys.argv[1] fname_spot = sys.argv[2] if len(sys.argv) < 4: fname_fea = 'aj17-gsub-jp04.fea' else: fname_fea = sys.argv[3] class MapGsub: NAME_LIST = ['fwid','hwid','jp78','jp83','jp90','nlck','pwid','ruby','vert','vrt2'] # ソース map 読み込み def read_map(self,fname): f = open(fname, 'rt') lines = f.readlines() f.close() mo_cid = re.compile(r'(\d+)\[(\d+)\]$') self.dat = [] self.dat.append([0,None]) self.srcmap = {} for l in lines: l = l.strip() if not l: continue sp = l.split('#') uclist = [] # cid if '[' in sp[0]: m = mo_cid.match(sp[0]) dstid = int(m.group(1)) srcid = int(m.group(2)) else: dstid = int(sp[0]) srcid = None # unicode if len(sp) > 1: for sl in sp[1].split('/'): if ' ' in sl: uclist = sl else: uclist.append(int(sl,base=16)) if not uclist: uclist = None self.dat.append([srcid,uclist]) # Unicode マップ if uclist: if type(uclist) is str: # 異体字 if srcid: self.srcmap[uclist] = srcid else: for uc in uclist: if srcid: self.srcmap[uc] = srcid # feature src ファイル読み込み def read_feature_src(self,fname): f = open(fname, 'rt') lines = f.readlines() f.close() self.srcfea = {} curname = None mo = re.compile(r'sub\s+\\(\d+)\s+by\s+\\(\d+);') for l in lines: l = l.strip() if not l: continue if curname: if l[0] == '#': if l.find('End Lookup') != -1: curname = None else: m = mo.match(l) if m: self.srcfea[curname][int(m.group(1))] = int(m.group(2)) elif l[0] == '#' and l.find('Printing') != -1: # feature 開始 for name in self.NAME_LIST: if l.find("'" + name + "'") != -1: curname = name if name not in self.srcfea: self.srcfea[curname] = {} break # feature dst ファイル読み込み def read_feature_dst(self,fname): f = open(fname, 'rt') lines = f.readlines() f.close() self.dstfea = {} curname = None mo = re.compile(r'substitute\s+\\(\d+)\s+by\s+\\(\d+);') for l in lines: l = l.strip() if (not l) or l[0] == '#': continue if curname: if l[0] == '}': curname = None else: m = mo.match(l) if m: self.dstfea[curname].append([int(m.group(1)), int(m.group(2))]) elif l.startswith('feature') and l[-1] == '{': sp = l.split() if sp[1] in self.NAME_LIST: curname = sp[1] self.dstfea[curname] = [] # マッピング def mapping(self): for name,lst in self.dstfea.items(): # src に同じ feature がない if name not in self.srcfea: continue for sid,repid in lst: if repid >= len(self.dat): self.dat.extend([[None,None]] * (repid - len(self.dat) + 1)) if self.dat[repid][0]: continue # 置換元の Unicode に一致する、ソースの cid 取得 uclist = self.dat[sid][1] srcid = None if uclist: if type(uclist) is str: if uclist in self.srcmap: srcid = self.srcmap[uclist] else: for uc in uclist: if uc in self.srcmap: srcid = self.srcmap[uc] break # ソースの置換先 CID if srcid and (srcid in self.srcfea[name]): srcid = self.srcfea[name][srcid] self.dat[repid] = [srcid, self.dat[repid][1]] # 書き込み def write(self): datlen = len(self.dat) i = 1 num = 0 while i < datlen: sid = self.dat[i][0] uclist = self.dat[i][1] o = '{0:05d}'.format(i) # src 割り当て if sid: o += '[{0}]'.format(sid) num += 1 # Unicode if uclist: o += '#' if type(uclist) is str: o += uclist else: for uc in uclist: o += '{0:X}/'.format(uc) o = o[:-1] print(o) i += 1 print('{0}/{1} ({2:.2%})'.format(num, datlen, num / datlen) ,file=sys.stderr) #----- c = MapGsub() c.read_map(fname_map) c.read_feature_src(fname_spot) c.read_feature_dst(fname_fea) c.mapping() c.write()