जानें कि Local Font Access API की मदद से, उपयोगकर्ता के डिवाइस पर इंस्टॉल किए गए फ़ॉन्ट को कैसे ऐक्सेस किया जा सकता है. साथ ही, उनके बारे में कम लेवल की जानकारी कैसे पाई जा सकती है
वेब सेफ़ फ़ॉन्ट
अगर आपने लंबे समय तक वेब डेवलपमेंट किया है, तो आपको वेब सेफ़ फ़ॉन्ट के बारे में पता होगा.
ये फ़ॉन्ट, सबसे ज़्यादा इस्तेमाल किए जाने वाले ऑपरेटिंग सिस्टम के लगभग सभी वर्शन पर उपलब्ध होते हैं. जैसे, Windows, macOS, Linux के सबसे आम डिस्ट्रिब्यूशन, Android, और iOS. साल 2000 की शुरुआत में, Microsoft ने पहल की थी. इसका नाम TrueType core fonts for the Web था. इसके तहत, इन फ़ॉन्ट को मुफ़्त में डाउनलोड करने की सुविधा दी गई थी. इसका मकसद यह था कि "जब भी कोई व्यक्ति ऐसी वेबसाइट पर जाए जो इन फ़ॉन्ट का इस्तेमाल करती है, तो उसे पेज ठीक वैसे ही दिखें जैसे साइट डिज़ाइनर ने डिज़ाइन किए हैं". हां, इसमें 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, इन चुनौतियों को हल करने की एक कोशिश है. इसके दो हिस्से होते हैं:
- फ़ॉन्ट की गिनती करने वाला एपीआई. इसकी मदद से, उपयोगकर्ता सिस्टम में मौजूद सभी फ़ॉन्ट का ऐक्सेस दे सकते हैं.
- गिनती के हर नतीजे से, लो-लेवल (बाइट ओरिएंटेड) 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 डेटा को ऐक्सेस करना
FontData
ऑब्जेक्ट के blob()
तरीके से, SFNT का पूरा ऐक्सेस मिलता है. SFNT, फ़ॉन्ट फ़ाइल फ़ॉर्मैट है. इसमें PostScript, TrueType, OpenType, Web Open Font Format (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 पर जाकर, गड़बड़ी की रिपोर्ट करें. इसमें ज़्यादा से ज़्यादा जानकारी शामिल करें. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दें और कॉम्पोनेंट बॉक्स में Blink>Storage>FontAccess
डालें.
एपीआई के लिए सहायता दिखाना
क्या आपको Local Font Access API का इस्तेमाल करना है? सार्वजनिक तौर पर आपकी मदद से, Chrome टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे अन्य ब्राउज़र बनाने वाली कंपनियों को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है.
@ChromiumDev को ट्वीट करें. इसके लिए, हैशटैग #LocalFontAccess
का इस्तेमाल करें. साथ ही, हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.
काम के लिंक
- ज़्यादा जानकारी
- ड्राफ़्ट की खास जानकारी
- फ़ॉन्ट की गिनती के लिए Chromium बग
- फ़ॉन्ट टेबल ऐक्सेस करने से जुड़ी Chromium की समस्या
- ChromeStatus एंट्री
- GitHub repo
- TAG की समीक्षा
- Mozilla के स्टैंडर्ड की स्थिति
Acknowledgements
Local Font Access API की खास जानकारी में बदलाव किया गया है. यह बदलाव Emil A. एक्लंड, ऐलेक्स रसेल, जोशुआ बेल, और ओलिवियर यिपटोंग. इस लेख की समीक्षा जो मेडली, डोमिनिक रोट्शेस, और ओलिवियर यिपटोंग ने की है. Unsplash पर ब्रेट जॉर्डन की हीरो इमेज.