जानें कि 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 नाम का एक कॉर्पोरेट फ़ॉन्ट होता है.
कोई हमलावर, Google Sans जैसे जाने-पहचाने कॉर्पोरेट फ़ॉन्ट की बड़ी संख्या के मौजूद होने की जांच करके, यह पता लगा सकता है कि कोई व्यक्ति किस कंपनी के लिए काम करता है. हमलावर, कैनवस पर इन फ़ॉन्ट में सेट किए गए टेक्स्ट को रेंडर करने की कोशिश करेगा और ग्लिफ़ को मेज़र करेगा. अगर ग्लिफ़, कॉर्पोरेट फ़ॉन्ट के जाने-पहचाने आकार से मेल खाते हैं, तो हमलावर को हिट मिलता है. अगर ग्लिफ़ मेल नहीं खाते हैं, तो हमलावर को पता चल जाता है कि कॉर्पोरेट फ़ॉन्ट इंस्टॉल न होने की वजह से, डिफ़ॉल्ट तौर पर उपलब्ध फ़ॉन्ट का इस्तेमाल किया गया था. इस और ब्राउज़र पर फ़िंगरप्रिंट से किए जाने वाले अन्य हमलों की पूरी जानकारी के लिए, Laperdix et al का सर्वे पेपर पढ़ें.
कंपनी के फ़ॉन्ट के अलावा, इंस्टॉल किए गए फ़ॉन्ट की सूची से भी पहचान की जा सकती है. इस अटैक वेक्टर की स्थिति इतनी खराब हो गई है कि हाल ही में WebKit टीम ने "उपलब्ध फ़ॉन्ट की सूची में सिर्फ़ वेब फ़ॉन्ट और ऑपरेटिंग सिस्टम के साथ आने वाले फ़ॉन्ट शामिल करने का फ़ैसला लिया है. इसमें, उपयोगकर्ता के स्थानीय तौर पर इंस्टॉल किए गए फ़ॉन्ट शामिल नहीं किए जाएंगे. (और यहां मैं, स्थानीय फ़ॉन्ट का ऐक्सेस देने के बारे में एक लेख लेकर आया हूं.)
Local Font Access API
इस लेख की शुरुआत से शायद आपका मूड खराब हो गया हो. क्या हमारे पास अच्छी चीज़ें नहीं हो सकतीं? परेशान न हों. हमें लगता है कि हम ऐसा कर सकते हैं और शायद सब कुछ उम्मीद के मुताबिक न हो. इससे पहले, एक सवाल का जवाब दें जो शायद आपने खुद से पूछा हो.
वेब फ़ॉन्ट मौजूद होने पर, हमें Local Font Access API की ज़रूरत क्यों है?
अब तक, वेब पर प्रोफ़ेशनल क्वालिटी के डिज़ाइन और ग्राफ़िक टूल उपलब्ध कराना मुश्किल था. एक समस्या यह है कि डिज़ाइनर ने लोकल तौर पर जो फ़ॉन्ट इंस्टॉल किए हैं उन्हें ऐक्सेस और इस्तेमाल नहीं किया जा सकता. ये फ़ॉन्ट, पेशेवर तरीके से बनाए गए और हिंट वाले होते हैं. वेब फ़ॉन्ट, पब्लिश करने के कुछ उदाहरणों के लिए काम करते हैं. हालांकि, वेक्टर ग्लिफ़ आकार और फ़ॉन्ट टेबल को प्रोग्राम के हिसाब से ऐक्सेस करने की सुविधा नहीं देते. ग्लिफ़ आउटलाइन को रेंडर करने के लिए, रेस्टराइज़र इनका इस्तेमाल करते हैं. इसी तरह, वेब फ़ॉन्ट के बाइनरी डेटा को ऐक्सेस करने का कोई तरीका नहीं है.
- डिज़ाइन टूल को OpenType लेआउट लागू करने के लिए, फ़ॉन्ट बाइट का ऐक्सेस चाहिए. साथ ही, डिज़ाइन टूल को निचले लेवल पर हुक इन करने की अनुमति भी चाहिए, ताकि वे ग्लिफ़ आकार पर वेक्टर फ़िल्टर लागू कर सकें या उन्हें ट्रांसफ़ॉर्म कर सकें.
- डेवलपर के पास अपने ऐप्लिकेशन के लिए, वेब पर उपलब्ध कराए जा रहे लेगसी फ़ॉन्ट स्टैक हो सकते हैं. इन स्टैक का इस्तेमाल करने के लिए, आम तौर पर उन्हें फ़ॉन्ट डेटा का सीधा ऐक्सेस चाहिए. वेब फ़ॉन्ट में यह ऐक्सेस नहीं मिलता.
- ऐसा हो सकता है कि कुछ फ़ॉन्ट को वेब पर डिलीवर करने के लिए लाइसेंस न मिला हो. उदाहरण के लिए, Linotype के पास कुछ फ़ॉन्ट का लाइसेंस है, जिनका इस्तेमाल सिर्फ़ डेस्कटॉप पर किया जा सकता है.
Local Font Access API, इन समस्याओं को हल करने की कोशिश है. इसमें दो हिस्से होते हैं:
- font enumeration API, जो उपयोगकर्ताओं को उपलब्ध सिस्टम फ़ॉन्ट के पूरे सेट का ऐक्सेस देने की अनुमति देता है.
- हर गिनती के नतीजे से, लो-लेवल (बाइट-ओरिएंटेड) SFNT कंटेनर ऐक्सेस का अनुरोध करने की सुविधा, जिसमें पूरा फ़ॉन्ट डेटा शामिल होता है.
ब्राउज़र समर्थन
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 डेटा ऐक्सेस करना
पूरा SFNT ऐक्सेस, FontData
ऑब्जेक्ट के blob()
तरीके से मिलता है. 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 रेपो पर, कोई खास समस्या दर्ज करें या किसी मौजूदा समस्या के बारे में अपनी राय दें.
लागू करने से जुड़ी समस्या की शिकायत करना
क्या आपको Chrome में इस सुविधा को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका, खास जानकारी से अलग है?
new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. इसमें ज़्यादा से ज़्यादा जानकारी शामिल करें. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दें. इसके बाद, Components बॉक्स में Blink>Storage>FontAccess
डालें.
Glitch, तुरंत और आसानी से समस्या की जानकारी शेयर करने के लिए बहुत अच्छा है.
एपीआई के लिए सहायता दिखाना
क्या आपको लोकल फ़ॉन्ट ऐक्सेस एपीआई इस्तेमाल करना है? सार्वजनिक तौर पर सहायता करने से, Chrome की टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे अन्य ब्राउज़र वेंडर को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है.
#LocalFontAccess
हैशटैग का इस्तेमाल करके, @ChromiumDev को ट्वीट करें और हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.
मददगार लिंक
- पूरी जानकारी देने वाला वीडियो
- स्पेक्ट ड्राफ़्ट
- फ़ॉन्ट की गिनती करने से जुड़ी क्रोमियम की गड़बड़ी
- फ़ॉन्ट टेबल को ऐक्सेस करने में Chromium की गड़बड़ी
- ChromeStatus एंट्री
- GitHub का डेटा स्टोर
- टैग की समीक्षा
- Mozilla के स्टैंडर्ड की स्थिति
धन्यवाद
Local Font Access API स्पेसिफ़िकेशन में बदलाव, Emil A. Eklund, Alex Russell, Joshua Bell, और Olivier Yiptong. इस लेख की समीक्षा, जो मेडली, डोमिनिक रोटशेस, और ओलिवर यिप्टॉन्ग ने की है. Unsplash पर, ब्रेट जॉर्डन की दी गई हीरो इमेज.