[poppler] [PATCH] [C++ frontend] - show page numbers with Table of Contents items (v2)

Albert Astals Cid aacid at kde.org
Thu Oct 16 10:17:23 PDT 2014


El Dijous, 16 d'octubre de 2014, a les 18:11:45, Martin Pelikan va escriure:
> Hi,
> 
> version 2 of my previous patch (that didn't make it to the list
> apparently) is tested on multiple different documents (mostly hw/sw
> manuals and documentation, some books or theses).
> 
> The problem it solves is simple -- the current C++ frontend does have a
> TOC, but it only contains titles and not pages where the TOC entries
> point to.  This patch (inspired by glib frontend) adds an API to get
> a page number passable to poppler::document::create_page.
> 
> ok?

Resolving all the toc items on load is not a great idea; findDest can be 
relatively slow and there's pages with llooooooooooots of items in the toc, so 
it's better to do it when people actually ask for the page number and not on 
load.

Cheers,
  Albert

> --
> Martin Pelikan
> 
> 
> diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
> index 1c24b47..ad20c90 100644
> --- a/cpp/poppler-document.cpp
> +++ b/cpp/poppler-document.cpp
> @@ -554,7 +554,7 @@ font_iterator* document::create_font_iterator(int
> start_page) const */
>  toc* document::create_toc() const
>  {
> -    return toc_private::load_from_outline(d->doc->getOutline());
> +    return toc_private::load_from_pdfdoc(d->doc);
>  }
> 
>  /**
> diff --git a/cpp/poppler-toc-private.h b/cpp/poppler-toc-private.h
> index e8841ff..b626fae 100644
> --- a/cpp/poppler-toc-private.h
> +++ b/cpp/poppler-toc-private.h
> @@ -25,6 +25,7 @@
>  #include <vector>
> 
>  class GooList;
> +class PDFDoc;
>  class Outline;
>  class OutlineItem;
> 
> @@ -37,7 +38,7 @@ public:
>      toc_private();
>      ~toc_private();
> 
> -    static toc* load_from_outline(Outline *outline);
> +    static toc* load_from_pdfdoc(PDFDoc *);
> 
>      toc_item root;
>  };
> @@ -49,12 +50,13 @@ public:
>      toc_item_private();
>      ~toc_item_private();
> 
> -    void load(OutlineItem *item);
> -    void load_children(GooList *items);
> +    void load(PDFDoc *, OutlineItem *item);
> +    void load_children(PDFDoc *, GooList *items);
> 
>      std::vector<toc_item*> children;
>      ustring title;
>      bool is_open;
> +    int page_number;
>  };
> 
>  }
> diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
> index a3149c6..504e696 100644
> --- a/cpp/poppler-toc.cpp
> +++ b/cpp/poppler-toc.cpp
> @@ -23,6 +23,8 @@
> 
>  #include "GooList.h"
>  #include "Outline.h"
> +#include "PDFDoc.h"
> +#include "Link.h"
> 
>  using namespace poppler;
> 
> @@ -34,8 +36,9 @@ toc_private::~toc_private()
>  {
>  }
> 
> -toc* toc_private::load_from_outline(Outline *outline)
> +toc* toc_private::load_from_pdfdoc(PDFDoc *doc)
>  {
> +    Outline *outline = doc->getOutline();
>      if (!outline) {
>          return 0;
>      }
> @@ -47,13 +50,13 @@ toc* toc_private::load_from_outline(Outline *outline)
> 
>      toc *newtoc = new toc();
>      newtoc->d->root.d->is_open = true;
> -    newtoc->d->root.d->load_children(items);
> +    newtoc->d->root.d->load_children(doc, items);
> 
>      return newtoc;
>  }
> 
>  toc_item_private::toc_item_private()
> -    : is_open(false)
> +    : is_open(false), page_number(0)
>  {
>  }
> 
> @@ -62,15 +65,41 @@ toc_item_private::~toc_item_private()
>      delete_all(children);
>  }
> 
> -void toc_item_private::load(OutlineItem *item)
> +void toc_item_private::load(PDFDoc *doc, OutlineItem *item)
>  {
>      const Unicode *title_unicode = item->getTitle();
>      const int title_length = item->getTitleLength();
>      title = detail::unicode_to_ustring(title_unicode, title_length);
>      is_open = item->isOpen();
> +
> +    LinkAction *link_action = item->getAction();
> +    if (link_action == NULL)
> +        return;
> +
> +    switch (link_action->getKind()) {
> +    case actionGoTo:
> +        if (LinkGoTo *l = dynamic_cast<LinkGoTo *>(link_action)) {
> +            LinkDest *ld = l->getDest();
> +
> +            if (ld == NULL)
> +                ld = doc->findDest(l->getNamedDest());
> +
> +            if (ld != NULL) {
> +                if (ld->isPageRef()) {
> +                    Ref pr = ld->getPageRef();
> +                    page_number = doc->findPage(pr.num, pr.gen);
> +                }
> +                else
> +                    page_number = ld->getPageNum();
> +            }
> +        }
> +        break;
> +    default:
> +        break;
> +    }
>  }
> 
> -void toc_item_private::load_children(GooList *items)
> +void toc_item_private::load_children(PDFDoc *doc, GooList *items)
>  {
>      const int num_items = items->getLength();
>      children.resize(num_items);
> @@ -78,13 +107,13 @@ void toc_item_private::load_children(GooList *items)
>          OutlineItem *item = (OutlineItem *)items->get(i);
> 
>          toc_item *new_item = new toc_item();
> -        new_item->d->load(item);
> +        new_item->d->load(doc, item);
>          children[i] = new_item;
> 
>          item->open();
>          GooList *item_children = item->getKids();
>          if (item_children) {
> -            new_item->d->load_children(item_children);
> +            new_item->d->load_children(doc, item_children);
>          }
>      }
>  }
> @@ -175,6 +204,14 @@ bool toc_item::is_open() const
>  }
> 
>  /**
> + Returns the page number this TOC item points to, to be used in
> create_page. + */
> +int toc_item::page_number() const
> +{
> +    return d->page_number - 1;
> +}
> +
> +/**
>   \returns the children of the TOC item
>   */
>  std::vector<toc_item *> toc_item::children() const
> diff --git a/cpp/poppler-toc.h b/cpp/poppler-toc.h
> index 8b09736..9d9618d 100644
> --- a/cpp/poppler-toc.h
> +++ b/cpp/poppler-toc.h
> @@ -55,6 +55,7 @@ public:
> 
>      ustring title() const;
>      bool is_open() const;
> +    int page_number() const;
> 
>      std::vector<toc_item *> children() const;
>      iterator children_begin() const;
> _______________________________________________
> poppler mailing list
> poppler at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/poppler



More information about the poppler mailing list