Created
June 16, 2018 08:30
-
-
Save nixeneko/4a88d302be218c12349819358b6b3132 to your computer and use it in GitHub Desktop.
Convert Type 2 Charstring to human-readable commands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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