Theppitak's blog

My personal blog.

31 พฤษภาคม 2550

Stem Hinting

ขณะที่ rasterizer พยายามปรับ spline ให้ลงล็อคกับตารางจุดจอภาพนั้น จะต้องมีการขยับจุดต่าง ๆ ซึ่งการ hint เกี่ยวกับความกว้าง stem จะช่วยรักษาระยะห่างระหว่างจุดที่ควรจะไปด้วยกันให้คงที่ เพื่อให้เส้นหนาสม่ำเสมอ hint ที่เกี่ยวกับ stem มีสองส่วน คือ global hint กับ hint ใน glyph

global hint อยู่ใน PS Private ได้แก่ StdHW, StdVW, StemSnapH, StemSnapV โดยแต่ละตัวมีความหมายดังนี้:

  • StdHW และ StdVW หมายถึงความกว้างปกติของเส้นนอนและเส้นตั้งของทั้งฟอนต์ เวลา rasterize ฟอนต์ที่ขนาดเล็ก ๆ ซึ่งความหนาที่ต่างกันเพียงหนึ่งจุดจะมีผลมากนั้น ถ้า stem ไหนความกว้างต่างจากค่าความกว้างปกติเพียงเล็กน้อย ก็จะตบให้เท่าค่าปกตินี้
  • StemSnapH และ StemSnapV เป็นแอร์เรย์ของความกว้าง stem แนวนอนและแนวตั้งที่ปรากฏมากในฟอนต์ตามลำดับ ค่า snap เหล่านี้ จะใช้ตบความกว้าง stem ให้ลงล็อคที่ค่าเหล่านี้ในทำนองเดียวกัน

ส่วน hint ที่อยู่ใน glyph นั้น ก็มีสองชนิด คือ hstem (HHint) และ vstem (VHint) สำหรับกำกับความกว้างของเส้นแนวนอนและแนวตั้งแต่ละเส้นใน glyph ตามลำดับ ซึ่งการใส่ hint เหล่านี้ จะเป็นการกำกับเส้นแต่ละเส้น ว่าตรงไหนเป็น stem บ้าง พร้อมทั้งความกว้างด้วย

ในการปรับตำแหน่ง spline ให้ลงล็อค rasterizer จะอาศัยข้อมูล hstem และ vstem ในการรักษาความกว้างของเส้น และในโพสต์สคริปต์รุ่นใหม่ ๆ จะมีการตบเส้นด้วย global hint ที่กล่าวถึงข้างต้นนี้ด้วย

วิธีการเพิ่มและปรับแต่ง hint ด้วย fontforge อ่านได้จาก คู่มือ อนึ่ง ถ้าจะอ่านข้อมูลอ้างอิง เรื่อง hstem และ vstem ใน Adobe Type 1 Font Format จะอยู่ในบทที่ 6 เรื่อง CharStrings Dictionary

ทิ้งท้ายด้วยเกร็ดนิดหนึ่ง เกี่ยวกับการ hint ฟอนต์ไทยบางฟอนต์ ที่มีลักษณะหัวพยัญชนะล้ำเข้าไปในเส้นตั้ง เช่น Garuda ซึ่งหากสั่ง Autohint แล้ว fontforge จะกำกับ vstem ทั้งเส้นตั้งและด้านในของหัว โดยใช้ hint mask กำกับเพื่อแยก vstem ที่ซ้อนเหลื่อมกัน (สังเกตวงกลมที่วงรอบจุดควบคุม บ่งบอกว่ามี hint mask กำกับ) ผลคือ เส้นขวาสุดของ ว แหวน ในตัวอย่างนี้ จุดบนกับจุดล่างถูก hint แยกกัน ทำให้ในบางขนาด เส้นนี้กลับไม่อยู่ในแนวดิ่ง ทำให้หัวเลอะ ดังตัวอย่าง Garuda Bold ที่ 18 pt:

Garuda Bold witn auto-hinted vstem -- font design Garuda Bold witn auto-hinted vstem -- rendered at 18 pt

เมื่อตัด hint ที่ overlap นั้นออก เส้นก็กลับมาอยู่ในแนวดิ่งอีกครั้ง:

Garuda Bold with head vstem removed -- font design Garuda Bold with head vstem removed -- rendered at 18 pt

เรื่องนี้อาจเป็นเรื่องได้อย่างเสียอย่าง เพราะการได้เส้นที่ตั้งตรงมา ก็แลกกับการที่หัวพยัญชนะบางตัวไม่กลมดิก ซึ่งเรื่องนี้คงไม่มีสูตรสำเร็จตายตัว ต้องพิจารณาเป็นรายฟอนต์ไป ผ่านการทดลองฟอนต์ที่หลาย ๆ ขนาด แล้วหาวิธี hint ที่ดีที่สุดสำหรับฟอนต์นั้น ๆ

ป้ายกำกับ:

30 พฤษภาคม 2550

Postscript Hinting

หลังจากเตรียม spline อย่างถูกต้องไปแล้ว ก็มาถึงแนวคิดการทำ hint ของฟอนต์โพสต์สคริปต์ ซึ่งแตกต่างจาก hint ของ TrueType

คำอธิบาย ในเอกสารของ fontforge ให้แนวคิดคร่าว ๆ ได้ดี คือ hint ของโพสต์สคริปต์นั้น มีค่า global ของฟอนต์อยู่ แล้วก็มี stem hint ที่แต่ละ glyph การบรรยาย hint จะอยู่ในรูปพารามิเตอร์ แล้ว rasterizer จะนำพารามิเตอร์ต่าง ๆ เหล่านี้มาใช้ประกอบการวาด glyph ตามขั้นตอนของ rasterizer เอง ซึ่งต่างจาก hint ของ TrueType ที่ hint จะกำหนดเป็น "instruction" ที่ระบุเป็นขั้น ๆ ลงใน glyph แต่ละ glyph เลย ว่าจะปรับ spline ตามขั้นตอนอย่างไร rasterizer ของ TrueType มีหน้าที่ execute instruction เหล่านั้นแบบทื่อ ๆ เท่านั้น

ฉะนั้น คนทำฟอนต์ TrueType จึงเหนื่อยกว่าคนทำฟอนต์โพสต์สคริปต์เยอะ และในขณะเดียวกัน อักษรที่วาดจากฟอนต์โพสต์สคริปต์จะสวยไม่สวย ขึ้นอยู่กับความเก่งของ rasterizer เป็นหลัก ฟอนต์เดียวกันอาจวาดออกมาไม่เหมือนกันในระบบต่าง ๆ ได้

global hint ที่สำคัญของฟอนต์โพสต์สคริปต์ ได้แก่ค่า BlueValues ซึ่งใช้ตีเส้นความสูงระดับต่าง ๆ ของอักขระ เส้นเหล่านี้แต่ละเส้นจะเป็นแถบในแนวนอนให้จุดควบคุม spline ไปเกาะ โดยความกว้างของแถบจะกลายเป็นระยะ overshoot ของอักขระที่ส่วนสัมผัสแถบเป็นเส้นโค้ง เช่น O C G Q เป็นอักขระที่ด้านบนเป็นเส้นโค้ง เวลาวาดจะต้องให้สูงกว่าเส้นที่เป็นหัวตัดตรง เช่น I H E เพราะถ้าสูงเท่ากันมันจะลวงตา ทำให้ดูเหมือนเตี้ยกว่า

สรุปว่า BlueValues คือชุดของแถบที่ตีกำหนดขอบเขตความสูงระดับต่าง ๆ ไล่จากเส้น baseline ขึ้นข้างบน โดยกำหนดเป็นตัวเลขเป็นคู่ ๆ แทนด้านล่างและด้านบนของแถบ เริ่มจากแถบที่ baseline เอง ขึ้นไปที่แถบของ x-height แล้วก็แถบความสูงอักษรไทย ตามด้วยแถบ Capital Ascender

BlueValues

คุณกำหนดค่าของ BlueValues ได้ที่ Element > Font Info > PS Private โดยสามารถเพิ่มค่าแล้วให้โปรแกรมประเมินค่าเอาได้ แต่มีโอกาสที่จะเดาไม่เจอความสูงอักษรไทย ซึ่งไม่เป็นไร คุณสามารถแทรกข้อมูลเพิ่มได้ ในการแทรก อย่าลืมว่าค่า BlueValues ต้องเรียงลำดับจากน้อยไปมาก และไม่นับรวม blue zone ที่อยู่ใต้ baseline ลงไป ถ้าจะกำหนดแถบใต้ baseline คุณต้องกำหนดใน OtherBlues แทน

ที่ เว็บของ Adobe มีข้อมูลเทคนิคของฟอนต์โพสต์สคริปต์ สำหรับเรื่อง global hint เหล่านี้ อ่านได้ในเอกสาร Adobe Type 1 Font Format อยู่ในบทที่ 5 เรื่อง Private Dictionary ในนั้นมีค่าอื่น ๆ ที่น่าสนใจอีก คือ StdHW, StdVW, StemSnapH, StemSnapV

ค่า BlueValues จะช่วยกำกับให้ตัวอักษรสูงสม่ำเสมอทั้งบรรทัด ค่าอื่น ๆ ก็ช่วยควบคุมความสม่ำเสมออื่น ๆ แต่ก็ยังมี hint สำหรับ stem แต่ละ stem ของตัวอักษรอีก ไว้เขียนคราวหน้า

ป้ายกำกับ:

28 พฤษภาคม 2550

Font Tips Notes

บันทึกเกร็ดของการทำฟอนต์ ทำยังไงให้ hint สวย ซึ่งความจริงถ้าเข้าใจหลักการ ก็ไม่ยากอย่างที่คิด (เฉพาะ Postscript นะครับ TrueType ไม่นับ) ที่เหลือก็อยู่ที่ความปราณีตและความอดทนเท่านั้น

ผมพยายามเก็บประสบการณ์จากการทำงานกับฟอนต์มาอยู่ระดับหนึ่ง ก็พอจะจับทางได้บ้าง แต่เมื่อไปพบตำราฟอนต์ Type by Design - The Art and Science of Digital Typeface Design ทำให้เข้าใจอะไรมากขึ้น และมั่นใจในสิ่งที่เรียนรู้มากขึ้น หากใครสนใจศึกษาการทำฟอนต์ ขอแนะนำให้อ่านครับ

เข้าเรื่องล่ะนะ ว่าด้วยการทำฟอนต์ให้ hint สวย

ต้องเริ่มจากการวาด spline ของตัวอักษรก่อน ถ้าวางจุดไม่เหมาะสม จะ hint ให้ตายยังไงก็ไม่เป็นผล เพราะการ hint คือการปรับตำแหน่งจุดให้ลงล็อคกับจุดสีบนหน้าจอ ถ้าตำแหน่งสำคัญที่จะปรับกลับไม่มีที่ให้จับ ก็จะไม่สามารถ hint ได้

Spline and Hinting

จากรูป แสดงจุดสำคัญของอักษร p ที่จะมีผลกับการ hint โดย 2 จุดซ้ายไม่เกี่ยว แต่ 3 จุดขวานั้น เส้นนอนและเส้นตั้งของโค้งจะถูกปรับตำแหน่งและความหนาของเส้นให้พอดีกับ grid ของจอภาพ โดยมี stem hint กำกับความหนาของเส้นไว้ การวาดเส้นโค้ง จึงจำเป็นอย่างยิ่งที่ต้องกำหนดจุดตรงจุดวิกฤติเหล่านี้

ดังนั้น การวาด spline จึงมีหลักการโดยทั่วไปคือ

Do and Don't for spline drawing

  1. ต้องมีจุดของเส้นโค้งที่ตำแหน่งที่เส้นโค้งอยู่ในแนวราบและตั้งฉากเสมอ เพราะเป็นจุดสำคัญสำหรับการ hint อีกทั้งยังทำให้แก้ไขเส้นโค้งได้ง่ายอีกด้วย ใน fontforge คุณสามารถใช้คำสั่ง Element > Add Extrema เพื่อเพิ่มจุดที่ตำแหน่งเหล่านี้ได้
  2. ส่วนที่เส้นโค้งมีความสมมาตร ก็ควรให้ความยาวของเส้นควบคุมต่าง ๆ มีความสมมาตรกันด้วย
  3. ไม่ควรมีจุดควบคุมมากเกินไปหรือน้อยเกินไป ถ้ามีมากเกินไป ก็จะทำให้ข้อมูลฟอนต์ใหญ่เกินจำเป็น ทั้งยังทำให้แก้ไขยาก และถ้าน้อยเกินไป ข้อมูลสำหรับ hint ก็อาจไม่พอ หรืออาจกินเวลา rasterize นานขึ้น ใน fontforge คุณสามารถใช้คำสั่ง Element > Simplify > Simplify เพื่อตัดจุดที่ไม่จำเป็นออกได้ ส่วนจุดที่ขาดนั้น Add Extrema ช่วยคุณได้
  4. ระวังอย่าให้เกิดเส้นขมวด (kink) โดยเส้นควบคุมไม่ควรตัดกันหรือพุ่งเกยกัน (ดูรูปข้างล่าง) เส้นขมวดนี้ถือเป็นข้อบกพร่องของ spline เพราะทำให้เส้นโค้งขาดความแน่นอน ไม่ควรตระหนี่จุดควบคุมด้วยการลักไก่เช่นนั้น

Kinks in spline

เครื่องมือที่น่าใช้ของ Fontforge เกี่ยวกับการปรับ spline:

  • Element > Add Extrema สำหรับเพิ่มจุดที่จุดวิกฤติของเส้นโค้ง
  • Element > Simplify > Simplify สำหรับค้นหาและตัดจุดที่ไม่จำเป็นออก
  • Edit > Elide สำหรับเลือกตัดจุดที่ต้องการออก โดยพยายามประมาณค่าที่จุดข้างเคียงเพื่อชดเชยด้วย ใช้สำหรับการ simplify เส้นโค้งแบบ manual และแน่นอนว่าคุณต้องปรับจุดข้างเคียงที่เครื่องคำนวณให้นั้นอีกครั้ง เพื่อความลงตัว
  • Element > Round > To Int ช่วยปัดค่าของจุดต่าง ๆ ให้เป็นจำนวนเต็ม คุณควรสั่ง Round to int ไว้เสมอ เพื่อให้กำหนดสัดส่วนต่าง ๆ ที่ตายตัวได้ เช่น ความกว้างของเส้น

ยาวแล้วละ คิดว่าคงเป็นประโยชน์ต่อผู้สนใจศึกษา แต่อย่างน้อยก็มีประโยชน์ที่เป็นบันทึกช่วยจำสำหรับตัวผมเอง :-)

ภาพประกอบต่าง ๆ ได้มาจากเว็บตำราทำฟอนต์ข้างต้นครับ

ป้ายกำกับ:

24 พฤษภาคม 2550

Mozilla Pango Break Checked-in!

แพตช์ตัดคำด้วย Pango ใน Gecko ได้ check-in แล้ว หลังจากแช่แพตช์รอคอมเมนต์อยู่ใน bug มาเกือบเดือน เห็นว่าโค้ดใน trunk เริ่มเข้าที่เข้าทาง ตัวเองก็เริ่มนั่งทำงานได้นานขึ้น เลย request ขอ review ไปคืนวันที่ 19 ได้รับ review comment ชุดแรกเช้าวันที่ 21 เป็นอันว่าวันนั้นไม่เป็นอันทำอย่างอื่น รีบแก้ patch ตาม roc เองก็ดีใจหาย ตอบอย่างรวดเร็ว แก้ไปแก้มา โค้ดดูสะอาดขึ้นเรื่อย ๆ จนในที่สุดก็ผ่าน review + superreview ภายในเย็นวันนั้น

ผ่านมาวันเศษ เช้าวันที่ 23 roc บอกว่า check-in patch ให้แล้ว!! แต่หลังจากนั้นไม่นานก็เอา patch ออก เนื่องจาก build ไม่ผ่าน เพราะ patch ผมใช้ pango API ที่ต้องการ pango รุ่นใหม่กว่าที่ mozila ใช้ แต่หลังปรับแก้ patch ก็ได้ check-in อีกครั้งในเช้าวันนี้ โดยโค้ดนี้จะมีผลใน Firefox® 3

เป็นอันว่า bug ตัดคำไทย ที่รอมาเกือบ 8 ปี วันนี้ได้ solution แรกที่ต้นน้ำ (โดยไม่ต้องอาศัย extension หรือ local patch) แล้วบน Unix platform นับตั้งแต่ที่ rule-based solution ของพี่สัมพันธ์ถูกตัดออกไป ส่วนแพลตฟอร์มอื่นๆ รอคนทำโค้ดเชื่อม Uniscribe, ATSUI ต่อไปครับผม

ป้ายกำกับ: , ,

19 พฤษภาคม 2550

Rainy

สี่ห้าวันก่อน หลังฝนตก อากาศดี ไปเดินเล่นในสวนเลยได้ภาพชุดนี้มา

'Rainy' Photo Set

วันที่ถ่าย: ๑๕ พ.ค. ๒๕๕๐ สวนดอกไม้ของแม่ครับ ขอยกเครดิตความงามให้ :-)

ป้ายกำกับ:

14 พฤษภาคม 2550

Justified Text in Pango

เห็นจาก blog ของ Behdad หลายวันละ เกี่ยวกับ justified text ใน pango อดรนทนไม่ได้ เลย build GNOME 2.19 ซะ เพื่อดูว่าภาษาไทยเป็นยังไง

Justified Thai text

ปรากฏว่าใช้การได้ดี แต่ติดที่ว่า เขาทำ character spacing เฉพาะในบรรทัดที่ไม่มี space นี่สิ ภาษาไทยเราใช้ space น้อย ทำให้เวลาเว้นทีมันห่างเป็นวาเลย

แต่แค่นี้ก็เจ๋งละ รอมานาน :)

ป้ายกำกับ:

11 พฤษภาคม 2550

Dry-Eye Candidate

อาการตาแห้งยังไม่ค่อยดีขึ้น หลังจากหมอตรวจแล้ว บอกว่าพบอาการภูมิแพ้ที่เยื่อบุตา โห.. ฟังดูน่ากลัวจัง แต่จริง ๆ ไม่มีอะไรมากหรอก อาการคือตาขาวแดงเล็กน้อย ไม่มีน้ำตา ทำให้รู้สึกแสบ โดยเฉพาะเมื่อโดนลม ไม่ว่าจะเป็นพัดลมหรือลมธรรมชาติ แต่ฟังหมอแล้วก็อยากรู้ต่อ อาจเป็นอาการที่เรียกว่า Allergic conjunctivitis แต่คิดว่า Keratoconjunctivitis sicca (Dry Eye) น่าจะตรงกว่า ก็คงไม่มีอะไรมากครับ แค่หยอดยาหยอดตา กินยา หลีกเลี่ยงการปะทะลมในช่วงนี้ แล้วก็พักผ่อนสายตามาก ๆ

แต่ยอมรับว่า ระหว่างพักก็ไม่ได้พักจริง ๆ หรอก จู่ ๆ จะให้ทิ้งคอมพ์ไปเลยคงยาก (ขนาดจะหารายละเอียดอาการและการรักษา ยังมาเปิดวิกิพีเดียเลย) ก็ยังเอางานมาทำเท่าที่ทำได้ แต่ไม่ทำมากเกินไป เป็นงานจิปาถะที่คั่งค้าง เช่น ปรับข้อมูลบางชิ้นของโรงเรียน แล้วก็มาทำข้อสอบ Debian NM ที่ดองไว้เป็นชาติต่อ ดองเก่งขนาดนี้ กว่าจะผ่านคงเป็นปลาร้าพอดี คนที่ตั้งใจทำจริง ๆ แบบไม่ติดงานอื่น แค่ 6 เดือนก็ผ่านหมดแล้ว :P ช่วงนี้ผ่านมาถึงขั้น Tasks and Skills อยู่ เป็นการลุยงานพิสูจน์ฝีมือ ด้วยการช่วยแก้บั๊กต่าง ๆ ซึ่งความจริง เขาบอกให้เริ่มทำตั้งแต่ช่วง etch freeze ซึ่งจะได้ช่วยเขาแก้ RC bug ด้วย แต่ดันติดงานอื่นเสีย เลยเสียโอกาสเข้าร่วม Bug Squad Party อย่างน่าเสียดาย ความจริงถ้าได้ทำช่วงนั้นจะเหมาะ เพราะทำ NMU ได้รวดเร็ว แต่มัวติดงานอื่นอยู่ แถมตอนที่เขาบอก ก็เป็นช่วงท้ายของ etch freeze แล้ว บั๊กที่เหลือส่วนมากแก้ยาก หรือเป็นบั๊กระดับที่ต้องอาศัยการตัดสินใจระดับนโยบาย

ตอนนี้ได้โอกาส ระหว่างพักก็เลยหยิบ bug เล็ก ๆ น้อย ๆ ขึ้นมาทำ ทำ NMU ปิดบั๊กไปบางตัว แต่ก็เล่นเอาหืดจับเหมือนกัน ต้องขออนุญาต maintainer ตัวจริง ขอทำ NMU ด้วย ต้องติดต่อ sponsor ด้วย แต่สภาพร่างกายเป็นอย่างนี้ก็ใจร้อนไม่ได้ ค่อย ๆ ทำ ค่อย ๆ รอไป ตอนนี้ NMU ไปได้หนึ่งรายการ (pcmanx-gtk2 โดยอาศัยการ sponsor ของ Mike Hommey) เดี๋ยวว่าง ๆ มาแก้บั๊กอื่นต่อ

ปล. ยังมีใครอยากสมัครเป็น New Maintainer ของ Debian หรือ MOTU ของ Ubuntu อยู่หรือเปล่า? รู้สึกคุยกับใครก็เน้นแต่ชุมชนผู้ใช้ ฝั่งนักพัฒนาเงียบเกินไปหรือเปล่า?

ป้ายกำกับ: ,

03 พฤษภาคม 2550

Dry Eyes

สงสัยต้องหยุดทำงานสักพัก.. หลังจากเสร็จ Garuda ก็กลับมา Loma อีกครั้ง โดยพยายามปรับความกว้างของ stem ให้สม่ำเสมอตลอดฟอนต์ แล้วก็แก้ปัญหาของ spline แบบที่พบใน Garuda จบแล้วต่อด้วย TlwgTypist

ทำฟอนต์ติดต่อกันนาน ๆ เป็นอาทิตย์ นิ้วชักปวดจากการลาก spline ด้วย mouse และกด hot key แถมแผลสังกะสีบาดนิ้วจากการขึ้นไปช่วยแม่ซ่อมหลังคาก็ยังไม่หายดี ที่สำคัญ ตาที่เพ่งหน้าจอติดต่อกันนาน ๆ เริ่มแห้งและแสบ

คงต้องยอมรับข้อจำกัดของร่างกาย ใจนั้นอยากทำมากกว่านั้น เพราะจังหวะเวลาว่างต่อเนื่องแบบนี้หาไม่ได้ง่ายนัก แต่ถึงจะอยากตักตวงใช้ยังไง เราก็ทำได้แค่นี้แหละ ขอออฟไลน์สักพักเพื่อพักฟื้นนะครับ

กะจะ blog เรื่องเกร็ดของการทำฟอนต์ ไว้พักเสร็จแล้วค่อยกลับมาเขียน

ป้ายกำกับ:

hacker emblem