https://github.com/geometer/FBReaderJ

第十章、epub文件处理 -- 样式处理

这一章的内容比较简单,因为第九章中集中了篇幅介绍显示的流程,所以把处理样式的流程单独列一章来介绍。

对样式的处理包含两个部分:第一是创建样式,第二是应用样式。

创建样式

创建样式的过程其实就是对样式文件的解析。1.0的版本中是直接去读取程序内置的资源文件style.xml,这个文件的位置是在assets\default内。

我们曾在第二章中介绍过如果通过解析资源文件来获得要显示在进度条上的文字。style.xml文件也是资源文件,所以两者在解析的过程中是很相似的。

我们先来回下第二章对解析xml文件的三个核心类ZMLZMLProcessor、ZLXMLParser、ZLXMLReader互相之间调用顺序的描述:

1、ZLXMLReaderAdapter抽象类的子类(ResourceTreeReader类)里面的read方法调用ZLXMLProcessor类的read方法

2、ZLXMLProcessor类的read方法通过AndroidAssetsFile类(ZLResourceFile类的子类)的getInputStream方法获取一个针对资源文件的字节流类(AssetInputStream类),并以这个字节流类为参数初始化了一个针对资源文件的字符流类。接着,就调用了ZLXMLParser类的doIt方法。

3、 ZLXMLParser类的doIt方法利用字符流类将文件转换成一个char数组。再利用for循环迭代char数组的过程中,doIt方法又反过来调用ZLXMLReaderAdapter抽象类的子类(ResourceTreeReader类)的startElementHandler与endElementHandler方法对byte数组中元素所代表的不同节点进行操作。

把上述调用顺序中的标红的TextStyleReader类替换成ResourceTreeReader类,就可以适用于对样式文件的解析流程。

关于解析的顺序我们在第二章以及第六章中已经反复介绍过了,这一章中就不再重复。我们只将注意力放在用for循环迭代char数组的过程对于不同节点的操作。而对于节点的操作都是在TextStyleReader类的startElementHandler方法中完成的。

在style.xml文件中,主要是两种节点:base、style。base节点代表基本样式,而style节点则代表各种标签对应的标签样式。

.xhtml文件中所有的字都会先应用base标签代表的基本样式,然后不同标签内的文本内容会在基本样式的基础上再应用标签对应的样式,标签样式会覆盖基本样式。

TextStyleReader类的startElementHandler方法主要就是针对这两种节点进行操作。

TextStyleReader类的startElementHandler方法

在这个方法中,代码会判断是否有读取到base和style标签。

如果读取到base标签,代码会新建一个ZLTextBaseStyle类来代表基本样式;

如果读取到style标签,代码会新建一个ZLTextFullStyleDecoration类代表特定的标签样式。

标签内的属性都会被一一赋值给ZLTextFullStyleDecoration类的各个属性,其中比较重要的包括:左缩进LeftIndentOption、右缩进RightIndentOption、首行缩进FirstLineIndentDeltaOption、字体类型FontFamilyOption、字体大小FontSizeDeltaOption、字体加粗BoldOption、字体斜体ItalicOption,当然还包括最终的当前标签的名字myName。

新建出来的ZLTextFullStyleDecoration类会以标签的id属性为键名加入ZLTextStyleCollection类myDecorationMap属性指向的数组

当对char数组的for循环完成时,创建样式的流程也就相应完成了。这个流程完成之后,我们会得到一个“代表基本字体样式的ZLTextBaseStyle类”以及“一系列对应代表不同标签样式的ZLTextFullStyleDecoration类”。

应用样式

应用样式的流程会由两个方法组成:ZLTextViewBase类中resetTextStyle方法与applyControl方法。

ZLTextViewBase类resetTextStyle方法

getBaseStyle方法会在ZLTextView类的buildInfos方法中被调用(参考第九章)。

getBaseStyle方法将获取解析样式文件生成的ZLTextBaseStyle类。接着,setTextStyle方法会将代表基本样式的ZLTextBaseStyle类赋值给ZLTextViewBase类的myTextStyle属性。与此同时,字体相关的样式会被存储到ZLTextViewBase类的myContext属性中。

ZLTextViewBase类applyControl方法

applyControl方法会在程序读取到代表标签信息的ZLTextControlElement类时被触发。该方法会首先根据当前ZLTextControlElement类的IsStart属性来会判断当前的这个类对应的是标签对的起始部分还是结束部分。

标签对起始部分

如果当前ZLTextControlElement类对应的是标签对的起始部分,此时,代码会去根据ZLTextControlElement类的Kind属性(该属性的赋值请参考第七章)从ZLTextStyleCollection类myDecorationMap属性指向的数组中获取对应的ZLTextFullStyleDecoration类(102行,参考刚才介绍的创建流程)。

然后,代码会调用ZLTextStyleDecoration类createDecoratedStyle方法(109行),这个方法会根据ZLTextFullStyleDecoration类生成对应的ZLTextFullDecoratedStyle类。

在ZLTextStyleDecoration类createDecoratedStyle方法中,会调用 ZLTextFullDecoratedStyle类的构造函数,在这个函数中,ZLTextFullStyleDecoration类会被存储在ZLTextFullDecoratedStyle类的myFullDecoration属性中(33行)。

(这里要特别注意,ZLTextStyleDecoration类createDecoratedStyle方法还会调用到ZLTextStyle的构造函数,这个构造函数会将已有的ZLTextFullDecoratedStyle类(或者ZLTextBaseStyle类,ZLTextBaseStyle类和ZLTextFullDecoratedStyle类都是ZLTextStyle类的子类)存储到新建的ZLTextFullDecoratedStyle的Base属性。)

最终,在ZLTextViewBase类的setTextStyle方法中,当前的ZLTextBaseStyle类或ZLTextFullDecoratedStyle类被存储在了ZLTextViewBase类的myTextStyle属性,字体相关的样式被存储到ZLTextViewBase类的myContext属性中。

标签对结束部分

如果当前ZLTextControlElement类对应的是标签对的结束部分,此时,代码就会样式还原到ZLTextFullDecoratedStyle类的Base属性指向的旧的ZLTextFullDecoratedStyle类。

applyControl方法在标签对的起始部分与结束部分中分别对ZLTextFullDecoratedStyle类Base属性的操作构成了一种层级存储的结构(这种存储结构与第二章中介绍的利用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属性中取出基本样式。至此为止,代码又开始恢复应用基本样式了。

第十章、epub文件处理 -- 样式处理相关推荐

  1. Linux系统上用Sigil创建和编辑 EPUB 文件

    Sigil 是一个开源的 Linux.Windows 和 MacOS 上的 EPUB 编辑器.你可以使用 Sigil 创建一个新的 EPUB 格式的电子书,或编辑现有的 EPUB 电子书(以 .epu ...

  2. 第四章、epub文件处理 -- epub文件内部组成

    2019独角兽企业重金招聘Python工程师标准>>> 第四章.epub文件处理 -- epub文件内部组成 第三章的结尾,我们说到从FBReaderApp类的openBookInt ...

  3. epub文件打开乱码_什么是EPUB文件(以及如何打开一个文件)?

    epub文件打开乱码 A file with the .epub file extension is a popular file format used for storing eBooks and ...

  4. jQueryMobile引入文件后样式无法正常显示

    jQueryMobile引入文件后样式无法正常显示解决方法: jQuery文件必须放在jQueryMobile文件之前 eg: 转载于:https://www.cnblogs.com/yingww/p ...

  5. 第六章、epub文件处理 -- 解析container文件与.opf文件

    2019独角兽企业重金招聘Python工程师标准>>> 第六章.epub文件处理 -- 解析container文件与.opf文件 这一章我们会接着第三章结尾介绍的FBReaderAp ...

  6. epublib java_使用Epublib处理epub文件 | 学步园

    通过wlw发布在我的博客funba.cn 希望csdn能重新支持wlw Epublib是一个用于处理epub文件的java类库,可以对epub文件进行读写处理:而且提供了一个阅读器,可以直接运行(ja ...

  7. epub文件是什么文件?如何在windows系统上打开?

    我们在电脑上下载小说.书本时,经常遇到epub格式的文件.其实,EPUB是一种电子文档格式. 如同word txt pdf一样可以承载很多文字信息.但在这种格式中,使用了不同的开放标准.区别在于,EP ...

  8. epub文件是什么文件?如何用安卓手机打开?

    大家在查找资料时,越来越多的遇见epub格式了.其实EPUB是一种电子文档格式, 如同word txt pdf一样可以承载很多文字信息.但在这种格式中,使用了不同的开放标准.区别在于,EPub文件属于 ...

  9. 使用Epub.js打开本地Epub文件

    使用Epub.js打开本地Epub文件 1. 导入epubjs:下载地址:https://github.com/futurepress/epub.js/ 2. 辅助工具jszip:是一个用于创建.读取 ...

最新文章

  1. Origin对于标注点
  2. 试求由a,b,c三个字母组成的n位符号串中不出现aa图像的符号串的数目
  3. c++ vector嵌套传参
  4. 微信小程序数据拼接_微信小程序用户数据解密算法Java版
  5. 聊聊spring cloud gateway的SecureHeadersGatewayFilter
  6. 5G NR SRS (R15)
  7. JVM系列之:从汇编角度分析Volatile
  8. Sharepoint COMException 0x81020037
  9. 第三方服务-阿里云视频点播服务java服务端SDK相关代码
  10. VS2010中的顺序图
  11. SpringBoot AOP 理解和用途
  12. 并发编程(六)并发容器
  13. 模糊PID控制算法 之 C语言实现
  14. Java 小游戏(骑士大战魔王)
  15. 一次关于聚合根的激烈讨论
  16. 如何用python爬取抖音视频列表
  17. React的消息订阅全过程
  18. 好友返利网站开发 二
  19. 有什么方法可以免费查重呢?
  20. 超厉害的CSS3图片破碎爆炸效果!

热门文章

  1. 影视/动漫 短视频专栏来啦!
  2. 现代诗一首 怀念。。。
  3. PEST分析顺丰服务需求_快递行业宏观环境分析
  4. win 10 亮度调节不能使用了
  5. 怎么接受对方tp_恋爱关系中怎么和回避型有效沟通
  6. “中国无人车第一案”出现神转折:景驰为何“投诚”百度?
  7. 【新知实验室-TRTC开发】实时音视频之集美真心话
  8. 使用pyautogui和inspect快速准确定位鼠标位置
  9. [cocos2dx]基于Cocos2d-x引擎的游戏框架设计
  10. SDK emulator directory is missing | Android Studio报错