Nhà phát triển tạo ra 175 font pixel bằng Rust
(chevyray.dev)- 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
butlercho 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
- Với 176 ký tự được hỗ trợ, số cặp kerning có thể lên tới
- 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*"
pifocắ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:
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
- Cấu hình bao gồm
- 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
tcó 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àoHashSetcủa structPoint - 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
- Từ
- 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,ltsang trái 1 pixel sẽ đẹp hơn
- Kerning thủ công được khai báo trong
manual_kerningcủ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ư
àáâãäåchoađể áp dụng cùng giá trị kerning
- Cú pháp có dạng
- 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éoVsang 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_leftvàskip_kerning_right - Tất cả các cặp kerning được tính song song bằng
rayon
- Có thể loại bỏ glyph theo từng phía bằng
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()vàend_table()
- Công cụ export điền các bảng
- 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 render ở cỡ 16, mỗi pixel sẽ chính xác là
- 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 - Boldrồ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
butlerdo 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
- Việc phát hành có dạng
1 bình luận
Ý 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...
Cảnh trong bản mockup đó tham chiếu đến cảnh mở đầu của Celeste
Ý đị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
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
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”
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
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_-...
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
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
Beacon cũng rất hay — gợi nhớ ngày xưa, và mình nhớ game indie
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
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à đủ
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
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
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