DVI:TeX的原生輸出格式
在之前的文章里面,我提到過我現(xiàn)在對于DVI和PDF的看法。DVI的優(yōu)勢突然就顯現(xiàn)出來了:簡單,簡潔。但是缺點(diǎn)是缺乏標(biāo)準(zhǔn)化,或者不存在一個(gè)委員會(huì)。歷史上,這個(gè)委員會(huì)曾經(jīng)存在過,但是最后沒形成影響力。
因?yàn)椋河绊懥@種事情既需要文本,又需要執(zhí)行力。
對于之前提到過的PDF標(biāo)準(zhǔn)落后于其他標(biāo)準(zhǔn)的問題,做私有方案不是不可以的。比如說,我以前在某家電商公司,做電子書app(不要吐槽),就碰到了這種做法。
需求是什么呢?保證PDF只能在自己的app端上能看。他們的某一代程序員(2014年以前的)的做法就是實(shí)現(xiàn)了一個(gè)新的filter類型。這個(gè)filter我之前介紹過,壓縮,或者加密,都算是filter。他們就創(chuàng)造了一套不在PDF標(biāo)準(zhǔn)中的filter類型。
結(jié)果確實(shí)是只能在這個(gè)app上看。在Adobe Acrobat上看,就會(huì)顯示一個(gè)個(gè)的空白頁。在其他的閱讀器上,幾乎也是這個(gè)結(jié)果。當(dāng)然,不保證這一點(diǎn)在特定的PDF庫上也是如此的。
現(xiàn)在,iOS上的一些PDF筆記軟件,大多數(shù)還是把筆記層獨(dú)立保存的。保存到PDF中其實(shí)也沒那么難。做起來就有兩種方案了。一種是轉(zhuǎn)換成PDF定義的那些annotation類型,但是這種做法,可能會(huì)損失一些特定的風(fēng)格。另一種是,以PDF的Objects形式保存到PDF中,這就會(huì)保證只能在這種軟件上顯示正確,在其他的軟件上幾乎不顯示。
上面的第二種做法,沒有任何問題,因?yàn)椋篈dobe的InDesign軟件就是這么做的,它那個(gè)文件是.ai為結(jié)尾的,但是本質(zhì)上就是PDF文件,只不過加了一些只能他們自己解析的Objects。
回到DVI上的話題上。在PDF上能這樣搞,其實(shí)在DVI上做就更簡單。簡單到,想怎么弄就怎么弄。嵌入字體?可以,放special里面。加壓縮方案?可以,zstd都沒什么問題。
DVI文件,是byte流,能切分成各種具有語義的command。這些command基本上就是在控制繪制操作。

從寫代碼解析DVI到相應(yīng)的數(shù)據(jù)結(jié)構(gòu)上看,基本上200行代碼就夠用了。解析完甚至可以保存成JSON或YAML格式。涉及到具體的繪制,我嘗試過Qt的Painter,cairo,Android的Canvas,iOS的CoreGraphics,都是很簡單的。不過,對于很多人來說還有一個(gè)隱含著的問題:這個(gè)簡單,是建立在了解字體格式的前提下的。
DVI配合的字體,最早就是METAFONT生成的GF格式文件。這是一個(gè)存粹的位圖格式。在這呢,不要拿現(xiàn)在的看法來理解這種位圖格式:因?yàn)镸ETAFONT生成GF格式的時(shí)候是可以調(diào)整分辨率的。這個(gè)要不理解,就會(huì)認(rèn)為DVI輸出用的位圖字體是很爛的玩意。
不過GF的文件尺寸比較大,后來就誕生了PK格式。PK格式采取了一種壓縮方案:將重復(fù)的行用run-length壓縮。比如:

不過,隨著80年代PostScript在商業(yè)上的成功,社區(qū)開始對于Type 1格式有了一定的需求。社區(qū)的一些DVI軟件開始使用Type 1來生成PostScript文件。不過,這也不意味著,GF和PK的消失:它們以PostScript繪制指令的形式被保存到了PostScript文件里。
而到了九十年代,PDF出現(xiàn),Type 1依然能夠使用,GF和PK就被轉(zhuǎn)換成Type 3格式:一種略微簡單一些的數(shù)據(jù)形式的字體描述。
在后來,就是TrueType和OpenType之類的字體了。
除了格式支持外,還有映射的問題。比如我們知道原生的TeX只支持8位的字體,那么如果想要輸出中文,可能就需要把字體信息拆成十幾個(gè)TFM文件,告訴TeX每個(gè)字的基本信息。但是輸出到DVI的時(shí)候,又得知道某一組TFM文件,其實(shí)是對應(yīng)單獨(dú)的某一個(gè)字體的。
相反的情況也存在,比如說某些字體,原生幾十個(gè)(wadalab造出來的那些字體),在pTeX中使用,可能就是一個(gè)TFM文件,輸出的時(shí)候,需要映射到幾十個(gè)文件上。
我這說著簡單一些,但是,這些東西可真是大坑套小坑。昨天,讀Fonts & Encodings讀到了一段文本,我就釋然了:
我倒也不是說我把OpenType/TrueType的東西全弄明白了,比如說Variable Font的部分是我司某同事做的,以及TrueType的Instructions部分我就還沒做完(雖然確實(shí)很簡單,就是一堆極坐標(biāo)的玩法)。
和字體比起來,我覺得圖像格式的支持就顯得比較無趣,直接接入特定的庫就好了。字體這東西的難點(diǎn)在于,它很基礎(chǔ),細(xì)節(jié)多,想要在跨平臺(tái)的時(shí)候保持一致性,就得使用同一套等效的代碼。