浅谈百度阅读/文库na端排版技术

百度Geek说      2022-02-17     236

关键词:

导读:当前主流的排版引擎:Gecko、Blink、Trident、Webkit/Webcore等等,虽然能实现基本的图、文排版需求,但对于复杂的版面,特别是图书类文档的排版,无法实现或者实现起来非常困难,同时排版效果不够专业,为此百度文库/百度阅读开发了一套跨平台的排版引擎。本文期望通过排版引擎的相关技术介绍,向大家展示图书(内容)排版方面的一些实现技术、技巧。

全文3680字,预计阅读时间12分钟。

一、背景

百度文库是百度旗下的在线互动式文档分享平台,在这里,用户上传、分享自己的文档,搜索、阅读、下载其他用户的文档。

在2013年后,百度文库为了满足用户在手机端阅读文档、图书资源的需要,先后推出了百度阅读app、百度文库app,期望通过精致的、专业的排版、原生的端阅读体验,打造一款小而美的阅读类app,其核心是排版引擎的实现,本文希望通过百度阅读/文库排版引擎的相关技术,向大家介绍图书(内容)排版方面的一些实现技术。

二、技术选型

在设计排版引擎之初设定了以下几个目标:

  • Android、IOS两端采用同一套排版引擎排版,两端展示效果一致,提升开发效率;

  • 采用图书印刷行业的排版标准,实现图书专业级排版;

  • 支持个性化阅读体验、复杂排版效果的快速迭代;

  • 原生的端阅读体验,排版引擎包尽可能小;

市场上主流的几个排版引擎:Gecko、Blink、Trident、Webkit/Webcore,它们虽然能实现基本的图、文排版需求,但对于复杂的版面,比如文本框竖排标题、绕排等效果,无法实现或者实现起来非常困难;同时排版效果不够专业,不能满足未来排版效果的快速迭代,因此百度阅读决定自己实现跨平台的排版引擎。

三、技术架构

3.1 整体架构

图1 百度阅读/文库排版引擎架构图

排版引擎主要由四部分构成,分别是:

Control/Interface模块:它接受外部传过来的内容,并调起、管理排版,同时排版完成后把排版结果以指令形式回传给显示层进行渲染;

Parser模块:用户阅读的内容格式是多种多样的,它可能是epub、txt、docx,也可能是各自业务线自定义的格式,针对各种格式通过parser模块统一映射到自定义的DOM树上,后续排版只需要针对这个DOM树进行处理即可,这样可提升开发效率,同时也方便未来快速扩展到更多的格式上去。

自定义的DOM树参考的是ooxml结构描述,并在此基础上进行了简化,改造,DOM树基本结构如下:

图2 抽象DOM树结构

这其中CBox节点是一个虚节点,它可能是一个字符,也可能是一个片断、一个对象,比如文本框、数学公式、拼音结构等等。它可以具有与CDoc节点相似的结构,支持无穷嵌套,从而实现对各种复杂结构的描述。

Layout模块:读取DOM树结构,遍历节点,结合版面大小,并运用各种排版规则,把文字、内容、对象布局到显示区域,结果输出成LDF。

这部分是整个排版引擎主要技术所在,后面会详细介绍。

LDF模块:排版结果描述结构。

排版引擎排完一页内容后,并没有调用绘制指令,直接绘制显示,而是输出成LDF数据,缓存在内存中管理。这么处理是出于两个方面的考虑:一是性能和内存考虑,用户在阅读当前页时,排版引擎会在后台把它前、后几页内容进行排版,缓存,在用户翻页时异步绘制;二是提供交互操作需要的数据基础,它在LDF上进行区域、数据计算,快速定位到指定的节点,提取相应的内容。

当然提前准备多少页排版结果,提前预绘多少页,可由各自业务依据自身需要和设备情况进行动态设置,以达到最优的阅读体验效果。

LDF数据结构更多的倾向于版面描述,其结构如下:

图3 LDF结构

LDF数据定义涵盖了版面的所有元素,包括页、块、分栏、段落、行、内容片断,通过嵌套实现各种复杂效果展示。

3.2 主要技术

排版过程涉及到很多技术细节和处理技巧,比如glyph处理、标点禁则、行拉压对齐处理、块排版等等,本文阐述几个主要的排版技术,其它技术、处理技巧可参考开源的排版引擎,它们在很多细节处理技术上是相通、相似的。

3.2.1 基本排版

排版过程可简单理解成把文档逻辑结构(DOM树)通过一些技术手段映射成版面结构(LDF),排版过程涉及到文档逻辑结构和版面结构,基本排版处理包括:

  • 段落排版(para_layout)

段落排版处理段落属性,比如段前距、段后距、段首缩进、段落悬挂等等,并调用行排版。

  • 行排版(line_layout)

内容最终在显示时,展现的是一行行内容,它是排版中常用的一个处理,其它排版引擎均提供了行排版的接口。

行排版处理行间距等属性,并调用片断排版,排版完成后依据段落对齐属性进行x方向的调整和y方向对齐调整。

  • 片断排版(section_layout)

在某些效果下,一行内容是由多个小区域组成,比如文字两端绕排图片,文字阅读顺序设定为通栏从左到右,此时一行是由图片两边两个片断组成,在选中内容时光标走位是穿过图片选中两端文字。

片断排版计算当前片断可排区域、传递段落、内容属性,并调用对象排版。

  • 对象排版(obj_layout)

对象排版是排版引擎的基本单元,它包括字符排版、结构排版,它依据对象的属性、类型进行特定的、分别的处理。

3.2.2 复用与抽象

(对象)内容的类型有很多种,从普通的中英文字符到数学公式、拼音结构、块结构等等,甚至对象嵌套对象,这就需要排版引擎对所有的对象进行抽象,通过递归调用、基础的排版处理复用,实现各类复杂效果的实现。

复杂对象,从结构上来看,它是由一段或多段内容组成,在这个意义上,它可以理解成CDoc节点,即它是一个子文档(而对于对象嵌套对象结构,可以理解成子文档嵌套子文档),通过数据结构抽象,从而实现的排版的复用。

一个对象的排版,即子文档在子区域内的排版,它同样经过基本的段落、行、片断、内容排版,并依据对象进行特定的位置修正(比如拼音排版,上下两个子盒子分别排版,y方向位置调整,x方向居中对齐),最终实现对象的排版。

3.2.3 相对排版

排版最终结果就是把字符、图元或图片定位到屏幕指定位置,即给内容赋予x/y坐标值,在处理纯文字内容的排版时,非常简单,排完一个字符,计算下一个字符的x坐标,依此类推,直到当前行排不下内容为止。

但对于复杂结构又该如何处理了?以数学公式为例,它是一2X2矩阵,其中第一个元素是一个二次公式。

首先排第一个元素,此时排版引擎不用关注该元素入口的x/y坐标是多少,而是采用相对原点坐标(0,0)排版这个二次公式。

但这个二次公式又是由分子、分母组成,在排版分子、分母时,依旧采取相对排版原则,从(0,0)坐标原点开始排版,分别得到分子、分母排版结果,此时把分子和分母排版结果分别当作一个黑块,依据上下分式排版规则,调整分子、分母,使之中线对齐、上下位置合适。

调整完二次公式后,把它的排版结果当作一个黑块,参与到矩阵排版和位置调整中,此时二次公式内部内容相对位置不再变化。

相对位置排版,即每个子对象先不用关注入口位置坐标,而采用相对原点坐标进行排版,排版完成后依据对象特点、入口坐标信息,调用correct_xy,统一修正x/y坐标,一层层递归,最终实现复杂对象和整页的排版。

3.2.4 多方向排版

不同语言有着不同的排版方向,比如汉字是正向横排,古籍书是反向竖排,蒙文正向竖排,维文是反向横排,如何统一这些排版,从而支持所有语言排版?

先来看下反向模排,下图是模拟了正向横排和反向横排的效果图:

图4 正、反向横排效果图

从上图可以看出,反向横排其实就是正向横排相对于版心中轴线的镜像,理解了这一点,反向横排就变成了正向横排完后再做一次x坐标镜像处理,至于正向竖排、反向竖排也可以采用类似方式处理,甚至在排版层不处理,而在绘制时做坐标矩阵转换。当然各语言有各自的特点,细节可能需要微调下。

四、总结和展望

图5 效果展示

百度阅读/文库排版引擎未来发展的方向:

  • 依据内容以及属性,精准的排出指定的效果,支持更多对象的排版,并不断完善排版标准和体验;

  • 理解内容,理解设备,智能排版,提供更佳的阅读体验;

比如对于期刊类文档,摘要、关键词可采用不同的字体、字号,设置一定的段左、右距排版。

比如对于大屏显示和图文绕排内容,图片尽可能排到九宫位置,而对于小屏,动态调整图片尺寸,甚至取消图文绕排等等。

各排版引擎本质上区别不大,没有好坏之分,百度阅读/文库自研排版引擎更多的是出于自身业务需要,所用到的排版技术既有通用性,也有自己的特点,文章的目的是一起探索排版底层的技术,一起去挖掘排版技术的发展。

推荐阅读:

|百度短视频推荐系统的目标设计

百度信誉认证中台架构解析

图数据库在百度汉语中的应用

一年数十万次实验背后的架构与数据科学

---------- END ----------

百度Geek说

百度官方技术公众号上线啦!

技术干货 · 行业资讯 · 线上沙龙 · 行业大会

招聘信息 · 内推信息 · 技术书籍 · 百度周边

欢迎各位同学关注

仿百度文库,在线文库网站制作,文库网站定制

我们的优势:支持主流文件格式:doc、docx、ppt、xls、txt、pdf等网页单点批量上传:可在网页WEB端单个,或批量文件上传操作新一代建站技术-多屏适配:电脑/平板/手机/微信站一步到位多种支付方式:支持支付宝、微信、银联等... 查看详情

好用的百度文库下载工具:易读

 有时侯想把百度文库上的文档下载到本地阅读,但是提示需要下载分值,如果没有分值,则下载不了。现在有了易读就可以解决这个问题: 把对应的文档的url复制到易读对应的url框中,几秒后,它会自动把相应的文档下... 查看详情

如何在网上直接打开word文档,不用下载

网上直接打开Word文档的方法:将文档上传至百度云、百度文库等;浏览器上面打开百度云或者百度文库,然后点击Word文档即可打开。参考技术A在网上比如某个网站的附带的文件可以下载,如果是word格式,在点击下载后,有一... 查看详情

类似百度文库在线预览文件内容技术探讨

 类似百度文库之类的控件如何实现?也就是不管什么类型的文件上传后,都可以预览,而不管客户端浏览器是否安装有对应的软件。  由于项目需要,也需要一个类似的功能,于是自己也翻阅了相关资料。... 查看详情

百度文库里读取word文档的技术是怎么做的要具体的代码

参考技术A用php调用openoffice转换成pdf;用php调用pdf2swf.exe生成swf格式;swf格式就是动画格式;就可以用flexpaper读取出来;显示出文库的界面;、至于代码;木有!!1 参考技术B是视频格式的,一般你上传的文档客服先给做成视频格... 查看详情

移动端重排版pdf阅读器比较

小白PDF阅读器是一款能自动重排PDF页面的移动端阅读器,能给用户在移动端阅读PDF文档时带来更好的体验。PDF是一种跨操作系统平台的电子文件格式,它能在各种不同的平台上以相同的版式显示。很多扫描书籍或者电子书籍都会... 查看详情

dedecms如何实现上传的docppt文档在线阅览,就像百度文库一样。

参考技术A需要在webconfigure服务器配置文件里配置好像 查看详情

百度文库下载

文库下载在baidu的后面加vvv直接回车即可进入解析界面 查看详情

百度文库下载器v2.3.4.3支持豆丁百度文库道客巴巴

支持豆丁百度文库道客巴巴免下载劵财富值导出word下载地址:http://pan.baidu.com/s/1qYCmQde  查看详情

百度文库免费下载

百度文库远程代下系统,免下载券。授权码:kk9988网址:  http://120.77.53.50:8888/本文出自“51CTO张省博客”博客,谢绝转载! 查看详情

实战操作百度文库百度经验营销,让您的“流量”稳居首页

  其实百度系列的产品,一直是做营销的首选,但近来百度在出现不断的“地震”,什么则西事件,数据事件,但依然也撼动不了他中文搜索引擎行业“霸主”的地位,而对于营销者来说百度文库/经验,一直是获取百度流量... 查看详情

浅谈基于web的跨平台桌面应用开发

近些年来,跨平台跨端一直是比较热门的话题,因为跨平台方案的优势十分明显。对于开发者而言,可以做到一次开发,多端复用,一套代码就能够运行在不同设备上,今天我们聊聊桌面应用开发。作者:京东物流王泽知近些年... 查看详情

分享免费下载百度文库在线网站

 分享免费下载百度文库在线网站1  VVV文档在线导出工具  http://wenku.baiduvvv.com/doc/ 查看详情

浅谈基于web的跨平台桌面应用开发

作者:京东物流王泽知近些年来,跨平台跨端一直是比较热门的话题,Writeonce,runanywhere,一直是我们开发者所期望的,跨平台方案的优势十分明显,对于开发者而言,可以做到一次开发,多端复用,一套代码就能够运行在不同设... 查看详情

浅谈服务端渲染

最近在把一个c端的项目重构成首屏服务端渲染(SSR:serversiderender)项目用到的技术:React、webpack、koa2、webpack对于重构成SSR,redux并不是必须的,所以没用redux本篇文章先讲述一些理论的东西,之后会写代码篇一、什么是服务端... 查看详情

浅谈cauchy不等式

形式[sum_i=1^na_i^2sum_i=1^nb_i^2geqsum_i=1^na_i^2b_i^2]等号成立的条件:[iff:b_i=0||existskinmathbbR,a_i=kcdotb_i(iinmathbbN^+)]证明法一:参数配方思路:巧妙的把常数与方程结合起来,利用性质即可。证明:构造函数:[f(t)=sum_i=1^nb_i^2cdott^2-2sum_i=1^na_i... 查看详情

百度文库爬虫

FreeForWenku免费下载百度文库收费资料,支持关键字搜索,以及url批量爬取。目前本项目仅对原项目的doc、txt爬取优化,其余的待完成优化。项目地址:whxf/FreeForWenku声明:本项目fork自Lz1y/FreeForWenku。对原有项目进行优化,添加支... 查看详情

浅谈非法外联检测技术的演变

针对隔离内网,非法外联因其危害巨大,一直都是网络边界完整性防护的重中之重。早期非法外联主要是指以电话拨号为主的私自连接互联网的行为,早期电话拨号还是非常方便的,如163拨号,263拨号等,只要有电话线,就可以... 查看详情