fonts: ตัวอย่างการ hint ก.ไก่

มีค่า cvt ของฟอนต์ DejaVu Sans ที่เกี่ยวข้อง ทำเป็นตัวแปรแบบดิกชันนารีในไพธอน คือ
cvt_dict = {
    ...
    "front_kai":      11,     #113    =front spacing of ko_kai 
    "hstem":          8,      #184    =horizontal stem width
    "w_881":          163,    #881    =width of ko kai
    "vheight_shoot":  184,    #1147   =overshoot height
    "vstem_curve":    185,    #156    =curve vertical stem width
    ...
}
ค่า cvt ของฟอนต์ ดูได้จากเมนูของ FontForge คือ Hints -> Edit 'cvt' ... โดยจะเรียงตั้งแต่ลำดับที่ 0 เป็นต้นไป
ค่า cvt ของ ก.ไก่ข้างต้น คือ กำหนดให้ลำดับที่ 11 (ซึ่งมีค่า 113) เป็นระยะช่องไฟด้านหน้า เป็นต้น โครง ก.ไก่ ตัวอย่างจะเริ่มด้วยการ hint ในแนวแกน X ก่อน (เป็นค่าปริยาย) จะแสดงเป็นโค๊ด instruction แบบจำลอง เพื่อให้ดูง่าย เวลาใช้งานจริง ก็นำไปเขียนเป็นโค๊ดในไพธอน โปรแกรม dfont.py จะคลี่แสต็กและเรียงออกมาเป็นโค๊ดจริง ๆ อีกที แนวแกน X
เส้นทาง hint ในแนวแกน X จุดเริ่มต้นคือจุดที่ 26 (จุดสุดท้ายคือ 25 + 1)
srp0                26
จากจุดเริ่มต้น จะเคลื่อนจุดอ้างอิง rp0 ไปยังจุดที่ใกล้ขอบซ้ายที่สุด คือจุด 18 เพื่อกั้นเป็นระยะช่องไฟด้านหน้า ด้วยค่า cvt คือ front_kai
การเคลื่อนด้วยการอ้างอิงค่า คำสั่งคือ MIRP
การเคลื่อนจุดอ้างอิงไปด้วย ใช้อาร์กิวเมนต์ rp0
การปัดเศษให้ลงจุด (round) ใช้อาร์กิวเมนต์ rnd
การแรเงาพื้นที่ ใช้อาร์กิวเมนต์ grey (ปกติควรเป็น white แต่ DejaVu ใฃ้ grey เสมอ จึงใช้ตาม เพื่อกันสับสน)
ค่า cvt ที่ใช้ คือ front_kai
จุดที่จะเคลื่อนไป คือ 18
mirp[rp0,min,rnd,grey]  front_kai 18
จุดที่จะไปต่อคือ จุด 8 แต่เนื่องจากเมื่อเคลื่อนไปแล้ว ไม่มีจุดที่จะไปต่อ เราจึงไม่ต้องเคลื่อนจุด rp0 ไปด้วย จึงไม่ต้องใส่อาร์กิวเมนต์ rp0
ระยะของปาก ก.ไก่ ไม่จำเป็นต้องเป็นค่าที่แน่นอนนัก เราจึงไม่ต้องอ้างค่า cvt จึงใช้คำสั่ง MDRP
ปัดเศษด้วย ใช้ rnd
แรเงา ใช้ grey
จุดที่เคลื่อนไปคือ 8
mdrp[min,rnd,grey]  8
ตอนนี้ rp0 ยังอยู่ที่เดิม คือ จุด 18 เราต้องเคลื่อนไปต่อที่จุด 17 และ 10 ตามลำดับ แต่หากเราเคลื่อนไปจุด 17 ก่อน แล้วต่อไปที่ 10 จะทำให้ระยะที่ถูกทด (round) แล้ว มีค่ามากเกินไป ทำให้ปาก ก.ไก่ ไม่สวยงาม เราจึงใช้การเคลื่อนไปที่จุด 10 ก่อน แล้วจึงย้อนมาที่ 17 อีกครั้งหนึ่ง ทำให้ได้ภาพที่สวยงามกว่า
mdrp[rp0,rnd,grey]  10
mdrp[min,rnd,grey]  17
จุดที่จะไปต่อคือจุด 14 แต่ตอนนี้จุดอ้างอิง rp0 มาอยู่ที่จุด 10 แล้ว หากเราเคลื่อนจากจุดนี้ไปเลย จะทำให้ระยะทดไม่แน่นอน จึงควรย้อนกลับไปที่จุดแรกคือ 18 จะดีกว่า
srp0                18
mdrp[rp0,rnd,grey]  14
ต่อไปเป็นการกำหนดความหนาของเส้นตั้ง (hstem) ต้องใช้ค่า cvt เสมอ
ต้องอ้างอิงจาก cvt คำสั่งคือ MIRP
ไม่ต้องย้าย rp0 ไปด้วย เพราะไม่มีจุดที่จะไปต่อ จึงไม่ต้องใช้อาร์กิวเมนต์ rp0
ถึงแม้ขนาดเส้นจะบางอย่างไร การแสดงผลต้องกำหนดค่าให้อย่างน้อย 1 จุดเสมอ ใช้อาร์กิวเมนต์ min
แรเงาใช้ grey
mirp[min,rnd,grey]  hstem  12
ต่อไปเป็นการกำหนดความกว้างของตัวอักษร ต้องใช้ cvt เสมอ โดยต้องย้ายจุด rp0 ไปด้วย เพื่อไปทำงานต่อ โดยจะกำหนดขนาดให้คลุมความกว้างรวมก่อน แล้วจึงย้อนมากำหนดความหนาของเส้นตั้งตัวหลังอีกครั้งหนึ่ง
mirp[rp0,rnd,grey]  w_881 25
mirp[min,rnd,grey]  hstem  1
กั้นเป็นฃ่องไฟด้านหลัง โดยไม่ต้องกำหนดระยะ min และเผื่อการแรเงาเป็น white เพื่อให้มีช่องว่างอย่างน้อย 1 จุดคั่นกับอักษรตัวถัดไป มีประโยชน์สำหรับฟอนต์ที่มีการทดลงจุดในแนวแกน X มาก ๆ ซึ่งจะทำให้ล้นความกว้างที่มีอยู่ (คำสั่งนี้คิดเอง เพื่อให้ไม่ต้องทำ delta hint ตามแบบของ DejaVu)
mdrp[rnd,white]     27
เกลี่ยจุดที่เรายังไม่ได้อ้างอิงในแนวแกน X ซึ่งจะใช้คำสั่งสี้ปิดท้ายเสมอ (IUP คือ Interpolate Untouched Point)
IUP[x]
แนวแกน Y
เส้นทาง hint ในแนวแกน Y เริ่มย้ายมาแกน Y
SVTCA[y-axis]
จะเริ่มต้นที่จุด 1 ในแนวแกน Y นี้ เรายังไม่ได้ทำอะไรเลย จึงควรปัดให้ลงจุดเสียก่อน
mdap[rnd]           1
บอกว่าจุด 13 อยู่ในระดับเดียวกับจุด 1
alignrp             13
กำหนดความสูงของฟอนต์
mirp[rp0,rnd,grey]  vheight_shoot    22
กำหนดความหนาของเส้นในแนวนอน
mirp[min,rnd,grey]  vstem_curve  5
กำหนดให้ rp1 เป็นจุด 5 และ rp2 เป็นจุด 13 เพื่อจะเกลี่ยจุดที่สำคัญอื่น ๆ โดยใช้ rp1 และ rp2 เป็นจุดอ้างอิงในการเฉลี่ยค่า
srp1                5
srp2                13
sloop               10
ip      19 8 18 9 17 10 2 25 15 12
เกลี่ยจุดที่เหลือ ในแนวแกน Y
IUP[y]
เมื่อนำโค๊ดที่เขียนมาถอดด้วยสคริปต์ dfont.py จะได้โค๊ด instruction ดังนี้
NPUSHB
 15
 27
 1
 8
 25
 163
 12
 8
 14
 18
 17
 10
 8
 18
 11
 26
SRP0
MIRP[rp0,min,rnd,grey]
MDRP[min,rnd,grey]
MDRP[rp0,rnd,grey]
MDRP[min,rnd,grey]
SRP0
MDRP[rp0,rnd,grey]
MIRP[min,rnd,grey]
MIRP[rp0,rnd,grey]
MIRP[min,rnd,grey]
MDRP[rnd,white]
IUP[x]
NPUSHB
 19
 12
 15
 25
 2
 10
 17
 9
 18
 8
 19
 10
 13
 5
 5
 185
 22
 184
 13
 1
SVTCA[y-axis]
MDAP[rnd]
ALIGNRP
MIRP[rp0,rnd,grey]
MIRP[min,rnd,grey]
SRP1
SRP2
SLOOP
IP
IUP[y]
จบแล้วครับ
Topic: