Theppitak's blog

My personal blog.

26 มิถุนายน 2552

TlwgTypo Bold Emboldened

ใน ThaiFonts-Scalable 0.4.12 ที่ออกไปเมื่อสัปดาห์ที่แล้วนั้น การเปลี่ยนแปลงส่วนหนึ่งคือเอาการแทนที่จุดสามจุดด้วยจุดไข่ปลาตัวเดียวออกในฟอนต์ monospace เนื่องจากมักสร้างความรำคาญ และทำให้ความกว้างข้อความสั้นลง ผิดธรรมชาติของฟอนต์ monospace

ตอนนี้ก็มาปรับเพิ่มอีกหน่อย โดยปรับไปปรับมาก็พบว่า fontforge รุ่นใหม่กลับมาทำ diagonal hint ได้อีก โดยมีคำแนะนำเพิ่มด้วย ว่า ควรเปิดใช้ diagonal hint ถ้าจะทำ AutoInstr สำหรับฟอนต์ TrueType ว่าแล้วเลยจัดการตามที่เขาแนะนำ ปรากฏว่าสามารถช่วยลดปัญหา ฟอนต์จางเมื่อใช้พื้นหลังดำ ลงได้บ้าง

ก่อน:

TlwgTypo with dark BG, before adjustment

หลัง (สังเกตความเปลี่ยนแปลงที่เลข 4, ตัว M, x, X เป็นต้น):

TlwgTypo with dark BG, after adjustment

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

ดูเหมือนคุณวิทยาก็ พบปัญหานี้ แต่ก็ได้แก้ด้วยการออกแบบ glyph ภาษาไทยใหม่หมด

ครั้งนี้ ผมคิดว่าควรจะพยายามปรับดูจริง ๆ จัง ๆ ละ โดยเริ่มลองกับ TlwgTypist ก่อน ด้วยการขยาย stroke อัตโนมัติแบบไม่แยแสการเกยทับกันของเส้น แล้วก็สั่ง merge overlap ซะ แต่พอจะมาทำกับ TlwgTypo ก็เกิดไอเดียว่า แล้วถ้าลองดัดเส้นไม่ให้มันเกยทับกันล่ะ? อาจจะแอบหดบางเส้น ดัดบางเส้นหลบออกไป อย่างละนิดละหน่อย จัดไปจัดมาก็ได้ glyph ตัวหนาแบบที่สองที่โครงสร้างตัวอักษรเดิมยังอยู่ครบ

สังเกตความเปลี่ยนแปลงได้จากรูป ซึ่งแสดงสี่ฟอนต์เทียบกัน คือ TlwgTypewriter ของคุณพูลลาภ ซึ่งไม่มีปัญหาเรื่องตัวหนา, TlwgTypo ก่อนแก้, TlwgTypist ที่ขยาย stroke แบบอัตโนมัติ และ TlwgTypo ที่ขยาย stroke แบบทำมือ:

TlwgTypewriter, Old TlwgTypo, New TlwgTypist, New TlwgTypo comparison

จะเห็นว่า:

  • TlwgTypo ก่อนแก้ ภาษาไทยตัวหนานั้นจะบางกว่าภาษาอังกฤษอย่างเห็นได้ชัด และแตกต่างจากตัวธรรมดาน้อยมากที่ขนาดเล็ก ๆ
  • TlwgTypist ที่ขยาย stroke แบบอัตโนมัติ รูปร่างจะไม่เพี้ยนมาก แต่มีจุดดำทึบหลายจุด เช่น ที่ ฑ นางมณโฑ, ฒ ผู้เฒ่า
  • TlwgTypo ที่ขยาย stroke แบบทำมือ รูปร่างผิดเพี้ยนบ้างจากการขยับเส้น แต่ไม่น่าเป็นที่สังเกตนัก และฟอนต์ตัวหนาโดยทั่วไปก็ไม่ได้เหมือนตัวธรรมดาเป๊ะ ๆ อยู่แล้ว แต่ตัว rasterize ฟอนต์จะมีอิสระมากขึ้นในการ hint เส้น แทนที่จะต้องเชื่อมติดกันเป็นพืดเสมอ

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

ป้ายกำกับ: ,

18 มิถุนายน 2552

LibThai 0.1.12 and libthai.la Dropping

ในที่สุดก็ ปล่อย libthai 0.1.12 ออกมาแล้ว โดยในรุ่นนี้ เน้นเรื่องการจัดการ unknown word เป็นพิเศษ นอกเหนือจากเรื่อง การใช้กฎอักขรวิธีเข้าช่วย แล้ว ก็ยังมีการแก้บั๊กจิปาถะที่เกี่ยวข้องที่ไม่ได้ตรวจละเอียดมาก่อน เช่น การ recover จากจุด error ที่เริ่มจากตำแหน่งไกลไปหน่อย ทำให้บางครั้ง unknown word ยาวกว่าที่ควรจะเป็น ก็เป็นอาการที่เคยสังเกตพบตอนท่องเว็บมาบ้าง แต่ก็เพิ่งได้ตรวจสอบจริงจังกับกรณีตัวอย่างคราวนี้เอง

เรื่องถัดมาคือการทำ symbol versioning แบบที่ เคยทำกับ libdatrie มาก่อน ไว้รองรับการเปลี่ยน API ในอนาคต

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

เรื่องถัดไป คือ upload deb เข้า Debian โดยในรุ่นนี้ ผมเริ่มพิจารณาที่จะตัด libthai.la ออกจาก deb package แล้ว เนื่องจากเจ้าเดียวที่ต้องการไฟล์นี้ คือ kdelibs 3.x ตอนนี้ก็ได้ถูกแทนที่ด้วย KDE 4 เป็นที่เรียบร้อยแล้ว แต่ก็ยังคงมีซอฟต์แวร์อีกหลายตัวที่ยังไม่ได้พอร์ตไปยัง KDE 4 ดังมีรายชื่อที่ได้ ประกาศใน mailing list ดังนั้น ถ้าคุณเป็นผู้ใช้ KDE บน Debian หรือ Kubuntu ก็กรุณาสำรวจแพกเกจในรายการดังกล่าว ว่าถ้าถอดถอนแพกเกจ libthai-dev ออกแล้ว ยังทำงานผิดเพี้ยนอย่างไรหรือไม่ เช่น มีจุดที่ตัดบรรทัดภาษาไทยไม่ถูกต้อง ถ้ามี ก็กรุณาแจ้งให้ผมทราบ จะทาง blog นี้ หรือทาง mailing list ก็ได้ครับ ผมจะได้คง libthai.la ใน libthai-dev ไว้ให้

ถ้าถึงเย็นวันเสาร์ (20 มิ.ย. 2552) ที่จะถึงนี้ ยังไม่มีการแจ้งเข้ามา ผมก็จะถือว่าไม่มีความต้องการใช้ libthai กับโปรแกรม KDE 3.x ใน Debian หรือ Kubuntu อีกต่อไป แล้วก็จะตัด libthai.la ออกในแพกเกจใหม่นะครับ

ที่ต้องขีดเส้นตายก็เพราะ ต้องการให้แพกเกจใหม่ที่ upload เข้าสู่ Debian ได้ผ่านเข้าไปยัง Ubuntu Karmic ทันทีด้วย ซึ่งการ sync อัตโนมัติดังกล่าว จะปิดลงในวันที่ 25 มิ.ย. ตาม กำหนดเวลาของ Karmic ครับ

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

05 มิถุนายน 2552

Improved Unknown-Word Boundaries in LibThai

เมื่อตอนที่ออกแบบอัลกอริทึมตัดคำใน libthai นั้น การจัดการคำที่ไม่อยู่ในพจนานุกรม (unknown word) จะไม่เน้นละเอียดมากนัก โดยจะอาศัยการตรวจสอบจุดตั้งต้นพยางค์ถัดไปที่เป็นไปได้อย่างคร่าว ๆ แล้วพยายาม recover ด้วยการหาจุดแรกที่สามารถเริ่มตัดคำต่อได้

การตรวจสอบที่ว่านั้นก็เขียนง่าย ๆ คือถ้าเจอสระหน้า พยัญชนะที่ไม่ได้ต่อท้ายสระหน้า หรือตัว ฤ ฦ ก็ถือเป็นจุดเริ่มพยางค์ให้ทดลองตัดคำเพื่อ recover ได้แล้ว เพราะฉะนั้น ผลลัพธ์จึงอาจดูโง่ ๆ ในบางกรณี เช่น ลองแกล้งมันดูแบบนี้:

> เชล็งบดลนที
เชล็|งบ|ดล|นที

ซึ่งจะดูฉลาดกว่าถ้าจะพยายามเดาว่าคำว่า "เชล็ง" อาจเป็นคำที่ไม่อยู่ในพจนานุกรม มากกว่าจะเดาว่า "เชล็" โดยไม่มีตัวสะกด มีตัวอย่างอื่นที่คุณ cwt เคยทำให้ดูขณะคุยกันทางห้อง #tlwg อีก

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

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

ก็ดูเป็นทางออกที่ดี ปรากฏว่าสามารถตรวจสอบกรณีซับซ้อนได้ โดยไม่ทำให้ช้าลง กรณีที่ตรวจสอบไปก็คือ:

  • พยัญชนะที่มีทัณฑฆาตตามหลังในระยะไม่เกิน 2 อักขระ เป็นจุดตั้งต้นพยางค์ไม่ได้ เช่น ธ์ ธุ์ ธิ์ ณ์
  • พยัญชนะที่ตามหลังไม้หันอากาศหรือสระอือโดยอาจมีวรรณยุกต์คั่นหรือไม่ก็ได้ เป็นจุดตั้งต้นพยางค์ไม่ได้ เช่น ขั ตั้ มื ซื้ ฟื้
  • พยัญชนะที่ตามด้วยไม้ไต่คู้ แล้วตามด้วย อ อ่าง หรือ ว แหวน ตัวพยัญชนะแรกสามารถเป็นจุดตั้งต้นพยางค์ได้ แต่อักขระที่ตามหลังอีก 3 ตัว ไม่สามารถเป็นจุดตั้งต้นพยางค์ได้ทั้งหมด เช่น ช็อก ช็วก
  • หากพบสระเอ/แอ:
    • ตัวสระเอ/แอ สามารถเป็นจุดตั้งต้นพยางค์ได้
    • พยัญชนะที่ตามมาเป็นจุดตั้งต้นพยางค์ไม่ได้ เช่น เ
    • และถ้าพบต่อไปว่ามีไม้ไต่คู้หรือสระบนต่อท้ายพยัญชนะ (โดยอาจมีวรรณยุกต์ร่วมด้วยหรือไม่ก็ได้) พยัญชนะที่ตามหลังไม้ไต่คู้หรือสระบนนั้นก็ไม่สามารถเป็นจุดตั้งต้นพยางค์ได้เช่นกัน เช่น เก็ แข็ เสี เสื เสี่ เสื่
    • ถ้าพบว่าอักขระที่สามถัดจากสระเอ/แอ เป็นไม้ไต่คู้ โดยที่อักขระก่อนไม้ไต่คู้ไม่ใช่ ก ไก่ (ถ้าเป็น ก ไก่ จะกลายเป็นคำว่า "ก็") และอักขระถัดจากไม้ไต่คู้ไม่ใช่ อ อ่าง หรือ ว แหวน (ถ้าเป็น จะกลายเป็นพยางค์ใหม่ เช่น "ช็อก") อักขระถัดจากสระเอ/แอ 4 ตัวรวด ไม่สามารถเป็นจุดตั้งต้นพยางค์ได้ทั้งหมด เช่น เขบ็ดมล็ด
  • หากพบสระ โ ใ ไ พยัญชนะถัดไปไม่สามารถเป็นจุดตั้งต้นพยางค์ได้ เช่น โต้ท้
  • พยัญชนะกรณีอื่น ๆ มีโอกาสเป็นจุดตั้งต้นพยางค์ได้ทั้งหมด
  • ฤ ฦ มีโอกาสเป็นจุดตั้งต้นพยางค์ได้
  • อักขระอื่น ๆ ที่เหลือ ไม่สามารถเป็นจุดตั้งต้นพยางค์ได้ เช่น สระบน/ล่าง/ข้าง วรรณยุกต์ ทัณฑฆาต ไม้ไต่คู้ นิคหิต

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

ด้วยการตรวจสอบนี้ libthai รุ่นล่าสุดใน SVN จะตัดกรณีตัวอย่างข้างต้นเป็นอย่างนี้แทน:

> เชล็งบดลนที
เชล็ง|บด|ลน|ที

ซึ่งน่าจะให้ขอบเขตของ unknown word ในกรณีทั่วไปได้สมเหตุสมผลกว่า

นอกจากเรื่องนี้แล้ว อีกทางหนึ่งก็ทยอยปรับพจนานุกรมอยู่เรื่อย ๆ ครับ การเพิ่มคำที่พบในชีวิตประจำวันก็จะช่วยลดจำนวน unknown word ลงได้ ทำให้ตัดคำได้ถูกต้องยิ่งขึ้น ถ้าพบ libthai ตัดคำผิดตรงไหน ก็แจ้งเข้ามาได้ทุกเมื่อนะครับ

Update (5 มิ.ย. 2552 21.32 น.): ปรับแก้กฎเกี่ยวกับไม้ไต่คู้ เมื่อมี อ อ่าง หรือ ว แหวน ตามหลัง

ป้ายกำกับ:

hacker emblem