第十章、epub文件處理 -- 樣式處理

第十章、epub文件處理 -- 樣式處理


這一章的內容比較簡單,由於第九章中集中了篇幅介紹顯示的流程,因此把處理樣式的流程單獨列一章來介紹。 html

對樣式的處理包含兩個部分:第一是建立樣式,第二是應用樣式。 數組


建立樣式

建立樣式的過程其實就是對樣式文件的解析。1.0的版本中是直接去讀取程序內置的資源文件style.xml,這個文件的位置是在assets\default內。 app

咱們曾在第二章中介紹過若是經過解析資源文件來得到要顯示在進度條上的文字。style.xml文件也是資源文件,因此二者在解析的過程當中是很類似的。 函數

咱們先來回下第二章對解析xml文件的三個核心類ZMLZMLProcessorZLXMLParserZLXMLReader互相之間調用順序的描述: 字體

1ZLXMLReaderAdapter抽象類的子類ResourceTreeReader類)裏面的read方法調用ZLXMLProcessor類的read方法 ui

2ZLXMLProcessor類的read方法經過AndroidAssetsFile類(ZLResourceFile類的子類)的getInputStream方法獲取一個針對資源文件的字節流類(AssetInputStream類),並以這個字節流類爲參數初始化了一個針對資源文件的字符流類。接着,就調用了ZLXMLParser類的doIt方法。 spa

3、 ZLXMLParser類的doIt方法利用字符流類將文件轉換成一個char數組。再利用for循環迭代char數組的過程當中,doIt方法又反過來調用ZLXMLReaderAdapter抽象類的子類ResourceTreeReader類)startElementHandlerendElementHandler方法對byte數組中元素所表明的不一樣節點進行操做。 xml

把上述調用順序中的標紅的TextStyleReader類替換成ResourceTreeReader類,就能夠適用於對樣式文件的解析流程。 htm

關於解析的順序咱們在第二章以及第六章中已經反覆介紹過了,這一章中就再也不重複。咱們只將注意力放在用for循環迭代char數組的過程對於不一樣節點的操做。而對於節點的操做都是在TextStyleReader類的startElementHandler方法中完成的。 資源

style.xml文件中,主要是兩種節點:basestylebase節點表明基本樣式,而style節點則表明各類標籤對應的標籤樣式。

.xhtml文件中全部的字都會先應用base標籤表明的基本樣式,而後不一樣標籤內的文本內容會在基本樣式的基礎上再應用標籤對應的樣式,標籤樣式會覆蓋基本樣式。

TextStyleReader類的startElementHandler方法主要就是針對這兩種節點進行操做。


TextStyleReader類的startElementHandler方法

在這個方法中,代碼會判斷是否有讀取到basestyle標籤。

若是讀取到base標籤,代碼會新建一個ZLTextBaseStyle類來表明基本樣式;

若是讀取到style標籤,代碼會新建一個ZLTextFullStyleDecoration類表明特定的標籤樣式。

 

標籤內的屬性都會被一一賦值給ZLTextFullStyleDecoration類的各個屬性,其中比較重要的包括:左縮進LeftIndentOption、右縮進RightIndentOption、首行縮進FirstLineIndentDeltaOption、字體類型FontFamilyOption、字體大小FontSizeDeltaOption、字體加粗BoldOption、字體斜體ItalicOption,固然還包括最終的當前標籤的名字myName

新建出來的ZLTextFullStyleDecoration類會以標籤的id屬性爲鍵名加入ZLTextStyleCollectionmyDecorationMap屬性指向的數組

 

當對char數組的for循環完成時,建立樣式的流程也就相應完成了。這個流程完成以後,咱們會獲得一個「表明基本字體樣式的ZLTextBaseStyle類」以及「一系列對應表明不一樣標籤樣式的ZLTextFullStyleDecoration類」。


應用樣式

應用樣式的流程會由兩個方法組成:ZLTextViewBase類中resetTextStyle方法與applyControl方法。

ZLTextViewBaseresetTextStyle方法

getBaseStyle方法會在ZLTextView類的buildInfos方法中被調用(參考第九章)。

 

getBaseStyle方法將獲取解析樣式文件生成的ZLTextBaseStyle類。接着,setTextStyle方法會將表明基本樣式的ZLTextBaseStyle類賦值給ZLTextViewBase類的myTextStyle屬性。與此同時,字體相關的樣式會被存儲到ZLTextViewBase類的myContext屬性中。

 

ZLTextViewBaseapplyControl方法

applyControl方法會在程序讀取到表明標籤信息的ZLTextControlElement類時被觸發。該方法會首先根據當前ZLTextControlElement類的IsStart屬性來會判斷當前的這個類對應的是標籤對的起始部分仍是結束部分。

標籤對起始部分

若是當前ZLTextControlElement類對應的是標籤對的起始部分,此時,代碼會去根據ZLTextControlElement類的Kind屬性(該屬性的賦值請參考第七章)從ZLTextStyleCollectionmyDecorationMap屬性指向的數組中獲取對應的ZLTextFullStyleDecoration類(102行,參考剛纔介紹的建立流程)。

 

而後,代碼會調用ZLTextStyleDecorationcreateDecoratedStyle方法(109行),這個方法會根據ZLTextFullStyleDecoration類生成對應的ZLTextFullDecoratedStyle類。

ZLTextStyleDecorationcreateDecoratedStyle方法中,會調用 ZLTextFullDecoratedStyle類的構造函數,在這個函數中,ZLTextFullStyleDecoration類會被存儲在ZLTextFullDecoratedStyle類的myFullDecoration屬性中(33行)。

        (這裏要特別注意,ZLTextStyleDecorationcreateDecoratedStyle方法還會調用到ZLTextStyle的構造函數,這個構造函數會將已有的ZLTextFullDecoratedStyle類(或者ZLTextBaseStyle類,ZLTextBaseStyle類和ZLTextFullDecoratedStyle類都是ZLTextStyle類的子類)存儲到新建的ZLTextFullDecoratedStyleBase屬性。)

        

最終,在ZLTextViewBase類的setTextStyle方法中,當前的ZLTextBaseStyle類或ZLTextFullDecoratedStyle類被存儲在了ZLTextViewBase類的myTextStyle屬性,字體相關的樣式被存儲到ZLTextViewBase類的myContext屬性中。


標籤對結束部分

若是當前ZLTextControlElement類對應的是標籤對的結束部分,此時,代碼就會樣式還原到ZLTextFullDecoratedStyle類的Base屬性指向的舊的ZLTextFullDecoratedStyle類。


applyControl方法在標籤對的起始部分與結束部分中分別對ZLTextFullDecoratedStyleBase屬性的操做構成了一種層級存儲的結構(這種存儲結構與第二章中介紹的利用ZLTreeResource類的myChildren屬性構成存儲結構是很相似的,能夠互相參考)。

咱們能夠用B標籤做爲例子,來看下這種層級存儲結構有着怎樣的做用。下圖中,咱們能夠看到「暫名」兩個字是B標籤內的內容。


當代碼讀到B標籤以前的內容時,一直都在應用基本樣式(ZLTextBaseStyle),一旦讀到B標籤的起始部分,就會開始新建一個B標籤的樣式(ZLTextFullDecoratedStyle類),並覆蓋掉基本樣式,於此同時,代碼會將基本樣式(ZLTextBaseStyle)存儲到B標籤樣式(ZLTextFullDecoratedStyle類)的Base屬性中。在代碼讀取到B標籤的結束部分以前,一直會應用B標籤的樣式。一旦讀到B標籤的結束部分,就會從B標籤樣式(ZLTextFullDecoratedStyle類)的Base屬性中中取出基本樣式(ZLTextBaseStyle)。而後又開始應用基本樣式。

相似的例子還有H1標籤。在顯示流程以前,H1標籤會被轉化爲這樣的格式:「表明P標籤起始部分的ZLTextControlElement類 表明P標籤起始部分的ZLTextControlElement類 + P標籤內的文本內容 表明P標籤結束部分的ZLTextControlElement類 表明P標籤結束部分的ZLTextControlElement類」(請參考第七章中對相關流程的介紹)。

當代碼在讀取帶P標籤的起始部分以前,都在應用基本樣式。一旦讀到P標籤的起始部分,代碼就會新建一個P標籤樣式覆蓋掉基本樣式,並將基本樣式存儲到P標籤樣式的Base屬性。接着,程序又讀取到H1標籤的起始部分,此時又會新建一個H1標籤樣式覆蓋掉P標籤樣式,並將P標籤樣式存儲到H1標籤樣式的Base屬性。當代碼讀取到H1標籤內的文本內容時,會一直應用H1標籤的樣式。以後,一旦代碼讀取到H1標籤的結束部分,就會從H1標籤樣式的Base屬性中取出P標籤樣式,以後代碼又讀到P標籤的結束部分,又從P標籤樣式的Base屬性中取出基本樣式。至此爲止,代碼又開始恢復應用基本樣式了。

相關文章
相關標籤/搜索