瀏覽器是我們最常用的軟件之一,文本又是網頁中最主要的元素,在瀏覽器顯示文本的過程中有許多有趣的細節,值得展開來講講,或許能減少一些誤解。這是一個比較粗略的,概括性的介紹,盡可能不涉及過多的技術細節和具體實現,而立足于給 Web 開發者和設計師提供一些正確的概念。
下面的介紹主要根據我對 WebKit 和 Gecko (Firefox) 的印象來談,其他的瀏覽器也大致相同,如有闕漏之處歡迎指出。
當瀏覽器收到來自 Web 服務器的網頁數據之后,第一步是要把它解碼成可以閱讀的文本,因為歷史原因,不同區域和語言的網頁可能會使用不同的編碼方式,而瀏覽器判斷編碼主要是依據以下方法:
1.Web 服務器返回的 HTTP 頭中的 Content-Type: text/html; charset= 信息,這一般有最高的優先級;
2.網頁本身 meta header 中的 Content-Type 信息的 charset 部分,對于 HTTP 頭未指定編碼或者本地文件,一般是這么判斷;
3.假如前兩條都沒有找到,瀏覽器菜單里一般允許用戶強制指定編碼;
4.部分瀏覽器 (比如 Firefox) 可以選擇編碼自動檢測功能,使用基于統計的方法判斷未定編碼。
編碼確定后,網頁就被解碼成了 Unicode 字符流,可以進行進一步的處理,比如 HTML 解析了,不過我們這里跳過 HTML/XML 解析的細節,單講得到了解析后的文本元素之后該怎么處理。
因為我們得到的文本可能是很多種語言混雜的,里面可能有中文、有英文,它們可能要用不同的字體顯示;也可能有阿拉伯文、希伯來文這種從右到左書寫的文字;也有可能涉及印度系文字這樣涉及復雜布局規則的文字;另外,還可能有網頁內自己指定的文本語言,比如 <span lang="jp">日本語</span> 這樣的標記,使得日文漢字可以使用日文字體顯示 (因為 Han Unification 導致這些漢字和中文里的漢字使用同樣的代碼點,盡管很多寫法不同),"lang" 屬性也可以在 HTTP 頭、<meta> 或者 <html> 出現,用于標記整個文檔的全局語言,通常這是一種好的習慣,方便瀏覽器進行字體匹配。
為了統一處理所有這些復雜的情況,我們要將文本分為由不同語言組成的小段,在有的文本布局引擎里,這個步驟稱為“itemize”,分解后的文本段常被稱作“text run”,但是具體劃分的規則可能根據不同的引擎有所區別,比如 HarfBuzz 和 ICU 一般是根據要使用的不同排版類來劃分 (常稱作“shaper”),比如英語和法語可能使用同一個 shaper 排版,那么相鄰的英語和法語文本就會劃分到同一個 run 里,而希伯來文需要另一個 shaper,就劃分到它自己的 run 里,以 HarfBuzz 為例,它有這樣一些 shaper:
通用的 (適用于中文、英文等等大多數布局規則簡單的語言)
新聞熱點
疑難解答