เหตุมาจากต้องการดูการ instruct ของฟอนต์ DejaVu Sans
แต่โค๊ดอ่านยากเหลือเกิน เพราะเขียนข้อมูลเป็นสแต็กไว้ก่อน แล้วจึงเขียนโค๊ดตามหลัง ทำให้ดูยาก
จึงเขียนสคริปต์แบบหยาบ ๆ มาคลี่ข้อมูลเรียงต่อท้ายคำสั่ง เพื่อให้ดูง่ายขึ้น
ตั้งชื่อชั่วคราวว่า dfont.py
$ touch dfont.py; chmod 755 dfont.py; vi dfont.py
#!/usr/bin/env python
import sys
# ins_dict = { "COMMAND" : ("Description",pops,push), ... }
# pops,push: 0=NOOP, 1=1BYTE, 2=2BYTE, ...
# -1=FIRST BYTE IS ONE BYTE COUNTER,
# -2=FIRST BYTE IS TWO BYTE COUNTER,
# -3=CLEAR STACK
# -4=REQUIRE SOME PROCESSING
ins_dict = {
"AA" : ("Adjust Angle", 1, 0),
"ABS" : ("ABSolute value", 1, 1),
"ADD" : ("ADD", 2, 1),
"ALIGNPTS" : ("ALIGN Points", 2, 0),
"ALIGNRP" : ("ALIGN to Reference Point", 1, 0),
"AND" : ("logical AND", 2, 1),
"CALL" : ("CALL function", 1, 0),
"CEILING" : ("CEILING", 1, 1),
"CINDEX" : ("Copy the INDEXed element to the top of the stack", 1, -1),
"CLEAR" : ("CLEAR the stack", -3, 0),
"DEBUG" : ("DEBUG call", 1, 0),
"DELTAC1" : ("DELTA exception C1", -2, 0),
"DELTAC2" : ("DELTA exception C2", -2, 0),
"DELTAC3" : ("DELTA exception C3", -2, 0),
"DELTAP1" : ("DELTA exception P1", -2, 0),
"DELTAP2" : ("DELTA exception P2", -2, 0),
"DELTAP3" : ("DELTA exception P3", -2, 0),
"DEPTH" : ("DEPTH of the stack", 0, 1),
"DIV" : ("DIVide", 2, 1),
"DUP" : ("DUPlicate top stack element", 1, 1),
"EIF" : ("End IF", 0, 0),
"ELSE" : ("ELSE clause", 0, 0),
"ENDF" : ("END Function definition", 0, 0),
"EQ" : ("EQual", 2, 1),
"EVEN" : ("EVEN", 1, 1),
"FDEF" : ("Function DEFinition", 1, 0),
"FLIPOFF" : ("set the auto FLIP Boolean to OFF", 0, 0),
"FLIPON" : ("set the auto FLIP Boolean to ON", 0, 0),
"FLIPPT" : ("FLIP PoinT", 1, 0),
"FLIPRGOFF" : ("FLIP RanGe OFF", 2, 0),
"FLIPRGON" : ("FLIP RanGe ON", 2, 0),
"FLOOR" : ("FLOOR", 2, 0),
"GC" : ("Get Coordinate projected onto the projection vector", 1, 1),
"GETINFO" : ("GET INFOrmation", 1, 1),
"GFV" : ("Get Freedom Vector", 0, 2),
"GPV" : ("Get Projection Vector", 0, 2),
"GT" : ("Greater Than", 2, 1),
"GTEQ" : ("Greater Than or EQual", 2, 1),
"IDEF" : ("Instruction DEFinition", 1, 0),
"IF" : ("IF test", 1, 0),
"INSTCTRL" : ("INSTRuction execution ConTRoL", 2, 0),
"IP" : ("Interpolate Point", 1, 0),
"ISECT" : ("moves point p to the InterSECTion of two lines", 5, 0),
"IUP" : ("Interpolate Untouched Points through the outline", 0, 0),
"JMPR" : ("JuMP Relative", 1, 0),
"JROF" : ("Jump Relative On False", 1, 0),
"JROT" : ("Jump Relative On True", 3, 0),
"LOOPCALL" : ("LOOP and CALL function", 2, 0),
"LT" : ("Less Than", 2, 1),
"LTEQ" : ("Less Than or Equal", 2, 1),
"MAX" : ("MAXimum of top two stack elements", 2, 1),
"MD" : ("Measure Distance", 2, 1),
"MDAP" : ("Move Direct Absolute Point", 1, 0),
"MDRP" : ("Move Direct Relative Point", 1, 0),
"MIAP" : ("Move Indirect Absolute Point", 2, 0),
"MIN" : ("MINimum of top two stack elements", 2, 1),
"MINDEX" : ("Move the INDEXed element to the top of the stack", 1, 3),
"MIRP" : ("Move Indirect Relative Point", 2, 0),
"MPPEM" : ("Measure Pixels Per EM", 0, 1),
"MPS" : ("Measure Point Size", 0, 1),
"MSIRP" : ("Move Stack Indirect Relative Point", 1, 0),
"MUL" : ("MULtiply", 2, 1),
"NEG" : ("NEGate", 1, 1),
"NEQ" : ("Not EQual", 2, 1),
"NOT" : ("logical NOT", 1, 1),
"NPUSHB" : ("PUSH N Bytes", -1, 0),
"NPUSHW" : ("PUSH N Words", -1, 0),
"NROUND" : ("No ROUNDing of value", 1, 1),
"ODD" : ("ODD", 1, 1),
"OR" : ("logical OR", 2, 1),
"POP" : ("POP top stack element", 1, 0),
"PUSHB" : ("PUSH Bytes", -4, 0),
"PUSHW" : ("PUSH Words", -4, 0),
"RCVT" : ("Read Control Value Table entry", 1, 1),
"RDTG" : ("Round Down To Grid", 0, 0),
"ROFF" : ("Round OFF", 0, 0),
"ROLL" : ("ROLL the top three stack elements", 3, 3),
"ROUND" : ("ROUND value", 1, 1),
"RS" : ("Read Store", 1, 1),
"RTDG" : ("Round To Double Grid", 0, 0),
"RTG" : ("Round To Grid", 0, 0),
"RTHG" : ("Round To Half Grid", 0, 0),
"RUTG" : ("Round Up To Grid", 0, 0),
"S45ROUND" : ("Super ROUND 45 degrees", 1, 0),
"SANGW" : ("Set Angle Weight", 1, 0),
"SCANCTRL" : ("SCAN conversion ConTRoL", 1, 0),
"SCANTYPE" : ("SCANTYPE", 1, 0),
"SCFS" : ("Sets Coordinate From the Stack using projection vector and freedom vector", 2, 0),
"SCVTCI" : ("Set Control Value Table Cut-In", 1, 0),
"SDB" : ("Set Delta Base in the graphics state", 1, 0),
"SDPVTL" : ("Set Dual Projection Vector To Line", 2, 0),
"SDS" : ("Set Delta Shift in the graphics state", 1, 0),
"SFVFS" : ("Set Freedom Vector From Stack", 2, 0),
"SFVTCA" : ("Set Freedom Vector To Coordinate Axis", 0, 0),
"SFVTL" : ("Set Freedom Vector To Line", 2, 0),
"SFVTP" : ("Set Freedom Vector To Projection Vector", 0, 0),
"SHC" : ("SHift Contour using reference point", 1, 0),
"SHP" : ("SHift Point using reference point", 1, 0),
"SHPIX" : ("SHift point by a PIXel amount", 2, 0),
"SHZ" : ("SHift Zone using reference point", 1, 0),
"SLOOP" : ("Set LOOP variable", 1, 0),
"SMD" : ("Set Minimum Distance", 1, 0),
"SPVFS" : ("Set Projection Vector From Stack", 2, 0),
"SPVTCA" : ("Set Projection Vector To Coordinate Axis", 0, 0),
"SPVTL" : ("Set Projection Vector To Line", 2, 0),
"SROUND" : ("Super ROUND", 1, 0),
"SRP0" : ("Set Reference Point 0", 1, 0),
"SRP1" : ("Set Reference Point 1", 1, 0),
"SRP2" : ("Set Reference Point 2", 1, 0),
"SSW" : ("Set Single Width", 1, 0),
"SSWCI" : ("Set Single Width Cut-In", 1, 0),
"SUB" : ("SUBtract", 2, 1),
"SVTCA" : ("Set freedom and projection Vectors To Coordinate Axis", 0, 0),
"SWAP" : ("SWAP the top two elements on the stack", 2, 2),
"SZP0" : ("Set Zone Pointer 0", 1, 0),
"SZP1" : ("Set Zone Pointer 1", 1, 0),
"SZP2" : ("Set Zone Pointer 2", 1, 0),
"SZPS" : ("Set Zone PointerS", 1, 0),
"UTP" : ("UnTouch Point", 1, 0),
"WCVTF" : ("Write Control Value Table in Funits", 1, 0),
"WCVTP" : ("Write Control Value Table in Pixel units", 2, 0),
"WS" : ("Write Store", 2, 0),
}
stack1_command = ("NPUSHB", "NPUSHW")
stack2_command = ("PUSHB", "PUSHW")
normal_command = []
for i in range(6):
normal_command.append( [ j for j in ins_dict.keys() if ins_dict[j][1]==i ] )
# -1=FIRST BYTE IS ONE BYTE COUNTER,
# -2=FIRST BYTE IS TWO BYTE COUNTER,
# -3=CLEAR STACK
# -4=REQUIRE PROCESS
pop_command = []
pop_command.append([])
for i in range(-1, -4, -1):
pop_command.append( [ j for j in ins_dict.keys() if ins_dict[j][1]==i ] )
def line_format(cmd,stack,desc):
#STRING, LIST, STRING
return "%-24s %-10s ;%10s" % (cmd, " ".join(stack), desc,)
def ins_decode(txt):
txtlist = txt.split("\n")
newlist = []
commentlist = []
stacklist = []
sloop = 0
i = 0
while i < len(txtlist):
if "[" in txtlist[i]:
c1,c2 = txtlist[i].strip().split("[",1)
else:
c1,c2 = txtlist[i].strip(), ""
#SKIP EMPTY LINE
if c1 == "":
i += 1
continue
#STACK: NPUSHB, NPUSHW
if c1 in stack1_command:
i += 1
n = int(txtlist[i].strip())
i += 1
while n > 0:
stacklist.append(txtlist[i].strip())
i += 1
n -= 1
continue
#STACK2: PUSHB, PUSHW
if c1[:5] in stack2_command:
n = int(txtlist[i].strip()[6:])
i += 1
while n > 0:
stacklist.append(txtlist[i].strip())
i += 1
n -= 1
continue
temp_list = []
#POP ONE
if c1 in pop_command[1]:
idx = stacklist.pop()
temp_list = [idx]
for j in range(int(idx)):
temp_list.append(stacklist.pop())
newlist.append(line_format(txtlist[i],temp_list,ins_dict[c1][0]))
i += 1
continue
#POP PAIR
elif c1 in pop_command[2]:
idx = stacklist.pop()
temp_list = [idx]
for j in range(int(idx)):
temp_list.append(stacklist.pop())
temp_list.append(stacklist.pop())
newlist.append(line_format(txtlist[i],temp_list,ins_dict[c1][0]))
i += 1
continue
#POP ALL (CLEAR STACK)
elif c1 in pop_command[3]:
stacklist = []
newlist.append(line_format(txtlist[i],temp_list,ins_dict[c1][0]))
i += 1
continue
#NORMAL COMMAND
if c1 in normal_command[0]:
count = 0
elif c1 in normal_command[1]:
count = 1
elif c1 in normal_command[2]:
count = 2
elif c1 in normal_command[3]:
count = 3
elif c1 in normal_command[4]:
count = 4
elif c1 in normal_command[5]:
count = 5
else:
count = -1
print 'count-1:',c1
if count > 0:
if sloop > 0:
count += sloop-1
sloop = 0
while count > 0:
cnum = stacklist.pop()
temp_list.append(cnum)
if c1 == 'SLOOP':
sloop = int(cnum)
count -= 1
newlist.append(line_format(txtlist[i],temp_list,ins_dict[c1][0]))
i += 1
print '--------------------------------------'
print '\n'.join(newlist)
if __name__ == "__main__":
txt = sys.argv[1]
ins_decode(txt)
เนื่องจากทำแบบหยาบ ๆ ใช้ลำบากหน่อย
เรียกใช้ด้วยคำสั่ง
$ ./dfont.py "
แปะด้วยโค๊ดที่คัดลอกมาจากฟอนต์ อักขระ n
"
ได้ผลเป็น
SRP0 20 ;Set Reference Point 0
MIRP[rp0,min,rnd,grey] 70 11 ;Move Indirect Relative Point
MIRP[min,rnd,grey] 8 9 ;Move Indirect Relative Point
SHP[rp2] 13 ;SHift Point using reference point
MIRP[rp0,rnd,grey] 78 0 ;Move Indirect Relative Point
MIRP[min,rnd,grey] 8 2 ;Move Indirect Relative Point
IUP[x] ;Interpolate Untouched Points through the outline
SVTCA[y-axis] ;Set freedom and projection Vectors To Coordinate Axis
MDAP[rnd] 1 ;Move Direct Absolute Point
ALIGNRP 10 ;ALIGN to Reference Point
MIRP[rnd,grey] 188 12 ;Move Indirect Relative Point
MIRP[rp0,rnd,grey] 184 17 ;Move Indirect Relative Point
MDRP[rnd,grey] 14 ;Move Direct Relative Point
MIRP[min,rnd,grey] 135 6 ;Move Indirect Relative Point
SRP1 1 ;Set Reference Point 1
SRP2 14 ;Set Reference Point 2
SLOOP 3 ;Set LOOP variable
IP 0 9 3 ;Interpolate Point
IUP[y] ;Interpolate Untouched Points through the outline
SVTCA[x-axis] ;Set freedom and projection Vectors To Coordinate Axis
DELTAP1 2 21 207 21 96 ;DELTA exception P1
ทดสอบอีกอันนึง เป็นอักขระ a
SRP0 38 ;Set Reference Point 0
MIRP[rp0,min,rnd,grey] 69 20 ;Move Indirect Relative Point
MIRP[min,rnd,grey] 8 3 ;Move Indirect Relative Point
MDRP[min,rnd,grey] 31 ;Move Direct Relative Point
MDRP[rp0,rnd,grey] 11 ;Move Direct Relative Point
MIRP[min,rnd,grey] 8 9 ;Move Indirect Relative Point
SHP[rp2] 13 ;SHift Point using reference point
SHP[rp2] 24 ;SHift Point using reference point
SRP1 3 ;Set Reference Point 1
IP 23 ;Interpolate Point
IP 0 ;Interpolate Point
IUP[x] ;Interpolate Untouched Points through the outline
SVTCA[y-axis] ;Set freedom and projection Vectors To Coordinate Axis
MDAP[rnd] 12 ;Move Direct Absolute Point
MDRP[rnd,grey] 23 ;Move Direct Relative Point
MIRP[rnd,grey] 140 17 ;Move Indirect Relative Point
MIRP[rp0,rnd,grey] 184 35 ;Move Indirect Relative Point
MIRP[rp0,min,rnd,grey] 185 28 ;Move Indirect Relative Point
MIRP[rp0,rnd,grey] 186 31 ;Move Indirect Relative Point
MIRP[min,rnd,grey] 134 32 ;Move Indirect Relative Point
SRP0 17 ;Set Reference Point 0
MDRP[rnd,white] 14 ;Move Direct Relative Point
MIRP[min,rnd,white] 185 6 ;Move Indirect Relative Point
SRP0 23 ;Set Reference Point 0
MIRP[min,rnd,white] 169 0 ;Move Indirect Relative Point
SRP1 14 ;Set Reference Point 1
IP 9 ;Interpolate Point
SRP1 23 ;Set Reference Point 1
IP 11 ;Interpolate Point
SRP2 31 ;Set Reference Point 2
IP 25 ;Interpolate Point
IUP[y] ;Interpolate Untouched Points through the outline
DELTAP1 24 33 128 32 128 31 128 30 128 33 112 32 112 31 112 30 112 33 96 32 96 31 96 30 96 33 80 32 80 31 80 30 80 33 64 32 64 31 64 30 64 33 48 32 48 31 48 30 48 ;DELTA exception P1
SVTCA[x-axis] ;Set freedom and projection Vectors To Coordinate Axis
DELTAP1 30 39 240 39 160 39 144 34 133 33 135 32 135 31 135 30 135 29 133 39 112 39 80 34 80 33 80 32 80 31 80 30 80 29 80 34 64 33 64 32 64 31 64 30 64 29 64 39 63 34 48 33 48 32 48 31 48 30 48 29 48 ;DELTA exception P1