Yerel Yazı Tipi Erişimi API'sinin, kullanıcının yerel olarak yüklediği yazı tiplerine erişmenize ve bu yazı tipleriyle ilgili düşük düzeyli ayrıntılar elde etmenize nasıl olanak tanıdığını öğrenin.
Web'de kullanıma uygun yazı tipleri
Web geliştirme işiyle yeterince uzun süredir uğraşıyorsanız web'de güvenli yazı tipleri olarak adlandırılan yazı tiplerini hatırlayabilirsiniz.
Bu yazı tiplerinin, en çok kullanılan işletim sistemlerinin (Windows, macOS, en yaygın Linux dağıtımları, Android ve iOS) neredeyse tüm örneklerinde kullanılabildiği bilinmektedir. 2000'li yılların başında Microsoft, "Bu yazı tiplerini belirten bir web sitesini her ziyaret ettiğinizde sayfaları tam olarak site tasarımcısının istediği şekilde görürsünüz" hedefiyle bu yazı tiplerini ücretsiz olarak indirmenizi sağlayan Web için TrueType temel yazı tipleri adlı bir girişime bile öncülük etti. Evet, bu kapsamda Comic Sans MS yazı tipiyle ayarlanmış siteler de yer alır. İşte klasik bir web'de kullanıma uygun yazı tipi yığını (nihai yedek olarak sans-serif
yazı tipiyle) şu şekilde görünebilir:
body {
font-family: Helvetica, Arial, sans-serif;
}
Web yazı tipleri
Web'de kullanıma uygun yazı tiplerinin gerçekten önemli olduğu günler çoktan geride kaldı. Günümüzde web yazı tipleri var. Bunlardan bazıları, çeşitli açığa çıkarılmış eksenlerin değerlerini değiştirerek daha da ince ayar yapabileceğimiz değişken yazı tipleri. CSS'nin başında, indirilecek yazı tipi dosyalarını belirten bir @font-face
bloğu bildirerek web yazı tiplerini kullanabilirsiniz:
@font-face {
font-family: 'FlamboyantSansSerif';
src: url('flamboyant.woff2');
}
Bundan sonra, font-family
öğesini normal şekilde belirterek özel web yazı tipini kullanabilirsiniz:
body {
font-family: 'FlamboyantSansSerif';
}
Parmak izi vektörü olarak yerel yazı tipleri
Çoğu web yazı tipi web'den alınır. Ancak ilginç bir nokta, @font-face
bildirimindeki src
özelliğinin, url()
işlevinin yanı sıra local()
işlevini de kabul etmesidir. Bu sayede özel yazı tipleri yerel olarak yüklenebilir. Kullanıcının işletim sisteminde FlamboyantSansSerif yüklüyse indirmek yerine yerel kopya kullanılır:
@font-face {
font-family: 'FlamboyantSansSerif';
src: local('FlamboyantSansSerif'), url('flamboyant.woff2');
}
Bu yaklaşım, bant genişliğini koruyabilecek güzel bir yedek mekanizma sağlar. İnternette maalesef güzel şeyler olmuyor. local()
işleviyle ilgili sorun, tarayıcı parmak izi için kötüye kullanılabilmesidir. Kullanıcının yüklediği yazı tiplerinin listesi, kullanıcıyı tanımlamak için kullanılabilir. Birçok şirketin, çalışanların dizüstü bilgisayarlarına yüklenen kendi kurumsal yazı tipleri vardır. Örneğin, Google'ın Google Sans adlı bir kurumsal yazı tipi vardır.

Saldırganlar, Google Sans gibi çok sayıda bilinen kurumsal yazı tipinin varlığını test ederek bir kişinin hangi şirkette çalıştığını belirlemeye çalışabilir. Saldırgan, bu yazı tiplerinde ayarlanan metni bir tuvalde oluşturmaya ve glifleri ölçmeye çalışır. Glifler, kurumsal yazı tipinin bilinen şekliyle eşleşiyorsa saldırgan başarılı olur. Glifler eşleşmiyorsa saldırgan, kurumsal yazı tipi yüklenmediği için varsayılan bir yedek yazı tipinin kullanıldığını bilir. Bu ve diğer tarayıcı parmak izi saldırıları hakkında ayrıntılı bilgi edinmek için Laperdix ve diğerleri tarafından hazırlanan anket makalesini okuyun.
Şirket yazı tipleri dışında, yalnızca yüklü yazı tiplerinin listesi bile tanımlayıcı olabilir. Bu saldırı vektörüyle ilgili durum o kadar kötüleşti ki WebKit ekibi kısa süre önce "yalnızca [mevcut yazı tipi listesinde] web yazı tiplerini ve işletim sistemiyle birlikte gelen yazı tiplerini dahil etmeye, ancak kullanıcı tarafından yerel olarak yüklenen yazı tiplerini dahil etmemeye"karar verdi. (Ve ben de yerel yazı tiplerine erişim izni verme hakkında bir makale yazıyorum.)
Local Font Access API
Bu makalenin başlangıcı sizi olumsuz bir ruh haline sokmuş olabilir. Can we really not have nice things? Endişelenmeyin. Bunu yapabileceğimizi düşünüyoruz ve belki de her şey umutsuz değildir. Ancak önce kendinize soruyor olabileceğiniz bir soruyu yanıtlayayım.
Web yazı tipleri varken neden Yerel Yazı Tipi Erişim API'sine ihtiyacımız var?
Profesyonel kalitede tasarım ve grafik araçları, geçmişte web'de sunulmakta zorlanıyordu. Tasarımcıların yerel olarak yüklediği profesyonelce oluşturulmuş ve ipuçları içeren yazı tiplerinin tüm çeşitliliğine erişememe ve bunları kullanamama, bir engel teşkil ediyordu. Web yazı tipleri bazı yayıncılık kullanım alanlarını etkinleştirir ancak glif ana hatlarını oluşturmak için rasterleştiriciler tarafından kullanılan vektör glif şekillerine ve yazı tipi tablolarına programatik erişimi etkinleştiremez. Aynı şekilde, web yazı tipinin ikili verilerine erişmenin de bir yolu yoktur.
- Tasarım araçlarının kendi OpenType düzen uygulamalarını yapabilmesi ve tasarım araçlarının glif şekillerinde vektör filtreleri veya dönüşümler gerçekleştirme gibi işlemler için daha düşük seviyelerde bağlanmasına izin vermesi için yazı tipi baytlarına erişmesi gerekir.
- Geliştiricilerin, web'e taşıdıkları uygulamaları için eski yazı tipi yığınları olabilir. Bu yığınları kullanmak için genellikle yazı tipi verilerine doğrudan erişim gerekir. Web yazı tipleri bunu sağlamaz.
- Bazı yazı tipleri, web üzerinden yayınlanmak üzere lisanslanmamış olabilir. Örneğin, Linotype'ın bazı yazı tipleri için yalnızca masaüstü kullanımını içeren bir lisansı vardır.
Yerel Yazı Tipi Erişimi API'si, bu zorlukları çözmeye yönelik bir girişimdir. İki bölümden oluşur:
- Kullanıcıların, kullanılabilir sistem yazı tiplerinin tamamına erişim izni vermesine olanak tanıyan bir yazı tipi numaralandırma API'si.
- Her numaralandırma sonucundan, tam yazı tipi verilerini içeren düşük düzeyli (bayt odaklı) SFNT kapsayıcısı erişimi isteğinde bulunma olanağı.
Tarayıcı desteği
Local Font Access API'yi kullanma
Özellik algılama
Yerel Yazı Tipi Erişim API'sinin desteklenip desteklenmediğini kontrol etmek için şunu kullanın:
if ('queryLocalFonts' in window) {
// The Local Font Access API is supported
}
Yerel yazı tiplerini numaralandırma
Yerel olarak yüklenen yazı tiplerinin listesini almak için window.queryLocalFonts()
işlevini çağırmanız gerekir. Bu işlem ilk kez yapıldığında, kullanıcı tarafından onaylanabilecek veya reddedilebilecek bir izin istemi tetiklenir. Kullanıcı, yerel yazı tiplerinin sorgulanmasını onaylarsa tarayıcı, üzerinde döngü oluşturabileceğiniz yazı tipi verileri içeren bir dizi döndürür. Her yazı tipi, family
(ör. "Comic Sans MS"
), fullName
(ör. "Comic Sans MS"
), postscriptName
(ör. "ComicSansMS"
) ve style
(ör. "Regular"
) özelliklerine sahip bir FontData
nesnesi olarak gösterilir.
// Query for all available fonts and log metadata.
try {
const availableFonts = await window.queryLocalFonts();
for (const fontData of availableFonts) {
console.log(fontData.postscriptName);
console.log(fontData.fullName);
console.log(fontData.family);
console.log(fontData.style);
}
} catch (err) {
console.error(err.name, err.message);
}
Yalnızca belirli bir yazı tipi grubuyla ilgileniyorsanız postscriptNames
parametresi ekleyerek bunları PostScript adlarına göre de filtreleyebilirsiniz.
const availableFonts = await window.queryLocalFonts({
postscriptNames: ['Verdana', 'Verdana-Bold', 'Verdana-Italic'],
});
SFNT verilerine erişme
Tam SFNT erişimi, FontData
nesnesinin blob()
yöntemiyle kullanılabilir. SFNT, PostScript, TrueType, OpenType, Web Open Font Format (WOFF) yazı tipleri gibi diğer yazı tiplerini içerebilen bir yazı tipi dosyası biçimidir.
try {
const availableFonts = await window.queryLocalFonts({
postscriptNames: ['ComicSansMS'],
});
for (const fontData of availableFonts) {
// `blob()` returns a Blob containing valid and complete
// SFNT-wrapped font data.
const sfnt = await fontData.blob();
// Slice out only the bytes we need: the first 4 bytes are the SFNT
// version info.
// Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
const sfntVersion = await sfnt.slice(0, 4).text();
let outlineFormat = 'UNKNOWN';
switch (sfntVersion) {
case '\x00\x01\x00\x00':
case 'true':
case 'typ1':
outlineFormat = 'truetype';
break;
case 'OTTO':
outlineFormat = 'cff';
break;
}
console.log('Outline format:', outlineFormat);
}
} catch (err) {
console.error(err.name, err.message);
}
Demo
Yerel Yazı Tipi Erişimi API'sinin nasıl çalıştığını demoda görebilirsiniz. Kaynak kodunu da incelemeyi unutmayın. Demoda, yerel bir yazı tipi seçici uygulayan <font-select>
adlı özel bir öğe gösterilmektedir.
Gizlilikle ilgili olarak göz önünde bulundurulması gerekenler
"local-fonts"
izni, parmak izi oluşturmaya uygun bir yüzey sağlıyor gibi görünüyor. Ancak tarayıcılar, istedikleri her şeyi ücretsiz olarak döndürebilir. Örneğin, anonimliğe odaklanan tarayıcılar yalnızca tarayıcıya yerleştirilmiş bir dizi varsayılan yazı tipini sağlamayı seçebilir. Benzer şekilde, tarayıcıların tablo verilerini diskte göründüğü gibi sağlaması gerekmez.
Mümkün olan her yerde, Yerel Yazı Tipi Erişim API'si yalnızca belirtilen kullanım alanlarını etkinleştirmek için gereken bilgileri sunacak şekilde tasarlanmıştır. Sistem API'leri, rastgele veya sıralı bir düzende değil, yazı tipi kurulum sırasına göre yüklü yazı tiplerinin listesini oluşturabilir. Bu tür bir sistem API'si tarafından verilen yüklü yazı tiplerinin listesini tam olarak döndürmek, parmak izi oluşturmak için kullanılabilecek ek verileri ortaya çıkarabilir ve etkinleştirmek istediğimiz kullanım alanları, bu sıralamayı koruyarak desteklenmez. Bu nedenle, bu API'nin döndürülen verilerin döndürülmeden önce sıralanması gerekir.
Güvenlik ve izinler
Chrome ekibi, kullanıcı kontrolü, şeffaflık ve ergonomi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme'de tanımlanan temel ilkeleri kullanarak Local Font Access API'yi tasarladı ve uyguladı.
Kullanıcı denetimi
Kullanıcıların yazı tiplerine erişim tamamen kullanıcıların kontrolündedir ve "local-fonts"
izni verilmediği sürece izin verilmez. Bu izin, izin kayıt defterinde listelenmiştir.
Şeffaflık
Bir siteye kullanıcının yerel yazı tiplerine erişim izni verilip verilmediği site bilgi sayfasında gösterilir.
İzin kalıcılığı
"local-fonts"
izni, sayfa yeniden yüklemeleri arasında kalıcı olur. Bu izin, site bilgileri sayfasından iptal edilebilir.
Geri bildirim
Chrome Ekibi, Yerel Yazı Tipi Erişimi API'si ile ilgili deneyimlerinizi öğrenmek istiyor.
API tasarımı hakkında bilgi verin.
API'nin beklentilerinizi karşılamayan bir yönü var mı? Yoksa fikrinizi uygulamak için eksik yöntemler veya özellikler mi var? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var? İlgili GitHub deposunda bir spesifikasyon sorunu bildirin veya düşüncelerinizi mevcut bir soruna ekleyin.
Uygulamayla ilgili sorun bildirme
Chrome'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?
new.crbug.com adresinden hata bildirin. Mümkün olduğunca fazla ayrıntı ve hatayı yeniden oluşturmayla ilgili basit talimatlar eklediğinizden emin olun. Ayrıca Bileşenler kutusuna Blink>Storage>FontAccess
girin.
API'ye desteğinizi gösterme
Local Font Access API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özellikleri önceliklendirmesine yardımcı olur ve diğer tarayıcı satıcılarına bu özelliklerin desteklenmesinin ne kadar önemli olduğunu gösterir.
@ChromiumDev adresine #LocalFontAccess
hashtag'ini kullanarak tweet gönderin ve nerede, nasıl kullandığınızı bize bildirin.
Faydalı bağlantılar
- Açıklama
- Spec draft
- Yazı tipi numaralandırmasıyla ilgili Chromium hatası
- Yazı tipi tablosu erişimiyle ilgili Chromium hatası
- ChromeStatus girişi
- GitHub deposu
- TAG review
- Mozilla'nın standartlar konusundaki tutumu
Teşekkür
Local Font Access API spesifikasyonu, Emil A. Eklund, Alex Russell, Joshua Bell ve Olivier Yiptong. Bu makale, Joe Medley, Dominik Röttsches ve Olivier Yiptong tarafından incelenmiştir. Unsplash'te Brett Jordan tarafından çekilen lokomotif resim.