基于MuPDF和Qt的PDF阅读器的开发

96
容我三思兮
2018.07.17 15:22 字数 782

基于MuPDF和Qt的PDF阅读器的开发

一、引言

设备上要渲染显示PDF文档,类似Adobe Reader、福昕阅读器等软件。如何去实现?Handling PDF这篇文档讨论介绍了在Qt应用程序中各种操作PDF的资料。从资料中看出,我们是要阅读渲染PDF文档到我们的设备中,关键还要能交叉编译移植到我们的设备上。在渲染显示方面整体给出三种方案:

  • QtPDF(基于PDFium),不太好交叉编译。
  • poppler-qt,与我们设备操作系统版本匹配的版本bug太多。
  • muPDF,非常成熟,很多产品上都已使用,格式支持丰富,方便交叉编译。

最终选muPDF库来实现。

二、muPDF下载和编译

muPDF官网muPDF-1.12.0源码下载

1、交叉编译iMX6-ARM版本

修改Makerules

...
157:
158: ifeq "$(OS)" "imx6-linux"
159: CCPATH = /opt/linaro-14.04/gcc-linaro-arm-linux-gnueabihf-4.8/bin
160: CC = $(CCPATH)/arm-linux-gnueabihf-gcc
161: LD = $(CCPATH)/arm-linux-gnueabihf-gcc
162: AR = $(CCPATH)/arm-linux-gnueabihf-ar
163: CROSSCOMPILE=yes
164: HAVE_GLUT := no
165: HAVE_PTHREAD := yes
166: SYS_PTHREAD_CFLAGS :=
167: SYS_PTHREAD_LIBS := -lpthread
168: HAVE_X11 := yes
169: SYS_X11_CFLAGS += -I/opt/linaro-14.04/usr/include
170: SYS_X11_LIBS += -L/opt/linaro-14.04/usr/lib/arm-linux-gnueabihf -lX11 -lXext -lxcb -lXau -lXdmcp -lpthread
171: endif
172: 
...

执行命令:make generate && make OS=imx6-linux HAVE_GLUT=no -j32
最后源码目录的build/release/下生成四个库文件和多个二进制程序工具。libcurl.a libmupdf.a libmupdfthird.a libmuthreads.a mjsgen mujstest mupdf-x11 mupdf-x11-curl muraster mutool

使用的时候把四个库放到Qt工程里面使用,curl又依赖libcrypto.a库,所以去交叉编译工具链下找到libcrypto.a放进去。

2、编译win版本

用VS打开源码目录下的platform/win32/mupdf.sln,把所有工程中的属性--配置属性--C/C++--代码生成--运行库改为多线程调试DLL(/MDd)
编译mupdf生成三个库libmupdf.lib、libthirdparty.lib,编译libresources工程,生成libresources.lib,目前项目需要这三个库就够了。

三、使用muPDF库

其实重点在于如何使用muPDF库,这个库的API实在是难用,也没有帮助文档,只能看它提供的例子或这小工具的源码来学习。
先看工程目录结构:

main.cpp
mainwindow.h
mainwindow.cpp
mupdfdocument.h
mupdfdocument_p.h
mupdfdocument.cpp
mupdfpage.h
mupdfpage_p.h
mupdfpage.cpp
pagerender.h
pagerender.cpp
sequentialpagewidget.h
sequentialpagewidget.cpp

mupdfdocument:主要实现加载文档,提供文档信息功能。对mupdf接口封装主要实现在mupdfdocument_p里面;
mupdfpage和mupdfpage_p:主要实现渲染单个页面,输出QImage。主要难度在reanderImage函数;
pagerender:主要是借助QThread线程来渲染单个PDF页面;
sequentialpagewidget:实现对PDF文件显示的封装,如何做到高效显示,而又不占用太多资源?如何实现跳页?放大?缩小?滚动页面?非常小的屏幕下实现页码的正确显示?这里面都有所体现。

整个工程,都是短时间完成的,并且没有时间对muPDF做深入研究,所以肯定还有很多不足之处,还请见谅。整个工程代码没什么大的难度,难点在如何封装使用muPDF的API,以及如何使用Qt的控件更有效率的显示出来。

这是基于VS2013的PDFReader的工程。
资源工程下载

PDF Reader

Qt
Gupao