Rust ile 175 piksel font üreten geliştirici
(chevyray.dev)- Aralık 2023’te yayımlanan 175 Pixel Font Megapack, font üretiminden kalite testine ve dağıtıma kadar her şeyi kendi Rust araç zinciriyle yöneten bir piksel font projesi.
- Önceki paketler 2016’da 12, 2018’de 40 fonttan oluşuyordu; yeni paket ise kalite, stil, dil desteği ve dağıtım otomasyonunu aynı anda ileri taşımak hedefiyle başladı.
- Yeni fontlar, yalnızca ASCII desteğiyle sınırlı kalmayıp EFIGS için 176 genişletilmiş Latin karakterini destekliyor; ancak Asya dilleri ve Latin dışı yazılar, kalite ve üretim süresi sorunları nedeniyle kapsam dışında bırakıldı.
- Rust aracı pifo, PNG tilesheet’ler ve TOML yapılandırmalarından glif konturları, otomatik kerning, TTF, tilesheet ve paketlenmiş texture atlas üretiyor; 175 fontu da birkaç saniye içinde işleyebiliyor.
- Büyük örnek görseller, otomatik kerning ve itch.io için
butlerdağıtım script’leri; elle inceleme, düzeltme ve yükleme yükünü azaltarak neredeyse 200’e yaklaşan fontun kalitesinin hızla iyileştirilmesini sağladı.
Önceki piksel font paketlerinden Megapack’e
- 2016’daki ilk font paketi, Ikenfell üzerinde çalışmaya başlanan dönemde hazırlanan 12 fontluk bir koleksiyondu.
- Oyun için yapılan fontlar düzenlenip birkaç yenisi eklenerek itch.io’da satışa çıkarıldı.
- Birçok bağımsız oyunda kullanıldı ve iyi geri dönüş aldı.
- 2018’deki ikinci paket 40 fonta çıktı ve kalite de ciddi biçimde yükseldi.
- Cümlelerin daha iyi görünmesi için kerning tablosu hazırlandı.
- Çeşitli oyun motorlarında kolay kullanım için önceden derlenmiş formatlar da sunuldu.
- Tanıtım, bağımsız geliştiricilerin oyun ekran görüntülerine kendi fontlarını uygulayarak gösterme yöntemiyle yapıldı.
- Önceki paketler yüzlerce bağımsız oyunda kullanıldı ve Nintendo’nun Cadence of Hyrule oyununda da yer aldı.
- Love Conquers All Games’in Get in the Car, Loser oyununda da birden fazla font kullanıldı.
- Ikenfell çıktıktan sonraki uzun tükenmişlik döneminde bile Rust becerilerini geliştirdi ve bir gün yeni bir piksel font paketi yapmak için font çalışmalarını sürdürdü.
Megapack’in hedefleri
- Yeni paketin ilk hedefi 100 fonttu, ancak nihai sonuç 175 piksel font oldu.
- Önceki paketler sırasıyla 12 ve 40 fonttan oluşuyordu.
- Yeni paket; bilim kurgu, fantezi, korku, çiftlik ve cozy game gibi farklı türlerde kullanılabilecek fontları hedefliyordu.
- Önceki paketlerde en büyük talep ve şikâyet, yalnızca ASCII karakterlerini desteklemeleriydi.
- Yeni paket, English, French, Italian, German, Spanish anlamına gelen EFIGS desteği için genişletilmiş Latin karakter setini benimsedi.
- Nihai karakter seti 176 karakterden oluşuyor.
- Asya dilleri veya Latin tabanlı olmayan diller, karakter setlerine aşinalık eksikliği nedeniyle istenen kaliteyi sağlamanın zor olması ve üretim süresini ciddi artırması yüzünden hariç tutuldu.
- Oyun arayüzlerinde görsel hiyerarşi gerektiği için, her fontu tek bir stil yerine font ailesi olarak tasarlamak istendi.
- Örneğin Virtue font ailesi 20 stil içeriyor.
- Böylece geliştiriciler, farklı havadaki fontları karıştırmadan boyut ve kalınlık çeşitliliği kullanabiliyor.
- Kerning, önceki paketlerde üretim süresini en çok tüketen işlerden biriydi.
- Desteklenen karakter sayısı 176 olunca olası kerning çiftleri en fazla
176²seviyesine çıkabiliyor. - Tüm çiftleri elle girmek yerine çoğu otomatik hesaplandı, algoritmanın yetersiz kaldığı yerler ise elle tamamlandı.
- Desteklenen karakter sayısı 176 olunca olası kerning çiftleri en fazla
- Kalite kontrol ve dağıtım da otomasyon kapsamına alındı.
- Eskiden piksel hataları veya kerning bug’ları düzeltildikten sonra yeniden dışa aktarmak, test etmek ve itch.io’ya elle yüklemek gerekiyordu.
- Yeni araç zinciri; örnek metinler ve kerning görselleştirmeleri oluşturarak sorunları hızlı bulmayı ve düzeltme sonuçlarını anında görmeyi hedefledi.
Font tasarım kalitesini yükseltmek için hazırlık
- Piksel art ve piksel font konusunda çok deneyimi olmasına rağmen, geleneksel typeface design alanında ciddi bir eğitim almamıştı.
- Çalışma sırasında Richard Poulin’in Design School: Type kitabına başvurdu.
- Kitap, yazı karakteri tasarımının terminolojisini ve geleneklerini öğrenmek için bir giriş kaynağı olarak kullanıldı.
- Çevresinde gördüğü metinlerin fotoğraflarını da referans olarak topladı.
- Küçük dükkân tabelaları, müzeler, galeriler, festivaller, yerel etkinlik afişleri ve kitap kapakları kaynak olarak kullanıldı.
- Amaç bir yazı tipini kopyalamak değil; harf biçimlerini, taban çizgisinin altına inen karakterleri ve ince-geniş harf farklarını incelemekti.
- Dışarıda gördüğü dekoratif fontları incelerken, birçok “gösterişli” fontun tüm harfleri aşırı süslemek yerine süslemeyi büyük harflere yoğunlaştırıp küçük harfleri daha ince işlediğini fark etti.
Rust aracı pifo’nun rolü
- Bu hedeflere ulaşmak için kendi Rust programı
pifoyazıldı. - Font tasarımının kendisi genel amaçlı piksel art araçlarıyla yapıldı.
- Girdi olarak PNG tilesheet ve ayarlar için bir TOML dosyası kullanılıyor.
- Örnek komut
pifo --all --output "Faraway" --input "Faraway*"biçiminde.
pifo, girdi görsellerini tek tek glif tile’larına ayırıyor, glif konturları oluşturuyor, kerning çiftlerini otomatik hesaplıyor ve ardından TTF dosyası olarak dışa aktarıyor.- Farklı motorlarda doğrudan kullanım için başka formatlar da birlikte üretiliyor.
- Tek tek glif işlemleri paralelleştirildiği için tek bir font neredeyse anında işleniyor.
- 175 font tek tek işlense bile sadece birkaç saniye sürüyor.
- Kullanılan başlıca Rust crate’leri şunlar:
Glif konturu oluşturma süreci
- Her font sheet’i bir tilesheet ve TOML yapılandırma dosyasından oluşuyor.
- Yapılandırmada
version,baseline,line_gap,spacing,metrics,auto_kerning,auto_kerning_min,manual_kerning,skip_kerning_left,skip_kerning_rightgibi alanlar bulunuyor. - Izgara boyutu değişebilir, ancak her zaman tutarlı bir ızgara olmalı ve karakterler belirlenmiş konumlarda yer almalı.
- Araç yalnızca %100 beyaz pikselleri işler; dama desenli arka plan ve baseline yalnızca kılavuz olarak kullanılır.
- Yapılandırmada
- TrueType glifleri bir veya daha fazla contour’dan oluşur.
- Piksel fontlarda, bağlı piksel grupları yani her küme için ayrı bir kontur oluşturmak gerekir.
- Örneğin küçük
tharfinde birbirinden ayrık iki piksel bloğu varsa iki kontur gerekir.
- Kontur üretimi birkaç aşamada ilerliyor.
RgbaImageiçinden yalnızca beyaz pikseller seçilipPointyapılarından oluşan birHashSetiçine toplanıyor.- Rastgele bir pikselden başlayıp komşu piksellere flood fill uygulanıyor ve ziyaret edilmemiş piksel kalmayana kadar bu işlem tekrarlanarak kümeler bulunuyor.
- Her kümede komşu pikseli olmayan yüzler açığa çıkan edge olarak toplanıyor.
- Edge’lerin head ve tail uçları birleştirilerek kapalı yollar oluşturuluyor ve bunlar kontura dönüştürülüyor.
- Delikli kümeler birden fazla kontur üretebiliyor.
- Dış kontur saat yönünde, içteki delikler ise saat yönünün tersine sarılıyor.
- Bu yön farkı, TTF’de delik ifade etme yöntemiyle uyumlu.
- Aynı düz çizgi üzerindeki ara noktalar kaldırılıyor.
- Bu, dosya boyutunu azaltmak ve rasterizasyon hızını artırmak için yapılan bir optimizasyon.
Kerning tablosunun otomasyonu
- TTF üretmek için konturlardan sonra gereken bir diğer şey kerning tablosu.
- Kerning tablosu, belirli karakter çiftlerini sola çekerek kelimelerin daha doğal görünmesini sağlar.
- Örneğin
Vaveltçiftlerini 1 piksel sola çekmek daha iyi bir görünüm verir.
- Elle kerning, TOML içindeki
manual_kerningalanında tanımlanıyor.- Bunun biçimi
{ left = "V", right = "a", kern = -1 }şeklinde. - Tüm aksanlı karakterleri tek tek belirtmemek için
alts = trueseçeneği destekleniyor. - Böylece
aiçinàáâãäågibi alternatif karakterler eşlenip aynı kerning uygulanabiliyor.
- Bunun biçimi
- Otomatik kerning, sağdaki glifi sola doğru her seferinde 1 piksel kaydırarak hesaplanıyor.
- Soldaki glifle çakışmadan ulaşılabilecek en yakın konum bulunuyor.
- Köşe temasları da temas sayılıyor.
- Örneğin
LVdurumundaV1 piksel çekilebiliyor ama 2 pikselde pikseller çakıştığı için kerning değeri-1oluyor.
- Otomatik kerning hesabı, elle verilen değerleri ve hariç tutma ayarlarını dikkate alıyor.
skip_kerning_leftveskip_kerning_rightile belirli yönlerdeki glifler dışarıda bırakılabiliyor.- Tüm kerning çiftleri
rayonile paralel hesaplanıyor.
Dışa aktarma formatları
- PIFO, yalnızca TTF değil; tilesheet ve paketlenmiş texture atlas da üretiyor.
- TTF dosyası, birden çok tablodan oluşan ikili bir dosya yapısıdır.
- Dışa aktarma aracı
head,hhea,maxp,OS/2,hmtx,cmap,loca,glyf,kern,name,posttablolarını dolduruyor. - Her tablo için konum, uzunluk ve checksum kaydedilmeli; bu da
begin_table()veend_table()ile yapılıyor.
- Dışa aktarma aracı
- Piksel fontların temel boyutu 16 olarak belirlendi.
- 16 boyutunda render edildiğinde her piksel tam
1 pxoluyor. - Titreme olmadan büyütmek için
32,48,64gibi 16’nın katları kullanılmalı.
- 16 boyutunda render edildiğinde her piksel tam
- Tilesheet dışa aktarımı, giriş sheet’inden farklı olarak Unicode codepoint sırasına göre diziliyor.
- Birlikte üretilen veri dosyası; satır-sütun bilgisi, tile boyutu, baseline, satır aralığı, boşluk genişliği, glif metrikleri ve kerning tablosunu içeriyor.
- Bunlar
serdeile JSON, XML, TOML gibi farklı formatlara serileştiriliyor.
- Paketlenmiş atlas da oluşturuluyor.
- Bunun için kendi dikdörtgen paketleyici crate’i crunch kullanılıyor.
- Sıkı paketlemede konum bilgisi kaybolduğu için render sırasında
x,y,w,h,off_x,off_y,advgibi ek veriler de ekleniyor.
Kalite testi ve örnek görseller
- İstenen kaliteye ulaşmak için PIFO’ya devasa örnek görsel üretimi özelliği eklendi.
- Örnek görseller birkaç test bloğundan oluşuyor.
- Tüm harfler ve bazı test cümleleri
- Terry Bisson’ın kısa öyküsü They're Made out of Meat’ten bir bölüm
- Text for Proofing Fonts: A farewell to The Quick Brown Fox yazısındaki stratejilerden yararlanılarak oluşturulmuş test kelimeleri
- Tüm sayı kombinasyonları ve para birimi simgeleri
- Büyük harf, küçük harf ve karışık büyük-küçük harf kerning çiftleri
- Çeşitli noktalama işaretleri
- Çalışma sırasında örnek görseller anında üretilebildiği için sorunlar hızlıca bulunup düzeltilebildi.
- Bu süreç, neredeyse 200’e yaklaşan fontun genel kalite ve bitiş düzeyini yükseltti.
itch.io dağıtım otomasyonu
- Nihai çıktı 175 piksel font oldu ve bunların indirilebilir çevrim içi satış noktası olarak daha önce de kullanılan itch.io seçildi.
- En zahmetli iş, her font için ayrı bir itch projesi oluşturmaktı.
- Bu işlem her font için yalnızca bir kez gerekiyordu.
- Sonrasında yükleme ve bakım komut satırı script’leriyle yapılabildi.
- Dağıtım script’i üç aşamadan oluşuyor.
- PIFO’yu release modunda derlemek
- İstenen font varlıklarını build etmek
- Her fontun itch projesini yeni varlıklarla güncellemek
--input "Faraway*"gibi giriş kalıpları,Faraway - Regular,Faraway - Boldgibi aynı ön eke sahip stilleri bulup bunları tek bir font ailesi paketi altında topluyor.- Son yükleme için itch’in sunduğu komut satırı dağıtım aracı
butlerkullanıldı.- Dağıtım
butler push ../distro/faraway chevyray/pixel-font-faraway:assetsbiçiminde yapılıyor. - Butler değişen dosyaları izleyip yalnızca gerekli kısımları güncellediği için ayrıca dosya hash’leme veya özel sürüm yönetimi gerekmiyordu.
- Dağıtım
1 yorum
Hacker News yorumları
Fontlar harika ve yazı da ilgi çekici
Sağ üstteki sahte oyun görselinin https://chevyray.dev/blog/creating-175-fonts/old_previews.pn... gerçek bir oyun olmasını isterdim
Bende “GBA için Wonder Boy in Monster World” havası uyandırıyor, o yüzden hoşuma gitti
Ancak lisansa bakınca, TTF'yi açık kaynak yazılım projelerinde kullanmaya izin verilmiyor gibi görünüyor; buna dikkat etmek lazım
Avukat değilim ama son maddeyi açık bir yasak olarak okuyorum: https://github.com/ChevyRay/pixel_font_megapack_license/blob...
O mockup'taki sahne, Celeste'in açılış sahnesinden esinlenmiş
Amaç açıkça oyun motorları ya da şablonlardan ziyade, açık kaynağın nispeten daha az görüldüğü nihai ürün aşamasındaki oyunlarda kullanılması gibi görünüyor
Bunu okurken aklıma telif hakkındaki başka sınır durumlar da geldi; ABD'de typeface'lerin telif korumasına tabi olmaması gibi
Fontlar bilgisayar programı olarak korunuyor ama typeface'ler ve basit bitmap fontlar korunmuyor
Yani bu iş akışı, telifsiz bir kaynak tileset'ten telifli bir TTF üretip sonra yeniden telifsiz çıktı tileset/atlas'a dönmek gibi bir şey oluyor
Gerçekten etkileyici
Tam bir font seti oluşturmak kolayca 1 yıl sürebilir
'A'dan 'Z'ye, büyük-küçük harfler, parantez, ampersand, ünlem gibi tüm glifleri yapmak ve mümkünse kalın, italik gibi varyasyonları da hazırlamak gerekir
Bu tür varyasyonlar olmazsa fontun kullanım alanı kısıtlanır
Özellikle ustalığı belirleyen şey kerning, yani harfler arası boşluk; takıntılıysanız bunun sonu gelmez
Yazıda da 176 karakter desteklenince en fazla 176² = 37.976 kerning çifti girmek gerektiği, bu yüzden de çoğunu yarı otomatikleştirmek ve algoritmanın yetersiz kaldığı yerleri elle girmek için kendi araçlarını yaptığı söyleniyor
Başka dilleri desteklemek isterseniz, Latin alfabesi kullanan Fransızca, İspanyolca, İtalyanca, Portekizce gibi diller için bile ek karakterler gerekir
Sonrasında Yunanca, Kiril, Japonca, Çince desteği de eklemek isteyebilirsiniz
Örneğin Wikipedia'ya göre “Noto fonts 77.000'den fazla karakter destekliyor; bu da Unicode 15.0'da tanımlanan 149.186 karakterin yaklaşık yarısı”
İstenirse her şeye sonsuz takıntı geliştirilebilir
Dil, yazı, müzik, hat gibi alanlar da zaten takıntılı insanları güçlü biçimde kendine çekiyor gibi
Mesele şu ki bu tür sözler biraz gereksiz bir giriş bariyeri koyma gibi duyuluyor
Bir alana yeni girmeye çalışan insanları caydıran laflar bana hep biraz hassas gelir
Çok iyi
Merak ettiğim bir şey, İskandinav özel karakterleri içinde neden bu alt kümenin seçildiği
İsveççede äöå, Norveççe/Dancada ise æøå var, ama bu fontta æ var ve ø yok
Bu durumda æ çıkarılsa İsveççe desteği korunur, ø eklenirse Norveççe ve Danca da desteklenebilir
Bunun basit bir eksiklik mi olduğunu, yoksa æ kullanıp ø kullanmayan bir locale olup olmadığını merak ediyorum
Bu arada æ'yi Fransızcada kullanılan ayrı bir glif olan œ ligatürüyle karıştırmış değilim
Yine de Æ, “encyclopædia” gibi eski İngilizce metinlerde veya Latinceden gelen sözcüklerin çoğul biçimlerinde de kullanılır: https://en.wiktionary.org/wiki/Category:English_plurals_in_-...
Aslında projede epey ilerledikten sonra karakter setimde ø'nun eksik olduğunu fark ettim
Elbette geri dönüp bunu tüm fontlara ekleyerek yamalayabilirim ama bunun için yeterli talep olup olmadığını görmek üzere bekliyordum
Yine de iki dili daha destekleyebilmek oldukça hoş olurdu
Sitede kullanılan bazı fontları ve sade stil anlayışını da beğendim
Neyse ki bu da ayrı bir yazıda paylaşılmış: https://chevyray.dev/blog/how-this-site-is-made/#catppuccin-...
İlginç
Piksel fontları TTF olarak kodlarken vektöre dönüştürüldüğünü daha önce bilmiyordum
Düzgün bir metin render edicisine yükleyenler için bir ölçüde pürüzsüz yakınlaştırma/uzaklaştırma da mümkün hale geliyor gibi
Elbette piksel fontları neredeyse bire bir kullanan oyun motorları tarafı istisna olabilir
Bu araçlarda piksel font diye bir kavram olmadığından, hinting ve anti-aliasing kapalı bir TTF kullanırsanız bu uygulamalarda da işe yarıyor
Harika
Bu çalışmanın bunu yapan kişiye maddi olarak da yardımcı olması güzel
Chevy Ray adını indie oyun tarafında hatırlıyorum ama tam olarak ne yaptığını çıkaramıyorum
Aşağı yukarı 2010~2012 civarı, VVVVVV, Nidhogg ya da Canabalt çizgisinde bir şeydi sanırım
Beacon da harikaydı — eski günleri hatırlatıyor, indie oyunları özlüyorum
Muhteşem
Bu yazının yazarı gibi Da Vinci tipi birini görünce, sanatçı ile mühendisin net biçimde ayrılmayıp tek bir şey olduğu zamanları hatırlıyorum
“Da Vinci'nin en iyi 10 icadı” türü yazılar değil
Gerçekte ikisi arasında epey büyük bir ayrım vardı
Ben de Maya'da doğrulanmamış, şüpheli dinamiklerle Alpha Centauri'ye gidecek bir uzay gemisi modelleyebilirim
Ama onu gerçekten inşa edip yıldızlararası boşluğa göndermek bambaşka bir şey
Resimler güzel ve hayal gücü yüksek tabii
Rust'ta böyle bir işi birden fazla çekirdekte çalıştırmak şaşırtıcı derecede kolay
Fonksiyon zincirine tek bir çağrı eklemek bile yeterli olabilir
Dilin koyduğu kurallara uyduğun sürece multithreading neredeyse “bedava”
Amdahl yasası hâlâ geçerli ama en azından uygulama gözünün önünde patlamıyor
Scala ve Java da bunu varsayılan olarak destekliyor
Gerçekten çok iyi bir çalışma ve yazı da güzel
Birkaç numarayla birçok algoritmayı daha hızlı hâle getirmek mümkün gibi görünüyor
Okuduğum kadarıyla, karakter çizimi ve ASCII-türevi eşlemede hash map'leri bitmap'ler ve bayt indeks dizileriyle değiştirmek ipucu olabilir
Tabii zaten yeterince hızlı olduğu için bu kodda çok önemli değil
Sitede tüm kod yok ama gerçekte epey fazla string ve veri yapısı allocate edip kopyalıyor
Açık yerlerde optimize kod kullandım; bitmap kopyalama ya da kolayca paralelleştirilebilen işler gibi kısımlar ise anında bitecek kadar hızlı olduğundan başka bölümleri optimize etmeyi denemedim bile
Yine de istenirse yapılabilir
Rust, C++ ve Go gibi düşük seviyeye yakın dillerin ne kadar hızlı olabildiğini unutmak kolay; hele buna varsayılan multithreading araçları ve iş kuyrukları da eklenince
Fontlarla ilgilenenler https://tomorrow.type.today/ sitesine de bakabilir
Harika, özgün ve deneysel fontlar üreten bir tipografi stüdyosu
Ekibimizden biri tipografiye çok meraklı, bu yüzden çalışmalarından bir koleksiyon oluşturuyor: https://play.soot.com/tomorrowtypetoday