टर्मिनल के लिए Glyph Protocol का परिचय
(rapha.land)- टर्मिनल एप्लिकेशन में custom icons render करने के लिए patched fonts (जैसे Nerd Font) install करने की पुरानी समस्या को हल करने हेतु एक नया terminal protocol सामने आया है
- Glyph Protocol एक ऐसी संरचना है जिसमें application runtime पर vector glyphs को सीधे terminal में register कर सकता है, और यह query कर सकता है कि किसी specific codepoint को render किया जा सकता है या नहीं
- Glyph data TrueType के
glyfformat का उपयोग करता है, इसलिए terminal अपने पास पहले से मौजूद rasterizer का ही उपयोग कर सकता है और बिना किसी नई dependency के इसे implement किया जा सकता है - registration के target codepoints को Unicode Private Use Area (PUA) तक सीमित करके phishing और visual spoofing हमलों को मूल रूप से रोका गया है
- Rio terminal में पहली implementation चल रही है, और Bubble Tea, Ratatui, Ink जैसे प्रमुख TUI frameworks के लिए example code भी जारी किया जा चुका है
मौजूदा समस्या: patched font dependency
- टर्मिनल editor, prompt, और TUI में icons सही तरह दिखाने के लिए user को Nerd Font या Powerline जैसे patched fonts खुद install करने पड़ते हैं
- font install न होने पर icon की जगह tofu(□) दिखाई देता है, और patched fonts का आकार प्रति font 6~12MB तक बड़ा हो सकता है
- JetBrainsMono Nerd Font Regular लगभग 7.8MB, FiraCode Nerd Font Regular लगभग 10.4MB, और पूरा symbol archive लगभग 60MB
- application developers के पास अपनी इच्छित glyphs को सीधे distribute करने का कोई तरीका नहीं होता, इसलिए उन्हें यही उम्मीद करनी पड़ती है कि user के पास सही font, version, और codepoint mapping हो
Glyph Protocol की मुख्य क्षमताएँ
- दो प्रमुख operations को support करता है
- custom glyph registration: application Unicode PUA codepoint चुनता है और vector outline को सीधे terminal में भेजकर runtime पर register करता है
- codepoint query: यह पूछना कि कोई specific codepoint system font द्वारा covered है, session registration द्वारा covered है, दोनों से covered है, या किसी से भी नहीं
- यदि user ने पहले से Nerd Font install किया है, तो query के ज़रिये glyph transfer को skip किया जा सकता है; और install न होने पर भी application outline सीधे भेजकर icon को सही तरह दिखा सकता है
protocol की संरचना
transport
- OSC की जगह APC (Application Program Command) का उपयोग किया जाता है
- APC को application-defined commands के लिए design किया गया है, और जिन terminals में यह implement नहीं है वे इस sequence को सुरक्षित रूप से ignore कर सकते हैं
- OSC एक single decimal integer command identifier वाले global namespace को share करता है, इसलिए collision का जोखिम होता है; APC में अपना अलग identification structure होने से यह समस्या नहीं है
identifier
- सभी Glyph Protocol messages में
25a1(U+25A1, WHITE SQUARE) codepoint prefix के रूप में जुड़ा होता है- यह वही standard symbol है जिसे terminal glyph न होने पर tofu के रूप में दिखाता है
- framing format:
ESC _ 25a1 ; <verb> [ ; key=value ]* [ ; <payload> ] ESC \\ - 4 verbs:
s(support),q(query),r(register),c(clear)
Support (s): terminal support की जाँच
- यह जानने के लिए कि terminal कौन-से payload formats और protocol versions support करता है
- यह Glyph Protocol की मौजूदगी detect करने का standard तरीका भी है
- response का
fmtएक bitfield है, जहाँ हर bit एक payload format को दर्शाता है1=glyf: TrueType simple glyph, v1 में अनिवार्य2=colrv0: layered flat color glyph (OpenType COLR v0), v1.2 में जोड़ा गया4=colrv1: gradient और transform वाले full paint graph (OpenType COLR v1), v1.2 में जोड़ा गया
- response मिलने पर protocol support की पुष्टि होती है; timeout होने पर unsupported माना जाता है;
fmt=0का अर्थ है कि protocol implement है लेकिन कोई format supported नहीं है (completeness के लिए परिभाषित)
Query (q): codepoint renderability query
- किसी specific codepoint के render होने की क्षमता पूछी जाती है और
statusvalue के रूप में response मिलता है0(free): कुछ भी render नहीं होता, tofu दिखेगा1(system): system font cover करता है2(glossary): session registration cover करती है3(both): दोनों cover करते हैं, और registration render के समय system font को override करती है
- यदि system में icon पहले से मौजूद हो तो TUI registration skip कर सकता है, और न होने पर custom codepoint register करके graceful fallback दे सकता है
Register (r): glyph registration
- application PUA codepoint चुनकर base64-encoded
glyfoutline भेजता है और registration करता है - मुख्य parameters
cp: target codepoint (hex), यह ज़रूर 3 Unicode PUA ranges में से किसी एक में होना चाहिए (U+E000–U+F8FF,U+F0000–U+FFFFD,U+100000–U+10FFFD); range के बाहर होने परreason=out_of_namespaceके साथ reject किया जाता हैfmt: payload format; v1 में केवलglyfपरिभाषित है और यही default है, इसलिए अक्सर इसे छोड़ा जा सकता हैupm: units per em, जो outline coordinate space को define करता है; default 1000
- उसी
cpपर दूसराrभेजने से पहली registration overwrite हो जाती है - error की स्थिति में (non-PUA codepoint, invalid payload, composite glyph आदि)
status=<nonzero>; reason=<code>के रूप में response मिलता है
glyf format चुनने के कारण
vector क्यों
- glyph कोई photo नहीं है, इसलिए इसकी fixed resolution नहीं होती: वही icon 12px dense TUI और 24px HiDPI display दोनों में render होना चाहिए
- raster glyph किसी खास resolution पर fixed होता है, इसलिए HiDPI पर blurry हो सकता है या छोटे cell में पढ़ा नहीं जा सकता
विशेष रूप से glyf क्यों
- text render करने वाले हर terminal में पहले से
glyfrasterizer linked होता है (FreeType, swash, ttf-parser, fontdue, allsorts आदि) - Glyph Protocol अपनाने पर terminal side में कोई नई dependency जोड़ने की ज़रूरत नहीं
- यदि SVG चुना जाता, तो
resvgलाना पड़ता या नया XML+path parser लिखना पड़ता - wire size भी छोटा है: सामान्य icon के लिए
glyfdata 150~400 bytes के बीच होता है, जो equivalent SVG की तुलना में 2~3 गुना छोटा है (base64 overhead सहित)- 50 icons register करने पर लगभग 13KB बनाम 35KB का अंतर, जो tmux pipe या mobile SSH link पर महसूस किया जा सकता है
glyf का संक्षिप्त परिचय
glyfrecord glyph को closed contours के set के रूप में store करता है- हर point के पास on-curve या off-curve metadata का 1 bit होता है
- दो on-curve points लगातार हों → straight line
- on-curve points के बीच off-curve point हो → quadratic Bézier curve
- दो off-curve points लगातार हों → बीच में implicit on-curve point माना जाता है (compression trick)
- coordinates EM square के भीतर integer grid positions होते हैं;
upm=1000पर(500, 900)का अर्थ है आधी चौड़ाई और 90% ऊँचाई - closed triangle लगभग 30 bytes, और 30-point icon लगभग 200 bytes
protocol द्वारा परिभाषित glyf subset
- केवल simple glyphs की अनुमति: composite glyph, दूसरे glyph का reference, या font-level context की अनुमति नहीं
- OpenType spec में परिभाषित standard flag encoding का उपयोग
- hinting commands नहीं: hinting पूरे font के control value set पर निर्भर करता है, जो यहाँ मौजूद नहीं है
- coordinate space
upmसे define होती है; default 1000 है, और registration per override किया जा सकता है
color, scaling, और authoring
glyfoutline में color information नहीं होती और यह current foreground color से render होता है → ठीक Nerd Font inheritance case की तरह- color glyphs को अलग payload formats
fmt=colrv0/fmt=colrv1से support किया जाता है upmvalue glyph coordinate space define करती है, और terminal render के समय इसे cell पर map करता है → font size बदलने पर दोबारा registration की ज़रूरत नहीं- ज़्यादातर developers
glyfbytes हाथ से नहीं लिखेंगे, बल्कि build time पर SVG से convert करेंगे:fonttoolsकेttx/pensinterface का उपयोग किया जा सकता है, औरsvg2glyfhelper भी Rio reference implementation के साथ distribute किया जाएगा
lifetime और capacity
- हर terminal session के पास 3 PUA ranges के codepoints से keyed एक glossary होता है, जिसमें एक साथ अधिकतम 1024 registrations रखी जा सकती हैं
- registrations session की lifetime तक valid रहती हैं
- 1025वीं glyph registration होने पर FIFO क्रम में सबसे पुरानी registration निकाल दी जाती है → कोई "glossary full" error नहीं
- जिन applications के लिए silent eviction स्वीकार्य नहीं है, उन्हें output से पहले उस codepoint पर query करनी चाहिए
वास्तविक उदाहरण: खाली PUA में icon register करना
U+100000(Supplementary PUA-B का पहला codepoint) पर stylized outline register करने की पूरी pipeline का उदाहरणfontToolsको SVG→glyfconverter के रूप में इस्तेमाल किया गया हैTTGlyphPenसे outline draw करने के बाद उसेbase64encode करके APC sequence में भेजा जाता है, और फिर उस codepoint को output किया जाता है- सामान्य 20-point icon का
glyfpayload लगभग 150 bytes, और APC wrapping तथा base64 सहित लगभग 250 bytes होता है - जिन developers के पास SVG assets हैं, उनके लिए
svg2glyfhelper उपलब्ध कराया जाएगा → 2 lines में registration पूरा
bulk registration के लिए विकल्प: reply=
- default रूप से terminal हर
rके लिए ACK response भेजता है, लेकिन 100 glyphs register करने वाले startup hook में 100 queued ACKs PTY से निकलकर shell में कचरे की तरह दिखने की समस्या आती है - 3-step control
reply=1(default): success और failure दोनों पर response; interactive single registration के लिएreply=2: केवल failure पर response, success पर silence; bulk registration में सिर्फ errors detect करने के लिएreply=0: कोई response नहीं, fire-and-forget; startup hook जैसी स्थिति में उपयोगी जहाँ response पढ़ने वाला कोई न हो
- unknown values अपने-आप
reply=1पर fallback हो जाते हैं, इसलिए future extension में backward compatibility बनी रहती है
Clear (c): registration हटाना
- editor बंद करते समय terminal defaults restore करने, TUI theme बदलने, या debugging में उपयोगी
- single slot clear करना:
cpparameter से specific codepoint चुनें - पूरी glossary clear करना:
cpछोड़ दें - खाली slot को clear करना error नहीं बल्कि no-op है, और
status=0response मिलता है cpPUA range के भीतर होना चाहिए; बाहर होने परreason=out_of_namespaceलौटता है
वे सुविधाएँ जो जानबूझकर v1 में शामिल नहीं की गईं
- non-PUA codepoints register नहीं किए जा सकते: केवल 3 Unicode PUA ranges तक सीमित
- ligatures नहीं: registration सिर्फ single codepoint पर लागू होती है; sequence key replacement v1 के दायरे से बाहर है; programming ligatures (
->→⟶) पहले से OpenType fonts संभाल लेते हैं - sessions के बीच persistence नहीं: हर run पर glyphs फिर से भेजने होंगे; terminal को font cache में बदलने से बचाने के लिए
- cross-application sharing नहीं: हर terminal session की अपनी glossary होती है; कोई IPC या daemon नहीं
- v1
glyfpayload में color glyphs नहीं: rendering foreground color से होती है; color को v1.2 केcolrv0/colrv1में अलग रखा गया है - ज़रूरत पड़ने पर ये सुविधाएँ बाद में जोड़ी जा सकती हैं, लेकिन एक बार जोड़ने के बाद इन्हें आसानी से हटाया नहीं जा सकता, इसलिए इन्हें जानबूझकर बाहर रखा गया है
PUA restriction का सुरक्षा आधार
- PUA restriction केवल API aesthetics नहीं, बल्कि ऐसी property है जो protocol को default-on होने पर भी सुरक्षित बनाती है
- यदि arbitrary codepoint registration की अनुमति हो, तो
U+0061(a) परoजैसा glyph register करकेbad.comकोbod.comजैसा दिखाया जा सकता है- cell buffer में तब भी
bad.comही रहेगा, इसलिए copy-paste में bytes सही होंगी, लेकिन user जो पढ़ेगा वह झूठ होगा - इससे हर terminal program में phishing primitive पैदा हो जाएगा, और उसका असर उसी session में बाद में चलने वाले programs पर भी रहेगा
- cell buffer में तब भी
- PUA तक सीमित करने पर इस तरह का हमला यांत्रिक रूप से असंभव हो जाता है: user PUA codepoints type नहीं करते, और filenames, URLs, commands, variable names, या logs में PUA codepoints नहीं होते
- यह Nerd Font द्वारा स्थापित trust model को protocol level पर enforce करता है: custom glyphs केवल reserved range में रहेंगे, वास्तविक text के ऊपर नहीं
- अतिरिक्त सुरक्षा गुण
- cell buffer authoritative रहता है: selection, copy, search, hyperlink detection, shell history आदि को वही codepoints लौटाने चाहिए जो application ने output किए थे; "जो दिख रहा है और जो copy हो रहा है वह अलग है" जैसी trap नहीं बनाई जा सकती
- session isolation: दो tabs
U+E0A0पर अलग-अलग branch icons स्वतंत्र रूप से register कर सकते हैं; एक tab की registration दूसरे tab की rendering को प्रभावित नहीं कर सकती
मौजूदा तरीकों से तुलना
Kitty Image Protocol (KIP) + Unicode Placeholders
- KIP के Unicode placeholder के ज़रिये Glyph Protocol जैसा व्यवहार लगभग बनाया जा सकता है, लेकिन integration जटिल है और placeholder implement करने वाले terminals सिर्फ Kitty, Ghostty, और Rio हैं
- KIP एक image protocol है, जबकि glyph image नहीं है
- per-use cost: यदि कोई glyph स्क्रीन पर 200 बार reuse होती है (जैसे table borders, bullet markers), तो 200 image references रखने पड़ते हैं, जिससे layout और composition cost बढ़ती है। Glyph Protocol में codepoint register होने के बाद font speed पर render होता है
- native resolution नहीं:
glyfoutline का कोई fixed pixel size नहीं होता, इसलिए font size बदलने पर यह अपने-आप adapt हो जाता है। KIP में specific-size bitmap भेजी जाती है, इसलिए size बदलने पर blur हो सकती है या re-upload करनी पड़ सकती है, और font size change detect करने का भी कोई तरीका नहीं - foreground color inheritance: monochrome
glyfoutline cell के current foreground color से render होती है, इसलिए theme अपने-आप apply हो जाता है। image अपने pixel साथ लाती है, इसलिए text coloring में भाग नहीं लेती
DEC DECDLD / DRCS
- VT220 द्वारा 1983 में पेश किए गए Dynamically Redefinable Character Sets रूप में Glyph Protocol से मिलते-जुलते हैं
- दो मुख्य समस्याएँ
- bitmap approach: terminal के current cell size के हिसाब से pixel grid upload की जाती है, इसलिए font size change, HiDPI, या 4K monitor switch पर blocky pixels scale up/down हो जाते हैं। यह fixed 10×20 CRT युग का तरीका है और आधुनिक विविध cell sizes के लिए उपयुक्त नहीं
- namespace restriction नहीं: DECDLD ऐसे character sets को overwrite कर सकता है जिन्हें GL range (जहाँ
a,b,cजैसे अक्षर होते हैं) में map किया जा सकता है, इसलिए कोई untrusted programaकी rendering redefine कर सकता है → यही कारण है कि आधुनिक terminals DECDLD enable करने में हिचकते हैं
Rio terminal में implementation की स्थिति
- Glyph Protocol Rio terminal की main branch में पहले से उपलब्ध है, और मई के दौरान औपचारिक landing की योजना है → यह पहली implementation है
- पूरा spec release के साथ सार्वजनिक किया जाएगा, जिसमें glyph registration और terminal query के example code भी शामिल होंगे
- काम करने वाले examples raphamorim/glyph-protocol-examples repository में देखे जा सकते हैं: Bubble Tea, Ratatui, और Ink के लिए sample integrations सहित
- protocol में अभी बदलाव की संभावना है, और जैसे-जैसे अधिक applications और terminals जुड़ेंगे, message format, query responses, और edge cases बदल सकते हैं → अभी build करते समय इसे moving target मानें और implementation version pin करने की सलाह दी जाती है
- उम्मीद है कि दूसरे terminal emulators भी इसे अपनाएँगे, क्योंकि पूरे ecosystem के लिए लाभ बड़ा है और implementation scope जानबूझकर छोटा रखा गया है
समुदाय के लिए खुले प्रश्न
- क्या font size change notification protocol scope का हिस्सा होना चाहिए?: Glyph Protocol खुद outline को resolution-independent रखकर इस समस्या से बच जाता है, लेकिन image और glyph दोनों मिलाकर UI बनाने वाली TUI के पास cell metrics change जानने का polling के अलावा कोई तरीका नहीं है →
resizeयाmetrics-changednotification scope के भीतर है या बाहर, इस पर चर्चा जारी है - क्या non-PUA registration को अनुमति देने का कोई जिम्मेदार तरीका है?: PUA-only नियम default safety देता है, लेकिन इससे CJK input methods द्वारा missing Han glyphs भेजने या language-specific tools द्वारा glyph override जैसे use cases रुक जाते हैं → explicit user-level opt-in, signed capability, trusted-source flag आदि के माध्यम से phishing को फिर से सक्षम किए बिना इन use cases को खोलने के तरीकों पर राय मांगी गई है
अभी कोई टिप्पणी नहीं है.