Yerel yazı tipleriyle gelişmiş yazı biçimi kullanma

Yerel Yazı Tipi Erişimi API'sinin, kullanıcının yerel olarak yüklenen yazı tiplerine erişmenize ve bunlarla ilgili ayrıntılı bilgiler edinmenize nasıl olanak tanıdığını öğrenin

Web'de güvenli yazı tipleri

Web geliştirme konusunda uzun süredir çalışıyorsanız web'de kullanılabilen yazı tipleri olarak bilinenleri 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 sürümlerinde kullanılabildiği bilinmektedir. 2000'lerin başlarında Microsoft, Web için TrueType temel yazı tipleri adlı bir girişime öncülük etti. Bu girişim, bu yazı tiplerini belirten bir web sitesini her ziyaret ettiğinizde sayfaları site tasarımcısının amaçladığı şekilde göreceğiniz hedefiyle bu yazı tiplerini ücretsiz olarak indirmenizi sağlıyordu. Evet, Comic Sans MS yazı tipiyle ayarlanmış siteler de bu kapsamdadır. Klasik bir web'de kullanıma uygun yazı tipi grubu (sans-serif yazı tipinin nihai yedeğiyle birlikte) aşağıdaki gibi görünebilir:

body {
  font-family: Helvetica, Arial, sans-serif;
}

Web yazı tipleri

Web için güvenli yazı tiplerinin gerçekten önemli olduğu günler çoktan geride kaldı. Günümüzde, bazılarında çeşitli eksenlerin değerlerini değiştirerek daha fazla değişiklik yapabileceğimiz web yazı tipleri ve hatta değişken yazı tipleri kullanıyoruz. CSS'nin başında, indirilecek yazı tipi dosyalarını belirten bir @font-face bloğu tanımlayarak web yazı tiplerini kullanabilirsiniz:

@font-face {
  font-family: 'FlamboyantSansSerif';
  src: url('flamboyant.woff2');
}

Ardından, normalde olduğu gibi font-family değerini 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 gelir. Ancak @font-face beyanında yer alan src özelliğinin, url() işlevinin yanı sıra local() işlevini de kabul etmesi ilginç bir durumdur. Bu, özel yazı tiplerinin yerel olarak yüklenmesine olanak tanır (şaşırtıcı!). Kullanıcının işletim sisteminde FlamboyantSansSerif yüklüyse indirilmek yerine yerel kopya kullanılır:

@font-face {
  font-family: 'FlamboyantSansSerif';
  src: local('FlamboyantSansSerif'), url('flamboyant.woff2');
}

Bu yaklaşım, bant genişliğinden tasarruf etmenizi sağlayacak iyi bir yedek mekanizma sağlar. İnternette maalesef her şey yolunda gitmez. local() işlevinin sorunu, tarayıcı parmak izi için kötüye kullanılabilmesidir. Kullanıcının yüklediği yazı tiplerinin listesi oldukça tanımlayıcı olabilir. Birçok şirketin, çalışanlarını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.

Google Sans yazı tipinin önizlemesini gösteren macOS Font Book uygulaması.
Bir Google çalışanının dizüstü bilgisayarına yüklenen Google Sans yazı tipi.

Bir saldırgan, Google Sans gibi çok sayıda bilinen kurumsal yazı tipinin olup olmadığını test ederek bir kişinin hangi şirkette çalıştığını belirlemeye çalışabilir. Saldırgan, bu yazı tiplerinde ayarlanmış metni bir kanvasta oluşturmaya ve glifleri ölçmeye çalışır. Glifler, kurumsal yazı tipinin bilinen şekliyle eşleşirse saldırgan isabet elde eder. Simgeler eşleşmiyorsa saldırgan, kurumsal yazı tipi yüklenmediği için varsayılan bir değişim yazı tipinin kullanıldığını bilir. Bu ve diğer tarayıcı parmak izi saldırılarıyla ilgili tüm ayrıntılar için Laperdix ve arkadaşları tarafından yazılan araştırma makalesini okuyun.

Şirket yazı tipleri dışında, yüklü yazı tiplerinin listesi bile kimliği tanımlayabilir. Bu saldırı vektöründeki durum o kadar kötü hale geldi ki son zamanlarda WebKit ekibi "işletim sistemiyle gelen ancak yerel olarak kullanıcı tarafından yüklenen yazı tiplerini değil, yalnızca [listedeki mevcut yazı tiplerine] web yazı tiplerini ve yazı tiplerini dahil etmeye" karar verdi. (Burada yerel yazı tiplerine erişim izni vermeyle ilgili bir makale bulabilirsiniz.)

Yerel Yazı Tipi Erişimi API'si

Bu makalenin başlangıcı sizi olumsuz bir ruh haline sokmuş olabilir. Gerçekten güzel şeylere sahip olamaz mıyız? Endişelenmeyin. Bunu yapabileceğimizi düşünüyoruz ve her şeyin umutsuz olmadığını umuyoruz. Ancak önce, aklınızdan geçen bir soruyu yanıtlayayım.

Web yazı tipleri varken neden Yerel Yazı Tipi Erişimi API'sine ihtiyacımız var?

Profesyonel kalitede tasarım ve grafik araçlarını web'de sunmak geçmişte zordu. Tasarımcıların yerel olarak yüklediği profesyonelce oluşturulmuş ve ipucu verilmiş yazı tiplerinin tamamına erişip bunları kullanamama sorunuyla karşılaşıyorduk. Web yazı tipleri, bazı yayıncılık kullanım alanlarını mümkün kılar, ancak glif ana hatlarını oluşturmak için pikselleştiriciler tarafından kullanılan vektör glif şekillerine ve yazı tipi tablolarına programatik erişim sağlayamaz. Benzer şekilde, bir web yazı tipinin ikili verilerine erişmek de mümkün değildir.

  • Tasarım araçlarının, kendi OpenType düzen uygulamasını sağlamak için yazı tipi baytlarına erişmesi gerekir. Ayrıca, tasarım araçlarının, vektör filtreleri veya glif şekillerinde dönüştürme işlemleri gibi işlemler için daha alt düzeylerde bağlantı kurmasına izin verir.
  • Geliştiriciler, uygulamaları için web'e taşıdıkları eski yazı tipi yığınlarına sahip olabilir. Bu grupları kullanmak için genellikle yazı tipi verilerine doğrudan erişim gerekir. Web yazı tipleri bu erişimi sağlamaz.
  • Bazı yazı tipleri web üzerinden yayınlanmak için lisanslı olmayabilir. Örneğin, Linotype yalnızca masaüstü kullanımını içeren bazı yazı tipleri için lisansa sahiptir.

Yerel Yazı Tipi Erişimi API'si, bu zorlukların üstesinden gelmek için geliştirilmiştir. İki bölümden oluşur:

  • Kullanıcıların mevcut sistem yazı tiplerinin tamamına erişim izni vermesine olanak tanıyan bir yazı tipi numaralandırma API'si.
  • Her bir listeleme sonucunda, yazı tipi verilerinin tamamını içeren düşük düzey (bayt odaklı) SFNT kapsayıcı erişimi isteğinde bulunma olanağı.

Tarayıcı desteği

Tarayıcı desteği

  • Chrome: 103.
  • Edge: 103.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

Kaynak

Yerel Yazı Tipi Erişimi API'sini kullanma

Özellik algılama

Yerel Yazı Tipi Erişimi API'sinin desteklenip desteklenmediğini kontrol etmek için:

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 durumda ilk kez bir izin istemi tetiklenir. Kullanıcı bu istemi onaylayabilir veya reddedebilir. Kullanıcı, sorgulanacak yerel yazı tiplerini onaylarsa tarayıcı, üzerinden geçiş yapabileceğiniz yazı tipi verilerini 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 temsil edilir.

// 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 bir yazı tipi alt kümesiyle ilgileniyorsanız postscriptNames parametresi ekleyerek bunları PostScript adlarına göre filtreleyebilirsiniz.

const availableFonts = await window.queryLocalFonts({
  postscriptNames: ['Verdana', 'Verdana-Bold', 'Verdana-Italic'],
});

SFNT verilerine erişme

FontData nesnesinin blob() yöntemi aracılığıyla tam SFNT erişimi kullanılabilir. SFNT, PostScript, TrueType, OpenType, Web Open Font Format (WOFF) yazı tipleri gibi diğer yazı tiplerini içerebilen bir yazı tipi dosya 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'sini aşağıdaki demo'da görebilirsiniz. Kaynak koda da göz atmayı unutmayın. Bu demoda, yerel yazı tipi seçici uygulayan <font-select> adlı bir özel öğe gösterilmektedir.

Gizlilik konusunda dikkat edilmesi gereken noktalar

"local-fonts" izni, yüksek oranda parmak izi alınabilen bir yüzey sağlıyor. Ancak tarayıcıların istedikleri her şeyi iade etme hakkı vardır. Örneğin, anonimliğe odaklanan tarayıcılar yalnızca tarayıcıya yerleştirilmiş bir dizi varsayılan yazı tipi sunmayı tercih edebilir. Benzer şekilde, tarayıcıların tablo verilerini tam olarak diskte göründüğü şekilde sağlaması gerekmez.

Yerel Yazı Tipi Erişimi API'si, mümkün olduğunda yalnızca belirtilen kullanım alanlarını etkinleştirmek için gereken bilgileri tam olarak göstermek üzere tasarlanmıştır. Sistem API'leri, yüklü yazı tiplerinin bir listesini rastgele veya sıralı bir şekilde değil, yazı tipi yüklenme sırasına göre oluşturabilir. Bu tür bir sistem API'si tarafından sağlanan yüklü yazı tipleri listesini tam olarak döndürmek, parmak izi için kullanılabilecek ek verilerin açığa çıkmasına neden olabilir ve etkinleştirmek istediğimiz kullanım alanları, bu sıralamanın korunmasıyla desteklenmez. Sonuç olarak bu API, döndürülen verilerin döndürülmeden önce sıralanması gerektiğini belirtir.

Güvenlik ve izinler

Chrome ekibi, yerel yazı tipi erişim API'sini tasarlarken ve uygularken kullanıcı kontrolü, şeffaflık ve ergonomi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme başlıklı makalede belirtilen temel ilkeleri temel almıştır.

Kullanıcı denetimi

Kullanıcının yazı tiplerine erişim tamamen kullanıcının denetimindedir ve izin kaydında belirtildiği üzere "local-fonts" izni verilmediği sürece bunlara izin verilmez.

Şeffaflık

Bir siteye kullanıcının yerel yazı tiplerine erişim izni verilip verilmediği site bilgileri sayfasında gösterilir.

İzin kalıcılığı

"local-fonts" izni, sayfa yeniden yüklemeleri arasında devam eder. Site bilgileri sayfası üzerinden 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 ile ilgili olarak beklediğiniz gibi çalışmayan bir şey var mı? Yoksa fikrinizi uygulamak için ihtiyaç duyduğunuz yöntemler veya özellikler eksik mi? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var? İlgili GitHub deposunda bir spesifikasyon sorunu bildirin veya mevcut bir soruna düşüncelerinizi ekleyin.

Uygulamayla ilgili sorunları bildirme

Chrome&#39;un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı? new.crbug.com adresinden hata kaydı oluşturun. Mümkün olduğunca fazla ayrıntı ekleyin, hatayı yeniden oluşturmayla ilgili basit talimatlar verin ve Bileşenler kutusuna Blink>Storage>FontAccess yazın. Glitch, hızlı ve kolay yeniden oluşturma işlemlerini paylaşmak için idealdir.

API'yi destekleme

Local Font Access API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı tedarikçi firmalarına bu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.

#LocalFontAccess hashtag'ini kullanarak @ChromiumDev'e bir tweet gönderin ve etiketi nerede ve nasıl kullandığınızı bize bildirin.

Teşekkür

Yerel Yazı Tipi Erişimi 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'tan Brett Jordan tarafından oluşturulan hero resim.