Theppitak's blog

My personal blog.

07 มกราคม 2563

Fine-tuning Quadratic Splines in Fontforge

นับจากที่ได้เพิ่ม layer ผสมใน Fonts-TLWG เพื่อแก้ปัญหาเรื่อง build reproducibility ในรุ่น 0.7.0 ก็ได้เปิดช่องทางสำหรับการ fine-tune quadratric spline ของฟอนต์ TrueType เพียงแต่ผมยังไม่ได้ทำกับ Fonts-TLWG ในทันที เพราะได้กลับไปทำ layer ผสมกับ Fonts-Arundina เสียก่อน และได้ถือโอกาสทดลอง fine-tune quadratic spline ต่อด้วย

หลังจากที่เพิ่ม layer ผสมกับทุกฟอนต์ในชุด Arundina แล้ว ก็ได้ทดลอง fine-tune quadratic spline ต่อ ซึ่งก็ทำเสร็จแค่ Arundina Sans เท่านั้น พอมาทำ Arundina Sans Mono ต่อ ปรากฏว่าเกิดเหตุ Fontforge ตายกลางคันขณะ save ทำให้ข้อมูลที่แก้ไขมาได้ครึ่งทางแล้วสูญหายทั้งหมด แม้แต่กระบวนการ recovery ของ Fontforge เองก็กู้ข้อมูลขึ้นมาไม่ได้! ถ้าจะเริ่มใหม่ก็ต้อง check out ฉบับที่ยังไม่ปรับเส้นจาก git ออกมาทำใหม่นั่นแหละ

เป็นอุทาหรณ์ว่าควร commit git ให้บ่อยกว่านี้ ถึงยังไม่เสร็จก็ควร commit ไว้ก่อน แล้วค่อยใช้ option --amend ในครั้งต่อ ๆ ไปก็ยังได้!

ก็เลยตัดสินใจหยุดทำ Arundina ไว้แค่นั้น แล้วเตรียมตัดออกรุ่นใหม่เสียก่อน โดยขอบันทึกสิ่งที่ได้เรียนรู้จากการปรับเส้นฟอนต์ Arundina ไว้ ณ ที่นี้ก่อน ก่อนที่จะนำไปใช้กับ Fonts-TLWG ต่อไป

ปรับ Quadratic และ Cubic Spline ไปด้วยกัน

ในระยะแรกนั้น ผมปรับเฉพาะ quadratic layer เข้าหา cubic layer โดยพยายามให้ curve ทาบกับ cubic layer ได้สนิทด้วยจำนวนจุดที่พอเหมาะ โดยตัดจุดที่ไม่จำเป็นออก และเติมจุดบางจุดที่เห็นว่าน่าจะเป็นประโยชน์ต่อการ hint แต่เมื่อได้ปรับไปเรื่อย ๆ ก็ได้พบกรณีที่ต้องปรับ cubic layer ควบคู่กันมากขึ้นเรื่อย ๆ จนในที่สุดผมก็ปรับทั้งสอง layer ควบคู่กัน ซึ่งปรากฏว่าคุณสมบัติของโค้งทั้งสองแบบได้เสริมกันและกันในการจัด control point ต่าง ๆ ได้เป็นอย่างดี

การปรับทั้งสอง layer ควบคู่กันยังมีข้อดีอีกอย่าง คือเราสามารถลดปริมาณงานในอนาคตหากมีการ copy ข้ามจาก cubic layer มายัง quadratic layer อีกด้วย เพราะจะได้จำนวนจุด quadratic ที่เหมาะสมทันที ไม่ต้องมานั่งปรับใหม่ รวมถึงกรณีที่ต้องการ generate ฟอนต์ TrueType ด้วยการแปลงจาก cubic layer กลางอากาศ (อย่างที่เราเคยทำในสมัยก่อน)

หรือแม้กระทั่งสำหรับการ generate ฟอนต์ PostScript หรือฟอนต์ OpenType ที่ใช้ cubic spline เอง ก็จะได้โค้งที่ได้สมมาตรสวยงาม และยังอาจช่วยให้ rasterize ได้เร็วขึ้นสำหรับบาง engine ได้อีกด้วย (เช่น สำหรับ rasterizer ที่ render Bézier curve ด้วยการแบ่งครึ่ง curve แบบ recursive บนพื้นฐานของ De Casteljau’s algorithm)

ส่วนวิธีการปรับนั้นจะกล่าวถึงต่อไปเป็นลำดับ

Quadratic Spline ใน Fontforge

จากที่ผมเคยเขียนเปรียบเทียบ quadratic และ cubic spline ไว้เมื่อนานมาแล้ว ทั้งในแง่คณิตศาสตร์ การแปลงระหว่างกัน จำนวนจุดที่ใช้แทนโค้ง และการแก้ไข โดยในส่วนของการแก้ไขนั้น ผมได้กล่าวไว้ว่าโค้ง quadratic แก้ไขยากกว่า เพราะการแก้ไขแต่ละจุดจะกระทบถึงจุดข้างเคียงเสมอ แต่ Fontforge มีสิ่งที่ช่วยคลายความอึดอัดตรงนี้ ด้วยจุดต่อโค้งชนิด interpolated ที่ตำแหน่งของจุดต่อโค้งจะคำนวณจากจุดควบคุมข้างเคียง ทำให้ลดการกระทบกระทั่งลงได้

จุด interpolated ในที่นี้ขอเรียกว่า จุดกะ ในโค้ง quadratic เป็นจุดต่อโค้ง (curve point) ที่อยู่กึ่งกลางระหว่างจุดควบคุมสองจุด และในทางกลับกัน จุดต่อโค้งที่มีแขนสองข้างยาวเท่ากันก็จะถือเป็นจุดชนิด interpolated โดยอัตโนมัติใน Fontforge เช่นกัน (ยกเว้นจุดที่ผู้ใช้กำหนดให้ห้าม interpolate)

Quadratic interpolated point

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

Editing with quadratic interpolated point

การประมาณ Cubic Curve ด้วย Quadratic Curve

ดังที่ได้กล่าวไว้ใน blog เดิม ว่าการแปลง quadratic curve เป็น cubic จะเป็นการแปลงแบบแม่นตรง แต่ในทางกลับกัน คือจาก cubic curve เป็น quadratic จะเป็นการประมาณเท่านั้น เนื่องจาก quadratic curve มีความเป็นอิสระ (degree of freedom) น้อยกว่า ดังนั้น เมื่อคุณคัดลอก spline จาก cubic layer มา quadratic layer จึงมีการประมาณค่าเกิดขึ้น

มีอัลกอริทึมจำนวนหนึ่งสำหรับประมาณ cubic curve ด้วย quadratic เช่น แบ่ง curve เป็นส่วนย่อย ๆ ที่เมื่อตัดสัมประสิทธิ์ดีกรีสามออกแล้วได้ quadratic curve ที่ใกล้เคียงพอ (มี paper ที่คล้ายกัน), แบ่งครึ่ง curve ที่ t=0.5 แล้ว solve หาจุดควบคุม quadratic curve ที่ใกล้เคียงของทั้งสองส่วน ฯลฯ

สำหรับ Fontforge แล้ว ใช้การประมาณด้วยจุดกะ โดยอยู่บนพื้นฐานของทฤษฎีซึ่งพบจากการทดลองแต่ยังไม่มีข้อพิสูจน์ทางคณิตศาสตร์ว่า ถ้าแบ่ง cubic curve เป็นช่วง ๆ ด้วย parameter ที่ห่างเท่า ๆ กันแล้ว ปรากฏว่าจุดแบ่งเหล่านั้นจะอยู่กึ่งกลางระหว่างจุดควบคุมข้างเคียงพอดี ซึ่งหมายความว่าสามารถแทนจุดแบ่งทุกจุดด้วยจุดกะได้ ด้วยทฤษฎีนี้ Fontforge จึงประมาณ cubic spline ด้วย quadratic spline ที่เติมจุดกะตามแนวเส้นโค้งเสมอ

Cubic spline approximation with quadratic spline

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

การลดจำนวนจุดกะใน Quadratic Curve

การประมาณของ Fontforge คือการประมาณในทางคณิตศาสตร์ที่มีความแม่นยำสูง แต่ในทาง design แล้ว เราอาจยอมรับความคลาดเคลื่อนได้บ้างโดยไม่ทำให้รูปตัวอักษรเพี้ยนไปจากเดิม ซึ่งแน่นอนว่าเรื่องการผ่อนผันที่ต้องใช้วิจารณญาณอย่างนี้ Fontforge จะไม่สู่รู้ตัดสินใจให้ เราจึงต้องปรับเองด้วยมือ

จากภาพในตัวอย่างข้างต้น มีการเติมจุดกะระหว่างกลาง 4 จุดใน quadratic curve แต่เราสามารถลดจำนวนจุดกะนี้ลงได้ ไม่ว่าจะเพื่อความเรียบง่าย เพื่อลดขนาดข้อมูล (ซึ่งสำคัญสำหรับ web font) หรือเพื่อประสิทธิภาพในการ hint และการ rasterize ก็ตาม โดยแนวทางการลดจุดกะที่เป็นไปได้คือ:

  1. ตัดจุดกะด้วยมือ โดยเลือกจุดกะที่ต้องการตัดแล้วสั่ง Merge (Ctrl-M)
  2. ปรับ cubic curve ต้นทางด้วยมือให้สามารถประมาณได้ด้วยจำนวนจุดที่น้อยลง

ทั้งสองวิธีจะได้ quadratic curve ที่คลาดเคลื่อนจาก cubic curve เดิมเล็กน้อย แต่วิธีที่สองจะทำให้ได้ spline สองแบบที่ทาบกันสนิทกว่าแบบแรก เพราะมันถูกปรับไปด้วยกัน

ในฟอนต์ตัวแรก ๆ ที่ทำ ผมใช้วิธีแรก แต่ต่อมาก็ค่อย ๆ เกิดความคิดว่าวิธีที่สองน่าจะเหมาะกว่า และในที่สุดก็เลือกวิธีที่สองเป็นหลัก

แล้ว cubic curve แบบไหนที่จะใช้จำนวนจุดกะน้อยลง?

ก่อนอื่น คนที่เคย edit cubic curve จะรู้ว่าเราสามารถปรับแขนทั้งสองของโค้งได้โดยยังได้โค้งที่ใกล้เคียงกับโค้งเดิม ด้วยการเพิ่มความยาวของแขนข้างหนึ่ง และลดความยาวของแขนอีกข้างหนึ่ง

Cubic curve adjustment

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

สำหรับโค้งในตัวอย่างข้างต้น เมื่อปรับแล้ว copy ข้ามมา quadratic layer เรากลับได้ curve ที่ใช้จุดกะเพียงจุดเดียว จากเดิมที่ใช้ถึง 4 จุด

Quadratic curve of the adjusted cubic curve

ถามว่า cubic curve แบบไหนที่ใช้จุดกะน้อย? แรก ๆ ที่ลองผิดลองถูกน้ัน ผมอาศัย sense เป็นหลัก คือพยายามให้แขนทั้งสองข้างได้ดุลกัน แต่เมื่อทำไปก็เริ่มถามตัวเองถึงคุณสมบัติทางคณิตศาสตร์ที่ชัดเจนกว่าการใช้ sense ซึ่งในที่สุดก็ได้คำตอบที่กลับไปหาพื้นฐานทางคณิตศาสตร์ของ cubic และ quadratic curve นั่นเอง

จาก blog เดิม ผมได้กล่าวไว้ว่า quadratic curve ที่มีจุดควบคุม P0, P1 และ P2 สามารถแทนได้ด้วย cubic curve ที่สมมูลกันโดยมีจุดควบคุม P0, (P0/3 + 2P1/3), (2P1/3 + P2/3), และ P2

Equivalent cubic curve of a quadratic curve

เราสามารถพูดในทางกลับกันได้ว่า cubic curve ที่ว่านี้ เมื่อแปลงเป็น quadratic curve ก็จะใช้จุดควบคุม P0, P1 และ P2 ได้ทันทีโดยไม่ต้องเติมจุดกะ

ถือเป็นอุดมคติของการประมาณโค้ง ยิ่งเราปรับ cubic curve ให้เข้าใกล้อุดมคตินี้มากเท่าไร เมื่อแปลงเป็น quadratic ก็จะใช้จุดกะระหว่างกลางน้อยลงเท่านั้น

อุดมคติที่ว่านี้ มีคุณสมบัติที่เห็นได้จากเรขาคณิตก็คือ เส้นตรงที่เชื่อมระหว่างจุดควบคุมทั้งสองขนานกันกับเส้นตรงที่เชื่อมระหว่างจุดปลายทั้งสอง โดยถ้าความยาวของแขนควบคุมเท่ากับ 2/3 ของระยะไปยังจุดตัดของแขนควบคุมทั้งสองพอดี ก็จะไม่ต้องใช้จุดกะเพิ่มเลย แต่ถ้าไม่ใช่ก็ต้องมีจุดกะเพิ่ม

ฉะนั้น แนวทางโดยทั่วไปก็คือ พยายามเล็งให้ polygon ที่เชื่อมระหว่างจุดปลายและจุดควบคุมของ cubic curve กลายเป็นสี่เหลี่ยมคางหมูหรือใกล้เคียง ซึ่งโดยทั่วไปก็จะทำให้มีจุดกะเพิ่มไม่เกิน 1 จุด

การปรับอื่น ๆ

ในบางกรณี ก่อนที่จะได้ cubic curve ที่สามารถแทนด้วย quadratic curve ที่เติมจุดกะไม่เกิน 1 จุด ก็อาจจำเป็นต้องปรับจุดต่อโค้งต่าง ๆ เพิ่มตามจำเป็น เช่น

  • เติมจุดบิดโค้ง (inflection point) เพื่อแบ่งโค้งที่บิดเป็นรูปตัว S ออกเป็นสองส่วน เนื่องจาก quadratic curve ไม่สามารถบิดเป็นตัว S ได้เหมือน cubic curve
  • เติมจุดต่อโค้งในโค้งที่หักเลี้ยวไม่สมมาตร จนจำเป็นต้องเติมจุดกะมากกว่า 1 จุด เช่น ในฟอนต์ตัวเอียงที่โค้งเดิมกำหนดจุดต่อโค้งที่ extrema เท่านั้น

การเติมจุดเหล่านี้ หากพิจารณาเฉพาะฟอนต์ที่ใช้ cubic spline อาจดูไม่จำเป็น แต่การเติมจุดต่อโค้งนอกจากจะช่วยให้ใช้จุดกะน้อยเมื่อแปลงเป็น quadratic แล้ว ก็ยังมีผลดีต่อการควบคุมความหนาของเส้นหมึกสำหรับ cubic spline เองด้วย เช่น การมีจุดกำกับที่จุดบิดโค้งก็ย่อมเพิ่มโอกาสการ hint หรือตรึงตำแหน่งที่จุดบิดโค้ง แทนที่จะปล่อยให้โค้งลอยไปมาตามผลการขยับจุดปลายระหว่าง apply hint

แผนการต่อไป

ในฟอนต์ชุด Arundina ที่กำลังจะตัดออกรุ่นนี้ ผมได้ปรับ spline เฉพาะฟอนต์ Arundina Sans เท่านั้น โดยใช้วิธีแรก (ยุบจุดกะใน quadratic spline เท่านั้น) และ commit ไปแล้ว ส่วน Arundina Sans Mono ผมเริ่มใช้วิธีที่สอง แต่น่าเสียดายที่ข้อมูลสูญหายไปหมด จึงไม่ได้รวมมาในรุ่นใหม่นี้ แต่จะนำหลักการที่ได้นี้ไปใช้ปรับฟอนต์ชุด Fonts-TLWG ในลำดับต่อไป

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

16 กันยายน 2562

Thanks

ขอขอบคุณ ท่านที่ได้ สนับสนุน งานพัฒนาซอฟต์แวร์เสรีของผมในช่วงที่ผ่านมาครับ

นับจาก ครั้งที่แล้ว ขอขอบคุณผู้สนับสนุนงานของผมดังนี้:

  • เดือนกุมภาพันธ์ 2562
    • คุณวิทยา ไตรสารวัฒนะ
  • เดือนสิงหาคม 2562
    • ผู้ไม่ประสงค์จะออกนาม 1 ท่าน

ขอให้ทั้งสองท่านประสบความสำเร็จในหน้าที่การงาน สุขภาพแข็งแรงครับ

ปีนี้อาจเป็นปีที่งานพัฒนาซอฟต์แวร์ของผมขาดช่วงไปบ้าง เนื่องจากรับงานสอนพิเศษนักเรียนอยู่ช่วงหนึ่ง แต่ก็พอสรุปงานตั้งแต่ต้นปีได้ดังนี้:

  • งานแปล
    • ระดมแปล Xfce เพื่อเตรียมพร้อมสำหรับ Xfce 4.14 ซึ่งก็ได้ออกรุ่นไปแล้วเมื่อ 12 สิงหาคมที่ผ่านมา
  • Fonts-Arundina (ยังไม่ release):
    • ตรวจสอบปัญหา build reproducibility ต่อ สุดท้ายพบว่าเป็นปัญหาของ FontForge ใน Debian ที่ยังอัปเดตไม่ครบสำหรับฟอนต์ PostScript จึงคอมเมนต์ไปใน Debian #774274 เพื่อขออัปเดต
    • ทยอยปรับ quadratic spline ในเลเยอร์ Quad ต่อ (ยังไม่เสร็จ งานนี้เป็นงานมาราธอน)
  • งานต้นน้ำ:
    • release gtk-im-libthai 0.2.2 เพื่อปล่อยสิ่งที่ค้างอยู่ใน repository ถึงเกือบ 8 ปี โดยสิ่งเปลี่ยนแปลงหลัก ๆ คือการกำจัดการใช้ GTK+ API ที่ deprecated
  • Debian packaging:
    • ย้ายไป debhelper level 12 พร้อมกับใช้ debhelper-compat dependency แทน debian/compat และแก้ปัญหาที่เกิดกับ dh_missing ใน level 12 นี้
    • ปรับโครงสร้าง Git repository ตาม DEP-14 ครบทุกแพกเกจในความดูแล (แต่ยังรออัปโหลดอยู่ 2 แพกเกจ)
    • ปรับแพกเกจที่สร้าง udeb โดยให้ dh_makeshlibs สแกนหา udeb โอยอัตโนมัติแทนการใช้ option --add-udeb สำหรับ debhelper รุ่น 12.3 ขึ้นไป
    • ตรวจสอบและตัดสิ่งที่เก่าเกินไปจนไม่จำเป็นสำหรับ Bullseye แล้ว
    • อัปเดตทั่วไป
  • Debian อื่น ๆ:
    • file Debian #934804 สำหรับ bsdmainutils เพื่อขอปรับข้อมูลวันหยุดของไทยเพิ่มเติมในคำสั่ง calendar อันเนื่องมาจากพระราชพิธีบรมราชาภิเษก
  • OpenStreetMap
    • ปรับข้อมูลแผนที่ในตัวเมืองขอนแก่น
    • เป็นวิทยากรฝึกอบรมการสร้างแผนที่ OSM ที่ Thailand ICT Camp 2019 (ชะอำ) ร่วมกับคุณ Mishari Muqbil
    • เริ่มทดลองเก็บข้อมูล Mapillary ในตัวเมืองขอนแก่นตามคำแนะนำของคุณ Mishari
    • ปรับข้อมูลแผนที่รายทางที่ชะอำ และแผนที่อุทยานสิ่งแวดล้อมนานาชาติสิรินธร
    • ปรับข้อมูลแผนที่บริเวณ ต.นาจอมเทียน อ.สัตหีบ จ.ชลบุรี
    • เริ่มทำแผนที่จุดรับขยะอันตรายในเขตเทศบาลนครขอนแก่น

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

01 กรกฎาคม 2562

DTAC Leaked Net Data Problem

หลังจากเจอปัญหา DTAC เน็ตมือถือรั่วมานานพอควร คือการหักค่า net data ทั้ง ๆ ที่ผมปิด net data ตลอดเวลา และใช้เน็ตผ่าน Wi-Fi เท่านั้น เดือน มิ.ย. ที่ผ่านมาเลยเช็กตัวเลขจริงจัง พบว่าค่าเน็ตรั่วที่ผมจ่ายทั้งเดือนคือ 57.78 บาท ในขณะที่ค่าโทรผมใช้แค่ 21.25 บาท ผมจ่ายเงินไปฟรี ๆ เกือบสามเท่าของที่ใช้จริง!

เมื่อตรวจสอบปริมาณการใช้ net data จากแอนดรอยด์เอง กลับพบว่าปริมาณการใช้เน็ตทั้งเดือนคือ 0 ไบต์! แล้ว DTAC ตัดเงินผมจากอะไร?

คำอธิบายมีสองแนว

  1. comment หนึ่งใน Pantip อธิบายว่า เทคโนโลยี 4G ออกแบบมาให้ใช้ data ล้วน จึงเชื่อมต่อ data ตลอดเวลาที่เปิดเครื่อง แม้แต่การโทรก็ใช้ data ผ่าน VoLTE แต่เพื่อการติดต่อกับเครือข่าย 3G หรือ 2G ก็จะทำ Circuit Switched FallBack (CSFB) สำหรับการโทรหรือ SMS ได้ แต่สำหรับการเชื่อมต่อ 4G ปกติ ยังไงก็ปิด data ไม่ได้ทั้งหมด ยังต้องมีส่วนที่ใช้ maintain การเชื่อมต่ออยู่ดี
  2. DTAC อธิบายถึงสาเหตุอื่นที่ไม่เกี่ยวกับเทคโนโลยี 4G คือ
    • เมื่อ Wi-Fi สัญญาณอ่อนหรือช้าลง เครื่องจะสลับมาใช้สัญญาณ 3G/4G โดยอัตโนมัติเพื่อความต่อเนื่อง
    • บาง app เช่น passbook จำเป็นต้องใช้สัญญาณ 3G/4G สื่อสารกับเครือข่ายเพื่อยืนยันเบอร์ที่ใช้งาน
    • เมื่อเครื่องเข้าสู่ sleep mode จะสลับจากการจับสัญญาณ Wi-Fi มาเป็น 3G/4G อัตโนมัติ

กรณีของผม ผมเชื่อว่ามาจากข้อ 1 เพราะเริ่มสังเกตเห็นอาการเน็ตรั่วหลังจากที่ในพื้นที่มีสัญญาณ DTAC-Turbo และมือถือผมก็จับสัญญาณนี้ ในขณะที่เครื่องของอีกคนที่ใช้ DTAC เหมือนกันจับสัญญาณ VoLTE และไม่มีปัญหาเน็ตรั่ว

ฉะนั้น ผมจึงแก้ปัญหาด้วยการตั้งมือถือให้เชื่อมต่อกับเครือข่าย 3G เท่านั้น แทนที่จะเชื่อม 3G/4G อัตโนมัติ

อย่างไรก็ดี ปัญหาข้อ 2 ก็ยังอาจมีได้สำหรับเครือข่าย 3G ก็เลยสั่งปิดสัญญาณอินเทอร์เน็ตที่เครือข่ายไปเลย โดยสำหรับ DTAC ใช้เบอร์ดังนี้

  • ปิดสัญญาณอินเทอร์เน็ต กด *104*72#
  • เปิดสัญญาณอินเทอร์เน็ต กด *104*71#

จากที่ผมสังเกตเปรียบเทียบกับเครื่องของเพื่อนที่ไม่มีปัญหาเน็ตรั่วทั้งที่ใช้ 4G เหมือนกัน ซึ่งก็ควรต้องใช้ data ในการ maintain การเชื่อมต่อเหมือนกัน แต่ VoLTE กลับไม่มีปัญหาการตัดเงิน ในขณะที่เครื่องที่ใช้ DTAC-Turbo กลับมีปัญหา หรือจะเป็นปัญหาของ DTAC-Turbo?

ทั้งนี้ ก็ต้องพิจารณาด้วยว่าปัญหานี้ไม่ได้พบแค่กับ DTAC เท่านั้น แต่ทั้ง AIS และ True ต่างก็ดูจะมีปัญหานี้เช่นกัน และถ้าทางแก้คือการถอยกลับไป 3G ก็หมายความว่าถ้าไม่แก้ปัญหาการคิดค่าใช้งานตรงนี้ การขยับไป 4G หรือ 5G ของประเทศก็อาจเกิดแรงเสียดทานจากผู้ใช้ได้

ป้ายกำกับ: ,

22 พฤษภาคม 2562

Esaan Tones

จาก blog เก่าเรื่อง ไตรยางศ์อยุธยา เมื่อ 7 ปีก่อน ผมทิ้งท้ายไว้ว่าจะเขียนถึงไตรยางศ์อีสานต่อ จนแล้วจนรอดก็หาเวลาเขียนไม่ได้ จนกระทั่งได้ไปร่วม Thailand ICT Camp ที่ชะอำ ซึ่งมีกิจกรรม BarCamp ในวันสุดท้าย ผมไม่เคยร่วม BarCamp มาก่อน แต่ก็ลองเสนอหัวข้อ ไตรยางศ์ไทย-อีสาน ดู พอได้นำเสนอจึงถือโอกาสนำมาเขียนบันทึกต่อเสียเลย

ก่อนอื่นเพื่อเป็นการปูพื้นสำหรับท่านที่ตามมาอ่านจาก BarCamp และไม่เคยอ่าน blog ของผมมาก่อน ผมมีข้อสังเกตถึงความลักลั่นของการสะกดคำของภาษาอีสานอันเนื่องมาจากการขาดหลักไตรยางศ์ที่แน่นอน ทำให้บางคำเขียนรูปวรรณยุกต์เหมือนภาษาไทยกลางแล้วผันเอา ซึ่งมักเป็นคำที่ใช้ร่วมกับไทยกลาง เช่น เขียน หม้อ แล้วผันเป็น [หม่อ] แต่พอเป็นคำที่เป็นคำเฉพาะถิ่น เช่น หม้ำ (ไส้กรอกตับ) ซึ่งออกเสียงว่า [หม่ำ] กลับเขียนแบบแปลงสำเนียงให้คนบางกอกเสร็จสรรพ โดยเขียนเป็น หม่ำ

ปัญหาของการเขียนลักลั่นแบบนี้คือ หลักการอ่านจะไม่แน่นอน เอาหม่ำไปใส่หม้อ ควรอ่านเป็น [เอ่า-มัม^-ไป่-ใซ^-หม่อ] ตามกฎการผันเสียง หรือควรอ่านเป็น [เอ่า-หม่ำ-ไป่-ใซ^-หม่อ] โดยอาศัยความรู้ทางศัพท์แก้เสียงวรรณยุกต์ในระหว่างอ่าน? และเมื่อเด็กอีสานไปเรียนคำใหม่จากหนังสือ เขาจะรู้ได้อย่างไรว่าคำที่เขียนนั้นตั้งใจให้อ่านแบบไทยกลางหรือไทยอีสาน? เช่นคำว่า หล่า ถ้าอ่านแบบไทยกลางเป็น [หล่า] จะหมายถึงคนสุดท้อง แต่ถ้าอ่านแบบไทยอีสานเป็น [ลา^] จะหมายถึงอาการหน้าเจื่อน แล้วเราก็จะกลับไปสู่ยุค หนังสือหนังหา สมัยที่ยังเขียน หนังสือ แบบไม่ใส่วรรณยุกต์ แล้วให้คนอ่านอ่าน หนังหา คือหาเสียงวรรณยุกต์ที่ถูกต้องมาใส่เอาเอง ซึ่งถ้าเป็นเช่นนั้น เราจะใส่วรรณยุกต์ไปทำไมกัน?

รายละเอียดเพิ่มเติมเกี่ยวกับประเด็นการสะกดคำ กรุณาอ่านจาก blog Esaan Language Tidbits

สิ่งที่ควรจะเป็นคือเขียนภาษาเขียนเหมือนไทยกลาง แต่ใช้หลักไตรยางศ์เฉพาะของอีสานในการผันเสียง โดยเขียน หม้ำ แล้วผันเสียงเป็น [หม่ำ] เหมือนที่ผัน หม้อ เป็น [หม่อ] เพื่อที่จะใช้หลักการเดียวในการอ่านข้อความ เอาหม้ำไปใส่หม้อ ตลอดข้อความโดยไม่ต้องมีข้อยกเว้น

ไตรยางศ์ขอนแก่น

หลักไตรยางศ์ที่ว่านั้น ไทยแต่ละถิ่นก็จะมีหลักของตัวเอง ไม่ว่าจะเป็นล้านนา สุพรรณบุรี นครศรีธรรมราช บางกอก ขอนแก่น อุบลฯ เลย ฯลฯ ซึ่งจะทำให้อ่านข้อความเดียวกันที่เขียนด้วยอักษรไทยออกไปได้ตามสำเนียงของถิ่นตน โดยในที่นี้ผมขอพูดถึงสำเนียงขอนแก่นที่เป็นสำเนียงบ้านผมเท่านั้น

สำเนียงขอนแก่น มีวรรณยุกต์ทั้งหมด 5 เสียง

  1. เสียงเอก ตรงกับเสียงเอกในภาษาบางกอก เช่น ในคำว่า กิน ขาด ปาก หม้อ เข้า
  2. เสียงโทต่ำ คล้ายเสียงโทของภาษาบางกอก แต่เสียงต่ำกว่า (ต้นพยางค์เท่า ๆ กับเสียงสามัญของบางกอก แล้วลงต่ำที่ท้ายพยางค์) เช่น ในคำว่า ป้า (น้ำไหล)โจ้ก ค้า เคียด
  3. เสียงสามัญสูง เสียงเป็นระดับเดียวตลอดพยางค์เหมือนเวลาออกเสียงสามัญ แต่เสียงสูงกว่าเสียงสามัญของบางกอก เช่น ในคำว่า เต่า ข่า พ่อ งึด
  4. เสียงโท ตรงกับเสียงโทของภาษาบางกอก เช่น ในคำว่า คา งู มา
  5. เสียงจัตวา ตรงกับเสียงจัตวาของภาษาบางกอก เช่น ในคำว่า ขา กบ เห็ด

การเขียนบรรยายเสียงอ่าน จะมีสองเสียงที่เสียงไม่ตรงกับภาษาบางกอก คือเสียงโทต่ำและสามัญสูง จึงขอเขียนเครื่องหมายพิเศษเพื่อกำกับเสียง โดยเสียงโทต่ำจะเขียนเสียงโทแล้วตามด้วยขีดล่าง (_) เช่น ป้า [ป้า_], โจ้ก [โจ้ก_], ค้า [ค่า_], เคียด [เคียด_] ส่วนเสียงสามัญสูงจะเขียนเสียงสามัญแล้วตามด้วยหมวก (^) เช่น เต่า [เตา^], ข่า [คา^], พ่อ [พอ^] ยกเว้นกรณีที่ไม่สามารถเขียนเสียงสามัญได้ จะเขียนเสียงอื่นโดยอนุโลมแล้วใช้หมวกกำกับเสียง เช่น งึด [งึด^], คัก [คัก^]

หลักการผันวรรณยุกต์

คำเป็น

  • อักษรกลางรูปสามัญ (เช่น กิน) สำเนียงอีสานแต่ละถิ่นจะออกเสียงกันหลากหลาย สำเนียงขอนแก่นผันเป็นเสียงเอก สำเนียงอุบลฯ ผันเป็นเสียงสามัญเหมือนบางกอก (ทำให้สำเนียงอุบลฯ มีเสียงวรรณยุกต์ 6 เสียง เพิ่มเสียงสามัญแบบบางกอกเข้ามาอีกหนึ่ง)
  • อักษรสูงรูปสามัญ (เช่น ขา) ผันเป็นเสียงจัตวาเหมือนบางกอก
  • อักษรต่ำรูปสามัญ (เช่น คา) ผันเป็นเสียงโท
  • รูปเอก (เช่น เต่า ข่า ค่า) ผันเป็นเสียงสามัญสูงทั้งสามหมู่
  • รูปโทสำหรับอักษรกลางและอักษรต่ำ (เช่น ป้า ค้า) ผันเป็นเสียงโทต่ำ
  • รูปโทสำหรับอักษรสูง (เช่น ข้า) ผันเป็นเสียงเอก
  • รูปตรีและจัตวาสำหรับอักษรกลาง (เช่น ป๊า โป๊ ป๋า) ไม่มีในคำอีสาน เป็นการยืมจากภาษาบางกอก จึงใช้วิธีเทียบเสียงกับหมู่อื่น เช่น โป๊ [โป้_] เทียบกับเสียงตรีของอักษรต่ำ (เช่น ค้า) แต่ ป๊า [ปา^] ออกเป็นสามัญสูงเพื่อเลียนเสียงตรีของบางกอก ส่วนรูปจัตวา ผันเป็นเสียงจัตวาตรงตัว เช่น ป๋า [ป๋า]

คำตายสระเสียงยาว

  • รูปสามัญสำหรับอักษรกลางและสูง (เช่น เกิบ ขาด) ผันเป็นเสียงเอกเหมือนบางกอก
  • รูปสามัญสำหรับอักษรต่ำ (เช่น เคียด) และรูปโทสำหรับอักษรกลาง (เช่น โจ้ก) ผันเป็นเสียงโทคล้ายบางกอก แต่ระดับเสียงเป็นโทต่ำ
  • รูปโทสำหรับอักษรสูง ไม่พบคำที่สะกดจริง แต่สามารถเทียบกับการผันเป็นเสียงโทของบางกอกได้ แต่ระดับเสียงเป็นโทต่ำ
  • รูปตรีสำหรับอักษรกลาง (เช่น โจ๊ก) และรูปโทสำหรับอักษรต่ำ (เช่น โค้ก) เป็นคำยืมจากภาษาบางกอก จึงเลียนเสียงตรีของบางกอกด้วยเสียงสามัญสูง
  • รูปจัตวาสำหรับอักษรกลาง ไม่พบคำที่สะกดจริง แต่สามารถเทียบกับการผันเป็นเสียงจัตวาของบางกอกได้ และออกเป็นเสียงจัตวาตรงตัว

คำตายสระเสียงสั้น

  • รูปสามัญสำหรับอักษรกลาง (เช่น จก) และอักษรสูง (เช่น ขัด) ผันเป็นเสียงจัตวา
  • รูปสามัญสำหรับอักษรต่ำ (เช่น งึด) ผันเป็นเสียงตรีคล้ายหลักของบางกอก แต่ออกเสียงเป็นสามัญสูง
  • รูปเอกสำหรับอักษรต่ำ (เช่น ค่ะ) เป็นคำยืมจากภาษาบางกอก และผันเป็นเสียงโทเหมือนบางกอก
  • รูปโทสำหรับอักษรกลาง (เช่น จึ้ก) ผันเป็นเสียงโทคล้ายหลักของบางกอก แต่ระดับเสียงเป็นโทต่ำ
  • รูปโทของอักษรสูง ไม่พบคำที่สะกดจริง แต่สามารถเทียบกับการผันเป็นเสียงโทของบางกอกได้ แต่ระดับเสียงเป็นโทต่ำ
  • รูปตรีของอักษรกลาง (เช่น กั๊ก) เป็นคำยืมจากภาษาบางกอก และเลียนเสียงตรีของบางกอกด้วยเสียงสามัญสูง
  • รูปจัตวาสำหรับอักษรกลาง ถือว่าเสียงซ้ำกับรูปสามัญ ไม่ควรมีรูปเขียน แต่ถ้าให้ออกเสียง ก็ออกเป็นเสียงจัตวา

รูปสะกดที่คลาดกับไทยกลาง

หลักไตรยางศ์ข้างต้นสามารถใช้ได้กับทุกกรณี แต่คนอีสานอาจสังเกตพบบางคำที่เสียงอ่านไม่เป็นไปตามกฎนี้ เช่น น้ำท่วม [น่าม_-ถ่วม ไม่ใช่ น่าม_-ทวม^], คอยท่า [ค่อย-ถ่า ไม่ใช่ ค่อย-ทา^], ฆ่างัว [ข่า-งั่ว ไม่ใช่ คา^-งั่ว] ฯลฯ ทั้งนี้เป็นเพราะวิวัฒนาการของการสะกดคำของบางกอกได้เลือกเอาตัวสะกดที่ไม่ตรงกับอีสานไว้ กล่าวคือ:

  • น้ำท่วม ภาษาลาวปัจจุบันใน สปป. ลาวสะกดคำนี้ว่า ນ້ຳຖ້ວມ (น้ำถ้วม) ซึ่งเมื่อผันตามหลักไตรยางศ์ข้างต้นจะออกเสียงได้เป็น [น่าม_-ถ่วม] ตรงตามความเป็นจริง
  • คอยท่า ภาษาลาวปัจจุบันใน สปป. ลาวสะกดคำนี้ว่า ຄອຍຖ້າ (คอยถ้า) ซึ่งผันเสียงเป็น [ค่อย-ถ่า] ตามภาษาที่พูดกัน
  • ฆ่าวัว ภาษาลาวปัจจุบันใน สปป. ลาวสะกดคำนี้ว่า ຂ້າງົວ (ข้างัว) โดยคำว่า ฆ่า นี้ จารึกสุโขทัยเองก็สะกดว่า ฃ้า (ซึ่งใช้ ฃ ขวด เป็นคนละคำกับ ข้า ที่หมายถึงผู้อยู่ใต้ปกครอง) ต่อมาจึงได้วิวัฒน์การสะกดเป็น ฆ่า ในภายหลัง (อ่านเพิ่มเติมได้ใน blog เก่า)

ยังมีคำอื่น ๆ ในทำนองนี้ เช่น ໜ້າຮັກ (หน้าฮัก = น่ารัก), ຫຼິ້ນ (หลิ้น = เหล้น = เล่น) ซึ่งทำให้เห็นว่าการเสาะหาตัวสะกดที่สูญหายไปของภาษาอีสานอาจหาได้จากแหล่งใกล้เคียงคือภาษาลาวใน สปป. ลาวนั่นเอง

ย ยุง กับ ย ยา

อีกประเด็นหนึ่งที่สร้างความสับสนให้กับผู้ฝึกภาษาอีสานได้ไม่น้อยคือความแตกต่างระหว่าง ຍ ຍຸງ (ย ยุง) กับ ຢ ຢາ (ย ยา) ที่ผันวรรณยุกต์คนละแบบ เพราะ ຍ ຍຸງ นั้นนับเป็นอักษรต่ำ (เดี่ยว, นาสิก) ในขณะที่ ຢ ຢາ จะเทียบเท่ากับ อ นำ ย ในภาษาไทย และผันอย่างอักษรกลาง ซึ่งภาษาไทยปัจจุบันเหลือคำที่ใช้ อ นำ ย อยู่แค่ 4 คำ คือ อย่า อยู่ อย่าง อยาก แต่ในภาษาลาวและอีสานยังคงรักษาคำไว้มากกว่านั้น ตัวอย่างเช่น

  • ຢືນ (อยืน) [หยื่น] หมายถึงอาการตั้งตัวตรงบนพื้น ซึ่งจารึกสุโขทัยก็สะกดว่า อยืน จนต่อมาวิวัฒน์เหลือ ยืน และกลายเป็นคำพ้องรูปกับ ยืน ที่หมายถึงความยาวนาน เช่นในคำว่า ยั่งยืน แต่ในภาษาลาวยังคงสะกดคำหลังนี้ต่างกันเป็น ຍືນ (ยืน) โดยใช้ ຍ ຍຸງ
    ดังนั้น ชื่ออำเภอ พระยืน [พะ^-หยื่น] จึงผันวรรณยุกต์ต่างจากชื่ออำเภอ เชียงยืน [เซี่ยง-ญื่น]
  • ຢາງ (อยาง) [หย่าง] ใน ยางพารา [หย่าง-พ่า-ล่า] และ ยางรถยนต์ [หย่าง-ลด^-ญ่น] ก็ผันวรรณยุกต์ต่างจาก ຍາງ (ยาง) [ญ่าง] ใน ต้นยางนา [ต้น_-ญ่าง-น่า]
  • ຢາຍ (อยาย) [หย่าย] ที่หมายถึงการกระจายข้าวของ ก็ผันวรรณยุกต์ต่างจาก ຍາຍ (ยาย) [ญ่าย] ที่หมายถึงแม่ของแม่

ป้ายกำกับ:

02 มกราคม 2562

New Year Thanks

สวัสดีปีใหม่ 2562 ครับ ขอถือโอกาสนี้ ขอบคุณ ทุกท่านที่ได้ สนับสนุน งานพัฒนาซอฟต์แวร์เสรีของผมในปีที่ผ่านมาครับ

นับจาก ครั้งที่แล้ว ขอขอบคุณผู้สนับสนุนงานพัฒนาของผมในช่วงครึ่งหลังของปี 2561 ดังนี้:

  • เดือนสิงหาคม 2561
    • ผู้ไม่ประสงค์จะออกนาม 2 ท่าน
    • คุณวิทยา ไตรสารวัฒนะ
  • เดือนกันยายน 2561
    • ผู้ไม่ประสงค์จะออกนาม 1 ท่าน
  • เดือนตุลาคม 2561
    • คุณวิทยา ไตรสารวัฒนะ
  • เดือนพฤศจิกายน 2561
    • ผู้ไม่ประสงค์จะออกนาม 1 ท่าน
  • เดือนธันวาคม 2561
    • ผู้ไม่ประสงค์จะออกนาม 1 ท่าน
  • เดือนมกราคม 2562 (นับถึงวันที่ 2)
    • ผู้ไม่ประสงค์จะออกนาม 1 ท่าน

ขอให้ทุกท่านและครอบครัวมีความสุขกายสบายใจ มีพลังอันเต็มเปี่ยมที่จะสร้างสรรค์งานของท่านให้เจริญรุดหน้า และที่สำคัญคือขอให้มีสุขภาพพลานามัยที่สมบูรณ์แข็งแรงครับ

สรุปกิจกรรมซอฟต์แวร์เสรีในครึ่งหลังของปี 2561 ของผม:

  • LibThai:
    • ออกรุ่น 0.1.28
    • อัปเดต TeX hyphenation patterns ตามพจนานุกรมใหม่ของ LibThai
  • swath:
    • อัปเดตพจนานุกรมตัดคำตาม TeX hyphenation patterns ใหม่
    • ตรวจพบและแก้ปัญหาใน RTF filter
    • ออกรุ่น 0.6.1
  • libdatrie (ยังไม่ release):
  • พัฒนาและ release โครงการ thpronun
  • โครงการอักษรอีสาน:
    • ย้ายโครงการ Khottabun จาก SourceForge มายัง GitHub
    • เพิ่มฟอนต์ Viravong สำหรับเขียนบาลี-สันสกฤตด้วยอักษรลาวร่วมสมัย ตามแบบพุทธบัณฑิตสภาจันทบุรี ตามร่างข้อเสนอยูนิโค้ด โดยเป็นส่วนหนึ่งของโครงการ Khottabun (ผ่านการประสานงานจากพระอาจารย์ไชยศิริ)
    • เพิ่ม input method สำหรับป้อนภาษาบาลีอักษรลาวในโครงการ lanxang
  • Fonts-TLWG:
    • ปรับซอร์สเพื่อให้สามารถ build แบบ reproducible
    • แก้ปัญหาใน GSUB
    • จัดเตรียมฟอนต์ OpenType สำหรับ XeTeX
    • automate การ build binary font tarballs
    • ออกรุ่น 0.7.0 และ 0.7.1
  • Fonts-Arundina (ยังไม่ release):
  • Debian package ต่าง ๆ :
    • ทยอยปรับโครงสร้าง Git repository ตาม DEP-14
  • อัปเดตแผนที่ OpenStreetMap ในบริเวณตัวเมืองขอนแก่น, กรุงเทพฯ, และอำเภอวาปีปทุม จังหวัดมหาสารคาม
  • ปรับคำแปล Xfce เป็นระยะ

ป้ายกำกับ:

06 พฤศจิกายน 2561

Fonts-TLWG 0.7.0 and 0.7.1

Fonts-TLWG 0.7.0 ออกไปแล้วเมื่อปลายตุลาที่ผ่านมา หลังจากสะสมงานพัฒนามาได้ครึ่งปี โดยมีการเปลี่ยนแปลงตามลำดับเวลาดังนี้:

  • Issue #7: แก้ที่ผิดใน GSUB rules ของทุกฟอนต์ซึ่งทำให้แสดงข้อความที่มีพินทุตามด้วย Macron Below เป็นพินทุซ้อนกันสองตัว ปัญหาเกิดจากข้อผิดพลาดในกฎจัดการลำดับ คุณ @Richard57 ได้รายงานเข้ามาพร้อมวิเคราะห์สาเหตุให้ด้วย
  • Norasi:
    • แก้ warning จาก Fontforge เกี่ยวกับการอ้างถึง glyph ที่ไม่มีในฟอนต์ในกฎ 'liga'
    • แก้กฎ 'liga' ให้รองรับลำดับ space + combining character ในทุกกรณี
    • ตัดกฎ T + M → ™ เพื่อไม่ให้รบกวนกรณีที่ไม่ใช่ เช่น ATM
  • Issue #6: จัดเตรียมฟอนต์ OpenType ในแพกเกจ LaTeX (fonts-tlwg) ตามคำแนะนำของคุณ Abhabongse Janthong เพื่อให้บริการอย่าง ShareLaTeX และ Overleaf สามารถใช้ฟอนต์ไทยกับ XeLaTeX ได้โดยไม่ต้องอัปโหลดฟอนต์ร่วมกับเอกสาร ซึ่งข้อนี้ผมคิดไม่ถึง เพราะคิดแค่กรณีของผู้ใช้ XeTeX ในเครื่องส่วนตัว ซึ่งสามารถใช้ฟอนต์จากระบบได้อยู่แล้ว แต่สำหรับบริการออนไลน์ หรือแม้แต่เครื่องที่ผู้ใช้ไม่มีสิทธิ์ติดตั้งฟอนต์ในระบบแล้ว การจัดเตรียมฟอนต์ OpenType มากับชุด TeX distribution เลยย่อมอำนวยความสะดวกได้ดีกว่า
  • จัดการเรื่อง reproducibility ของการ build ฟอนต์ หลังจากที่ Debian รายงานมานาน และเขาได้ข้อยุติเรื่องการแก้ปัญหาใน Fontforge กันไปแล้ว โดยที่ Fonts-TLWG ของเราก็ยังไม่ reproducible อยู่ดี จึงคิดว่าควรได้ฤกษ์จัดการในฝั่งของเราเสียที ซึ่งในการแก้ก็ต้องจัดโครงสร้างของซอร์สและการ build ใหม่ จึงได้ขึ้นเลขรุ่นเป็น 0.7.x

หลังจาก อัปโหลด แพกเกจเข้า Debian ไปแล้ว ก็รอตรวจสอบหน้า reproducible build ของ fonts-tlwg ใน unstable ปรากฏว่ายังไม่ผ่าน ยังคงมีประเด็นตกค้างอยู่ ซึ่งเมื่อตรวจสอบ diff ดูแล้ว พบว่ามาจาก date stamp ที่เกิดจากฟิลด์ UniqueID ใน TTF Names ที่ Fontforge เติมให้โดยอัตโนมัติสำหรับฟอนต์ที่ไม่ได้จัดเตรียมไว้

(สังเกตที่คำว่า date stamp ซึ่งเป็นสาเหตุที่ทำให้มันหลุดรอดการทดสอบก่อนออกรุ่น 0.7.0 เพราะผมไม่ได้ทดสอบแบบข้ามวัน ทดสอบกี่รอบ date stamp มันก็ไม่เปลี่ยน)

Fonts-TLWG 0.7.1 จึงเกิดขึ้นตามมาเพื่ออุดช่องโหว่ดังกล่าว โดยเติมฟิลด์ UniqueID ใน TTF Names ให้ครบทุกฟอนต์เสีย

ขณะเดียวกัน เป็นธรรมเนียมของ Fonts-TLWG ที่จะ release พร้อมกับฟอนต์ OTF, TTF, WOFF ที่ build สำเร็จรูปแล้ว นอกเหนือจากซอร์สของฟอนต์ เพื่ออำนวยความสะดวกผู้ใช้ฟอนต์ทั่วไปที่ไม่สะดวกจะ build ฟอนต์เอง ซึ่งในทุกรุ่นที่ผ่านมา ผมสร้าง tarball เหล่านี้แบบ manual ด้วยการ configure และ build สามแบบเพื่อเก็บเข้า tarball ทีละก้อน ซึ่งถ้านาน ๆ ทำทีก็ไม่รู้สึกลำบาก แต่พอออกรุ่นนี้ไล่หลังรุ่นที่แล้วแบบค่อนข้างกระชั้นชิด เลยรู้สึกว่ามันควร automate มาตั้งนานแล้ว

จึงได้เป็น automation สำหรับการ build font tarballs โดยอิงอาศัย make rule ชุดเดิมที่เคยใช้ build ZIP file สำหรับ CTAN upload

พร้อมกันนี้ ในรุ่นนี้ผมเริ่มเผยแพร่ฟอนต์สำเร็จรูปในรูปแบบ ZIP file นอกเหนือจาก tarball ด้วย เพื่อส่งเสริมการใช้งานในวินโดวส์หรือแฟลตฟอร์มอื่นด้วย เพราะที่ผ่านมา Fonts-TLWG ถูกมองจากผู้ใช้ทั่วไปว่าเป็น ฟอนต์สำหรับ LaTeX บ้าง ฟอนต์สำหรับลินุกซ์ บ้าง ทั้งที่มันใช้ได้ในแพลตฟอร์มทั่วไป

upload เข้า Debian แล้ว ต่อไปก็รอดู reproducibility test ต่อไป

ทางด้าน CTAN ก็ได้ upload ไล่หลัง Debian แล้วทั้งสองรุ่น

ป้ายกำกับ: ,

21 ตุลาคม 2561

Reproducible Fonts-TLWG

ความเปลี่ยนแปลงล่าสุดใน Fonts-TLWG คือเรื่อง reproducibility คือการ build ที่ให้ผลลัพธ์เป็น binary file ที่เป็นข้อมูลเดิมทุกบิตทุกครั้งที่ build โดยไม่ขึ้นกับสภาวะที่ใช้ในการ build

สำหรับฟอนต์จากโครงการ Fonts-TLWG มีปัญหา reproducibility ตามที่รายงานโดย Debian คือ modification timestamp ที่เกิดจาก Fontforge script ที่ใช้ build โดยมีการเปลี่ยนแปลงข้อมูลของฟอนต์ระหว่างทาง ทำให้ timestamp ของการเปลี่ยนแปลงถูกปรับเป็นเวลาขณะ script ทำงานนั้น และทำให้ข้อมูลฟอนต์ผลลัพธ์แปรเปลี่ยนไปตามเวลาที่ build

Modification กลางอากาศ

script ที่ใช้ generate ฟอนต์ชนิดต่าง ๆ จะมีการเปลี่ยนแปลงข้อมูลฟอนต์กลางอากาศขณะ build ดังนี้

  • OTF และ WOFF จะมีการตัด PUA glyphs สำหรับสระบน-ล่างและวรรณยุกต์ที่เลื่อนหลบหางพยัญชนะ
  • TTF มีการแปลง cubic spline เป็น quadratic ก่อน apply AutoInstr
  • LaTeX fonts (Postscript + TeX virtual fonts) จะไม่มี modification ใด ๆ

PUA Glyphs

PUA (Unicode Private Use Area) glyphs สำหรับสระบน-ล่างและวรรณยุกต์ที่เลื่อนหลบหางพยัญชนะ เป็นสิ่งจำเป็นสำหรับการ render ข้อความในสภาวะที่ไม่มีเทคโนโลยี OpenType เช่น บน Windows XP และการใช้ virtual font ใน TeX engine เก่า (เช่น pdfTeX) ซึ่งเราได้ตัดสินใจยกเลิกการรองรับ TTF แบบเก่าไปนานแล้ว แต่ยังไม่สามารถตัดการรองรับ TeX engine เก่าได้ จึงยังคง PUA glyphs ไว้ใน source ของฟอนต์ แต่ใช้วิธีลบกลางอากาศขณะ gen OTF และ TTF เอา

แต่การลบ glyph กลางอากาศนี่เองที่เป็นสาเหตุหนึ่งที่ทำให้ modification timestamp ของฟอนต์เปลี่ยน และทำให้ได้ไฟล์ฟอนต์ที่ไม่ reproducible

วิธีแก้ปัญหาก็เป็นไปได้สองทาง:

  1. ไม่ต้องตัด PUA glyphs เลย ใส่เกินไว้ในฟอนต์อย่างนั้นแหละ การมีอยู่ของ OpenType tables ต่าง ๆ จะทำให้ shaping engine อย่าง Harfbuzz ไม่ fallback มาใช้ PUA shaping เมื่อเจอ PUA glyphs ในฟอนต์
  2. ตัด PUA glyphs ออกจาก source ไปเลย ซึ่งจะหมายถึงการตัดการรองรับ shaping ผ่าน TeX virtual font ด้วย ผลคือ ตัดการรองรับ pdfTeX ไปเลย และหยุดอัปเดตแพกเกจ fonts-tlwg บน CTAN ไปเสีย

ทางเลือก 2 ดูจะเป็นเรื่องใหญ่ ผมคิดว่าควรชะลอไปก่อน และเลือกทางเลือก 1 ไว้ก่อน และได้ commit ไปตามนี้

TrueType Instructions

เพื่อเพิ่ม hint ให้กับฟอนต์ TrueType ในขณะที่ source ของเราอยู่ในรูป cubic spline ตัว script จึงใช้วิธีแปลง spline ให้เป็น quadratic ก่อน แล้ว apply AutoInstr กลางอากาศก่อน generate TTF

ซึ่งการแปลงและสั่ง AutoInstr ทำให้ modification timestamp ของฟอนต์เปลี่ยน ทำให้ได้ไฟล์ฟอนต์ที่ไม่ reproducible อีกเช่นกัน

ผมค้นคิดวิธีที่จะแก้ปัญหานี้ไปเรื่อย ๆ จนในที่สุดก็ได้ไอเดียการทำ mixed layers โดยมีหลักการคือ:

  • เพิ่ม layer ที่สี่ในไฟล์ SFD เป็นชนิด quadratic แล้ว copy spline ทั้งหมดจาก Front Layer ซึ่งเป็น cubic มายัง qudratic layer นี้ ซึ่ง Fontforge จะแปลง spline ให้ขณะ copy
  • เราสามารถแก้ไข quadratic spline ใน layer ใหม่นี้ได้ หรือหากต้องการ fine-tune TrueType instructions ก็ทำได้ แต่ในเบื้องต้นนี้ยังไม่ edit ใด ๆ และใช้ AutoInstr ไปก่อน
  • ในการ generate TTF ใน dialog box จะสามารถเลือกให้ generate จาก quadratic layer แทน Front Layer ได้ และใน script อัตโนมัติก็สามารถกำหนด layer ที่จะใช้ได้เช่นกัน เพียงแต่การเลือก layer ยังไม่รองรับใน Fontforge native script ด้วยข้อจำกัดเรื่อง syntax แต่ใน Python script สามารถทำได้

เมื่อได้หลักการเช่นนี้แล้ว ก็ได้แตก branch mixed-layer-ttf เพื่อดำเนินการ โดยตั้งชื่อ quadratic layer ให้เหมือนกันทุกฟอนต์ว่า Quad เพื่อจะได้ใช้ชื่อนี้ใน script ให้ทำงานได้ทุกฟอนต์ และเปลี่ยนมาใช้ Python script สำหรับ TTF แทน native script เดิม

ด้วยหลักการเช่นนี้ source สำหรับ TTF ก็จะเตรียมพร้อมอยู่ใน source สำหรับ generate ได้โดยไม่ต้องแก้ไขกลางอากาศอีก

ทำเสร็จหมดแล้ว ก็ merge เข้า master เสีย เป็นอันเสร็จพิธี

ส่วน LaTeX fonts ไม่มีประเด็นอะไรต้องแก้ ผลคือ ขณะนี้ fonts-tlwg สามารถ build แบบ reproducible ได้ทั้งหมดแล้ว

อนาคต

ประเด็นที่น่าจะทำในอนาคต:

  • ตัดสินใจว่าจะทำอย่างไรกับ PUA glyphs เช่น
    • หาวิธี ข้าม PUA glyphs ขณะ generate โดยไม่ต้องลบ glyph เพื่อจะได้หลีกเลี่ยง modification timestamp
    • ตัด PUA glyphs ออกจาก source เลยไหม? ซึ่งจะหมายถึงการตัดการรองรับ shaping ผ่าน TeX virtual font สำหรับ engine เก่าอย่าง pdfTeX ด้วย
  • Quad layer ที่เกิดขึ้นได้ให้อิสระในการปรับแต่ง TrueType spline และ instruction แล้ว สามารถ fine-tune ต่อไปในอนาคตได้

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

hacker emblem