mupdf源码分析(五)加载文档之页面加载

这一章将详细讲解 fz_load_page接口的实现流程。此接口主要实现了根据页面索引加载指定页面资源,填充fz_page对象。

1,获取文档章节数 fz_count_chapters(ctx, doc);//n = 1

2,计算每个章节的页码数,int m = fz_count_chapter_pages(ctx, doc, i);

3,加载页面资源,fz_load_chapter_page(ctx, doc, i, number - start);

3.1)遍历所有已加载的页面链表

    for (page = doc->open; page; page = page->next)
            if (page->chapter == chapter && page->number == number)
            {//指定页面已经加载
                fz_unlock(ctx, FZ_LOCK_ALLOC);
                return fz_keep_page(ctx, page);//增加引用计数,返回已加载页面
            }

3.2)实际加载页面资源 page = doc->load_page(ctx, doc, chapter, number);//pdf_load_page_imp-->pdf_load_page

    3.2.1)pageobj = pdf_lookup_page_obj(ctx, doc, number);//Kids 查找页面对象,具体实现见附录一。

    3.2.2)page = pdf_new_page(ctx, doc);//创建页面结构对象,具体实现见附录四。
                       page->obj = pdf_keep_obj(ctx, pageobj);//增加引用计数,赋值page->obj

     3.2.3)page kid 中查找是否有Annots 具体实现见附录二。

     3.2.4)扫描页面透明和套印设置 具体实现见附录三。

3.3)头部插入加载的页面链表

     fz_lock(ctx, FZ_LOCK_ALLOC);
            //头部插入
            if ((page->next = doc->open) != NULL)//page.next->head
                doc->open->prev = &page->next;//head.prev->page->next
            doc->open = page;//head->page
            page->prev = &doc->open;//page.prev->head
            fz_unlock(ctx, FZ_LOCK_ALLOC);

附录一

pdf_obj *
pdf_lookup_page_obj(fz_context *ctx, pdf_document *doc, int needle)
{
    return pdf_lookup_page_loc(ctx, doc, needle, NULL, NULL);
}

//从Pages页面树中查找页面

pdf_obj *
pdf_lookup_page_loc(fz_context *ctx, pdf_document *doc, int needle, pdf_obj **parentp, int *indexp)
{
    pdf_obj *root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root));//Root
    pdf_obj *node = pdf_dict_get(ctx, root, PDF_NAME(Pages));//Pages
    int skip = needle;
    pdf_obj *hit;

    if (!node)
        fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find page tree");

    hit = pdf_lookup_page_loc_imp(ctx, doc, node, &skip, parentp, indexp);
    if (!hit)
        fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find page %d in page tree", needle+1);
    return hit;
}

附录二

obj = pdf_dict_get(ctx, pageobj, PDF_NAME(Annots));
       if (obj)
        {
            fz_rect page_mediabox;
            fz_matrix page_ctm;
            pdf_page_transform(ctx, page, &page_mediabox, &page_ctm);//页面尺寸和旋转矩阵
            page->links = pdf_load_link_annots(ctx, doc, obj, number, page_ctm);//加载链接对象
            pdf_load_annots(ctx, page, obj);//加载标注
        }

附录三

pdf_obj *resources = pdf_page_resources(ctx, page);
        //透明组XObject:子类型Transparency
        if (pdf_name_eq(ctx, pdf_dict_getp(ctx, pageobj, "Group/S"), PDF_NAME(Transparency)))
            page->transparency = 1;
        else if (pdf_resources_use_blending(ctx, resources))
            page->transparency = 1;
        for (annot = page->annots; annot && !page->transparency; annot = annot->next)
            if (annot->ap && pdf_resources_use_blending(ctx, pdf_xobject_resources(ctx, annot->ap)))
                page->transparency = 1;
        //指示图像是套印(true)还是镂空(false)在其他分色上的底层标记
        if (pdf_resources_use_overprint(ctx, resources))
            page->overprint = 1;
        for (annot = page->annots; annot && !page->overprint; annot = annot->next)
            if (annot->ap && pdf_resources_use_overprint(ctx, pdf_xobject_resources(ctx, annot->ap)))
                page->overprint = 1;

附录四

static pdf_page *
pdf_new_page(fz_context *ctx, pdf_document *doc)
{
    pdf_page *page = fz_new_derived_page(ctx, pdf_page);

    page->doc = (pdf_document*) fz_keep_document(ctx, &doc->super);

    page->super.drop_page = (fz_page_drop_page_fn*)pdf_drop_page_imp;//销毁页面
    page->super.load_links = (fz_page_load_links_fn*)pdf_load_links;//加载链接
    page->super.bound_page = (fz_page_bound_page_fn*)pdf_bound_page;//页面尺寸
    page->super.run_page_contents = (fz_page_run_page_fn*)pdf_run_page_contents;//加载页面元素,渲染用
    page->super.run_page_annots = (fz_page_run_page_fn*)pdf_run_page_annots;//注释元素
    page->super.run_page_widgets = (fz_page_run_page_fn*)pdf_run_page_widgets;//小部件
    page->super.page_presentation = (fz_page_page_presentation_fn*)pdf_page_presentation;//演示文稿
    page->super.separations = (fz_page_separations_fn *)pdf_page_separations;//分色
    page->super.overprint = (fz_page_uses_overprint_fn *)pdf_page_uses_overprint;//套印

    page->obj = NULL;

    page->transparency = 0;
    page->links = NULL;
    page->annots = NULL;
    page->annot_tailp = &page->annots;
    page->widgets = NULL;
    page->widget_tailp = &page->widgets;

    return page;
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值