美文网首页
制作安卓PDF阅读器:五、实现文本高亮、下划线、保存PDF

制作安卓PDF阅读器:五、实现文本高亮、下划线、保存PDF

作者: 天下第九九八十一 | 来源:发表于2020-11-15 18:54 被阅读0次

一、上下文菜单( context menu )

用 TextView 实现,通过clickaspan处理点击事件。

背景图用 Android 9-patch shadow generator 生成,参数如下:

round 8
shadow blur 8
shadow color #757575
Outline width 3
128x35
20%-30%
9%-6%

二、点击选取标注

1. 点击后绘制包裹框

头文件:fpdf_annot.h

API:FPDFPage_GetAnnotCount、FPDFAnnot_GetRect,获得标注的整体包裹Rect。

得到 Rect 后,将之绘制出来,与文本选择一样,不过绘制的是矩形方框。

2. 将标注形状转换为文本选择

标注仅是形状,无文本选择信息。需要通过 FPDFAnnot_CountAttachmentPoints、 FPDFAnnot_GetAttachmentPoints、FPDFText_GetCharIndexAtPos 恢复文本选择。

FPDFAnnot_GetRect 获得的仅仅是一个整体包裹框,并非实际形状。实际形状由 AttachmentPoints 定义,可以包含多个矩形信息,一组 AttachmentPoints 由矩形的四个顶点 (x1,y1)、 (x2,y2)、 (x3,y3)、 (x4,y4) 组成,这样的“矩形”可以是任意形状、任意旋转角度的。

2.1

在此之前需用 FPDFAnnot_GetAttachmentPoints 修改点击高亮标注的方法,因为多个高亮标注的包裹框可能有重叠,而包裹框的包裹范围大于高亮标注的实际范围。若存在多个结果,则用 FPDFAnnot_GetAttachmentPoints 剔除不符合的,并将其他符合条件(包含触点下的PDF像素)的高亮标注存储起来。若仍然存在多个结果,则需要计算出最符合条件的,可能是面积最小的,也可能是中心点距离最近的。

点击选取标注的第一步本质是在平面内用一个点选择包含该点的矩形,所有矩形的旋转为0。这样的问题可以简单迭代判断,或用R树解决达到性能最优化。

简单处理高亮标注的单击选取问题,会造成标注之间的错误遮蔽现象。

  • 反例:(静读天下)
    标注添加的先后顺序影响标注之间的错误遮蔽。


    未遮蔽
错误遮蔽,即使标注之间无实际覆盖,也无法选择较小的标注。
  • 反例:(ezpdf reader)
    较大的高亮标注覆盖并遮蔽较小的高亮标注,使其无法被选中。


2.2

AttachmentPoints 的坐标配合 FPDFText_GetCharIndexAtPos 可以用来恢复高亮标注的文本选择。


于是乎,标注选择与文本选择自然地共享几乎全部功能,都可以调用翻译、分享、查词典等菜单项。


三、新建高亮标记

关键 API:FPDFPage_CreateAnnot、FPDFAnnot_SetRect、FPDFAnnot_AppendAttachmentPoints.

FPDFAnnot_SetRect 和 FPDFAnnot_AppendAttachmentPoints 的区别参考 https://stackoverflow.com/questions/61524219/difference-between-fpdfannot-setrect-and-fpdfannot-appendattachmentpoints-when-a/64835128#64835128。(顺便帮我的回答点下赞也是好的。。。)

FPDFAnnot_AppendAttachmentPoints 定义的矩形与选区矩形差不多,但之前实现的选区矩形太过分散,可以用简单的算法,将同一行的矩形合并成大矩形。

生成的高亮标注两边没有鼓胀效果,不知如何实现。


四、保存PDF

API:FPDF_SaveAsCopy。虽然可以传入标志位FPDF_INCREMENTAL,但无法增量保存。不用增量保存的话,结果PDF文件体积较大。

相关文章

网友评论

      本文标题:制作安卓PDF阅读器:五、实现文本高亮、下划线、保存PDF

      本文链接:https://www.haomeiwen.com/subject/imfmbktx.html