欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

什么是easyFlow

錢瀠龍2年前25瀏覽0評論

什么是easyFlow?

EasyFlow基本系統(tǒng)介紹 從這一期起開始要介紹easyflow的基本程式,easyflow的基本程式非常的短,很適合用來了解一個排版系統(tǒng)的運作。以后將逐漸的在這個基礎上加入各種不同的功能,希望能以easyflow完成一個簡捷的核心,而使以后的功能都能以TCL巨集的形式出現(xiàn)。 王佑中 使用電腦來做編排版面的工作使得一本書的出版大為簡化,它的頁獻不比發(fā)明活字排版來得低。因為有了電腦我們才得以用更低廉的價格買到書,否則以今日飛漲的人工費用,一本書少說也要千把銀子才買得到吧!但是使用電腦后簡單的連個人都可以直接在電腦前排出一本有模有樣的書了。 使用電腦來排版基本上的概念和人工排版類似,但似有更多的變化。因為我們不再受限於字級,也不再受限於一些機械的格局,我們也更可以很容易的做出更多的特殊效果,如重疊或背景等。我們現(xiàn)在開始看一下easyflow所使用的排版觀念,有適當?shù)牡胤轿視c出easyflow還少了些什麼東西。 EasyFlow的排版觀念 easyflow把文件中每一個元素,包括每一個字、每一張圖、每一個欄框,都看成是一個方塊。所有的這些方塊一個接著一個的被放在紙張上,當一行滿了便放到下一行中,一個欄框滿了便移到下一個欄框中繼續(xù)填入,當一頁中所有各式的欄框都滿了則移到下一頁。 但有些方塊并不加入上述的過程中,它們被顯示在紙面上固定的地方。例如我們經(jīng)常希望插圖被放在紙面的上方,或是在某些特殊的頁上希望在紙張的正中央放入一個圖形。頁次是另一個特殊的例子,我們可能希望它被放在頁底的正中央。這些方塊的位置通常是被使用者,或是某些使用者提供的程式來決定它的實際上在頁面上的位置,而不是像一般文字般由easyflow的排版引擎來決定。 ■排版、固定方塊 所以方塊可大略分成二種,一種是由排版引擎決定其位置的方塊,我稱其為排版方塊。另一種是自行決定或是由TCL巨集決定位置的方塊,我稱其為固定方塊。 固定方塊會出現(xiàn)在其產(chǎn)生時被賦與的位置,而且就在產(chǎn)生它時的頁上。而排版方塊則會依周圍情況的不同而改變其位置,但彼此先后的次序會被維持。也就是說在原始檔中先出現(xiàn)的方塊在排版時也會優(yōu)先決定其位置,而其后的方塊則一定在其后面。如果我們在原始檔中先寫一段文字,然后在這個文字后面插入一個表格,則不論前面的文字如何改,表格永遠處於文字的后面,絕對不會因為在它前面文字做了修改而跑到文字的前面去。 但在排版方塊和固定方塊混合時會產(chǎn)生一個問題,它們可能會重疊在一起。因為固定方塊永遠固定在同一個位置,而排版方塊會一個接著一個的填滿整個版面??傆幸惶焖鼈儠丿B的,如何防止這種情況發(fā)生呢?這當然可以給每一個方塊一個防止疊覆的屬性,但隨著方塊的增加,效率一定會大減,因為我們每加入一個方塊就必須檢查它和所有有防止疊覆屬性的方塊有無重疊。 ■欄框(圖例) easyflow讓使用者自己負責防止重疊,它使用欄框的概念來防止重疊。使用者應負責將可能重疊的固定方塊放在一個被標示為禁止進入的欄框內(nèi)。這種欄框和其它欄框有重疊時,其它欄框在填入方塊時會避過它。中間那個就是標示為禁止進入的欄框,在它所占的位置上是不能放入任何排版方塊的,因為easyflow的排版引擎會避過這個區(qū)域。但固定方塊的位置是由使用者自己決定,所以不受這個欄框存在的影響。 欄框除了上述的功能外,它最主要的用處是把紙面上的文字分成很多塊。我們可以在紙面上定義很多的欄框,每一個欄框都可以獨立的排入各種方塊。這些欄框可以把紙面分成很多不同的方塊區(qū)域,利用上述的禁止進入?yún)^(qū)域甚至可以定義一些不規(guī)則的區(qū)域。我們可以利用欄框定義一個二欄式的文件,也可以在主文中插入一些方塊文章,或是一些后序發(fā)展等小文。 欄框可說是一般分別排版系統(tǒng)和文字列印系統(tǒng)的標準,像倚天等中文系統(tǒng)雖然也可以讓使用者在印列時做很多花樣,但它們沒有欄框,所以不能叫排版系統(tǒng)。easyflow的欄框非常強大,你可以定義不限數(shù)量的欄框,甚至在每一頁都使用不同的欄框。你可定義一個臨時的欄框,當它被填滿后就自動消失。你也可以如上的禁止進入欄框,欄框還可以用來計算某一串文字在填入紙面后所需的高度,透過這種功能你可以做出讓一群文字確定在同一頁的效果。這種欄框就有點像在TeX中的box。(在程式中可以看到,這種欄框有CT_BOX的屬性) ■參數(shù) easyflow提供了很多的參數(shù)讓你控制版面的編排,以后相信還會越來越多。和TeX一樣,easyflow提供了使用者由巨集中更改這些參數(shù)的機會。不同的是easyflow使用TCL做為內(nèi)建的巨集,TCL雖然不像TeX的巨集那麼有彈性,但它卻有更好的可讀性。TCL的語法簡單,不像TeX的巨集令即使是有經(jīng)驗的程式師也望而生畏。easyflow更利用一些可設定為TCL程序的回叫函數(shù)讓使用者能更進一步的控制整個排版的過程,你可以定義一個換頁函數(shù),一但定義后easyflow每當換頁時就呼叫這個函數(shù),你可以在這個函數(shù)中更新頁次,在頁面底部放入表示頁次的文字,或是更新索引和交互參考的索引等。easyflow另外提供了很多的回叫函數(shù)讓使用者在特殊情況發(fā)生時做適當?shù)奶幚怼asyflow甚至提供了區(qū)塊插入函數(shù),你可以每一個方塊插入時取得控制權,如此幾乎沒什麼事不可以做了。 所以構成easyflow的要素就是:●方塊●欄框●TCL巨集●回叫函數(shù)●排版核心●系統(tǒng)參數(shù)下面我將更詳細的講解easyflow的每一個動作。 系統(tǒng)的啟動 你可以想見easyflow在開始時應該做的工作應該是設定所有的系統(tǒng)變數(shù)。在easyflow中使用了非常多的整體變數(shù)來記錄系統(tǒng)的工作狀態(tài),這有點違反模組化的原則,但可能是最簡單的做法,這在后面可以看到,easyflow總是選擇最簡單的做法。 系統(tǒng)變數(shù)啟始的動作都在可分二部份,一部份簡單的變數(shù)在宣告時變給予初始值。而一些較復雜或可由組態(tài)檔中讀入的參數(shù)則在Init()中設定其初始值,當然也有二者均出現(xiàn)的情況,這些初始值保證即使沒有任何體裁檔存在系統(tǒng)也可以正常的運作。 在系統(tǒng)變數(shù)設定完后呼叫InitPage()函數(shù)輸出Postscript的檔頭,它被用來定義一些Postscript巨集以供以后使用。這些程序主要的目的是縮短輸出檔的長度,例如在輸出一個字元A時,我們可能會用:1200 1000 moveto (A) show 在(1200,1000)的地方顯示A這個字元。但我定義了一個程序s來做這件事:(A) 1200 1000s 在檔頭中s的定義為: /s {movetoshow} binddef 如此有二個好處,一是輸出的長度幾乎少了一半,另一個是速度也增加了。因為Postscript只要讀入一個字元s就可以知道要做些什麼事,我們用bind在一開始就讓Postscript把s和movetobind二個函式系結在一起,所以在后面使用時便沒有經(jīng)過解釋器編譯的過程,你可以把它當作己被解釋器編譯成中間碼,就像大多數(shù)解釋器做的一樣。接下來我們就將要進入系統(tǒng)的主回圈。 系統(tǒng)主回圈這個回圈很簡單只有叁行的碼: while(ch=GetChar(currentPage,in)){Page_addOneChar(currentPage,ch);} 它的動作很簡單,就是由先前開啟的輸入檔in中讀入一個字元,然后交給排版引擎排入目前頁中。不過這里的"讀入一個字元"這個動作并不像表面上那麼簡單,easyflow和TeX一樣在讀入的階段就做巨集展開及控制字元解釋的工作。easyflow提供了豐富的控制字元,它可以控制使用的字體及其大小,控制字元間矩、行矩及其它各種的系統(tǒng)變數(shù)。有關這部份的控制都在GetChar()中被處理,它會再呼叫DealWithControlCode來處理有關控制碼的部份。 在GetChar()中只有一個地方值得一提,那就是自動走文模式的設定。所謂自動走文是指無論原始輸入檔每一行的長度如何,easyflow會試圖將每一行填滿,而使每一行的右端盡量對齊。如果你要使一行文字在行的中間便換行,你必須用二個連續(xù)的換行來達到這個目的。 說起來有些復雜,但在實作上很簡單,我們只要忽略換行即可。但我們必須檢查是否有二個連續(xù)的換行存在,因為那代表真正的換行,排版引擎會對換行字元做特殊的處理。以后我將會介紹莎士比亞式的排版規(guī)則,大部份的修改都是在這個函數(shù)中做?,F(xiàn)在我們可以開始進入排版引擎之中了。 排版引擎 這個部份是整個程式的中心,但它也是將來做可能大幅度修改的地方。easyflow的排版規(guī)則目前還很粗糙,它沒有做行的最佳化,它沒有行的對齊模式,它的TCL回叫巨集定義也還不是很清楚,但我相信它在未來一年中將會得到很大的改進。不過即使是現(xiàn)在的狀態(tài),它也已比很多在DOS上自稱是排版系統(tǒng)的程式強多了。 整個排版引擎都在column.c這個檔中,檔案出乎意外的小吧!這也證明了排版程式本身是很簡單的一種程式,事實上即使給人復雜的TeX其排版引擎本身也是數(shù)千行的長度而已,easyflow所做的和TeX其實沒有太大的不同,但少了一些東西。如glue,kern,penalty這些東西,這是因為easyflow沒有行長最佳化的概念,這些東西以后應會加入吧!(雖然在中文中它們的重要性大減) 在column.c中最重要的函式是Page_addOneBlock(),它負責將各種不同的方塊依照它的下列五個參數(shù)決定其x,y座標的位置。 w 方塊的寬度 h 方塊的高度 ws 方塊水平方向的空白 hs 方塊垂直方向上的空白 type 方塊的種類 一個方塊在進入這個函數(shù)之前必須將這五個參數(shù)設定好。不過我們必須注意,只有排版方塊需要由這個函數(shù)來決定其(x,y)位置,固定方塊是不必經(jīng)過這個函數(shù)而是直接使用Page_addBlock將方塊加入紙面上。 在這個檔案中別有一個包裝函數(shù)Page_addOneChar,這是前面主回圈中所使用的函數(shù),它的功用是適當?shù)脑O定字元方塊,并且將它送給Page_addOneBlock去決定文字方塊的位置。這個函數(shù)放在這里當然是有一點錯誤,但這是easyflow發(fā)展過程中留下的結果。 所以現(xiàn)在我們開始來看一下Page_addOneBlock這個函式的動作,這個函式中注解相當?shù)亩?,讀者應該不難了解程式的意義。在這里我先用虛擬碼的方式展示其演算法: if是一個特殊方塊then 直接加入串列中不做其他處理endif if不是一個換行換欄或換頁方塊then 找尋一個可以放入此方塊的位置并設其為現(xiàn)在位置, 當找不到時變設其為欄框的右緣。endif if現(xiàn)在位置無法放入方塊或是遇到一個換行換欄換頁方塊 then將游標移到下一行 if己經(jīng)超過欄框底端then if此欄框不加入自動走文then return endif if不是換欄或換頁方塊then 此時最后一行的方塊應放在下一欄內(nèi),將這些方塊記成oldlist。endif 將欄框參數(shù)設回其初始值將目前欄框設為下一個欄框if找不到可用的下一個欄框或方塊為換頁方塊then 此時應換頁了,首見把頁中所有的方塊用ShipPage函數(shù)輸出至結果檔中。 將頁中的欄框參數(shù)設為最后一欄框的參數(shù) 將所有暫時欄框刪除 用ReadColumnFromStyleFile讀入體裁檔中下一個頁的欄框,如果己無資料則直接使用目前頁的欄框。endif 為新欄框插入一個字型定義方塊將oldlist中的方塊插入新找到的欄框中if不是換行換欄換頁方塊then 將目前方塊插入欄框中endifreturnelse 找到了可以放入方塊的位置后更改方塊資料中的位置參數(shù)后呼叫Page_addBlock將方塊插入。 endif 整個演算法可能還有些缺陷,我希望你可以告訴我你的想法。easyflow還是一個相當年輕的系統(tǒng),我們還有很多的彈性可加入其中。你應該仔細核對一下上面的演算法和實際程式之間的關系,我現(xiàn)在只提出幾乎加以說明。 (1)換行換欄換頁都是以一個方塊的形式出現(xiàn),這是為了在多欄排版時能得到正確的結果。 (2)尋找下一個可能位置的程式是在SearchInALine中,方法很簡單,雖然效率不是十分的好,不過這就是easyflow的哲學。永遠選最簡單的演算法,而不是最有效率的。 (3)當一行文字開始時,其游標位置是在文字的左上角,不過Postscript期望我們把文字放在其基準線上。所以我們把每一個方塊分成二部份,一行的文字可看成 當方塊被插入時其y座標都被放在A處,而當一行結束后會由下列這一段程式: nb=col->firstb;while(nb){/*對非自動走文區(qū)塊,我們不應改變它們的位置*/if(nb->type nb->y-=col->maxHeight;nb=nb->next;} 將所有方塊的y座標移到B處。而下一行的啟始位置則在C。 (4)我們每排完一頁就把所有方塊清出,也就是把所有記憶體釋出,所以能處理的文件大小幾乎沒有限制。 (5)上面演算法中省略了很多的TCL回叫函數(shù)的呼叫。 好了,了解easyflow的排版策略了嗎?很簡單是吧!我們現(xiàn)在就進入一些比較細節(jié)的部份。 Postscript圖形的處理 EasyFlow最令人振奮的功能可能就屬允許Postscript圖形的插入了。因為這意謂著我們可以插入幾乎任何的圖形檔,因為我們有很多免費的圖形轉換程式,如ImageMagic,xv...etc。它們都可以將幾乎市面上可見的所有格式的圖形檔轉成Postscript。不過這個功能的實作出奇的簡單,因為我們原本的輸出檔就是Postscript,所以插人的工作不過就是適當?shù)亩x一個轉換矩陣來縮放這些圖形檔而己。 EasyFlow可以插入二種不同類形的Postscript檔,一種是EPSF檔,一種是PS命令檔。所謂EPSF檔是指一種固定格式的Posrsctipt檔,這種檔中除了一般的Postscript命令外,多了一個所謂結構化注解,這些結構化注解使我們可以很容易的知道這個EPSF檔的大小位置等屬性,我們可以由這些屬性決定如何定義我們的轉換矩陣。 PS命令檔則是指一般的Postscript檔,easyflow處理這二種檔時采用不同的方法。插入一個EPSF檔時easyflow會在插入前先放入一個save命令,則在結束時放入一個restore命令。如 save100100translate0.30.3sacle........restore save是把所有目前的Postscript狀態(tài)備份起來,而restore則是存回先前儲存的狀態(tài)。但在PS命令檔的狀況下就沒有這二個命令了,也不會有第二行的轉換矩陣定義。此時這個插入的檔會影響實際的Postscript狀態(tài),這個命令通常不應被用來直接下達Postscript命令,而是被用來定義一些命令供后面的TCL巨集使用。在以后的文章中會更清楚的看到這一點。 而在EPSF的部份easyflow只使用BoundingBox來決定其大小,BoundingBox有四個參數(shù)。分別是整個圖形的左上角和右下角的位置,由這四個參數(shù)我們可以求得其寬度和高度。如果左上角不在(0,0)而在(x,y),則我們須做一個(-x,-y)的translate使它回到我們想要的點,而easyflow允許用使用者定義一個圖形的小大,所以我們也要用一個scale命令使圖形縮放至指定的大小,整個處理過程都在EPSF.c這個程式中。 這一期就到此為止,我己經(jīng)介紹過大多數(shù)的easyflow程式。剩下的就是TCL巨集的部份了,下一次我將介紹: (1) TCL的語法 (2) 如何為應用程式加上TCL巨集 (3) easyflow中的TCL巨集 (4) easyflow欄框的詳細介紹 (5) easyflow-TCL的簡單應用