2 पॉइंट द्वारा GN⁺ 2024-03-06 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Paper, Apple प्लेटफ़ॉर्म पर TextKit 1 आधारित TextView एडिटर के रूप में काम करता है, जहाँ NSTextStorage, NSTextContainer, NSLayoutManager, TextView, और ScrollView मिलकर एडिटिंग अनुभव बनाते हैं
  • NSAttributedString, स्ट्रिंग और रेंज-आधारित attributes के ज़रिए rich text को दर्शाता है, और Paper Markdown संरचना के लिए meta attributes तथा स्क्रीन डिस्प्ले के लिए style attributes को अलग रखता है
  • स्टाइल अपडेट, दस्तावेज़ खोलने, टेक्स्ट बदलने, और सेटिंग बदलने के अनुसार अलग तरह से होता है; layout को प्रभावित करने वाले attributes को transaction में बाँधा जाता है और decoration attributes को layout दोबारा निकाले बिना अपडेट किया जाता है
  • इनपुट performance को इस तरह बेहतर किया जाता है कि Markdown special characters के आसपास एडिट हो रहा है या नहीं, यह देखकर पूरे paragraph को दोबारा parse करने से बचा जाए; लेकिन code block जैसी संरचनाओं के लिए exception handling चाहिए, क्योंकि वे पूरे दस्तावेज़ की styling को प्रभावित कर सकती हैं
  • copy-paste, UTI और pasteboard पर मौजूद कई data representations के ऊपर काम करता है; Markdown जैसे Apple द्वारा परिभाषित न किए गए semi-public UTI में app-to-app priority mismatch के कारण RTF conversion और UX समस्याएँ हो सकती हैं

Apple TextView editing stack

  • Paper पुराने TextKit 1 framework पर बना है, और वही concepts व abstractions TextKit 2 में भी वैसे ही मौजूद हैं या बेहतर API के नीचे मिलते हैं
  • NSTextView और UITextView में अंतर है, लेकिन उनके API इतने समान हैं कि उन्हें एक ही TextView परिवार की तरह देखा जा सकता है
  • TextView, हर OS release के साथ और जटिल होता गया एक बड़ा component है, और TextEdit app लगभग एक ही TextView से बना है
  • एडिटर को बनाने वाली मुख्य layers

    • NSTextStorage
      • मूल text string को स्टोर करता है
      • text ranges पर लगे string-value pair attributes को स्टोर करता है
      • text और attribute change events उत्पन्न करता है
    • NSTextContainer
      • उस क्षेत्र का आकार और रूप तय करता है जिसमें glyphs रखे जाएँगे
      • यह अधिकतर rectangle होता है, लेकिन कोई भी arbitrary shape हो सकता है
    • NSLayoutManager
      • NSTextStorage की attribute ranges देखकर glyph size और spacing की गणना करता है
      • font से vector glyphs निकालता है, और एक character को एक या अधिक glyphs में बदलता है
      • हर line की शुरुआत और अंत, line count, और पूरे text की height की गणना करता है
    • TextView
      • NSLayoutManager द्वारा बनाई गई glyph layout को draw करता है
      • view height को मौजूदा text layout height के साथ sync करता है
      • input, selection range, caret, typing attributes, textContainerInset, dictation, copy-paste, spell check आदि को संभालता है
    • ScrollView
      • TextView का visible area, scrolling, scrollbar, और zoom संभालता है
      • TextView के textContainerInset से अलग इसका अपना contentInset भी हो सकता है
  • AppKit और UIKit में scrolling का अंतर

    • AppKit में NSScrollView, NSClipView और दो NSScroller को समेटे होता है, और NSClipView, NSTextView को रखकर कई classes मिलकर scrolling behavior बनाती हैं
    • UIKit में UITextView, UIScrollView को inherit करता है, इसलिए scrolling logic भी उसके अंदर ही होता है
    • जब caret, contentInset द्वारा सीमित visible area के बाहर चला जाता है, तो UITextView अपने-आप scroll करता है
    • iOS editor में जब caret keyboard के पीछे चला जाए और अगली line तक scroll हो, तो उसका कारण यह है कि नीचे का contentInset dynamically मौजूदा keyboard height पर सेट किया जाता है

NSAttributedString और attribute lookup

  • NSAttributedString, Apple frameworks में rich text editing की बुनियाद है और यह दो हिस्सों से बना होता है
    • plain text string
    • string के अंदर text ranges पर लगे string-value attribute pairs
  • attributes आमतौर पर styling के लिए उपयोग होते हैं, लेकिन developer अपनी ज़रूरत के arbitrary string-value pairs भी जोड़ सकता है
  • NSRange, location और length से बना होता है; NSMakeRange(10, 5) का मतलब location 10 से शुरू होने वाली 5 अक्षरों की range है, यानी position 10~14
  • अगर एक ही position पर एक ही attribute कई ranges में दिया गया हो, तो सबसे बाद में लागू की गई range को प्राथमिकता मिलती है
  • किसी खास position के attribute और range की जाँच

    • किसी position पर attribute value को attribute:atIndex:effectiveRange: से देखा जाता है
    • अगर return value nil हो तो वह attribute मौजूद नहीं है; अगर value हो, तो उदाहरण के अनुसार वह NSFont या UIFont object जैसा attribute value होता है
    • आख़िरी argument में NSRange pointer देने पर उसी value के लगातार चलने वाली range, या attribute न होने वाली खाली range, मिल सकती है
    • documentation के अनुसार effectiveRange का अधिकतम range होना ज़रूरी नहीं है; यह implementation पर निर्भर करता है
    • अगर गारंटीड maximum range चाहिए, तो attribute:atIndex:longestEffectiveRange:inRange: इस्तेमाल करना चाहिए
    • किसी position पर मौजूद attributes के पूरे combination और उस combination की continuous range पाने की method भी होती है
    • किसी range के अंदर attributes iterate करने के लिए enumerateAttribute:inRange:options:usingBlock: का उपयोग किया जा सकता है

Paper की Markdown styling pipeline

  • Paper की styling, text ranges पर framework द्वारा परिभाषित special attributes लागू करके होती है
  • styling से पहले text structure की पहचान के लिए custom meta attributes भी उपयोग किए जाते हैं
  • meta attributes और style attributes

    • meta attributes
      • Markdown parser इन्हें Markdown syntax के अलग-अलग हिस्सों की पहचान के लिए परिभाषित करता है
      • ये केवल semantic जानकारी के लिए custom string-value pairs होते हैं
      • ये text के visual appearance को प्रभावित नहीं करते
      • इन्हें Markdown के लिए simplified AST जैसा समझा जा सकता है
    • style attributes
      • ये meta attributes से चिह्नित हिस्सों पर लागू होने वाले visual attributes हैं
      • ये AppKit और UIKit द्वारा परिभाषित built-in string-value pairs हैं
  • attribute update ट्रिगर करने वाले events

    • attributes को NSTextStorage में मौजूद Markdown text और text को प्रभावित करने वाली settings के बदलाव के साथ sync किया जाता है
    • दस्तावेज़ खोलने पर meta attributes और style attributes दोनों का full refresh होता है
    • text change पर प्रभावित हिस्सों के meta attributes और style attributes का partial refresh होता है
    • settings change पर meta attributes नहीं बदले जाते, केवल style attributes का full refresh होता है
  • update order और layout cost

    • पहले text edit transaction शुरू करके attribute changes को एक साथ बाँधा जाता है
    • transaction के बिना attributes बदलने पर हर बार NSLayoutManager में महँगी layout recalculation होती है
    • Markdown string को parse करके meta attributes से चिह्नित टुकड़ों में बाँटा जाता है; settings change के समय Markdown structure नहीं बदलता, इसलिए यह चरण छोड़ा जाता है
    • glyph position या size को प्रभावित करने वाले visual attributes पहले अपडेट किए जाते हैं, और NSParagraphStyle को line व paragraph layout को प्रभावित करने वाला सबसे महत्वपूर्ण attribute माना जाता है
    • transaction खत्म होने के बाद उन decoration attributes को अपडेट किया जाता है जो layout को प्रभावित नहीं करते
    • Apple terminology में decoration attributes, rendering attributes के बराबर हैं, और ये NSTextStorage में नहीं बल्कि NSLayoutManager में होते हैं, इसलिए ये transaction को पहचानते नहीं हैं
  • typing attributes

    • typing attributes, खाली selection में caret के ठीक पहले की position के attributes से जुड़े होते हैं, और non-empty selection में selection start point के attributes से जुड़े होते हैं
    • character टाइप करने पर typing attributes अपने-आप नए insert किए गए text पर लागू हो जाते हैं
    • Markdown editor में styling Markdown syntax से निकलती है, इसलिए इनका महत्व कम होता है
    • rich text editor में ये ज़्यादा महत्वपूर्ण हैं, क्योंकि style को बंद करने या caret को दूसरी जगह ले जाने तक style caret के साथ बनी रहती है
    • Paper का Preview Mode, Markdown editor के भीतर भी toggle होने वाले typing attributes को उभारने वाला rich text editing अनुभव देता है

इनपुट performance और meta attributes का उपयोग

  • meta, layout, और decoration attributes को अलग रखना editor के कुछ बदलावों को तेज़ी से संभालने में मदद करता है
  • light/dark mode switch में केवल decoration attributes अपडेट होते हैं, इसलिए layout trigger नहीं होता और यह बहुत तेज़ है
  • text size adjustment जैसी settings changes में पूरे document की layout recalculation चाहिए, लेकिन पूरे Markdown structure को दोबारा parse करने से यह फिर भी तेज़ है
  • Markdown input optimization

    • text editor की सबसे अहम performance factor typing speed है
    • Markdown की प्रकृति के कारण text का एक बदलाव पूरे paragraph की styling को प्रभावित कर सकता है
    • हर key press पर पूरे paragraph को फिर से parse और style करना तकनीकी रूप से सबसे सही तरीका है, लेकिन लंबे paragraphs में इससे editing धीमी हो सकती है
    • Paper एक ऐसा algorithm इस्तेमाल करता है जो अगला input character और उसके आसपास के characters देखकर behavior तय करता है
    • अगर special Markdown symbols टाइप किए जाएँ, या edit position के आसपास ऐसे symbols हों, तो पूरा paragraph refresh किया जाता है
    • अन्यथा, ज़्यादातर typing स्थितियों में editor की speed बढ़ाने के लिए typing attributes पर निर्भर किया जाता है
  • code block exceptions और value object cache

    • code block, Paper में एकमात्र multi-paragraph Markdown structure है
    • code block वाले document में एक key press भी पूरे document की styling को प्रभावित कर सकती है
    • Paper, एक तय character count से बड़े documents में code block handling को अनदेखा करता है, ताकि code में रुचि न रखने वाले अधिकांश users के लिए editor तेज़ बना रहे
    • यह चुनाव, developer-adjacent users के लिए भी Paper को अधिक उपयोगी बनाता है
    • जटिल attribute value objects हर key press पर फिर से allocate होते हैं, लेकिन जब तक text-affecting settings नहीं बदलतीं, वे बदलते नहीं हैं; इसलिए उन्हें cache करके reuse किया जाता है
      • NSFont/UIFont
      • NSColor/UIColor
      • NSParagraphStyle
  • meta attributes का उपयोग करने वाली features

    • formatting shortcuts
      • toggle करने के लिए चुने गए Markdown text की मौजूदा style जानकारी जानना ज़रूरी है
      • अगर selection range पूरी तरह उसी style को घेरती है, तो वह style हटाई जाती है
      • अगर selection range में वही style नहीं है, तो style जोड़ी जाती है
      • अगर selection range केवल आंशिक रूप से उसी style को घेरती है, तो style को selection range पर शिफ्ट किया जाता है
      • heading और blockquote जैसी paragraph type परिभाषित करने वाली conflicting styles को मिलाया नहीं जा सकता, इसलिए नई style जोड़ने से पहले उन्हें हटाना पड़ता है
    • chapter navigation
      • पिछले या अगले chapter boundary पर जाने के लिए caret position के आधार पर heading खोजने में meta attributes काम आते हैं
    • Outline
      • सभी headings को iterate किया जाता है, और outline item पर tap/click करने पर caret उस chapter में चला जाता है
    • chapter rearrangement
      • outline में chapters को reorder किया जा सकता है
    • format conversion
      • Markdown को RTF, HTML, DOCX में बदलने के लिए text structure जानना ज़रूरी है
      • Paper external library शामिल नहीं करता, इसलिए वह पहले से parsed text model को iterate करके output format बनाता है

text container गणित और selection behavior

  • line length और margins की गणना

    • text container का मूल नियम यह है कि पसंदीदा line length बनाए रखी जाए और बची हुई जगह को दोनों तरफ़ inset में बाँटा जाए
    • कुछ स्थितियों में, जैसे heading tag को सामान्य text flow के बाहर रखना, symmetry को कृत्रिम रूप से मिलाना पड़ता है
    • ऐसे में text container को बाईं ओर खिसकाया जाता है, और paragraph को NSParagraphStyle से indent किया जाता है
    • पर्याप्त जगह होने पर margins को देखने में लगभग symmetric रखा जाता है
    • अतिरिक्त जगह न होने पर symmetry तोड़कर निर्धारित line length बनाए रखी जाती है, लेकिन केवल तब तक जब तक दाईं तरफ़ padding बची हो
    • padding भी न बचे तो preferred line width से पहले minimum margins को प्राथमिकता दी जाती है
    • min और max के संयोजन से धीरे-धीरे सिमटने वाले margins लागू किए जा सकते हैं
  • selection anchor

    • text selection में हमेशा एक anchor point होता है
    • Mac में click करके drag करने पर clicked point आधार बनता है, और उस point को पार करते ही selection के बढ़ने-घटने की दिशा उलट जाती है
    • iOS में selection handle के एक छोर को drag करने पर दूसरा छोर anchor बन जाता है, और उलटी दिशा में भी यही लागू होता है
    • keyboard से selection expand करते समय भी यही logic लागू होता है
    • Option+बायाँ/दायाँ arrow से word boundaries पर जाया जाता है, और Shift भी साथ दबाने पर word unit में selection होती है
    • click-drag से selection करने के बाद keyboard से उसे और बढ़ाएँ या घटाएँ, शुरुआती click point anchor बना रहता है
  • selection affinity

    • selection affinity तय करती है कि line break boundary पर insertion point पिछली line के आख़िरी character के बाद दिखेगा या अगली line के पहले character से पहले
    • arrow keys से caret हिलाने पर line break के आसपास की whitespace के बीच बस line बदलती है
    • shortcut से line end पर जाने पर caret उसी line में रह सकता है और line break whitespace के दाईं तरफ़ चिपक सकता है
    • TextView इसी तरह का selection affinity behavior दूसरी स्थितियों में भी करता है
  • Undo coalescing

    • Undo coalescing वह algorithm है जो तय करता है कि टाइप किए गए text को कब एक ही undo-able action में समूहित करना है
    • TextView संभवतः एक सरल algorithm इस्तेमाल करता है, जो बीच में किसी दूसरे action से बाधित न होने पर टाइप की गई चीज़ों को साथ समूहित करता है
    • बीच में रुककर फिर टाइप करने पर भी एक ही undo बन सकता है, और line break भी coalescing को नहीं तोड़ता
    • Sublime typing के दौरान अलग-अलग शब्दों को undo unit में बाँधना पसंद करता है, और लंबे शब्दों के दौरान उन्हें छोटे undo units में भी बाँट सकता है
    • इस behavior का कोई एक सही उत्तर नहीं है; अलग-अलग editors अलग रणनीति अपना सकते हैं

UTI, pasteboard, और apps के बीच data exchange

  • Uniform Type Identifiers

    • UTI एक hierarchical system है जिसमें data types, parent data type को inherit करने की तरह conform to करते हैं
    • public.* types Apple द्वारा परिभाषित होते हैं और public.html, public.jpeg जैसे व्यापक formats की पहचान करते हैं
    • developers conflict से बचने के लिए reverse-domain naming scheme में अपने identifiers बना सकते हैं
    • hierarchical system का फ़ायदा यह है कि अगर app सभी text formats देख सकती है, तो उसे हर format अलग से घोषित करने की जगह सिर्फ़ public.text घोषित करना होता है
    • Paper यह घोषित करता है कि वह सभी text files खोल सकता है, इसलिए highlighting न होने पर भी .html, .rtf जैसे text formats खोले जा सकते हैं
    • files cross-platform अवधारणा हैं, इसलिए व्यवहार में file extensions ही identifiers की तरह काम करते हैं
    • compatibility के लिए हर UTI से एक या अधिक file extensions जोड़े जा सकते हैं
    • Markdown व्यापक रूप से उपयोग होता है, लेकिन Apple द्वारा परिभाषित format नहीं है, इसलिए semi-public UTI से जुड़ी पेचीदा स्थितियाँ बनती हैं
  • pasteboard और multiple representations

    • Apple का pasteboard एक dictionary है जो UTI को serialized text या binary data से map करती है
    • Xcode Additional Tools का Clipboard Viewer pasteboard contents को real time में देखने देता है
    • एक single copy action, एक ही data की कई representations एक साथ लिख सकता है
    • कुछ apps backward compatibility के लिए NeXT Rich Text Format v1.0 pasteboard type जैसे legacy non-UTI identifiers भी उपयोग करते हैं
    • editors आमतौर पर वही सबसे rich format चुनते हैं जिसे वे संभाल सकते हैं
    • rich text editor में Paste and Match Style या Paste as Plain Text, pasteboard के plain text format का उपयोग कराते हैं
    • pasted text पर लागू होने वाली style आमतौर पर typing attributes से आती है
    • drag-and-drop भी दूसरे pasteboard के आधार पर काम करता है
    • standard copy-paste के लिए general pasteboard उपयोग होता है, और custom app-to-app interactions के लिए custom pasteboard बनाया जा सकता है
  • RTF और NSAttributedString

    • RTF मूल रूप से NSAttributedString का serialized रूप है, और उल्टा NSAttributedString, RTF का programming interface है
    • TextView, NSAttributedString की child class NSTextStorage पर काम करता है, इसलिए यह pasteboard के साथ मूल रूप से compatible है
    • बिना अलग coding के content को pasteboard पर copy किया जा सकता है
  • Markdown UTI की app-to-app समस्याएँ

    • Markdown editors के बीच copy-paste में, दोनों apps standard protocol लागू करें तब भी समस्या आ सकती है
    • अगर पहला editor Markdown को public.text और rich text representation को public.rtf के रूप में export करे, तो दूसरा editor यह नहीं पहचान पाएगा कि यह native Markdown है और public.rtf चुन सकता है
    • ऐसे में अनावश्यक double conversion होता है, और हर app की Markdown↔RTF conversion शैली अलग होने के कारण अतिरिक्त line breaks जैसी छोटी formatting समस्याएँ पैदा हो सकती हैं
    • Markdown और RTF के बुनियादी style differences भी सामने आ सकते हैं
    • स्वाभाविक behavior के लिए ज़रूरी है कि दोनों apps net.daringfireball.markdown UTI export करें और उसे public.rtf से ऊपर प्राथमिकता दें
    • Paper ने Markdown UTI export करने की कोशिश की, लेकिन लगता है कि दूसरी apps इसे rich text से ऊपर प्राथमिकता नहीं देती थीं
    • Pages, net.daringfireball.markdown को public.rtf से ऊपर प्राथमिकता देता है, लेकिन rich text में बदलने के बजाय मूल Markdown string को वैसा ही insert कर देता है
    • इसी कारण Paper ने Markdown UTI हटा दिया
  • Paper, RTF क्यों देता है और iOS share

    • Paper, rich text editors में स्वाभाविक copy-paste के लिए RTF प्रदान करता है
    • अच्छे OS नागरिक की तरह, copied data को कई formats में उपलब्ध कराना चाहिए ताकि receiving app अपने लिए सबसे rich format चुन सके
    • अगर Paper से Markdown text copy करके Mail app में paste किया जाए, तो वह Markdown markup की तरह नहीं बल्कि सुंदर formatted rich text के रूप में paste होता है
    • iOS का share फीचर copy-paste जैसा है, लेकिन उसमें UI भी जुड़ा होता है
    • iOS share में app कई formats में data export करता है और receiving app अपनी पसंद का format चुनता है
    • pasteboard से अलग, iOS share के top app list में दिखने के लिए app को custom UI वाली share extension स्पष्ट रूप से देनी होती है

1 टिप्पणियां

 
GN⁺ 2024-03-06
Hacker News की राय
  • वाकई शानदार। अब TextKit की शुरुआती सामग्री के लिए https://www.objc.io/issues/5-ios7/getting-to-know-textkit/ से पहले शायद मैं यही लेख देखूँगा

    • iOS 15.0 या उसके बाद और MacOS Monterey या उसके बाद में TextKit 2 देखना चाहिए। https://developer.apple.com/documentation/appkit/textkit/usi... देखें
      यह अभी iOS और MacOS के text fields में डिफ़ॉल्ट रूप से इस्तेमाल होने वाला नया layout engine है, और आगे चलकर संभव है कि यही एकमात्र विकल्प रह जाए
  • TextEdit ऐप लगभग पूरी तरह एक ही TextView से बना है
    Windows की तरफ इसका समकक्ष शायद RichEdit control पर आधारित WordPad है। एक और दिलचस्प बात यह है कि RTF असल में NSAttributedString का serialization format है
    Windows का RichEdit control भी ऐसा ही है, और वास्तव में लगता है कि Windows implementation पहले आई थी: https://en.wikipedia.org/wiki/Rich_Text_Format

  • editing transaction के बाहर decoration attributes को संभालने वाली बात थोड़ी उलझाने वाली लगी। यह व्याख्या थी कि “क्योंकि यह NSTextStorage में नहीं बल्कि NSLayoutManager पर होता है, इसलिए इसे transaction का पता नहीं होता”, लेकिन color जैसी decoration attributes आम तौर पर NSTextStorage में जाती हैं
    क्या लेखक का मतलब है कि Markdown characters पर लगाया गया color, NSLayoutManager के temporary attribute support से संभाला जाता है? आम तौर पर यह spelling error वाले शब्दों को रंगने के लिए इस्तेमाल होता है, तो इसका उद्देश्य क्या है, यह जानना चाहूँगा

    • हाँ। NSTextStorage भी temporary attributes जैसी attributes रख सकता है। TextKit 2 में इन्हें rendering attributes कहा जाता है
      temporary attributes इस्तेमाल करने का फ़ायदा यह है कि NSTextStorage की पूरी transaction को invoke करने की तुलना में बदलाव बहुत तेज़ होते हैं। उदाहरण के लिए Paper में light/dark mode switching बहुत तेज़ है
  • लेख सच में बहुत अच्छा है, और निजी तौर पर भी यह सही समय पर मिला क्योंकि मैं अभी NSTextView के साथ काम कर रहा हूँ
    जानना चाहूँगा कि इस तरह के लेख लिखने लायक जानकारी आपने कैसे जुटाई। क्या यह किसी और के code से आई, दर्दनाक अनुभव से, या developer.apple.com से?

    • मैं 9 साल से Paper पर काम कर रहा हूँ, और उस दौरान पूरे architecture के काम करने के तरीके को समझने के लिए मेरे पास काफ़ी समय था
  • DOM documents के दौर में भी, Notion या GitBook को देखते हुए, text parsing और manipulation में जादुई काम करने हों तो मैं अक्सर फिर से attributed strings पर लौट आता हूँ
    यह सचमुच बहुत elegant structure है, समझ नहीं आता कि यह इतना कम क्यों जाना जाता है। लेख भी अविश्वसनीय रूप से अच्छा है

    • अगर कोई उदाहरण हों तो मैं और सीखना चाहूँगा
    • सोच रहा हूँ कि क्या वेब rich text editor components में से कोई attributed strings का उपयोग करता है। DOM से थक चुका हूँ
  • जिसने कभी text editor को पूरी तरह scratch से बनाने की कोशिश की हो, उसके नज़रिए से देखें तो ऐसा लेख बहुत बड़ा resource होता

  • मैं इस ऐप का सच में बहुत अच्छा उपयोग कर रहा हूँ। इसने Obsidian और iA Writer समेत बाकी सभी Markdown apps की जगह ले ली है

    • Paper नाम ठीक बैठता है, लेकिन अगर मुझे सही याद है तो iOS apps में “Paper” नाम वाले कम से कम दो और apps हैं
    • दिलचस्प। लिखने के लिए मैं मुख्य रूप से वही दो apps इस्तेमाल करता हूँ, इसलिए इसे भी देखना पड़ेगा
  • काश और ज़्यादा iOS components के लिए इस तरह का documentation होता

  • यह देखकर अच्छा लगा कि 2024 में भी कोई न कोई अब भी Cocoa कर रहा है

  • लंबे समय से Android apps develop करने वाले के नज़रिए से, Apple का चीज़ों को थोड़ा अलग और ज़्यादा सोच-समझकर handle करना दिलचस्प लगा
    Android में मूल रूप से layout और rendering से जुड़ा लगभग सारा काम Layout class और उसकी subclasses संभालती हैं, जबकि TextView editing और selection logic का कुछ हिस्सा implement करता है। EditText और TextView के बीच एकमात्र अंतर यह है कि EditText, TextView में पहले से मौजूद editing features को enabled रखता है
    इस कुछ हद तक monolithic approach और कमजोर APIs की समस्या यह है कि जब आप अपने ऐप के text rendering पर ज़्यादा बारीक नियंत्रण चाहते हैं, तब यह रास्ता रोक देती है। उदाहरण के लिए, layout पूरा होने के बाद भी आप अलग-अलग glyphs तक पहुँच नहीं सकते