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

Local Font Access API'nin, kullanıcının yerel olarak yüklediği yazı tiplerine erişmenizi ve bunlarla ilgili alt düzey bilgileri edinmenizi nasıl sağladığını öğrenin

Web için güvenli yazı tipleri

Yeterince uzun süredir web geliştirme yapıyorsanız web için güvenli yazı tipleri denileni hatırlayabilirsiniz. Bu yazı tipleri, en çok kullanılan işletim sistemlerinin neredeyse tüm örneklerinde (yani Windows, macOS, en yaygın Linux dağıtımları, Android ve iOS) kullanılabilir. 2000'lerin başında Microsoft, "Web sitesini her ziyaret ettiğinizde sayfaları tam olarak site tasarımcısının amaçladığı şekilde görürsünüz" hedefiyle, bu yazı tiplerinin ücretsiz olarak indirilmesini sağlayan Web için TrueType temel yazı tipleri adlı bir girişime bile öncülük etti. Evet, buna Comic Sans MS'de ayarlanmış siteler de dahildir. Aşağıda, aşağıdaki gibi görünebilecek bir klasik, web için güvenli yazı tipi yığını (en son yedek sans-serif yazı tipiyle) verilmiştir:

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

Web yazı tipleri

Web için güvenli yazı tiplerinin gerçekten önemli olduğu günler geride kaldı. Bugün web yazı tiplerimiz var. Bunlardan bazıları değişken yazı tipleri bile olabilir. Açıkta kalan çeşitli eksenlerin değerlerini değiştirerek daha fazla ince ayar yapabiliriz. 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');
}

Bunun ardından, normal şekilde font-family 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 ilginç bir gerçek ise @font-face beyanındaki src özelliğinin url() işlevinin yanı sıra bir local() işlevini de kabul etmesidir. Bu, özel yazı tiplerinin yerel olarak yüklenmesine (sürpriz!) olanak tanır. Kullanıcının işletim sisteminde FlamboyantSansSerif yüklüyse indirilmesi 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 etme olanağı sunan güzel bir yedek mekanizma sağlar. Maalesef İnternet'te güzel şeyler yapamayız. local() işleviyle ilgili sorun, işlevin tarayıcı dijital parmak izi için kötüye kullanılabileceğidir. Kullanıcının yüklediği yazı tiplerinin listesi oldukça tanımlayıcı olabilmektedir. Pek çok şirket çalışanlarının dizüstü bilgisayarlarına yüklenen kendi kurumsal yazı tiplerine sahiptir. Örneğin, Google'ın Google Sans adında 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 bilinen çok sayıda kurumsal yazı tipinin varlığını test ederek bir kişinin hangi şirket için çalıştığını belirlemeye çalışabilir. Saldırgan, bu yazı tiplerinde bulunan metinleri bir kanvas üzerinde oluşturmaya çalışır ve glifleri ölçer. Karakterler, şirket yazı tipinin bilinen şekliyle eşleşirse saldırgan bir vuruş alır. Karakterler eşleşmezse saldırgan, şirket yazı tipi yüklenmediği için varsayılan eski yazı tipinin kullanıldığını bilir. Bu ve diğer tarayıcı dijital parmak izi saldırılarıyla ilgili tüm ayrıntılar için, Laperdix et al. tarafından hazırlanan anketi okuyun.

Şirket yazı tiplerinin dışında, yalnızca yüklü yazı tiplerinin listesi bile ayırt edilebilir. Bu saldırı vektörünün durumu o kadar kötü hale gelmiştir ki son zamanlarda WebKit ekibi, "işletim sistemiyle birlikte gelen web yazı tiplerini ve yazı tiplerini değil, yerel olarak kullanıcı tarafından yüklenen yazı tiplerini değil") "yalnızca [kullanılabilir yazı tipleri listesinde] yer almaya" karar verdiler. (Yerel yazı tiplerine erişim izni verme hakkında bir makale de buradadır.)

Yerel Yazı Tipi Erişimi API'si

Bu makalenin başlangıcı olumsuz bir ruh halinde olmanıza yol açmış olabilir. Gerçekten güzel şeyler olamayabilir mi? Endişelenmeyin. Bunu yapabiliriz, belki de her şey umutsuz değildir. Ama önce kendinize sorabileceğiniz bir soruyu yanıtlamak istiyorum.

Web yazı tipleri varken neden Local Font Access API'ye ihtiyaç duyarız?

Profesyonel kalitede tasarım ve grafik araçlarını web'de sunmak eskiden beri zordu. Zorluklardan biri, tasarımcıların yerel olarak yüklediği, profesyonel olarak hazırlanmış ve ipucu içeren çok çeşitli yazı tiplerine erişememe ve bunları kullanamamadır. Web yazı tipleri, bazı yayınlama kullanım alanlarını etkinleştirir, ancak glif ana hatlarını oluşturmak için kafes oluşturucular tarafından kullanılan vektör glif şekillerine ve yazı tipi tablolarına programatik erişim sağlayamaz. Aynı şekilde, bir web yazı tipinin ikili verilerine de erişmenin yolu yoktur.

  • Tasarım araçlarının, kendi OpenType düzen uygulamalarını gerçekleştirmek ve vektör filtreleri veya glif şekillerinde dönüşüm gerçekleştirmek gibi işlemler için tasarım araçlarının daha düşük düzeylerde ele alınmasını sağlamak için yazı tipi baytlarına erişmesi gerekir.
  • Geliştiriciler, web'e taşıdıkları uygulamaları için eski yazı tipi yığınlarına sahip olabilir. Bu yığınları kullanmak için genellikle yazı tipi verilerine doğrudan erişim gerekir. Web yazı tiplerinin sağladığı bir şey de bu değildir.
  • Bazı yazı tipleri web üzerinden dağıtım için lisanslanmamış olabilir. Örneğin, Linotype'ın yalnızca masaüstü kullanımını içeren bazı yazı tipleri için lisansı vardır.

Local Font Access API, bu zorlukların üstesinden gelmeyi amaçlayan bir girişimdir. Anket iki bölümden oluşur:

  • Kullanıcıların mevcut tüm sistem yazı tiplerine erişim izni vermelerine olanak tanıyan bir font enumeration API.
  • Her numaralandırma sonucundan, tam yazı tipi verilerini içeren düşük düzeyli (bayt yönlü) SFNT kapsayıcı erişimi isteme olanağı.

Tarayıcı desteği

Tarayıcı Desteği

  • 103
  • 103
  • x
  • x

Kaynak

Local Font Access API'yi kullanma

Özellik algılama

Yerel Yazı Tipi Erişimi 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üklü yazı tiplerinin listesini almak için window.queryLocalFonts() işlevini çağırmanız gerekir. İlk kez bu işlem, kullanıcının onaylayabileceği veya reddebileceği bir izin istemini tetikler. Kullanıcı sorgulanacak yerel yazı tiplerini onaylarsa tarayıcı, döngüye girebileceğiniz yazı tipi verilerini içeren bir dizi döndürür. Her yazı tipi, family (örneğin, "Comic Sans MS"), fullName (örneğin, "Comic Sans MS"), postscriptName (örneğin, "ComicSansMS") ve style (örneğin, "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);
}

Yazı tiplerinin yalnızca bir 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

Tam SFNT erişimi, FontData nesnesinin blob() yöntemi ile 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);
}

Demografi

Local Font Access API'nin nasıl çalıştığını aşağıdaki demoda görebilirsiniz. Kaynak koda da göz atmayı unutmayın. Demoda, yerel bir yazı tipi seçici uygulayan <font-select> adlı bir özel öğe gösterilmektedir.

Gizlilik konusunda dikkat edilmesi gereken noktalar

"local-fonts" izninin, yüksek düzeyde parmak izi alınabilir bir yüzey sunduğu anlaşılıyor. Ancak, tarayıcılar istedikleri şeyi getirmekte özgürdür. Örneğin, anonimliğe odaklanan tarayıcılar, yalnızca tarayıcıda yerleşik olarak bulunan bir dizi varsayılan yazı tipi sağlamayı tercih edebilir. Benzer şekilde, tarayıcıların tablo verilerini tam olarak diskte göründüğü gibi sağlaması gerekmez.

Mümkün olduğu durumlarda, Local Font Access API yalnızca belirtilen kullanım alanlarını etkinleştirmek için gereken bilgileri tam olarak gösterecek şekilde tasarlanmıştır. Sistem API'leri yüklü yazı tiplerinin rastgele veya sıralı değil, yazı tipi yükleme sırasında bir listesini oluşturabilir. Böyle bir sistem API'si tarafından sağlanan yüklü yazı tiplerinin tam listesini döndürmek, parmak izi için kullanılabilecek ek verileri ortaya çıkarabilir ve etkinleştirmek istediğimiz kullanım alanlarında bu sıralamanın korunması desteklenmez. Sonuç olarak bu API, döndürülen verilerin döndürülmeden önce sıralanmasını gerektirir.

Güvenlik ve izinler

Chrome ekibi, Yerel Yazı Tipi Erişimi API'sini Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme bölümünde tanımlanan (kullanıcı kontrolü, şeffaflık ve ergonomi) temel ilkeleri kullanarak tasarladı ve uyguladı.

Kullanıcı denetimi

Bir kullanıcının yazı tiplerine erişim tamamen kullanıcının kontrolündedir ve izin kayıt defteri'nde belirtildiği gibi "local-fonts" izni verilmediği sürece bu tür uygulamalara izin verilmez.

Şeffaflık

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

İzin kalıcılığı

"local-fonts" izni, sayfaların yeniden yüklenmesi arasında kullanılmaya devam eder. Site bilgileri sayfası aracılığıyla iptal edilebilir.

Geri bildirim

Chrome ekibi, Local Font Access API ile ilgili deneyimlerinizi öğrenmek istiyor.

Bize API tasarımı hakkında bilgi verin

API'de beklediğiniz gibi çalışmayan bir durum mu var? Fikrinizi uygulamak için gereken yöntem veya özellikler eksik mi? Güvenlik modeliyle ilgili bir sorunuz veya yorumunuz mu var? İlgili GitHub deposuna özellik sorunu bildiriminde bulunun veya mevcut bir soruna düşüncelerinizi ekleyin.

Uygulamayla ilgili bir sorunu bildirin

Chrome'un uygulamasında bir hata buldunuz mu? Yoksa uygulama, spesifikasyondan farklı mı? new.crbug.com adresinde hata bildiriminde bulunun. Mümkün olduğunca fazla ayrıntı eklediğinizden ve yeniden oluşturmaya ilişkin basit talimatları eklediğinizden emin olun ve Bileşenler kutusuna Blink>Storage>FontAccess yazın. Glitch, hızlı ve kolay yeniden oluşturmalar paylaşmak için idealdir.

API'ye desteği gösterin

Yerel Yazı Tipi Erişimi API'sini kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı satıcılarına onları desteklemenin ne kadar kritik olduğunu gösterir.

#LocalFontAccess hashtag'ini kullanarak @ChromiumDev'e tweet göndererek bunu 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. Brett Jordan'ın Unsplash'teki lokomotif resmi.