Skip to content

Instantly share code, notes, and snippets.

@nixeneko
Created June 16, 2018 08:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nixeneko/4a88d302be218c12349819358b6b3132 to your computer and use it in GitHub Desktop.
Save nixeneko/4a88d302be218c12349819358b6b3132 to your computer and use it in GitHub Desktop.
Convert Type 2 Charstring to human-readable commands.
#!/usr/bin/env python3
# coding: utf-8
# Input Type 2 Charstring hex dump (space-separated)
T2CHARSTR = "85 D2 F7 22 CC F7 90 DE 71 D1 12 F7 A1 D3 52 CE 52 D2 F5 D0 F7 93 D7 13 D9 80 F9 15 CC 15 53 5E A1 BE B3 B8 A8 BE BA B8 7E 74 B6 1F 4A 75 64 62 46 1B 13 D3 80 FB A3 F8 D4 15 3A 0A 13 E3 80 80 89 67 88 5D 1E 58 82 51 85 6B 89 73 8A 78 8A 75 8C 93 39 18 13 E5 80 31 0A 13 D9 80 24 0A B1 8C B7 8E B8 1E E8 E2 F7 14 EA E7 1B DD C8 3F FB 10 59 89 5C 85 61 1F 9E 60 5B 96 56 1B 26 44 51 3C 27 DB 62 EA EF C6 BB DF AC 1F A8 73 A9 6E A8 6A B5 CC 18 69 AF 67 AC 63 A7 08 94 BB 8F C2 C9 1A F7 38 44 F7 0C FB 1A 1E 13 D5 80 FB 00 FB 0F 33 40 37 1F 8C 9C 8D 9B 8C 9B 08 13 D3 80 B8 0A" #ね
#T2CHARSTR = "86 89 92 D0 93 C3 90 A3 19 2C 8E 05 90 72 8A 71 74 1A 0B"
#T2CHARSTR = "C9 93 E1 97 B8 90 89 6C 89 6B 89 6B 59 3D FB 06 FB 2E 54 46 BD 46 18 0B"
#T2CHARSTR = "BB CD CC EA BB D4 08 7C 8A 7E 81 1A 89 FB 02 8B 5A 8A 2C 08 7B 89 6E 8A 7D 1E E2 06 89 9D 89 A4 8A 9C 08 87 E4 8B C7 E5 1A 0B"
#T2CHARSTR = "9A A3 9C A6 97 9D 08 0E"
#T2CHARSTR = "77 DD F8 B6 DB 01 F7 44 DD 03 F7 81 F8 FF 15 84 DA DF 87 EE 1B E6 F7 01 92 90 CE 1F DD 07 84 44 26 5C 0A 62 FB CA 15 82 62 CB 0A 49 F7 5D F7 21 F7 12 9A 9E D2 1E 8A E1 05 74 60 0A BF D5 B0 93 AF 97 B3 1F 39 93 05 0E" #こ
#T2CHARSTR = "84 2C 1B 28 30 8F 94 43 1F 39 07 0B"
#T2CHARSTR = "80 5D 57 1A FB 10 F7 09 0B"
#T2CHARSTR = "40 FB 13 7C FB 1D 1B FB 32 3F 0B"
# This should be set properly according to the number of the hint stems
HINTMASK_STEM_BYTES = 2 # ceil(n_stems / 8)
charstr_data = list(map(lambda n: int(n, 16), T2CHARSTR.split()))
#print(charstr_data)
def twos_comp(val, bits):
"""compute the 2's complement of int value val"""
# https://stackoverflow.com/questions/1604464/twos-complement-in-python
if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255
val = val - (1 << bits) # compute negative value
return val
def operator_conv(n):
# 0-31 are operators
ops = ["-Reserved-", "hstem", "-Reserved-", "vstem", "vmoveto",
"rlineto", "hlineto", "vlineto", "rrcurveto", "-Reserved-",
"callsubr", "return", "escape", "-Reserved-", "endchar",
"-Reserved-", "-Reserved-", "-Reserved-", "hstemhm", "hintmask",
"cntrmask", "rmoveto", "hmoveto", "vstemhm", "rcurveline",
"rlinecurve", "vvcurveto", "hhcurveto", "shortint", "callgsubr",
"vhcurveto", "hvcurveto"]
return ops[n]
def operator_2b_conv(n):
# two byte operators. n: second byte
ops = ["-Reserved-", "-Reserved-", "-Reserved-", "and", "or",
"not", "-Reserved-", "-Reserved-", "-Reserved-", "abs",
"add", "sub", "div", "-Reserved-", "neg",
"eq", "-Reserved-", "-Reserved-", "drop", "-Reserved-",
"put", "get", "ifelse", "random", "mul",
"-Reserved-", "sqrt", "dup", "exch", "index",
"roll", "-Reserved-", "-Reserved-", "-Reserved-", "hflex",
"flex", "hflex1", "flex1"]
# 38 or higher are reserved
return ops[n]
idx = 0
while idx < len(charstr_data):
b0 = charstr_data[idx]
idx+=1
# operators
if b0 == 12: #two-byte operators
b1 = charstr_data[idx]
idx+=1
print(operator_2b_conv(b1), end=" ")
elif 19 <= b0 <= 20: # 2 or more bytes operator
#hintmask, cntrmask
flags = 0
for i in range(HINTMASK_STEM_BYTES):
flags = flags << 8 | charstr_data[idx+i]
idx+=HINTMASK_STEM_BYTES
print(operator_conv(b0), end=" ")
print( ("0x{:0"+str(HINTMASK_STEM_BYTES*2)+"X}").format(flags), end=" ")
elif 0 <= b0 <= 27 or 29 <= b0 <= 31:
print(operator_conv(b0), end=" ")
# operands
elif 32 <= b0 <= 246:
val = b0 - 139
print(val, end=" ")
elif 247 <= b0 <= 250:
b1 = charstr_data[idx]
idx+=1 #use b1
val=(b0 - 247)*256+b1+108
print(val, end=" ")
elif 251 <= b0 <= 254:
b1 = charstr_data[idx]
idx+=1 #use b1
val=-(b0 - 251)*256-b1-108
print(val, end=" ")
elif b0 == 28:
b1 = charstr_data[idx]
idx+=1 #use b1
b2 = charstr_data[idx]
idx+=1 #use b2
val = twos_comp(b1<<8|b2, 16) #-32768 - +32767
print(val, end=" ")
elif b0 == 255:
b1 = charstr_data[idx]
idx+=1 #use b1
b2 = charstr_data[idx]
idx+=1 #use b2
b3 = charstr_data[idx]
idx+=1 #use b3
b4 = charstr_data[idx]
idx+=1 #use b4
val = twos_comp(b1<<24|b2<<16|b3<<8|b4, 32) / (2**16)
print(val, end=" ")
else:
assert False, "an unknown operator or operand"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment