# -*- coding: cp932 -*-
# UString.py
import UCD
class GlyphBasedText:
def __init__(self,unicodetext=u"",direction="Left to Right"):
self.direction = direction;
g = self.start = self.current= Glyph(cp=-1);
for unichar in unicodetext:
g=g.insertNext(Glyph(cp = ord(unichar),unichar=unichar));
g.script = UCD.script(unichar);
self.end = g.insertNext(Glyph(cp=0));
self.font =None;
def isTag(self,Tag,tagString):
if Tag is None:
return False;
elif isinstance(Tag,str):
if Tag == "*": return True;
return (tagString == Tag);
elif isinstance(Tag,list):
return (tagString in Tag);
else:
raise 'UnknownType';
def setGID(self):
cmap = self.font.readTable('cmap');
subtable = cmap.getSubTable(0,6);
if not subtable: subtable = cmap.getSubTable(3,10);
if not subtable: subtable = cmap.getSubTable(0,4);
if not subtable: subtable = cmap.getSubTable(0,3);
if not subtable: subtable = cmap.getSubTable(3,1);
if not subtable: subtable = cmap.getSubTable(0,2);
if not subtable: subtable = cmap.getSubTable(0,1);
if not subtable: subtable = cmap.getSubTable(0,0);
if not subtable: raise;
for g in self.getIter():
try:
g.GID = subtable.charcode2gindex[g.cp];
except KeyError:
g.GID = 0;
def setAdvance(self):
hmtx = self.font.readTable('hmtx');
vmtx = self.font.readTable('vmtx');
if hmtx is None: raise;
direction = self.direction;
for Glyph in self.getIter(finished=False):
if direction =="Left to Right" or direction =="Right to Left":
advanceWidth,lsb = hmtx.getMetric(Glyph.GID);
if direction =="Right to Left":
advanceWidth =advanceWidth*-1;
Glyph.advance = [advanceWidth,0];
elif direction=="Top to Bottom" or direction=="Bottom to Top":
mtx =vmtx;
if vmtx is None: mtx=hmtx;
advanceWidth,lsb = mtx.getMetric(GID.GID);
if direction=="Bottom to Top":
advanceWidth =advanceWidth*-1;
Glyph.advance = [0,advanceWidth];
else:
raise;
def setGSUB(self):
GSUB = self.font.readTable('GSUB');
for glyph in self.getIter():
if glyph.script =='arab':
#アラビア語のinit,medi,fina,isolの判定
for e in self.getIter(script='arab',finished=False):
cclass = UCD.joining(e.unichar);
e.feature = 'isol'
if cclass =='R' and \
(UCD.joining(e.prev.unichar) in ['D','L','C']):
e.feature = 'fina';
if cclass =='D':
if (UCD.joining(e.prev.unichar) in ['D','L','C']):
if (UCD.joining(e.next.unichar) in ['D','R','C']):
e.feature = 'medi';
else:
e.feature = 'fina';
else:
if (UCD.joining(e.next.unichar) in ['D','R','C']):
e.feature = 'init';
#アラビア語のccmpの設定
GSUB.substitute(self.getGene('arab','default','*'),'arab','default','ccmp');
GSUB.substitute(self.getGene('arab','default','isol'),'arab','default','isol');
GSUB.substitute(self.getGene('arab','default','fina'),'arab','default','fina');
GSUB.substitute(self.getGene('arab','default','medi'),'arab','default','medi');
GSUB.substitute(self.getGene('arab','default','init'),'arab','default','init');
for e in self.getIter(script='arab',language='default',finished=False): e.finished=False;
GSUB.substitute(self.getGene('arab','default','*'),'arab','default','rlig');
for e in self.getIter(script='arab',language='default',finished=False): e.finished=True;
#このメソッドはfinishedフラグを初期化します
def initializeFinished():
for e in self.getIter(finished=False):
e.finished=False;
#このメソッドはジェネレーターです。
#条件にある要素のみを読みだすイテレーターを返します。
def getIter(self,script='*',language='*',feature='*',finished=True):
g=self.start.next;
while g.next is not None:
if finished and g.finished:
g = g.next;
continue;
if self.isTag(script,g.script) and \
self.isTag(language,g.language) and \
self.isTag(feature,g.feature):
yield g;
g = g.next;
#このメソッドは条件確定したジェネレーターを返します。
#技術的には単なるクロージャです。
def getGene(self,script='*',language='*',feature='*',finished=True):
def f():
return self.getIter(script=script,language=language,
feature=feature,finished=finished);
return f;
def html(self):
for glyph in self.getIter(finished=False):
print '<PATH>TRANSLATE %d %d</PATH><GID>%d</GID>' %(glyph.advance[0],
glyph.advance[1],
glyph.GID);
def debug(self):
for glyph in self.getIter(finished=False):
print glyph.unichar,glyph.script,glyph.cp,glyph.script,glyph.feature
class Glyph:
def __init__(self,cp =0,unichar=u'',GID=0):
self.cp = cp;
self.GID = GID;
self.unichar=unichar;
self.script='';
self.language ='default';
self.advance=[0,0];
self.feature ='';
self.finished=False;
self.prev=None;
self.next=None;
def Next(self):
return self.next;
def Prev(self):
return self.prev;
def Child(self):
return self.child;
def sub(self,GID):
if isinstance(GID,list):
for index,gid in enumerate(GID):
if index==0:
g=self.sub(gid);
else:
g = g.insertNext(Glyph(gid));
g.finished=True;
else:
newGlyph=Glyph(GID=GID);
newGlyph.next = self.next; newGlyph.prev = self.prev;
self.next.prev = newGlyph; self.prev.next = newGlyph;
newGlyph.finished =True;
newGlyph.script = self.script;
newGlyph.language = self.language;
newGlyph.feature = self.feature;
return newGlyph;
def sub2(self,Glyph2,GID):
newGlyph = Glyph(GID=GID);
self.prev.next = newGlyph;
newGlyph.prev = self.prev;
self.next.prev = newGlyph;
newGlyph.next = Glyph2.next;
newGlyph.finished =True;
newGlyph.script = self.script;
newGlyph.language = self.language;
newGlyph.feature = self.feature;
def insertNext(self,g):
g.next = self.next;
self.next = g;
g.prev = self;
if g.next:
g.next.prev = g;
return g;