This commit is contained in:
Kovid Goyal 2018-09-03 07:42:20 +05:30
parent db6d0dd2cb
commit 4777eeacef
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -29,6 +29,7 @@ real_nibbles = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'.', 'E', 'E-', None, '-'] '.', 'E', 'E-', None, '-']
real_nibbles_map = {x:i for i, x in enumerate(real_nibbles)} real_nibbles_map = {x:i for i, x in enumerate(real_nibbles)}
class ByteCode(dict): class ByteCode(dict):
def read_byte(self, b0, data, index): def read_byte(self, b0, data, index):
@ -97,20 +98,20 @@ class ByteCode(dict):
def write_int(self, value, encoding="cff"): def write_int(self, value, encoding="cff"):
four_byte_op = {'cff':29, 't1':255}.get(encoding, None) four_byte_op = {'cff':29, 't1':255}.get(encoding, None)
if -107 <= value <= 107: if -107 <= value <= 107:
code = bytes(bytearray([value + 139])) code = bytes(bytearray([value + 139]))
elif 108 <= value <= 1131: elif 108 <= value <= 1131:
value = value - 108 value = value - 108
code = bytes(bytearray([(value >> 8) + 247, (value & 0xFF)])) code = bytes(bytearray([(value >> 8) + 247, (value & 0xFF)]))
elif -1131 <= value <= -108: elif -1131 <= value <= -108:
value = -value - 108 value = -value - 108
code = bytes(bytearray([(value >> 8) + 251, (value & 0xFF)])) code = bytes(bytearray([(value >> 8) + 251, (value & 0xFF)]))
elif four_byte_op is None: elif four_byte_op is None:
# T2 only supports 2 byte ints # T2 only supports 2 byte ints
code = bytes(bytearray([28])) + pack(b">h", value) code = bytes(bytearray([28])) + pack(b">h", value)
else: else:
code = bytes(bytearray([four_byte_op])) + pack(b">l", value) code = bytes(bytearray([four_byte_op])) + pack(b">l", value)
return code return code
def write_offset(self, value): def write_offset(self, value):
return bytes(bytearray([29])) + pack(b">l", value) return bytes(bytearray([29])) + pack(b">l", value)
@ -119,6 +120,7 @@ class ByteCode(dict):
f = self.write_float if isinstance(value, float) else self.write_int f = self.write_float if isinstance(value, float) else self.write_int
return f(value, encoding) return f(value, encoding)
class Dict(ByteCode): class Dict(ByteCode):
operand_encoding = cff_dict_operand_encoding operand_encoding = cff_dict_operand_encoding
@ -149,47 +151,47 @@ class Dict(ByteCode):
if value is not None: if value is not None:
self.stack.append(value) self.stack.append(value)
def do_operator(self, b0, data, index): def do_operator(self, b0, data, index):
if b0 == 12: if b0 == 12:
op = (b0, ord(data[index])) op = (b0, ord(data[index]))
index += 1 index += 1
else: else:
op = b0 op = b0
operator, arg_type = self.operators[op] operator, arg_type = self.operators[op]
self.handle_operator(operator, arg_type) self.handle_operator(operator, arg_type)
return None, index return None, index
def handle_operator(self, operator, arg_type): def handle_operator(self, operator, arg_type):
if isinstance(arg_type, tuple): if isinstance(arg_type, tuple):
value = () value = ()
for i in xrange(len(arg_type)-1, -1, -1): for i in xrange(len(arg_type)-1, -1, -1):
arg = arg_type[i] arg = arg_type[i]
arghandler = getattr(self, 'arg_' + arg) arghandler = getattr(self, 'arg_' + arg)
value = (arghandler(operator),) + value value = (arghandler(operator),) + value
else: else:
arghandler = getattr(self, 'arg_' + arg_type) arghandler = getattr(self, 'arg_' + arg_type)
value = arghandler(operator) value = arghandler(operator)
self[operator] = value self[operator] = value
def arg_number(self, name): def arg_number(self, name):
return self.stack.pop() return self.stack.pop()
def arg_SID(self, name): def arg_SID(self, name):
return self.strings[self.stack.pop()] return self.strings[self.stack.pop()]
def arg_array(self, name): def arg_array(self, name):
ans = self.stack[:] ans = self.stack[:]
del self.stack[:] del self.stack[:]
return ans return ans
def arg_delta(self, name): def arg_delta(self, name):
out = [] out = []
current = 0 current = 0
for v in self.stack: for v in self.stack:
current = current + v current = current + v
out.append(current) out.append(current)
del self.stack[:] del self.stack[:]
return out return out
def compile(self, strings): def compile(self, strings):
data = [] data = []
@ -227,52 +229,53 @@ class Dict(ByteCode):
def encode_array(self, val): def encode_array(self, val):
return b''.join(map(self.encode_number, val)) return b''.join(map(self.encode_number, val))
def encode_delta(self, value): def encode_delta(self, value):
out = [] out = []
last = 0 last = 0
for v in value: for v in value:
out.append(v - last) out.append(v - last)
last = v last = v
return self.encode_array(out) return self.encode_array(out)
class TopDict(Dict): class TopDict(Dict):
TABLE = ( TABLE = (
#opcode name argument type default # opcode name argument type default
((12, 30), 'ROS', ('SID','SID','number'), None, ), ((12, 30), 'ROS', ('SID','SID','number'), None,),
((12, 20), 'SyntheticBase', 'number', None, ), ((12, 20), 'SyntheticBase', 'number', None,),
(0, 'version', 'SID', None, ), (0, 'version', 'SID', None,),
(1, 'Notice', 'SID', None, ), (1, 'Notice', 'SID', None,),
((12, 0), 'Copyright', 'SID', None, ), ((12, 0), 'Copyright', 'SID', None,),
(2, 'FullName', 'SID', None, ), (2, 'FullName', 'SID', None,),
((12, 38), 'FontName', 'SID', None, ), ((12, 38), 'FontName', 'SID', None,),
(3, 'FamilyName', 'SID', None, ), (3, 'FamilyName', 'SID', None,),
(4, 'Weight', 'SID', None, ), (4, 'Weight', 'SID', None,),
((12, 1), 'isFixedPitch', 'number', 0, ), ((12, 1), 'isFixedPitch', 'number', 0,),
((12, 2), 'ItalicAngle', 'number', 0, ), ((12, 2), 'ItalicAngle', 'number', 0,),
((12, 3), 'UnderlinePosition', 'number', None, ), ((12, 3), 'UnderlinePosition', 'number', None,),
((12, 4), 'UnderlineThickness', 'number', 50, ), ((12, 4), 'UnderlineThickness', 'number', 50,),
((12, 5), 'PaintType', 'number', 0, ), ((12, 5), 'PaintType', 'number', 0,),
((12, 6), 'CharstringType', 'number', 2, ), ((12, 6), 'CharstringType', 'number', 2,),
((12, 7), 'FontMatrix', 'array', [0.001,0,0,0.001,0,0], ), ((12, 7), 'FontMatrix', 'array', [0.001,0,0,0.001,0,0],),
(13, 'UniqueID', 'number', None, ), (13, 'UniqueID', 'number', None,),
(5, 'FontBBox', 'array', [0,0,0,0], ), (5, 'FontBBox', 'array', [0,0,0,0],),
((12, 8), 'StrokeWidth', 'number', 0, ), ((12, 8), 'StrokeWidth', 'number', 0,),
(14, 'XUID', 'array', None, ), (14, 'XUID', 'array', None,),
((12, 21), 'PostScript', 'SID', None, ), ((12, 21), 'PostScript', 'SID', None,),
((12, 22), 'BaseFontName', 'SID', None, ), ((12, 22), 'BaseFontName', 'SID', None,),
((12, 23), 'BaseFontBlend', 'delta', None, ), ((12, 23), 'BaseFontBlend', 'delta', None,),
((12, 31), 'CIDFontVersion', 'number', 0, ), ((12, 31), 'CIDFontVersion', 'number', 0,),
((12, 32), 'CIDFontRevision', 'number', 0, ), ((12, 32), 'CIDFontRevision', 'number', 0,),
((12, 33), 'CIDFontType', 'number', 0, ), ((12, 33), 'CIDFontType', 'number', 0,),
((12, 34), 'CIDCount', 'number', 8720, ), ((12, 34), 'CIDCount', 'number', 8720,),
(15, 'charset', 'number', 0, ), (15, 'charset', 'number', 0,),
((12, 35), 'UIDBase', 'number', None, ), ((12, 35), 'UIDBase', 'number', None,),
(16, 'Encoding', 'number', 0, ), (16, 'Encoding', 'number', 0,),
(18, 'Private', ('number','number'), None, ), (18, 'Private', ('number','number'), None,),
((12, 37), 'FDSelect', 'number', None, ), ((12, 37), 'FDSelect', 'number', None,),
((12, 36), 'FDArray', 'number', None, ), ((12, 36), 'FDArray', 'number', None,),
(17, 'CharStrings', 'number', None, ), (17, 'CharStrings', 'number', None,),
) )
# We will not write these operators out # We will not write these operators out
@ -281,31 +284,31 @@ class TopDict(Dict):
'UIDBase', 'Encoding', 'FDSelect', 'FDArray'} 'UIDBase', 'Encoding', 'FDSelect', 'FDArray'}
OFFSETS = {'charset', 'Encoding', 'CharStrings', 'Private'} OFFSETS = {'charset', 'Encoding', 'CharStrings', 'Private'}
class PrivateDict(Dict): class PrivateDict(Dict):
TABLE = ( TABLE = (
# opcode name argument type default # opcode name argument type default
(6, 'BlueValues', 'delta', None, ), (6, 'BlueValues', 'delta', None,),
(7, 'OtherBlues', 'delta', None, ), (7, 'OtherBlues', 'delta', None,),
(8, 'FamilyBlues', 'delta', None, ), (8, 'FamilyBlues', 'delta', None,),
(9, 'FamilyOtherBlues', 'delta', None, ), (9, 'FamilyOtherBlues', 'delta', None,),
((12, 9), 'BlueScale', 'number', 0.039625, ), ((12, 9), 'BlueScale', 'number', 0.039625,),
((12, 10), 'BlueShift', 'number', 7, ), ((12, 10), 'BlueShift', 'number', 7,),
((12, 11), 'BlueFuzz', 'number', 1, ), ((12, 11), 'BlueFuzz', 'number', 1,),
(10, 'StdHW', 'number', None, ), (10, 'StdHW', 'number', None,),
(11, 'StdVW', 'number', None, ), (11, 'StdVW', 'number', None,),
((12, 12), 'StemSnapH', 'delta', None, ), ((12, 12), 'StemSnapH', 'delta', None,),
((12, 13), 'StemSnapV', 'delta', None, ), ((12, 13), 'StemSnapV', 'delta', None,),
((12, 14), 'ForceBold', 'number', 0, ), ((12, 14), 'ForceBold', 'number', 0,),
((12, 15), 'ForceBoldThreshold', 'number', None, ), # deprecated ((12, 15), 'ForceBoldThreshold', 'number', None,), # deprecated
((12, 16), 'lenIV', 'number', None, ), # deprecated ((12, 16), 'lenIV', 'number', None,), # deprecated
((12, 17), 'LanguageGroup', 'number', 0, ), ((12, 17), 'LanguageGroup', 'number', 0,),
((12, 18), 'ExpansionFactor', 'number', 0.06, ), ((12, 18), 'ExpansionFactor', 'number', 0.06,),
((12, 19), 'initialRandomSeed', 'number', 0, ), ((12, 19), 'initialRandomSeed', 'number', 0,),
(20, 'defaultWidthX', 'number', 0, ), (20, 'defaultWidthX', 'number', 0,),
(21, 'nominalWidthX', 'number', 0, ), (21, 'nominalWidthX', 'number', 0,),
(19, 'Subrs', 'number', None, ), (19, 'Subrs', 'number', None,),
) )
OFFSETS = {'Subrs'} OFFSETS = {'Subrs'}