स्थानीय फ़ॉन्ट के साथ बेहतर टाइपोग्राफ़ी का इस्तेमाल करना

जानें कि Local Font Access API की मदद से, उपयोगकर्ता के डिवाइस पर इंस्टॉल किए गए फ़ॉन्ट को कैसे ऐक्सेस किया जा सकता है और उनके बारे में कम जानकारी कैसे पाई जा सकती है

वेब सेफ़ फ़ॉन्ट

अगर आपने वेब डेवलपमेंट का काम लंबे समय से किया है, तो आपको वेब सेफ़ फ़ॉन्ट के बारे में पता होगा. ये फ़ॉन्ट, ज़्यादातर इस्तेमाल किए जाने वाले ऑपरेटिंग सिस्टम (जैसे, Windows, macOS, सबसे ज़्यादा इस्तेमाल होने वाले Linux डिस्ट्रिब्यूशन, Android, और iOS) के ज़्यादातर इंस्टेंस पर उपलब्ध होते हैं. साल 2000 की शुरुआत में, Microsoft ने वेब के लिए TrueType कोर फ़ॉन्ट नाम की एक पहल शुरू की थी. इस पहल के तहत, इन फ़ॉन्ट को मुफ़्त में डाउनलोड किया जा सकता था. इसकी वजह यह थी कि "जब भी किसी ऐसी वेब साइट पर जाएं जिस पर ये फ़ॉन्ट इस्तेमाल किए गए हैं, तो आपको पेज ठीक वैसे ही दिखेंगे जैसे साइट डिज़ाइनर ने उन्हें दिखाने के लिए तय किया है". हां, इसमें Comic Sans MS में सेट की गई साइटें शामिल थीं. यहां एक क्लासिक वेब सेफ़ फ़ॉन्ट स्टैक दिया गया है. इसमें sans-serif फ़ॉन्ट के लिए फ़ॉलबैक के तौर पर, सबसे अच्छा फ़ॉन्ट दिख सकता है:

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

वेब फ़ॉन्ट

वेब सेफ़ फ़ॉन्ट का इस्तेमाल करने का दौर अब बीत चुका है. फ़िलहाल, हमारे पास वेब फ़ॉन्ट हैं. इनमें से कुछ वैरिएबल फ़ॉन्ट भी हैं. इनमें, एक्सपोज़ किए गए अलग-अलग ऐक्सिस की वैल्यू बदलकर, और भी बदलाव किए जा सकते हैं. सीएसएस की शुरुआत में @font-face ब्लॉक का एलान करके, वेब फ़ॉन्ट का इस्तेमाल किया जा सकता है. इस ब्लॉक में, डाउनलोड करने के लिए फ़ॉन्ट फ़ाइलों की जानकारी दी जाती है:

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

इसके बाद, सामान्य तरीके से font-family तय करके, कस्टम वेब फ़ॉन्ट का इस्तेमाल किया जा सकता है:

body {
  font-family: 'FlamboyantSansSerif';
}

फ़िंगरप्रिंट वेक्टर के तौर पर स्थानीय फ़ॉन्ट

ज़्यादातर वेब फ़ॉन्ट, वेब से मिलते हैं. हालांकि, एक दिलचस्प बात यह है कि @font-face एलान में, src प्रॉपर्टी, url() फ़ंक्शन के अलावा, local() फ़ंक्शन को भी स्वीकार करती है. इससे कस्टम फ़ॉन्ट, स्थानीय तौर पर लोड किए जा सकते हैं. अगर उपयोगकर्ता के ऑपरेटिंग सिस्टम पर FlamboyantSansSerif टाइप फ़ॉन्ट पहले से इंस्टॉल है, तो उसे डाउनलोड करने के बजाय, उसकी लोकल कॉपी का इस्तेमाल किया जाएगा:

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

इस तरीके से, बैकफ़ॉल के लिए एक अच्छा तरीका मिलता है, जिससे बैंडविड्थ की बचत होती है. माफ़ करें, इंटरनेट पर अच्छी चीज़ें नहीं मिलतीं. local() फ़ंक्शन की समस्या यह है कि इसका इस्तेमाल, ब्राउज़र फ़िंगरप्रिंट के लिए किया जा सकता है. ऐसा लगता है कि उपयोगकर्ता के इंस्टॉल किए गए फ़ॉन्ट की सूची से, उसके बारे में काफ़ी जानकारी मिल सकती है. कई कंपनियों के पास अपने कॉर्पोरेट फ़ॉन्ट होते हैं, जिन्हें कर्मचारियों के लैपटॉप पर इंस्टॉल किया जाता है. उदाहरण के लिए, Google का एक कॉर्पोरेट फ़ॉन्ट है, जिसे Google Sans कहा जाता है.

macOS के Font Book ऐप्लिकेशन में, Google Sans फ़ॉन्ट की झलक दिख रही है.
Google के किसी कर्मचारी के लैपटॉप पर इंस्टॉल किया गया Google Sans फ़ॉन्ट.

कोई हमलावर, Google Sans जैसे जाने-पहचाने कॉर्पोरेट फ़ॉन्ट की बड़ी संख्या के मौजूद होने की जांच करके, यह पता लगा सकता है कि कोई व्यक्ति किस कंपनी के लिए काम करता है. हमलावर, कैनवस पर इन फ़ॉन्ट में सेट किए गए टेक्स्ट को रेंडर करने की कोशिश करेगा और ग्लिफ़ को मेज़र करेगा. अगर ग्लिफ़, कॉर्पोरेट फ़ॉन्ट के जाने-पहचाने आकार से मेल खाते हैं, तो हमलावर को हिट मिलता है. अगर ग्लिफ़ मेल नहीं खाते हैं, तो हमलावर को पता चल जाता है कि कॉर्पोरेट फ़ॉन्ट इंस्टॉल न होने की वजह से, डिफ़ॉल्ट तौर पर उपलब्ध फ़ॉन्ट का इस्तेमाल किया गया था. इस और ब्राउज़र फ़िंगरप्रिंट से जुड़े अन्य हमलों के बारे में पूरी जानकारी के लिए, Laperdix et al. का सर्वे पेपर पढ़ें

कंपनी के फ़ॉन्ट के अलावा, इंस्टॉल किए गए फ़ॉन्ट की सूची से भी पहचान की जा सकती है. इस अटैक वेक्टर की स्थिति इतनी खराब हो गई है कि हाल ही में WebKit टीम ने "उपलब्ध फ़ॉन्ट की सूची में सिर्फ़ वेब फ़ॉन्ट और ऑपरेटिंग सिस्टम के साथ आने वाले फ़ॉन्ट शामिल करने का फ़ैसला लिया है. इसमें, उपयोगकर्ता के स्थानीय तौर पर इंस्टॉल किए गए फ़ॉन्ट शामिल नहीं किए जाएंगे. (और यहां मैं, स्थानीय फ़ॉन्ट का ऐक्सेस देने के बारे में एक लेख लेकर आया हूं.)

Local Font Access API

इस लेख की शुरुआत से शायद आपका मूड खराब हो गया हो. क्या हमारे पास अच्छी चीज़ें नहीं हो सकतीं? परेशान न हों. हमें लगता है कि हम ऐसा कर सकते हैं और शायद सब कुछ उम्मीद के मुताबिक न हो. हालांकि, सबसे पहले उस सवाल का जवाब दें जो शायद आपने खुद से पूछा हो.

वेब फ़ॉन्ट मौजूद होने पर, हमें Local Font Access API की ज़रूरत क्यों है?

अब तक, वेब पर प्रोफ़ेशनल क्वालिटी के डिज़ाइन और ग्राफ़िक टूल उपलब्ध कराना मुश्किल था. एक समस्या यह है कि डिज़ाइनर ने लोकल तौर पर जो फ़ॉन्ट इंस्टॉल किए हैं उन्हें ऐक्सेस और इस्तेमाल नहीं किया जा सकता. ये फ़ॉन्ट, पेशेवर तरीके से बनाए गए और हिंट वाले होते हैं. वेब फ़ॉन्ट, पब्लिश करने के कुछ उदाहरणों के लिए काम करते हैं. हालांकि, वेक्टर ग्लिफ़ आकार और फ़ॉन्ट टेबल को प्रोग्राम के हिसाब से ऐक्सेस करने की सुविधा नहीं देते. ग्लिफ़ आउटलाइन को रेंडर करने के लिए, रेस्टराइज़र इनका इस्तेमाल करते हैं. इसी तरह, वेब फ़ॉन्ट के बाइनरी डेटा को ऐक्सेस करने का कोई तरीका नहीं है.

  • डिज़ाइन टूल को OpenType लेआउट लागू करने के लिए, फ़ॉन्ट बाइट का ऐक्सेस चाहिए. साथ ही, डिज़ाइन टूल को निचले लेवल पर हुक इन करने की अनुमति भी चाहिए, ताकि वे ग्लिफ़ आकार पर वेक्टर फ़िल्टर लागू कर सकें या उन्हें ट्रांसफ़ॉर्म कर सकें.
  • डेवलपर के पास अपने ऐप्लिकेशन के लिए, वेब पर उपलब्ध कराए जा रहे लेगसी फ़ॉन्ट स्टैक हो सकते हैं. इन स्टैक का इस्तेमाल करने के लिए, आम तौर पर उन्हें फ़ॉन्ट डेटा का सीधा ऐक्सेस चाहिए. वेब फ़ॉन्ट ऐसा नहीं करते.
  • ऐसा हो सकता है कि कुछ फ़ॉन्ट का लाइसेंस, वेब पर डिलीवरी के लिए न दिया गया हो. उदाहरण के लिए, Linotype के पास कुछ फ़ॉन्ट का लाइसेंस है, जिनका इस्तेमाल सिर्फ़ डेस्कटॉप पर किया जा सकता है.

Local Font Access API, इन समस्याओं को हल करने की कोशिश है. इसमें दो हिस्से होते हैं:

  • फ़ॉन्ट की जानकारी देने वाला एपीआई, जिसकी मदद से उपयोगकर्ता, उपलब्ध सिस्टम फ़ॉन्ट के पूरे सेट का ऐक्सेस दे सकते हैं.
  • हर गिनती के नतीजे से, लो-लेवल (बाइट-ओरिएंटेड) SFNT कंटेनर ऐक्सेस का अनुरोध करने की सुविधा मिलती है. इसमें फ़ॉन्ट का पूरा डेटा शामिल होता है.

ब्राउज़र समर्थन

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 103.
  • Edge: 103.
  • Firefox: यह सुविधा काम नहीं करती.
  • Safari: यह सुविधा काम नहीं करती.

सोर्स

Local Font Access API का इस्तेमाल करने का तरीका

फ़ीचर का पता लगाना

यह देखने के लिए कि Local Font Access API काम करता है या नहीं, इनका इस्तेमाल करें:

if ('queryLocalFonts' in window) {
  // The Local Font Access API is supported
}

स्थानीय फ़ॉन्ट की सूची बनाना

डिवाइस में इंस्टॉल किए गए फ़ॉन्ट की सूची पाने के लिए, आपको window.queryLocalFonts() को कॉल करना होगा. पहली बार, इससे अनुमति का अनुरोध ट्रिगर होगा. उपयोगकर्ता इस अनुरोध को स्वीकार या अस्वीकार कर सकता है. अगर उपयोगकर्ता, अपने लोकल फ़ॉन्ट के बारे में क्वेरी करने की अनुमति देता है, तो ब्राउज़र फ़ॉन्ट के डेटा के साथ एक कलेक्शन दिखाएगा. इस कलेक्शन को लूप किया जा सकता है. हर फ़ॉन्ट को FontData ऑब्जेक्ट के तौर पर दिखाया जाता है. इसमें family (उदाहरण के लिए, "Comic Sans MS"), fullName (उदाहरण के लिए, "Comic Sans MS"), postscriptName (उदाहरण के लिए, "ComicSansMS"), और style (उदाहरण के लिए, "Regular") प्रॉपर्टी होती हैं.

// 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);
}

अगर आपको सिर्फ़ फ़ॉन्ट के किसी सबसेट में दिलचस्पी है, तो postscriptNames पैरामीटर जोड़कर, उन्हें PostScript नामों के आधार पर भी फ़िल्टर किया जा सकता है.

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

SFNT डेटा ऐक्सेस करना

FontData ऑब्जेक्ट के blob() तरीके से, SFNT का पूरा ऐक्सेस मिलता है. SFNT एक फ़ॉन्ट फ़ाइल फ़ॉर्मैट है. इसमें PostScript, TrueType, OpenType, वेब ओपन फ़ॉन्ट फ़ॉर्मैट (WOFF) फ़ॉन्ट वगैरह जैसे अन्य फ़ॉन्ट शामिल हो सकते हैं.

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);
}

डेमो

Local Font Access API के काम करने का तरीका जानने के लिए, यहां दिया गया डेमो देखें. सोर्स कोड भी देखना न भूलें. इस डेमो में, <font-select> नाम का एक कस्टम एलिमेंट दिखाया गया है. यह एलिमेंट, स्थानीय फ़ॉन्ट पिकर को लागू करता है.

निजता से जुड़ी बातें

ऐसा लगता है कि "local-fonts" अनुमति से, फ़िंगरप्रिंट की सुविधा देने वाला प्लैटफ़ॉर्म मिलता है. हालांकि, ब्राउज़र अपनी पसंद के मुताबिक, किसी भी चीज़ को वापस कर सकते हैं. उदाहरण के लिए, निजता को ध्यान में रखकर बनाए गए ब्राउज़र, सिर्फ़ ब्राउज़र में पहले से मौजूद डिफ़ॉल्ट फ़ॉन्ट का सेट उपलब्ध करा सकते हैं. इसी तरह, ब्राउज़र को टेबल का डेटा ठीक वैसा ही दिखाने की ज़रूरत नहीं है जैसा कि वह डिस्क पर दिखता है.

जहां भी हो सके, Local Font Access API को सिर्फ़ उस जानकारी को दिखाने के लिए डिज़ाइन किया गया है जो इस्तेमाल के बताए गए उदाहरणों को चालू करने के लिए ज़रूरी है. सिस्टम एपीआई, इंस्टॉल किए गए फ़ॉन्ट की सूची को रैंडम या क्रम में नहीं, बल्कि फ़ॉन्ट इंस्टॉल करने के क्रम में दिखा सकते हैं. इस तरह के सिस्टम एपीआई से मिले इंस्टॉल किए गए फ़ॉन्ट की सूची को ठीक से दिखाने पर, अतिरिक्त डेटा दिख सकता है. इसका इस्तेमाल फ़िंगरप्रिंट करने के लिए किया जा सकता है. साथ ही, इस क्रम को बनाए रखने से, इस्तेमाल के उन उदाहरणों को चालू करने में मदद नहीं मिलती जिन्हें हमें चालू करना है. इसलिए, इस एपीआई के लिए ज़रूरी है कि दिखाया गया डेटा, दिखाए जाने से पहले क्रम में लगाया गया हो.

सुरक्षा और अनुमतियां

Chrome की टीम ने वेब प्लैटफ़ॉर्म की बेहतर सुविधाओं के ऐक्सेस को कंट्रोल करना में बताए गए मुख्य सिद्धांतों का इस्तेमाल करके, Local Font Access API को डिज़ाइन और लागू किया है. इन सिद्धांतों में, उपयोगकर्ता कंट्रोल, पारदर्शिता, और काम करने के तरीके शामिल हैं.

उपयोगकर्ता कंट्रोल

उपयोगकर्ता के फ़ॉन्ट का ऐक्सेस पूरी तरह से उसके कंट्रोल में होता है. जब तक अनुमति रजिस्ट्री में बताई गई "local-fonts" अनुमति नहीं दी जाती, तब तक उसे ऐक्सेस करने की अनुमति नहीं दी जाएगी.

पारदर्शिता

साइट की जानकारी वाली शीट में यह दिखेगा कि किसी साइट को उपयोगकर्ता के स्थानीय फ़ॉन्ट का ऐक्सेस दिया गया है या नहीं.

अनुमति का बना रहना

पेज को फिर से लोड करने के दौरान, "local-fonts" की अनुमति बनी रहेगी. इसे साइट की जानकारी शीट से रद्द किया जा सकता है.

सुझाव/राय दें या शिकायत करें

Chrome की टीम, Local Font Access API के साथ आपके अनुभवों के बारे में जानना चाहती है.

हमें एपीआई के डिज़ाइन के बारे में बताएं

क्या एपीआई में कोई ऐसी चीज़ है जो आपकी उम्मीद के मुताबिक काम नहीं करती? क्या आपके आइडिया को लागू करने के लिए, कोई तरीका या प्रॉपर्टी मौजूद नहीं है? क्या आपका सुरक्षा मॉडल के बारे में कोई सवाल या टिप्पणी है? उससे जुड़े GitHub repo पर, खास समस्या की शिकायत करें या किसी मौजूदा समस्या में अपने सुझाव जोड़ें.

लागू करने से जुड़ी समस्या की शिकायत करना

क्या आपको Chrome में इस सुविधा को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका, खास जानकारी से अलग है? new.crbug.com पर गड़बड़ी की शिकायत करें. इसमें ज़्यादा से ज़्यादा जानकारी शामिल करें. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दें. इसके बाद, Components बॉक्स में Blink>Storage>FontAccess डालें. Glitch, तुरंत और आसानी से समस्या की जानकारी शेयर करने के लिए बहुत अच्छा है.

एपीआई के लिए सहायता दिखाना

क्या आपको Local Font Access API का इस्तेमाल करना है? सार्वजनिक तौर पर सहायता करने से, Chrome की टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे अन्य ब्राउज़र वेंडर को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है.

#LocalFontAccess हैशटैग का इस्तेमाल करके, @ChromiumDev को ट्वीट करें और हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.

आभार

Local Font Access API स्पेसिफ़िकेशन में बदलाव, Emil A. Eklund, Alex Russell, Joshua Bell, और Olivier Yiptong. इस लेख की समीक्षा, जो मेडली, डोमिनिक रोटशेस, और ओलिवर यिप्टॉन्ग ने की है. Unsplash पर, ब्रेट जॉर्डन की दी गई हीरो इमेज.