1 điểm bởi GN⁺ 2024-08-11 | 1 bình luận | Chia sẻ qua WhatsApp
  • 175 Pixel Font Megapack ra mắt vào tháng 12/2023 là một dự án font pixel xử lý cả việc tạo font, kiểm thử chất lượng và phát hành bằng toolchain Rust tự xây dựng
  • Các gói trước đó gồm 12 font vào năm 2016 và 40 font vào năm 2018, còn gói mới được bắt đầu với mục tiêu đồng thời nâng cấp chất lượng, phong cách, hỗ trợ ngôn ngữ và tự động hóa phát hành
  • Font mới vượt qua giới hạn chỉ hỗ trợ ASCII trước đây để hỗ trợ 176 ký tự Latin mở rộng cho EFIGS, nhưng các ngôn ngữ châu Á và ngôn ngữ phi-Latin bị loại trừ do vấn đề chất lượng và thời gian sản xuất
  • Công cụ Rust pifo tạo đường viền glyph, auto kerning, TTF, tilesheet và texture atlas đóng gói từ PNG tilesheet và cấu hình TOML, đồng thời có thể xử lý cả 175 font chỉ trong vài giây
  • Ảnh mẫu cỡ lớn, auto kerning và script phát hành butler cho itch.io đã giảm gánh nặng kiểm tra thủ công, chỉnh sửa và tải lên, giúp cải thiện nhanh chất lượng của gần 200 font

Từ các gói font pixel trước đây đến Megapack

  • Gói font đầu tiên năm 2016 là bộ 12 font được tạo ra vào thời điểm bắt đầu làm Ikenfell
    • Tác giả tinh chỉnh các font đang làm cho game và thêm vài font nữa rồi bán trên itch.io
    • Chúng được dùng trong nhiều game indie và nhận phản hồi tốt
  • Gói thứ hai năm 2018 tăng lên 40 font và chất lượng cũng được nâng cao đáng kể
    • Tác giả tạo bảng kerning để cải thiện việc render câu
    • Đồng thời cung cấp các định dạng build sẵn để dễ dùng trong nhiều game engine
    • Việc quảng bá được thực hiện bằng cách áp dụng chính các font này vào screenshot game của các nhà phát triển indie
  • Các gói trước đã được dùng trong hàng trăm game indie, bao gồm cả Cadence of Hyrule của Nintendo
    • Nhiều font cũng được dùng trong Get in the Car, Loser của Love Conquers All Games
  • Sau khi Ikenfell phát hành, dù trải qua thời gian burnout dài, tác giả vẫn nâng cao kỹ năng Rust và tiếp tục làm font với ý định một ngày nào đó tạo ra gói font pixel mới

Mục tiêu của Megapack

  • Mục tiêu ban đầu của gói mới là 100 font, nhưng kết quả cuối cùng là 175 font pixel
    • Các gói trước lần lượt có 12 và 40 font
    • Gói mới nhắm tới các font có thể dùng cho nhiều thể loại như sci-fi, fantasy, horror, nông trại và game cozy
  • Yêu cầu và phàn nàn lớn nhất với các gói trước là việc chúng chỉ hỗ trợ ký tự ASCII
    • Gói mới áp dụng bộ ký tự Latin mở rộng để hỗ trợ EFIGS, tức English, French, Italian, German, Spanish
    • Bộ ký tự cuối cùng gồm 176 ký tự
    • Các ngôn ngữ châu Á hoặc ngôn ngữ dựa trên phi-Latin bị loại do đây là các bộ ký tự không quen thuộc, khó đạt chất lượng mong muốn và làm tăng mạnh thời gian sản xuất
  • UI game cần phân cấp thị giác, nên mỗi font được định hướng làm thành font family thay vì chỉ một kiểu duy nhất
    • Ví dụ, font family Virtue bao gồm 20 style
    • Nhà phát triển có thể thay đổi kích thước và độ đậm mà không cần trộn nhiều font có không khí khác nhau
  • Kerning là một yếu tố tiêu tốn rất nhiều thời gian ở các gói trước
    • Với 176 ký tự được hỗ trợ, số cặp kerning có thể lên tới 176²
    • Để tránh nhập thủ công mọi cặp, phần lớn được tính tự động, còn những phần thuật toán chưa làm tốt mới được chỉnh tay
  • Kiểm soát chất lượng và phát hành cũng là mục tiêu tự động hóa
    • Trước đây, sau khi sửa lỗi pixel hoặc bug kerning, tác giả phải export lại, test lại và tự tải lên itch.io
    • Toolchain mới đặt mục tiêu tạo văn bản mẫu và trực quan hóa kerning để nhanh chóng tìm lỗi và kiểm tra ngay kết quả chỉnh sửa

Chuẩn bị để nâng cao chất lượng thiết kế font

  • Dù có nhiều kinh nghiệm với pixel art và pixel font, tác giả chưa từng học nghiêm túc về thiết kế chữ theo nghĩa truyền thống
  • Trong quá trình làm việc, tác giả tham khảo Design School: Type của Richard Poulin
    • Đây được dùng như sách nhập môn giúp làm quen với thuật ngữ và quy ước của thiết kế chữ
  • Tác giả cũng thu thập ảnh chụp văn bản bắt gặp xung quanh làm tài liệu tham khảo
    • Biển hiệu cửa hàng nhỏ, bảo tàng, gallery, lễ hội, poster sự kiện địa phương và bìa sách đều trở thành nguồn tham khảo
    • Mục đích không phải để sao chép font mà là nghiên cứu hình dáng chữ, các ký tự hạ xuống dưới baseline và sự khác biệt giữa chữ mảnh với chữ rộng
  • Khi quan sát các font trang trí ngoài đời, tác giả học được rằng nhiều font “cầu kỳ” không trang trí quá mức mọi ký tự mà thường tập trung chi tiết ở chữ in hoa, còn chữ thường được xử lý tinh tế hơn

Vai trò của công cụ Rust pifo

  • Để đạt được các mục tiêu trên, tác giả đã viết chương trình Rust riêng tên là pifo
  • Bản thân việc thiết kế font vẫn được thực hiện bằng các công cụ pixel art thông thường
    • Đầu vào là PNG tilesheet và file TOML cấu hình
    • Ví dụ lệnh là pifo --all --output "Faraway" --input "Faraway*"
  • pifo cắt ảnh đầu vào thành từng tile glyph riêng lẻ, tạo đường viền glyph, tự động tính các cặp kerning rồi export thành file TTF
    • Đồng thời nó cũng tạo ra các định dạng khác để dùng ngay trong nhiều engine
    • Công việc xử lý từng glyph được song song hóa nên một font đơn lẻ gần như được xử lý tức thì
    • Ngay cả khi xử lý lần lượt 175 font, toàn bộ cũng chỉ mất vài giây
  • Các crate Rust chính được dùng gồm:
    • clap: phân tích đối số dòng lệnh
    • image: giải mã và mã hóa ảnh
    • rayon: song song hóa
    • serde: tuần tự hóa dữ liệu
    • glyph-names: ánh xạ giữa ký tự và tên glyph
    • ab-glyph: nạp font và raster hóa
    • crunch: đóng gói hình chữ nhật

Quá trình tạo đường viền glyph

  • Mỗi font sheet gồm tilesheet và file cấu hình TOML
    • Cấu hình bao gồm version, baseline, line_gap, spacing, metrics, auto_kerning, auto_kerning_min, manual_kerning, skip_kerning_left, skip_kerning_right...
    • Kích thước lưới có thể khác nhau nhưng luôn phải là lưới đồng đều, và các ký tự phải nằm đúng vị trí đã quy định
    • Công cụ chỉ xử lý các pixel trắng 100%, còn nền caro và baseline chỉ dùng làm guide
  • Glyph TrueType được cấu thành từ một hoặc nhiều contour
    • Trong font pixel, mỗi nhóm pixel liền nhau, tức mỗi cluster, cần tạo thành một contour
    • Ví dụ, nếu chữ thường t có hai khối pixel tách rời thì cần hai contour
  • Việc tạo contour diễn ra qua nhiều bước
    • Từ RgbaImage, công cụ chọn các pixel trắng và gom chúng vào HashSet của struct Point
    • Bắt đầu từ một pixel bất kỳ, nó thực hiện flood fill sang các pixel kề bên, rồi lặp lại cho đến khi không còn pixel chưa được thăm để tìm các cluster
    • Từ mỗi cluster, nó thu thập các cạnh lộ ra là những mặt không có pixel kề bên
    • Sau đó nối head và tail của các cạnh để tạo thành đường khép kín rồi chuyển thành contour
  • Các cluster có lỗ có thể tạo ra nhiều contour
    • Contour ngoài quấn theo chiều kim đồng hồ, còn lỗ bên trong quấn ngược chiều kim đồng hồ
    • Sự khác biệt về hướng này khớp với cách TTF biểu diễn lỗ
  • Các điểm giữa nằm trên cùng một đoạn thẳng liên tiếp sẽ bị loại bỏ
    • Đây là tối ưu để giảm kích thước file và tăng tốc độ raster hóa

Tự động hóa bảng kerning

  • Để tạo TTF, thành phần cần thiết tiếp theo sau contour là bảng kerning
    • Bảng kerning kéo một số cặp ký tự cụ thể sang trái để từ trông tự nhiên hơn
    • Ví dụ, kéo cặp Va, lt sang trái 1 pixel sẽ đẹp hơn
  • Kerning thủ công được khai báo trong manual_kerning của TOML
    • Cú pháp có dạng { left = "V", right = "a", kern = -1 }
    • Công cụ hỗ trợ tùy chọn alts = true để không phải khai báo riêng mọi ký tự có dấu
    • Nó ánh xạ các ký tự thay thế như àáâãäå cho a để áp dụng cùng giá trị kerning
  • Auto kerning được tính bằng cách di chuyển glyph bên phải sang trái từng 1 pixel
    • Công cụ tìm vị trí gần nhất mà glyph đó vẫn chưa chạm glyph bên trái
    • Va chạm ở góc cũng được tính là chạm
    • Ví dụ với LV, có thể kéo V sang trái 1 pixel nhưng 2 pixel thì các pixel chạm nhau, nên giá trị kerning là -1
  • Việc tính auto kerning vẫn tôn trọng các giá trị chỉnh tay và thiết lập loại trừ
    • Có thể loại bỏ glyph theo từng phía bằng skip_kerning_leftskip_kerning_right
    • Tất cả các cặp kerning được tính song song bằng rayon

Các định dạng xuất

  • PIFO không chỉ tạo TTF mà còn tạo tilesheet và texture atlas đóng gói
  • File TTF là file nhị phân gồm nhiều bảng
    • Công cụ export điền các bảng head, hhea, maxp, OS/2, hmtx, cmap, loca, glyf, kern, name, post
    • Mỗi bảng cần ghi lại vị trí, độ dài và checksum, được xử lý bằng begin_table()end_table()
  • Kích thước cơ bản của font pixel được đặt là 16
    • Khi render ở cỡ 16, mỗi pixel sẽ chính xác là 1 px
    • Để phóng to không bị rung lệch, có thể vẽ ở các bội số của 16 như 32, 48, 64
  • Khi export tilesheet, thứ tự không giống sheet đầu vào mà được sắp theo thứ tự codepoint Unicode
    • File dữ liệu đi kèm chứa hàng/cột, kích thước tile, baseline, line gap, độ rộng khoảng trắng, metric glyph và bảng kerning
    • Dữ liệu được tuần tự hóa sang nhiều định dạng như JSON, XML, TOML bằng serde
  • Công cụ cũng tạo atlas đóng gói
    • Nó dùng crate đóng gói hình chữ nhật tự viết là crunch
    • Vì đóng gói chặt sẽ làm mất thông tin vị trí, dữ liệu bổ sung cho render sẽ gồm x, y, w, h, off_x, off_y, adv

Kiểm thử chất lượng và ảnh mẫu

  • Để đạt chất lượng mong muốn, tác giả đã thêm vào PIFO tính năng tạo ảnh mẫu khổng lồ
  • Ảnh mẫu gồm nhiều khối kiểm thử
    • Tất cả chữ cái và một số câu kiểm thử
    • Một phần truyện ngắn They're Made out of Meat của Terry Bisson
    • Các từ kiểm thử áp dụng chiến lược từ Text for Proofing Fonts: A farewell to The Quick Brown Fox
    • Mọi tổ hợp chữ số và ký hiệu tiền tệ
    • Các cặp kerning chữ in hoa, chữ thường và kiểu trộn hoa-thường
    • Nhiều loại dấu câu khác nhau
  • Trong lúc làm việc, tác giả có thể tạo ngay ảnh mẫu nên tìm ra vấn đề và sửa rất nhanh
    • Quy trình này đã nâng chất lượng tổng thể và độ hoàn thiện của gần 200 font

Tự động hóa phát hành lên itch.io

  • Thành phẩm cuối cùng là 175 font pixel, và tác giả chọn itch.io làm nơi bán trực tuyến tải về như trước đây
  • Công việc phiền nhất là tạo project itch riêng cho từng font
    • Việc này chỉ cần làm một lần cho mỗi font
    • Sau đó, việc upload và bảo trì có thể xử lý bằng script dòng lệnh
  • Script phát hành gồm ba bước
    • Biên dịch PIFO ở chế độ release
    • Build các asset font mong muốn
    • Cập nhật project itch của từng font bằng asset mới
  • Mẫu đầu vào như --input "Faraway*" sẽ tìm các style có cùng tiền tố như Faraway - Regular, Faraway - Bold rồi gộp thành một gói font family
  • Với lần upload cuối cùng, tác giả dùng công cụ phát hành dòng lệnh butler do itch cung cấp
    • Việc phát hành có dạng butler push ../distro/faraway chevyray/pixel-font-faraway:assets
    • Butler theo dõi các file đã thay đổi và chỉ cập nhật phần cần thiết nên không cần băm file riêng hay cơ chế quản lý phiên bản đặc biệt nào

1 bình luận

 
GN⁺ 2024-08-11
Ý kiến trên Hacker News
  • Những font rất đẹp và bài viết cũng thú vị
    Nhìn trò chơi giả ở góc trên bên phải https://chevyray.dev/blog/creating-175-fonts/old_previews.pn... mà nghĩ giá như đó là game thật
    Nó có cảm giác kiểu “Wonder Boy in Monster World cho GBA” nên tôi thích
    Tuy nhiên, nhìn vào giấy phép thì có vẻ không cho phép dùng TTF trong các dự án phần mềm nguồn mở, nên cần lưu ý
    Tôi không phải luật sư, nhưng điều khoản cuối đọc lên thấy rõ là cấm: https://github.com/ChevyRay/pixel_font_megapack_license/blob...

    • Nếu thích game platformer thì nên thử Celeste
      Cảnh trong bản mockup đó tham chiếu đến cảnh mở đầu của Celeste
    • Việc phân phối chính bản thân font dưới dạng nguồn mở hoặc kiểu CC thì chắc chắn là không được, nhưng nói rằng bị cấm cả việc đóng gói và phân phối cùng một phần mềm mà các phần còn lại là nguồn mở thì hơi khó khẳng định
      Ý định rõ ràng có vẻ là dùng cho game ở giai đoạn sản phẩm cuối, nơi nguồn mở tương đối hiếm, hơn là cho game engine hay template
      Đọc bài này cũng làm tôi nhớ đến một trường hợp ranh giới khác về bản quyền: ở Mỹ, typeface không thuộc đối tượng được bảo hộ bản quyền
      Font được bảo hộ như một chương trình máy tính, nhưng typeface và font bitmap đơn giản thì không
      Vì vậy quy trình này về cơ bản là tạo ra TTF có bản quyền từ tilesheet gốc không có bản quyền, rồi lại quay về tilesheet/atlas đầu ra không có bản quyền
    • Lẽ ra tôi nên viết là trong các dự án phần mềm nguồn mở, chứ không phải “trong phần mềm nguồn mở”
  • Thật sự ấn tượng
    Làm một bộ font hoàn chỉnh có thể dễ dàng mất 1 năm
    Phải tạo mọi glyph từ 'A' đến 'Z', chữ hoa chữ thường, ngoặc, dấu &, dấu chấm than, v.v.; nếu có thể thì còn phải làm các biến thể như đậm, nghiêng
    Nếu không có những biến thể này, mức độ hữu dụng của font sẽ bị hạn chế
    Đặc biệt thứ phân định tay nghề là kerning, tức khoảng cách giữa các chữ; nếu đã muốn ám ảnh thì có thể ám ảnh vô tận
    Ngay trong bài cũng nói rằng nếu hỗ trợ 176 ký tự thì tối đa phải nhập 176² = 37.976 cặp kerning, nên tác giả đã tự làm công cụ để bán tự động hóa phần lớn và chỉ nhập thủ công những chỗ thuật toán còn thiếu

    • Đó là khi giới hạn font chỉ dùng cho tiếng Anh thuần túy
      Nếu muốn hỗ trợ các ngôn ngữ khác, ngay cả các ngôn ngữ dùng chữ Latin như tiếng Pháp, Tây Ban Nha, Ý, Bồ Đào Nha cũng cần ký tự bổ sung
      Sau đó bạn có thể sẽ muốn hỗ trợ cả chữ Hy Lạp, Cyrillic, tiếng Nhật, tiếng Trung
      Ví dụ theo Wikipedia, “Noto fonts hỗ trợ hơn 77.000 ký tự, tức khoảng một nửa trong số 149.186 ký tự được định nghĩa trong Unicode 15.0”
    • Một bộ font hoàn chỉnh có thể dễ dàng mất 1 năm, nhưng làm một font family có thể trở thành dự án cả đời
    • Nói thật là tôi không thấy thuyết phục với câu “một bộ font hoàn chỉnh dễ dàng mất 1 năm”
      Với bất cứ thứ gì người ta cũng có thể ám ảnh vô tận
      Có vẻ những lĩnh vực như ngôn ngữ, viết lách, âm nhạc, thư pháp rất dễ thu hút mạnh những người có xu hướng ám ảnh
      Ý chính là những câu như vậy nghe giống như dựng rào cản gia nhập
      Những lời dễ làm người mới muốn bước vào một lĩnh vực thấy nản luôn nghe hơi nhạy cảm
  • Rất hay
    Một điều tôi tò mò là tại sao lại chọn đúng tập con này trong số các ký tự đặc biệt Scandinavia
    Tiếng Thụy Điển có äöå, tiếng Na Uy/Đan Mạch có æøå, nhưng font này có æ mà không có ø
    Như vậy nếu bỏ æ thì vẫn giữ được hỗ trợ tiếng Thụy Điển, còn nếu thêm ø thì có thể hỗ trợ cả tiếng Na Uy và Đan Mạch
    Tôi tự hỏi đây chỉ là thiếu sót đơn giản, hay có locale nào dùng æ nhưng không dùng ø
    Nói thêm là tôi không nhầm æ với ligature œ, một glyph riêng dùng trong tiếng Pháp

    • Tiếng Iceland dùng ö thay vì ø, nhưng đồng thời cũng cần ð và ý mà font này không có
      Tuy vậy Æ cũng được dùng trong các văn bản tiếng Anh cổ như “encyclopædia”, hoặc trong dạng số nhiều của các từ gốc Latin: https://en.wiktionary.org/wiki/Category:English_plurals_in_-...
    • Đây chỉ là thiếu sót thôi
      Thực ra mãi đến khi dự án đã tiến khá xa tôi mới nhận ra rằng bộ ký tự của mình thiếu ø
      Chắc chắn có thể thêm lại và vá cho tất cả font, nhưng tôi đang chờ xem có đủ nhu cầu để làm khối lượng công việc đó không
      Dù vậy, nếu có thể hỗ trợ thêm hai ngôn ngữ thì nghe cũng khá tuyệt
  • Tôi cũng thích một số font được dùng trên site và cách styling đơn giản
    May là nó đã được công bố trong một bài riêng: https://chevyray.dev/blog/how-this-site-is-made/#catppuccin-...

  • Thú vị
    Trước đây tôi không biết rằng khi mã hóa pixel font thành TTF thì sẽ chuyển thành vector
    Với những ai tải nó vào một text renderer tử tế, có lẽ cũng có thể phóng to/thu nhỏ mượt ở một mức nào đó
    Tất nhiên có thể ngoại trừ phía game engine, nơi pixel font gần như chỉ được dùng theo tỷ lệ 1:1

    • Làm vậy thì cũng có thể dùng trong các trình biên tập đồ họa truyền thống như Photoshop, InDesign, Affinity, Aseprite
      Những công cụ này không có khái niệm pixel font, nên nếu dùng TTF đã tắt hinting và anti-aliasing thì có thể tận dụng trong các ứng dụng đó
  • Tuyệt
    Cũng hay là công việc này đã giúp ích về mặt tài chính cho người tạo ra nó
    Mình nhớ cái tên Chevy Ray trong mảng game indie, nhưng không nhớ chính xác là đã làm gì
    Đại khái khoảng 2010–2012, có vẻ là thứ gì đó cùng dòng với VVVVVV, Nidhogg hay Canabalt

    • Là Flashpunk
      Beacon cũng rất hay — gợi nhớ ngày xưa, và mình nhớ game indie
    • Có lẽ game đang nói tới là Beacon
    • Ikenfell
    • Ikenfell mình cũng chơi rất vui
    • Flashpunk?
  • Xuất sắc
    Nhìn thấy một con người kiểu Da Vinci như tác giả bài này, mình nhớ đến thời mà nghệ sĩ và kỹ sư không được phân tách rõ ràng mà là một

    • Nếu vậy thì khuyên nên đọc kỹ hơn về Da Vinci
      Không phải kiểu bài “top 10 phát minh của Da Vinci”
      Thực tế là giữa hai vai trò đó có sự phân biệt khá lớn
      Mình cũng có thể dùng Maya để mô hình hóa một con tàu vũ trụ đi tới Alpha Centauri bằng thứ động lực học đáng ngờ chưa được kiểm chứng
      Nhưng điều đó còn rất xa so với việc thật sự chế tạo nó và phóng vào không gian liên sao
      Tranh thì đẹp và giàu trí tưởng tượng thật
  • Trong Rust, việc làm cho những tác vụ kiểu này chạy trên nhiều lõi dễ đến mức thú vị
    Có khi chỉ cần chèn thêm một lời gọi vào chuỗi hàm là đủ

    • Rust về cơ bản được thiết kế để có an toàn bộ nhớ và an toàn luồng
      Với điều kiện tuân theo các quy tắc mà ngôn ngữ đặt ra, đa luồng gần như là “miễn phí”
      Định luật Amdahl vẫn có tác động, nhưng ít nhất ứng dụng sẽ không nổ tung ngay trước mắt
    • Không phải đặc trưng riêng của Rust
      Scala và Java cũng hỗ trợ sẵn những khả năng như vậy
  • Công việc thật sự xuất sắc và bài viết cũng hay
    Dùng vài mẹo thì có vẻ có thể làm nhiều thuật toán nhanh hơn nữa
    Theo những gì đọc được, manh mối có thể là thay hashmap trong phần vẽ ký tự và ánh xạ biến thể ASCII bằng bitmap và mảng chỉ mục byte
    Tất nhiên là đã đủ nhanh rồi nên với đoạn mã này thì không quá quan trọng

    • Rất vui vì bạn nhắc đến chuyện này, hoàn toàn đúng
      Trên trang không có toàn bộ mã, nhưng thực tế là nó cấp phát và sao chép khá nhiều chuỗi cùng cấu trúc dữ liệu
      Ở những chỗ rõ ràng thì đã dùng mã tối ưu, còn những phần như sao chép bitmap hay các tác vụ dễ song song hóa thì nhanh đến mức hoàn tất gần như ngay lập tức, nên mình thậm chí không thử tối ưu các phần khác
      Dù vậy nếu muốn thì vẫn làm được
      Dễ quên mất các ngôn ngữ gần mức thấp như Rust, C++, Go nhanh đến mức nào, nhất là khi thêm các công cụ đa luồng mặc định và hàng đợi tác vụ, v.v.
  • Ai quan tâm đến font thì cũng nên xem https://tomorrow.type.today/
    Đây là một studio typography tạo ra các font độc đáo và thử nghiệm rất tuyệt
    Một người trong đội chúng tôi rất mê typography, nên đang tạo một bộ sưu tập các tác phẩm của họ tại https://play.soot.com/tomorrowtypetoday

    • Nhân tiện, công ty đó được đăng ký tại Nga