前段时间一直在研究在浏览器中预览PDF文档并对其进行相关的操作。其中研究了PDF.js(详情请看我的PDF.js系列的文章);这里来研究使用MuPDF构建一个Web应用程序并编写自己的自定义UI。在页面中可以滚动浏览文档,它将在页面进入视图时呈现页面。也可以更改缩放级别,按照页面上和目录中的链接进行操作。
备注:这里不去讲解怎么搭建webassembly的相关环境,如果要搭建这个环境,请查看我的另外一篇博客:https://blog.youkuaiyun.com/as3luyuan123/article/details/121648379 。
一、MuPDF简介
MuPDF是一个轻量级的PDF,是一个PDF文档解析器。详情查看官网: https://mupdf.com/ 。
二、环境概况
现在大多数项目都是使用ubuntu16进行开发,因此我的虚拟机系统由原先的ubuntu14升级成了ubuntu16。因此我现在的机器环境是:ubuntu 16-04 LTS版本。如下图所示:
Windows环境下怎么去编译mupdf的wasm版本,我测试了好几次,一直编译不成功。Makefile应该有对应的问题,建议在linux下进行编译调试。
三、MUPDF源码下载及编译
首先进入https://www.mupdf.com/releases/进行对应的版本下载,我下载的是最新的版本mupdf-1.20.0-source.tar.lz:
解压出的源码结构如下:
- docs目录:该目录包含了一些帮助文档,包括编译出来的一些命令帮助文档。熟悉这个目录,能够省很多事情。
- generated目录:该目录是字体资源文件的C目录,通过命令编译时,将编译成具体的字体文件。
- include目录:mupdf源码的相关头文件。
- platform目录:该目录包括各个开发平台的开发环境以及对应的demo。例如windows平台VS项目sln文件、wasm目录的编译demo。
- resources目录:资源文件目录。
- scripts目录:包含编译的执行的一些python文件,没有进行具体研究。
- sources目录:mupdf源码的相关实现文件。
- thirdparty目录:该目录主要包含mupdf整个项目依赖的第三方代码。例如:zlib、curl等。
- CHANGES文件:该版本基于上个版本的修改日志。
- CONTRIBUTORS文件:代码维护者以及捐助人的相关说明。
- COPYS文件:版权相关说明文件。
- Makefile文件:编译文件,可以直接使用make命令进行编译(指定不同的编译平台)。
- Makelists文件:需要编译的文件列表,配合Makefile文件使用。
- Makerules文件:Makefile文件的相关配置,并指定编译的相关平台或者架构,配合Makefile文件使用。
- Makethird文件:编译第三方库的配置文件,配合Makefile文件使用。
- README文件:mupdf的说明文件。
- setup.py文件:MUPDF的安装脚本。
1、编译源码的wasm静态库
通过查看Makerules文件,发现编译wasm版本很简单,直接通过一行命令解决问题:make OS=wasm
。执行这个命令后有可能会遇到下面的问题:
通过查资料发现,是我的WebAssembly开发环境设置的初始化内存太小,应该设置大一些。直接修改emsdk/upstream/emscripten/src目录里面的settings.js,将值设置大一些,相关设置如下图所示:(备注:一定要设置成64KB的倍数,要不然会报
emcc: error: INITIAL_MEMORY must be a multiple of WebAssembly page size (64KiB)的错误)。
我只遇到了这一个错误,然后编译完成。编译完成后,可以在build/wasm/release目录下看到对应的编译后的文件列表,如下图所示:
- generated目录:该目录是编译的字体文件中间文件目录,不会使用该目录。
- sources目录:该目录是编译的source文件夹下的中间文件目录,不会使用该目录。
- thirdparty目录:该目录是编译的thirdparty文件夹下的中间文件目录,不会使用该目录。
- libmupdf.a、libmupdf-pkcs7.a、libmupdf-third.a、libmupdf-threads.a:wasm版本的静态库文件,用于产生的wasm文件的相关链接。
- muraster、mutool:mupdf对应的命令行工具,详情查看doc目录,该目录有怎么使用这两个执行文件。
- muraster.wasm、mutool.wasm:编译好的命令行工具的wasm版本。
2、编译demo
前一章节编译的是对应的Wasm静态库,这一章节编译的是对应的demo。进入源码的platform/wasm目录,如下图所示:
- build.sh:编译wasm demo的相关脚本。
- index.html、viewer.html:测试demo的主界面以及展示打开的pdf文档。
- Makefile文件:编译文件,指定了对应的静态库所在目录以及对应的编译命令。
- mupdf-async.js、mupdf-worker.js:demo所需的js文件。
- readme.html:讲解了怎么去集成百衲衣好的Wasm实例。
- standalone.js:没有仔细研究,目前不知道有撒用。
- wrap.c、wrap.js:用于编译使用的wasm文件。
在终端中输入./build.sh
进行编译,有可能会报一下错误:如下图所示:
这是因为在build.sh文件中,默认指定的是去读/opt/emsdk/emsdk_env.sh的环境变量并进行设置,但在配置webassembly环境时,已经默认设置了对应的环境变量,这里把source /opt/emsdk/emsdk_env.sh
删除即可编译成功。最终在当前目录下多一个libmupdf.wasm文件。编译后的结果如下图所示:
至此为止,所有的编译都完成了。
在当前面目录下,使用python3 -m http.server 8000
命令,启动即可在chrome浏览器中访问网址,进行测试。在chrome浏览器中输入: http://localhost:8000/即可进行访问使用命令启动的服务器。如下图所示:
点击 PDF Document链接,先会装载Wasm模块,然后有可能会提醒 Error: Could not fetch document. 的错误。会出现这个错误原因是:该目录下没有一个叫pdfref13.pdf的文件。在该目录下放入一个pdf文件并命名为pdfref13.pdf,即可打开文档。打开后的文档截图如下图所示:
用F12命令打开chrome的调试器,就能够清楚的看出调用的结构:该结构分为两部分:
1、作为一个异步库,在 Web Worker 线程中生成 MuPDF,并提供用于加载 PDF 文件、获取目录以及将页面呈现为 PNG 图像以准备插入 DOM 的功能。
2、是执行异步库的基本 HTML 应用程序,由js写的,用于展示pdf文档。