PDF 注释 (Annotation)
Annotation 注释将对象(如注释,线条和高亮)与 PDF 文档页面上的位置相关联。PDF 包括以下表中列出的各种标准注释类型。在这些注释类型中,许多被定义为标记注释,因为它们主要用于标记 PDF 文档。表中的 Markup
列用来说明是否为标记注释。
福昕 PDF SDK 支持 PDF Reference 中定义的大多数注释类型,并提供了注释创建,属性访问和修改,外观设置和绘制的 APIs。
Annotation type | Description | Markup | Supported by SDK |
---|---|---|---|
Text(Note) | Text annotation | Yes | Yes |
Link | Link Annotation | No | Yes |
FreeText(TypeWriter/TextBox/Callout) | Free text annotation | Yes | Yes |
Line | Line annotation | Yes | Yes |
Square | Square annotation | Yes | Yes |
Circle | Circle annotation | Yes | Yes |
Polygon | Polygon annotation | Yes | Yes |
PolyLine | PolyLine annotation | Yes | Yes |
Highlight | Highlight annotation | Yes | Yes |
Underline | Underline annotation | Yes | Yes |
Squiggly | Squiggly annotation | Yes | Yes |
StrikeOut | StrikeOut annotation | Yes | Yes |
Stamp | Stamp annotation | Yes | Yes |
Caret | Caret annotation | Yes | Yes |
Ink(pencil) | Ink annotation | Yes | Yes |
Popup | Popup annotation | No | Yes |
File Attachment | FileAttachment annotation | Yes | Yes |
Sound | Sound annotation | Yes | No |
Movie | Movie annotation | No | No |
Widget* | Widget annotation | No | Yes |
Screen | Screen annotation | No | Yes |
PrinterMark | PrinterMark annotation | No | No |
TrapNet | Trap network annotation | No | No |
Watermark* | Watermark annotation | No | No |
3D | 3D annotation | No | No |
Redact | Redact annotation | Yes | Yes |
NOTE
福昕 PDF SDK 支持名为 PSI (pressure sensitive ink,压感笔迹) 的自定义注释类型。在 PDF 规范中没有对该注释进行描述。通常,PSI 用于手写功能,福昕 SDK 将其视为 PSI 注释,以便其他 PDF 产品可以对其进行相关处理。
如何向 PDF 页面中添加注释
js
import {FoxitRDKNative} from 'foxit_rdk';
class AnnotationUnit {
private addAnnot(): void {
try {
const pdfpath = "xxx/Sample.pdf";
const doc = new FoxitRDKNative.pdf.PDFDoc(pdfpath);
doc.Load('');
const pdfPage = doc.GetPage(1);
const rect = new FoxitRDKNative.common.fxcrt.RectF(100, 100, 120, 120);
const note = new FoxitRDKNative.pdf.annots.Note(pdfPage.AddAnnot(FoxitRDKNative.pdf.annots.Annot.e_Note, rect));
if (note == null || note.IsEmpty()) {
return;
}
note.SetIconName("Comment");
// 将边框颜色设置为蓝色
note.SetBorderColor(0xff0000ff);
note.SetContent("This is the note comment, write any content here.");
note.ResetAppearanceStream();
class SearchCancelCallbackImpl extends FoxitRDKNative.pdf.SearchCancelCallback {
NeedToCancelNow(): boolean {
return false;
}
}
// 以下代码展示如何在搜索到的文本上添加高亮注释
const textSearch = new FoxitRDKNative.pdf.TextSearch(pdfPage.GetDocument(), new SearchCancelCallbackImpl(),
FoxitRDKNative.pdf.TextPage.e_ParseTextNormal);
if (textSearch == null || textSearch.IsEmpty()) {
return;
}
// 假设需要高亮的文本是 "foxit"
textSearch.SetPattern("foxit");
const bMatched = textSearch.FindNext();
if (bMatched) {
const rects = textSearch.GetMatchRects();
const rectCount = rects.GetSize();
// 根据搜索到的文本矩形,填充quadpoints数组。
const arrayOfQuadPoints = new FoxitRDKNative.pdf.annots.QuadPointsArray();
let matchRect: FoxitRDKNative.common.fxcrt.RectF;
for (let i = 0; i < rectCount; i++) {
matchRect = rects.GetAt(i);
const quadPoints = new FoxitRDKNative.pdf.annots.QuadPoints();
quadPoints.first = new FoxitRDKNative.common.fxcrt.PointF(matchRect.left, matchRect.top);
quadPoints.second = new FoxitRDKNative.common.fxcrt.PointF(matchRect.right, matchRect.top);
quadPoints.third = new FoxitRDKNative.common.fxcrt.PointF(matchRect.left, matchRect.bottom);
quadPoints.fourth = new FoxitRDKNative.common.fxcrt.PointF(matchRect.right, matchRect.bottom);
arrayOfQuadPoints.Add(quadPoints);
}
// 只需给markup annotation设置一个空矩形,然后根据quadPoints的坐标值来计算annotation矩形
const rect2 = new FoxitRDKNative.common.fxcrt.RectF(0, 0, 0, 0);
const textMarkup =
new FoxitRDKNative.pdf.annots.TextMarkup(pdfPage.AddAnnot(FoxitRDKNative.pdf.annots.Annot.e_Highlight,
rect2));
// 将quadpoints设置给markup annotation
textMarkup.SetQuadPoints(arrayOfQuadPoints);
// 将边框颜色设置为红色
textMarkup.SetBorderColor(0xffff0000);
// 设置为30%的透明度
textMarkup.SetOpacity(0.3);
// 生成外观
textMarkup.ResetAppearanceStream();
}
} catch (e) {
console.error(e);
}
}
}
如何删除 PDF 页面中的注释
js
import {FoxitRDKNative} from 'foxit_rdk';
class AnnotationUnit2 {
private removeAnnot(): void {
try {
const pdfpath = "xxx/Sample.pdf";
const doc = new FoxitRDKNative.pdf.PDFDoc(pdfpath);
doc.Load('');
const pdfPage = doc.GetPage(1);
const annot = pdfPage.GetAnnot(0);
if (annot == null || annot.IsEmpty()) {
return;
}
// 删除第一个annot,使第二个annot变为第一个
pdfPage.RemoveAnnot(annot);
} catch (e) {
console.error(e)
}
}
}
如何注册监听器接收注释事件
在接收注释事件之前需要提前注册注释监听器。具体参考下述代码。
js
import {FoxitRDKNative} from 'foxit_rdk';
import {UIExtensionsManager} from 'uiextensions';
import {IAnnotEventListener} from 'uiextensions/src/main/ets/event/IAnnotEventListener';
class AnnotationUnit3 {
private annotEventListener: IAnnotEventListener = {
onAnnotAdded: (page: FoxitRDKNative.pdf.PDFPage, annot: FoxitRDKNative.pdf.annots.Annot
):
void
=> {
}
,
onAnnotWillDelete: (page: FoxitRDKNative.pdf.PDFPage, annot
:
FoxitRDKNative.pdf.annots.Annot
):
void
=>
{
}
,
onAnnotDeleted: (page: FoxitRDKNative.pdf.PDFPage, annot
:
FoxitRDKNative.pdf.annots.Annot
):
void
=>
{
}
,
onAnnotModified: (page: FoxitRDKNative.pdf.PDFPage, annot
:
FoxitRDKNative.pdf.annots.Annot
):
void
=>
{
}
,
onAnnotChanged: (lastAnnot: FoxitRDKNative.pdf.annots.Annot | null, currentAnnot
:
FoxitRDKNative.pdf.annots.Annot | null
):
void
=>
{
}
}
registerYourAnnotEventListener(extensionsManager
:
UIExtensionsManager
):
void {
// 调用registerAnnotEventListener来注册annot事件监听器以接收annot事件
extensionsManager.getDocumentManager().registerAnnotEventListener(this.annotEventListener);
}
unregisterYourAnnotEventListener(extensionsManager
:
UIExtensionsManager
):
void {
// 调佣unregisterAnnotEventListener来取消注册annot事件监听器
extensionsManager.getDocumentManager().unregisterAnnotEventListener(this.annotEventListener);
}
}