本章主要介绍mupdf标注渲染,接口是fz_run_page_annots ,下面是具体实现过程。
接口说明请参考上一章的fz_run_page_contents接口。
接口实现是通过pdf_run_page_annots->pdf_run_page_annots_with_usage接口实现。
1,处理cookie->progress_max
if (cookie && cookie->progress_max != (size_t)-1)
{//不超过max
int count = 1;
for (annot = page->annots; annot; annot = annot->next)
count++;
cookie->progress_max += count;
}
2,遍历标注,处理每一个标注
for (annot = page->annots; annot; annot = annot->next)
{
/* Check the cookie for aborting */
if (cookie)
{
if (cookie->abort)//终止
break;
cookie->progress++;//进度
}
//处理单个标注
pdf_run_annot_with_usage(ctx, doc, page, annot, dev, ctm, usage, cookie);
}
3, 处理单个标注pdf_run_annot_with_usage
static void
pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie)
{
fz_matrix page_ctm;//旋转矩阵
fz_rect mediabox;//页面矩形
pdf_processor *proc = NULL;
fz_default_colorspaces *default_cs = NULL;
int flags;
fz_var(proc);
fz_var(default_cs);
if (cookie && page->super.incomplete)
cookie->incomplete = 1;
/* Widgets only get displayed if they have both a T and a TF flag,
* apparently
小部件展示必须有T TF标记
*/
if (pdf_name_eq(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME(Subtype)), PDF_NAME(Widget)))
{
pdf_obj *ft = pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(FT));
pdf_obj *t = pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(T));
if (ft == NULL || t == NULL)
return;
}
fz_try(ctx)
{
//默认色彩空间加入设备显示链表中
default_cs = pdf_load_default_colorspaces(ctx, doc, page);
if (default_cs)
fz_set_default_colorspaces(ctx, dev, default_cs);
//页面矩形,页面转换矩阵
pdf_page_transform(ctx, page, &mediabox, &page_ctm);
//标注标记,缩放,旋转
flags = pdf_dict_get_int(ctx, annot->obj, PDF_NAME(F));
if (flags & PDF_ANNOT_IS_NO_ROTATE)
{
//页面旋转
int rotate = pdf_to_int(ctx, pdf_dict_get_inheritable(ctx, page->obj, PDF_NAME(Rotate)));
//标注矩形
fz_rect rect = pdf_dict_get_rect(ctx, annot->obj, PDF_NAME(Rect));
//标注旋转与页面一致
fz_point tp = fz_transform_point_xy(rect.x0, rect.y1, page_ctm);
page_ctm = fz_concat(page_ctm, fz_translate(-tp.x, -tp.y));
page_ctm = fz_concat(page_ctm, fz_rotate(-rotate));
page_ctm = fz_concat(page_ctm, fz_translate(tp.x, tp.y));
}
//标注转换矩阵
ctm = fz_concat(page_ctm, ctm);
//设置pdf处理器结构
proc = pdf_new_run_processor(ctx, dev, ctm, usage, NULL, default_cs, cookie);
//处理标注内容
pdf_process_annot(ctx, proc, doc, page, annot, cookie);
pdf_close_processor(ctx, proc);
}
fz_always(ctx)
{
pdf_drop_processor(ctx, proc);
fz_drop_default_colorspaces(ctx, default_cs);
}
fz_catch(ctx)
fz_rethrow(ctx);
}