diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2011-03-01 10:56:40 +0100 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2011-03-01 12:32:24 +0100 |
commit | 664865a2ddca9c20ac36a41aef52ebf12eab838d (patch) | |
tree | 35b8e56ca44eec26ae566696284754e4d3e9c4fd | |
parent | 1f6573e949aaba0eb0a4c2f9cd73d7ad45ba67be (diff) |
Merge Link and AnnotLink code
Annotations now belong to the Page and are created only once on demand.
Annots are now ref counted and Links is a list of AnnotLink objects,
Link object has been removed. The AnnotLink API is mostly the same than
Link and frontends APIs are not affected.
Qt4 changes made by Pino Toscano.
-rw-r--r-- | glib/poppler-document.cc | 2 | ||||
-rw-r--r-- | glib/poppler-page.cc | 29 | ||||
-rw-r--r-- | glib/poppler-private.h | 1 | ||||
-rw-r--r-- | poppler/Annot.cc | 79 | ||||
-rw-r--r-- | poppler/Annot.h | 24 | ||||
-rw-r--r-- | poppler/ArthurOutputDev.cc | 4 | ||||
-rw-r--r-- | poppler/ArthurOutputDev.h | 3 | ||||
-rw-r--r-- | poppler/CairoOutputDev.cc | 3 | ||||
-rw-r--r-- | poppler/CairoOutputDev.h | 6 | ||||
-rw-r--r-- | poppler/FontInfo.cc | 4 | ||||
-rw-r--r-- | poppler/Form.cc | 36 | ||||
-rw-r--r-- | poppler/Form.h | 5 | ||||
-rw-r--r-- | poppler/Link.cc | 124 | ||||
-rw-r--r-- | poppler/Link.h | 43 | ||||
-rw-r--r-- | poppler/OutputDev.h | 4 | ||||
-rw-r--r-- | poppler/PDFDoc.cc | 4 | ||||
-rw-r--r-- | poppler/Page.cc | 63 | ||||
-rw-r--r-- | poppler/Page.h | 11 | ||||
-rw-r--r-- | poppler/TextOutputDev.cc | 9 | ||||
-rw-r--r-- | poppler/TextOutputDev.h | 10 | ||||
-rw-r--r-- | qt4/src/poppler-link-extractor-private.h | 2 | ||||
-rw-r--r-- | qt4/src/poppler-link-extractor.cc | 3 | ||||
-rw-r--r-- | qt4/src/poppler-page.cc | 12 | ||||
-rw-r--r-- | utils/HtmlOutputDev.cc | 7 | ||||
-rw-r--r-- | utils/HtmlOutputDev.h | 4 |
25 files changed, 188 insertions, 304 deletions
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc index fd764d86..710a5b38 100644 --- a/glib/poppler-document.cc +++ b/glib/poppler-document.cc @@ -2493,7 +2493,7 @@ poppler_document_get_form_field (PopplerDocument *document, if (!page) return NULL; - widgets = page->getPageWidgets (); + widgets = page->getFormWidgets (document->doc->getCatalog ()); if (!widgets) return NULL; diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc index 8531bda6..d1f1bcfa 100644 --- a/glib/poppler-page.cc +++ b/glib/poppler-page.cc @@ -76,8 +76,6 @@ poppler_page_finalize (GObject *object) g_object_unref (page->document); page->document = NULL; - if (page->annots != NULL) - delete page->annots; if (page->text != NULL) page->text->decRefCnt(); /* page->page is owned by the document */ @@ -1139,15 +1137,12 @@ poppler_page_get_link_mapping (PopplerPage *page) GList *map_list = NULL; gint i; Links *links; - Object obj; double width, height; g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL); - links = new Links (page->page->getAnnots (&obj), - page->document->doc->getCatalog ()->getBaseURI ()); - obj.free (); - + links = new Links (page->page->getAnnots (page->document->doc->getCatalog ())); + if (links == NULL) return NULL; @@ -1158,7 +1153,7 @@ poppler_page_get_link_mapping (PopplerPage *page) PopplerLinkMapping *mapping; PopplerRectangle rect; LinkAction *link_action; - Link *link; + AnnotLink *link; link = links->getLink (i); link_action = link->getAction (); @@ -1250,7 +1245,8 @@ poppler_page_get_form_field_mapping (PopplerPage *page) g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL); - forms = page->page->getPageWidgets (); + forms = page->page->getFormWidgets (page->document->doc->getCatalog ()); + if (forms == NULL) return NULL; @@ -1273,6 +1269,8 @@ poppler_page_get_form_field_mapping (PopplerPage *page) map_list = g_list_prepend (map_list, mapping); } + + delete forms; return map_list; } @@ -1310,25 +1308,24 @@ poppler_page_get_annot_mapping (PopplerPage *page) GList *map_list = NULL; double width, height; gint i; + Annots *annots; g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL); - if (!page->annots) - page->annots = page->page->getAnnots (page->document->doc->getCatalog ()); - - if (!page->annots) + annots = page->page->getAnnots (page->document->doc->getCatalog ()); + if (!annots) return NULL; poppler_page_get_size (page, &width, &height); - for (i = 0; i < page->annots->getNumAnnots (); i++) { + for (i = 0; i < annots->getNumAnnots (); i++) { PopplerAnnotMapping *mapping; PopplerRectangle rect; Annot *annot; PDFRectangle *annot_rect; gint rotation = 0; - annot = page->annots->getAnnot (i); + annot = annots->getAnnot (i); /* Create the mapping */ mapping = poppler_annot_mapping_new (); @@ -1432,7 +1429,7 @@ poppler_page_add_annot (PopplerPage *page, g_return_if_fail (POPPLER_IS_PAGE (page)); g_return_if_fail (POPPLER_IS_ANNOT (annot)); - page->page->addAnnot (annot->annot); + page->page->addAnnot (annot->annot, page->document->doc->getCatalog ()); } /* PopplerRectangle type */ diff --git a/glib/poppler-private.h b/glib/poppler-private.h index f939fa57..4e06a0ef 100644 --- a/glib/poppler-private.h +++ b/glib/poppler-private.h @@ -60,7 +60,6 @@ struct _PopplerPage Page *page; int index; TextPage *text; - Annots *annots; }; struct _PopplerFormField diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 1475db3f..5a5ba2ea 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -46,13 +46,13 @@ #include "Catalog.h" #include "Gfx.h" #include "Lexer.h" +#include "Page.h" #include "Annot.h" #include "GfxFont.h" #include "CharCodeToUnicode.h" #include "PDFDocEncoding.h" #include "Form.h" #include "Error.h" -#include "Page.h" #include "XRef.h" #include "Movie.h" #include "OptionalContent.h" @@ -853,6 +853,7 @@ AnnotAppearanceCharacs::~AnnotAppearanceCharacs() { Annot::Annot(XRef *xrefA, PDFRectangle *rectA, Catalog *catalog) { Object obj1; + refCnt = 1; flags = flagUnknown; type = typeUnknown; @@ -875,6 +876,7 @@ Annot::Annot(XRef *xrefA, PDFRectangle *rectA, Catalog *catalog) { } Annot::Annot(XRef *xrefA, Dict *dict, Catalog* catalog) { + refCnt = 1; hasRef = false; flags = flagUnknown; type = typeUnknown; @@ -883,6 +885,7 @@ Annot::Annot(XRef *xrefA, Dict *dict, Catalog* catalog) { } Annot::Annot(XRef *xrefA, Dict *dict, Catalog* catalog, Object *obj) { + refCnt = 1; if (obj->isRef()) { hasRef = gTrue; ref = obj->getRef(); @@ -1048,6 +1051,17 @@ void Annot::initialize(XRef *xrefA, Dict *dict, Catalog *catalog) { } } +void Annot::getRect(double *x1, double *y1, double *x2, double *y2) const { + *x1 = rect->x1; + *y1 = rect->y1; + *x2 = rect->x2; + *y2 = rect->y2; +} + +GBool Annot::inRect(double x, double y) const { + return rect->contains(x, y); +} + void Annot::update(const char *key, Object *value) { /* Set M to current time */ delete modified; @@ -1128,6 +1142,15 @@ void Annot::readArrayNum(Object *pdfArray, int key, double *value) { valueObject.free(); } +void Annot::incRefCnt() { + refCnt++; +} + +void Annot::decRefCnt() { + if (--refCnt == 0) + delete this; +} + Annot::~Annot() { annotObj.free(); @@ -1999,11 +2022,7 @@ AnnotLink::AnnotLink(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj) : } AnnotLink::~AnnotLink() { - /* - if (actionDict) - delete actionDict; - */ - dest.free(); + delete action; /* if (uriAction) delete uriAction; @@ -2014,15 +2033,21 @@ AnnotLink::~AnnotLink() { void AnnotLink::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) { Object obj1; - /* - if (dict->lookup("A", &obj1)->isDict()) { - actionDict = NULL; + + action = NULL; + + // look for destination + if (!dict->lookup("Dest", &obj1)->isNull()) { + action = LinkAction::parseDest(&obj1); + // look for action } else { - actionDict = NULL; + obj1.free(); + if (dict->lookup("A", &obj1)->isDict()) { + action = LinkAction::parseAction(&obj1, catalog->getBaseURI()); + } } obj1.free(); - */ - dict->lookup("Dest", &dest); + if (dict->lookup("H", &obj1)->isName()) { GooString *effect = new GooString(obj1.getName()); @@ -2750,10 +2775,9 @@ void AnnotWidget::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) { } obj1.free(); + action = NULL; if(dict->lookup("A", &obj1)->isDict()) { - action = NULL; - } else { - action = NULL; + action = LinkAction::parseAction(&obj1, catalog->getBaseURI()); } obj1.free(); @@ -5235,7 +5259,6 @@ Annot3D::Activation::Activation(Dict *dict) { Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) { Annot *annot; Object obj1; - int size; int i; annots = NULL; @@ -5251,15 +5274,8 @@ Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) { if (annotsObj->arrayGet(i, &obj1)->isDict()) { annotsObj->arrayGetNF(i, &obj2); annot = createAnnot (xref, obj1.getDict(), catalog, &obj2); - if (annot && annot->isOk()) { - if (nAnnots >= size) { - size += 16; - annots = (Annot **)greallocn(annots, size, sizeof(Annot *)); - } - annots[nAnnots++] = annot; - } else { - delete annot; - } + appendAnnot(annot); + annot->decRefCnt(); } obj2.free(); obj1.free(); @@ -5267,6 +5283,17 @@ Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) { } } +void Annots::appendAnnot(Annot *annot) { + if (annot && annot->isOk()) { + if (nAnnots >= size) { + size += 16; + annots = (Annot **)greallocn(annots, size, sizeof(Annot *)); + } + annots[nAnnots++] = annot; + annot->incRefCnt(); + } +} + Annot *Annots::createAnnot(XRef *xref, Dict* dict, Catalog *catalog, Object *obj) { Annot *annot; Object obj1; @@ -5364,7 +5391,7 @@ Annots::~Annots() { int i; for (i = 0; i < nAnnots; ++i) { - delete annots[i]; + annots[i]->decRefCnt(); } gfree(annots); } diff --git a/poppler/Annot.h b/poppler/Annot.h index a3922674..8df1c67e 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -486,9 +486,11 @@ public: Annot(XRef *xrefA, PDFRectangle *rectA, Catalog *catalog); Annot(XRef *xrefA, Dict *dict, Catalog *catalog); Annot(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj); - virtual ~Annot(); GBool isOk() { return ok; } + void incRefCnt(); + void decRefCnt(); + virtual void draw(Gfx *gfx, GBool printing); // Get appearance object. Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } @@ -513,9 +515,11 @@ public: // getters XRef *getXRef() const { return xref; } + GBool getHasRef() const { return hasRef; } Ref getRef() const { return ref; } AnnotSubtype getType() const { return type; } PDFRectangle *getRect() const { return rect; } + void getRect(double *x1, double *y1, double *x2, double *y2) const; GooString *getContents() const { return contents; } int getPageNum() const { return page; } GooString *getName() const { return name; } @@ -529,6 +533,9 @@ public: int getId() { return ref.num; } + // Check if point is inside the annot rectangle. + GBool inRect(double x, double y) const; + private: void readArrayNum(Object *pdfArray, int key, double *value); // write vStr[i:j[ in appearBuf @@ -537,6 +544,7 @@ private: protected: + virtual ~Annot(); void setColor(AnnotColor *color, GBool fill); void drawCircle(double cx, double cy, double r, GBool fill); void drawCircleTopLeft(double cx, double cy, double r); @@ -550,6 +558,8 @@ protected: // and sets M to the current time void update(const char *key, Object *value); + int refCnt; + Object annotObj; // required data @@ -774,8 +784,7 @@ public: virtual void draw(Gfx *gfx, GBool printing); // getters - Dict *getActionDict() const { return actionDict; } - Object *getDest() { return &dest; } + LinkAction *getAction() const { return action; } AnnotLinkEffect getLinkEffect() const { return linkEffect; } Dict *getUriAction() const { return uriAction; } AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; } @@ -784,8 +793,7 @@ protected: void initialize(XRef *xrefA, Catalog *catalog, Dict *dict); - Dict *actionDict; // A - Object dest; // Dest + LinkAction *action; // A, Dest AnnotLinkEffect linkEffect; // H (Default I) Dict *uriAction; // PA @@ -1161,7 +1169,7 @@ public: AnnotWidgetHighlightMode getMode() { return mode; } AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; } - Dict *getAction() { return action; } + LinkAction *getAction() { return action; } Dict *getAdditionActions() { return additionActions; } Dict *getParent() { return parent; } @@ -1185,7 +1193,7 @@ private: FormWidget *widget; // FormWidget object for this annotation AnnotWidgetHighlightMode mode; // H (Default I) AnnotAppearanceCharacs *appearCharacs; // MK - Dict *action; // A + LinkAction *action; // A Dict *additionActions; // AA // inherited from Annot // AnnotBorderBS border; // BS @@ -1268,6 +1276,7 @@ public: // Iterate through list of annotations. int getNumAnnots() { return nAnnots; } Annot *getAnnot(int i) { return annots[i]; } + void appendAnnot(Annot *annot); private: Annot* createAnnot(XRef *xref, Dict* dict, Catalog *catalog, Object *obj); @@ -1275,6 +1284,7 @@ private: Annot **annots; int nAnnots; + int size; }; #endif diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc index d065d9b7..bfec6902 100644 --- a/poppler/ArthurOutputDev.cc +++ b/poppler/ArthurOutputDev.cc @@ -140,10 +140,6 @@ void ArthurOutputDev::startPage(int pageNum, GfxState *state) void ArthurOutputDev::endPage() { } -void ArthurOutputDev::drawLink(Link *link, Catalog *catalog) -{ -} - void ArthurOutputDev::saveState(GfxState *state) { m_painter->save(); diff --git a/poppler/ArthurOutputDev.h b/poppler/ArthurOutputDev.h index fc00c71b..984f95e8 100644 --- a/poppler/ArthurOutputDev.h +++ b/poppler/ArthurOutputDev.h @@ -91,9 +91,6 @@ public: // End a page. virtual void endPage(); - //----- link borders - virtual void drawLink(Link *link, Catalog *catalog); - //----- save/restore graphics state virtual void saveState(GfxState *state); virtual void restoreState(GfxState *state); diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 2ee51677..de0663c3 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -242,9 +242,6 @@ void CairoOutputDev::endPage() { } } -void CairoOutputDev::drawLink(Link *link, Catalog *catalog) { -} - void CairoOutputDev::saveState(GfxState *state) { LOG(printf ("save\n")); cairo_save (cairo); diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 9404d6d9..8ef2a932 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -128,9 +128,6 @@ public: // End a page. virtual void endPage(); - //----- link borders - virtual void drawLink(Link *link, Catalog *catalog); - //----- save/restore graphics state virtual void saveState(GfxState *state); virtual void restoreState(GfxState *state); @@ -386,9 +383,6 @@ public: // Does this device need non-text content? virtual GBool needNonText() { return gTrue; } - //----- link borders - virtual void drawLink(Link *link, Catalog *catalog) { } - //----- save/restore graphics state virtual void saveState(GfxState *state) { } virtual void restoreState(GfxState *state) { } diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc index 6560598f..ecf26fbb 100644 --- a/poppler/FontInfo.cc +++ b/poppler/FontInfo.cc @@ -73,8 +73,7 @@ GooList *FontInfoScanner::scan(int nPages) { if ((resDict = page->getResourceDict())) { scanFonts(resDict, result); } - annots = new Annots(doc->getXRef(), doc->getCatalog(), page->getAnnots(&obj1)); - obj1.free(); + annots = page->getAnnots(doc->getCatalog()); for (int i = 0; i < annots->getNumAnnots(); ++i) { if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) { obj1.streamGetDict()->lookup("Resources", &obj2); @@ -85,7 +84,6 @@ GooList *FontInfoScanner::scan(int nPages) { } obj1.free(); } - delete annots; } currentPage = lastPage; diff --git a/poppler/Form.cc b/poppler/Form.cc index 4e1b8e11..15e7e612 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -1360,50 +1360,40 @@ FormWidget* Form::findWidgetByRef (Ref aref) // FormPageWidgets //------------------------------------------------------------------------ -FormPageWidgets::FormPageWidgets (XRef *xrefA, Object* annots, unsigned int page, Form *form) +FormPageWidgets::FormPageWidgets (Annots *annots, unsigned int page, Form *form) { - Object obj1; numWidgets = 0; widgets = NULL; - xref = xrefA; - if (annots->isArray() && form) { - size = annots->arrayGetLength(); + + if (annots && annots->getNumAnnots() > 0 && form) { + size = annots->getNumAnnots(); widgets = (FormWidget**)greallocn(widgets, size, sizeof(FormWidget*)); /* For each entry in the page 'Annots' dict, try to find a matching form field */ for (int i = 0; i < size; ++i) { - if (!annots->arrayGetNF(i, &obj1)->isRef()) { + Annot *annot = annots->getAnnot(i); + + if (!annot->getHasRef()) { /* Since all entry in a form field's kid dict needs to be indirect references, if this annot isn't indirect, it isn't related to a form field */ - obj1.free(); continue; } - Ref r = obj1.getRef(); + + Ref r = annot->getRef(); /* Try to find a form field which either has this Annot in its Kids entry or is merged with this Annot */ FormWidget* tmp = form->findWidgetByRef(r); - if(tmp) { + if (tmp) { // We've found a corresponding form field, link it tmp->setID(FormWidget::encodeID(page, numWidgets)); + tmp->setFontSize(annot->getFontSize()); widgets[numWidgets++] = tmp; - //create a temporary Annot to get the font size - Object obj2; - if (annots->arrayGet(i, &obj2)->isDict()) { - Annot *ann; - - ann = new Annot(xref, obj2.getDict(), NULL); - tmp->setFontSize(ann->getFontSize()); - delete ann; - } - obj2.free(); - } - - obj1.free(); + } } - } + } } FormPageWidgets::~FormPageWidgets() diff --git a/poppler/Form.h b/poppler/Form.h index b38b92f4..833fa272 100644 --- a/poppler/Form.h +++ b/poppler/Form.h @@ -26,6 +26,7 @@ class GooString; class Array; class Dict; class Annot; +class Annots; class Catalog; class LinkAction; @@ -477,7 +478,7 @@ private: class FormPageWidgets { public: - FormPageWidgets (XRef *xrefA, Object* annots, unsigned int page, Form *form); + FormPageWidgets (Annots* annots, unsigned int page, Form *form); ~FormPageWidgets(); int getNumWidgets() const { return numWidgets; } @@ -487,8 +488,6 @@ private: FormWidget** widgets; int numWidgets; int size; - unsigned pageNum; - XRef* xref; }; #endif diff --git a/poppler/Link.cc b/poppler/Link.cc index b6d7f2df..d2812129 100644 --- a/poppler/Link.cc +++ b/poppler/Link.cc @@ -44,6 +44,7 @@ #include "Sound.h" #include "FileSpec.h" #include "Rendition.h" +#include "Annot.h" //------------------------------------------------------------------------ // LinkAction @@ -860,96 +861,10 @@ LinkUnknown::~LinkUnknown() { } //------------------------------------------------------------------------ -// Link -//------------------------------------------------------------------------ - -Link::Link(Dict *dict, GooString *baseURI) { - Object obj1, obj2; - double t; - - action = NULL; - ok = gFalse; - - // get rectangle - if (!dict->lookup("Rect", &obj1)->isArray()) { - error(-1, "Annotation rectangle is wrong type"); - goto err2; - } - if (!obj1.arrayGet(0, &obj2)->isNum()) { - error(-1, "Bad annotation rectangle"); - goto err1; - } - x1 = obj2.getNum(); - obj2.free(); - if (!obj1.arrayGet(1, &obj2)->isNum()) { - error(-1, "Bad annotation rectangle"); - goto err1; - } - y1 = obj2.getNum(); - obj2.free(); - if (!obj1.arrayGet(2, &obj2)->isNum()) { - error(-1, "Bad annotation rectangle"); - goto err1; - } - x2 = obj2.getNum(); - obj2.free(); - if (!obj1.arrayGet(3, &obj2)->isNum()) { - error(-1, "Bad annotation rectangle"); - goto err1; - } - y2 = obj2.getNum(); - obj2.free(); - obj1.free(); - if (x1 > x2) { - t = x1; - x1 = x2; - x2 = t; - } - if (y1 > y2) { - t = y1; - y1 = y2; - y2 = t; - } - - // look for destination - if (!dict->lookup("Dest", &obj1)->isNull()) { - action = LinkAction::parseDest(&obj1); - - // look for action - } else { - obj1.free(); - if (dict->lookup("A", &obj1)->isDict()) { - action = LinkAction::parseAction(&obj1, baseURI); - } - } - obj1.free(); - - // check for bad action - if (action) { - ok = gTrue; - } - - return; - - err1: - obj2.free(); - err2: - obj1.free(); -} - -Link::~Link() { - if (action) { - delete action; - } -} - -//------------------------------------------------------------------------ // Links //------------------------------------------------------------------------ -Links::Links(Object *annots, GooString *baseURI) { - Link *link; - Object obj1, obj2; +Links::Links(Annots *annots) { int size; int i; @@ -957,25 +872,21 @@ Links::Links(Object *annots, GooString *baseURI) { size = 0; numLinks = 0; - if (annots->isArray()) { - for (i = 0; i < annots->arrayGetLength(); ++i) { - if (annots->arrayGet(i, &obj1)->isDict()) { - if (obj1.dictLookup("Subtype", &obj2)->isName("Link")) { - link = new Link(obj1.getDict(), baseURI); - if (link->isOk()) { - if (numLinks >= size) { - size += 16; - links = (Link **)greallocn(links, size, sizeof(Link *)); - } - links[numLinks++] = link; - } else { - delete link; - } - } - obj2.free(); - } - obj1.free(); + if (!annots) + return; + + for (i = 0; i < annots->getNumAnnots(); ++i) { + Annot *annot = annots->getAnnot(i); + + if (annot->getType() != Annot::typeLink) + continue; + + if (numLinks >= size) { + size += 16; + links = (AnnotLink **)greallocn(links, size, sizeof(AnnotLink *)); } + annot->incRefCnt(); + links[numLinks++] = static_cast<AnnotLink *>(annot); } } @@ -983,7 +894,8 @@ Links::~Links() { int i; for (i = 0; i < numLinks; ++i) - delete links[i]; + links[i]->decRefCnt(); + gfree(links); } diff --git a/poppler/Link.h b/poppler/Link.h index ea10375b..a5dbfab5 100644 --- a/poppler/Link.h +++ b/poppler/Link.h @@ -37,6 +37,8 @@ class Array; class Dict; class Sound; class MediaRendition; +class AnnotLink; +class Annots; //------------------------------------------------------------------------ // LinkAction @@ -454,41 +456,6 @@ private: }; //------------------------------------------------------------------------ -// Link -//------------------------------------------------------------------------ - -class Link { -public: - - // Construct a link, given its dictionary. - Link(Dict *dict, GooString *baseURI); - - // Destructor. - ~Link(); - - // Was the link created successfully? - GBool isOk() { return ok; } - - // Check if point is inside the link rectangle. - GBool inRect(double x, double y) - { return x1 <= x && x <= x2 && y1 <= y && y <= y2; } - - // Get action. - LinkAction *getAction() { return action; } - - // Get the link rectangle. - void getRect(double *xa1, double *ya1, double *xa2, double *ya2) - { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; } - -private: - - double x1, y1; // lower left corner - double x2, y2; // upper right corner - LinkAction *action; // action - GBool ok; // is link valid? -}; - -//------------------------------------------------------------------------ // Links //------------------------------------------------------------------------ @@ -496,14 +463,14 @@ class Links { public: // Extract links from array of annotations. - Links(Object *annots, GooString *baseURI); + Links(Annots *annots); // Destructor. ~Links(); // Iterate through list of links. int getNumLinks() const { return numLinks; } - Link *getLink(int i) const { return links[i]; } + AnnotLink *getLink(int i) const { return links[i]; } // If point <x>,<y> is in a link, return the associated action; // else return NULL. @@ -514,7 +481,7 @@ public: private: - Link **links; + AnnotLink **links; int numLinks; }; diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index 65cfa2da..31767d0c 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -55,7 +55,7 @@ class GfxGouraudTriangleShading; class GfxPatchMeshShading; class Stream; class Links; -class Link; +class AnnotLink; class Catalog; class Page; class Function; @@ -304,7 +304,7 @@ public: virtual void clearSoftMask(GfxState * /*state*/) {} //----- links - virtual void processLink(Link * /*link*/, Catalog * /*catalog*/) {} + virtual void processLink(AnnotLink * /*link*/, Catalog * /*catalog*/) {} #if 1 //~tmp: turn off anti-aliasing temporarily virtual GBool getVectorAntialias() { return gFalse; } diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index cb3de02d..cf5cde9d 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -473,9 +473,7 @@ void PDFDoc::displayPageSlice(OutputDev *out, int page, Links *PDFDoc::getLinks(int page) { Page *p = getPage(page); if (!p) { - Object obj; - obj.initNull(); - return new Links (&obj, NULL); + return new Links (NULL); } return p->getLinks(catalog); } diff --git a/poppler/Page.cc b/poppler/Page.cc index caf233f2..5c7edf48 100644 --- a/poppler/Page.cc +++ b/poppler/Page.cc @@ -262,7 +262,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs xref = xrefA; num = numA; duration = -1; - pageWidgets = NULL; + annots = NULL; pageObj.initDict(pageDict); pageRef = pageRefA; @@ -289,18 +289,14 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs tmp.free(); // annotations - pageDict->lookupNF("Annots", &annots); - if (!(annots.isRef() || annots.isArray() || annots.isNull())) { + pageDict->lookupNF("Annots", &annotsObj); + if (!(annotsObj.isRef() || annotsObj.isArray() || annotsObj.isNull())) { error(-1, "Page annotations object (page %d) is wrong type (%s)", - num, annots.getTypeName()); - annots.free(); + num, annotsObj.getTypeName()); + annotsObj.free(); goto err2; } - // forms - pageWidgets = new FormPageWidgets(xrefA, this->getAnnots(&tmp),num,form); - tmp.free(); - // contents pageDict->lookupNF("Contents", &contents); if (!(contents.isRef() || contents.isArray() || @@ -331,17 +327,17 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs trans.initNull(); err2: - annots.initNull(); + annotsObj.initNull(); err1: contents.initNull(); ok = gFalse; } Page::~Page() { - delete pageWidgets; delete attrs; + delete annots; pageObj.free(); - annots.free(); + annotsObj.free(); contents.free(); trans.free(); thumb.free(); @@ -349,20 +345,26 @@ Page::~Page() { } Annots *Page::getAnnots(Catalog *catalog) { - Annots *annots; - Object obj; + if (!annots) { + Object obj; + annots = new Annots(xref, catalog, getAnnots(&obj)); + obj.free(); + } - annots = new Annots(xref, catalog, getAnnots(&obj)); - obj.free(); return annots; } -void Page::addAnnot(Annot *annot) { +void Page::addAnnot(Annot *annot, Catalog *catalog) { Object obj1; Object tmp; Ref annotRef = annot->getRef (); - if (annots.isNull()) { + // Make sure we have annots before adding the new one + // even if it's an empty list so that we can safely + // call annots->appendAnnot(annot) + getAnnots(catalog); + + if (annotsObj.isNull()) { Ref annotsRef; // page doesn't have annots array, // we have to create it @@ -372,31 +374,32 @@ void Page::addAnnot(Annot *annot) { tmp.free(); annotsRef = xref->addIndirectObject (&obj1); - annots.initRef(annotsRef.num, annotsRef.gen); - pageObj.dictSet ("Annots", &annots); + annotsObj.initRef(annotsRef.num, annotsRef.gen); + pageObj.dictSet ("Annots", &annotsObj); xref->setModifiedObject (&pageObj, pageRef); } else { getAnnots(&obj1); if (obj1.isArray()) { obj1.arrayAdd (tmp.initRef (annotRef.num, annotRef.gen)); - if (annots.isRef()) - xref->setModifiedObject (&obj1, annots.getRef()); + if (annotsObj.isRef()) + xref->setModifiedObject (&obj1, annotsObj.getRef()); else xref->setModifiedObject (&pageObj, pageRef); } obj1.free(); } + annots->appendAnnot(annot); + annot->setPage(&pageRef, num); } Links *Page::getLinks(Catalog *catalog) { - Links *links; - Object obj; + return new Links(getAnnots(catalog)); +} - links = new Links(getAnnots(&obj), catalog->getBaseURI()); - obj.free(); - return links; +FormPageWidgets *Page::getFormWidgets(Catalog *catalog) { + return new FormPageWidgets(getAnnots(catalog), num, catalog->getForm()); } void Page::display(OutputDev *out, double hDPI, double vDPI, @@ -485,9 +488,8 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, obj.free(); // draw annotations - annotList = new Annots(xref, catalog, getAnnots(&obj)); - obj.free(); - + annotList = getAnnots(catalog); + if (annotList->getNumAnnots() > 0) { if (globalParams->getPrintCommands()) { printf("***** Annotations\n"); @@ -502,7 +504,6 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, } out->dump(); } - delete annotList; delete gfx; } diff --git a/poppler/Page.h b/poppler/Page.h index 9d892b17..6db90497 100644 --- a/poppler/Page.h +++ b/poppler/Page.h @@ -55,6 +55,7 @@ public: PDFRectangle(double x1A, double y1A, double x2A, double y2A) { x1 = x1A; y1 = y1A; x2 = x2A; y2 = y2A; } GBool isValid() { return x1 != 0 || y1 != 0 || x2 != 0 || y2 != 0; } + GBool contains(double x, double y) { return x1 <= x && x <= x2 && y1 <= y && y <= y2; } void clipTo(PDFRectangle *rect); }; @@ -162,9 +163,9 @@ public: Dict *getResourceDict() { return attrs->getResourceDict(); } // Get annotations array. - Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); } + Object *getAnnots(Object *obj) { return annotsObj.fetch(xref, obj); } // Add a new annotation to the page - void addAnnot(Annot *annot); + void addAnnot(Annot *annot, Catalog *catalog); // Return a list of links. Links *getLinks(Catalog *catalog); @@ -183,7 +184,7 @@ public: Object *getTrans(Object *obj) { return trans.fetch(xref, obj); } // Get form. - FormPageWidgets *getPageWidgets() { return pageWidgets; } + FormPageWidgets *getFormWidgets(Catalog *catalog); // Get duration, the maximum length of time, in seconds, // that the page is displayed before the presentation automatically @@ -241,9 +242,9 @@ private: Ref pageRef; // page reference int num; // page number PageAttrs *attrs; // page attributes - Object annots; // annotations array + Annots *annots; // annotations + Object annotsObj; // annotations array Object contents; // page contents - FormPageWidgets *pageWidgets; // the form for that page Object thumb; // page thumbnail Object trans; // page transition Object actions; // page addiction actions diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index a946ba61..428cdb33 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -58,6 +58,7 @@ #include "Link.h" #include "TextOutputDev.h" #include "Page.h" +#include "Annot.h" #include "PDFDocEncoding.h" #ifdef MACOS @@ -184,12 +185,12 @@ public: class TextLink { public: - TextLink(int xMinA, int yMinA, int xMaxA, int yMaxA, Link *linkA) + TextLink(int xMinA, int yMinA, int xMaxA, int yMaxA, AnnotLink *linkA) { xMin = xMinA; yMin = yMinA; xMax = xMaxA; yMax = yMaxA; link = linkA; } ~TextLink() {} int xMin, yMin, xMax, yMax; - Link *link; + AnnotLink *link; }; //------------------------------------------------------------------------ @@ -2337,7 +2338,7 @@ void TextPage::addUnderline(double x0, double y0, double x1, double y1) { underlines->append(new TextUnderline(x0, y0, x1, y1)); } -void TextPage::addLink(int xMin, int yMin, int xMax, int yMax, Link *link) { +void TextPage::addLink(int xMin, int yMin, int xMax, int yMax, AnnotLink *link) { links->append(new TextLink(xMin, yMin, xMax, yMax, link)); } @@ -5347,7 +5348,7 @@ void TextOutputDev::eoFill(GfxState *state) { fill(state); } -void TextOutputDev::processLink(Link *link, Catalog * /*catalog*/) { +void TextOutputDev::processLink(AnnotLink *link, Catalog * /*catalog*/) { double x1, y1, x2, y2; int xMin, yMin, xMax, yMax, x, y; diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h index 438aee49..5bbcdfb2 100644 --- a/poppler/TextOutputDev.h +++ b/poppler/TextOutputDev.h @@ -42,7 +42,7 @@ class Gfx; class GfxFont; class GfxState; class UnicodeMap; -class Link; +class AnnotLink; class TextWord; class TextPool; @@ -160,7 +160,7 @@ public: GBool getSpaceAfter() { return spaceAfter; } #endif GBool isUnderlined() { return underlined; } - Link *getLink() { return link; } + AnnotLink *getLink() { return link; } double getEdge(int i) { return edge[i]; } double getBaseline () { return base; } GBool hasSpaceAfter () { return spaceAfter; } @@ -194,7 +194,7 @@ private: #endif GBool underlined; - Link *link; + AnnotLink *link; friend class TextPool; friend class TextLine; @@ -510,7 +510,7 @@ public: void addUnderline(double x0, double y0, double x1, double y1); // Add a hyperlink. - void addLink(int xMin, int yMin, int xMax, int yMax, Link *link); + void addLink(int xMin, int yMin, int xMax, int yMax, AnnotLink *link); // Coalesce strings that look like parts of the same line. void coalesce(GBool physLayout, GBool doHTML); @@ -727,7 +727,7 @@ public: virtual void eoFill(GfxState *state); //----- link borders - virtual void processLink(Link *link, Catalog *catalog); + virtual void processLink(AnnotLink *link, Catalog *catalog); //----- special access diff --git a/qt4/src/poppler-link-extractor-private.h b/qt4/src/poppler-link-extractor-private.h index 284f33cd..234ff6be 100644 --- a/qt4/src/poppler-link-extractor-private.h +++ b/qt4/src/poppler-link-extractor-private.h @@ -40,7 +40,7 @@ class LinkExtractorOutputDev : public OutputDev virtual GBool upsideDown() { return gFalse; } virtual GBool useDrawChar() { return gFalse; } virtual GBool interpretType3Chars() { return gFalse; } - virtual void processLink(::Link *link, Catalog *catalog); + virtual void processLink(::AnnotLink *link, Catalog *catalog); // our stuff QList< Link* > links(); diff --git a/qt4/src/poppler-link-extractor.cc b/qt4/src/poppler-link-extractor.cc index e9806b59..f10a16a3 100644 --- a/qt4/src/poppler-link-extractor.cc +++ b/qt4/src/poppler-link-extractor.cc @@ -23,6 +23,7 @@ #include <Link.h> #include <Object.h> #include <Page.h> +#include <Annot.h> #include "poppler-qt4.h" #include "poppler-page-private.h" @@ -48,7 +49,7 @@ LinkExtractorOutputDev::~LinkExtractorOutputDev() qDeleteAll(m_links); } -void LinkExtractorOutputDev::processLink(::Link *link, Catalog *catalog) +void LinkExtractorOutputDev::processLink(::AnnotLink *link, Catalog *catalog) { if (!link->isOk()) return; diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc index b0821cbc..3ca8c075 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -558,7 +558,6 @@ QList<Annotation*> Page::annotations() const const uint numAnnotations = annots->getNumAnnots(); if ( numAnnotations == 0 ) { - delete annots; return QList<Annotation*>(); } @@ -907,11 +906,9 @@ QList<Annotation*> Page::annotations() const // TODO // reading link action - if ( !linkann->getDest()->isNull() ) + if ( linkann->getAction() ) { - ::LinkAction *act = ::LinkAction::parseDest( linkann->getDest() ); - Link * popplerLink = m_page->convertLinkActionToLink( act, QRectF() ); - delete act; + Link * popplerLink = m_page->convertLinkActionToLink( linkann->getAction(), QRectF() ); if ( popplerLink ) { l->setLinkDestination( popplerLink ); @@ -1301,7 +1298,6 @@ QList<Annotation*> Page::annotations() const } } - delete annots; /** 5 - finally RETURN ANNOTATIONS */ return annotationsMap.values(); } @@ -1310,7 +1306,7 @@ QList<FormField*> Page::formFields() const { QList<FormField*> fields; ::Page *p = m_page->page; - ::FormPageWidgets * form = p->getPageWidgets(); + ::FormPageWidgets * form = p->getFormWidgets(m_page->parentDoc->doc->getCatalog()); int formcount = form->getNumWidgets(); for (int i = 0; i < formcount; ++i) { @@ -1343,6 +1339,8 @@ QList<FormField*> Page::formFields() const fields.append(ff); } + delete form; + return fields; } diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index ede5700d..19c1e5fa 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -52,6 +52,7 @@ #include "Error.h" #include "GfxState.h" #include "Page.h" +#include "Annot.h" #include "PNGWriter.h" #ifdef ENABLE_LIBJPEG #include "DCTStream.h" @@ -1395,10 +1396,10 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, -void HtmlOutputDev::doProcessLink(Link* link){ +void HtmlOutputDev::doProcessLink(AnnotLink* link){ double _x1,_y1,_x2,_y2; int x1,y1,x2,y2; - + link->getRect(&_x1,&_y1,&_x2,&_y2); cvtUserToDev(_x1,_y1,&x1,&y1); @@ -1411,7 +1412,7 @@ void HtmlOutputDev::doProcessLink(Link* link){ delete _dest; } -GooString* HtmlOutputDev::getLinkDest(Link *link,Catalog* catalog){ +GooString* HtmlOutputDev::getLinkDest(AnnotLink *link,Catalog* catalog){ char *p; switch(link->getAction()->getKind()) { diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h index 7afffa58..e6be5871 100644 --- a/utils/HtmlOutputDev.h +++ b/utils/HtmlOutputDev.h @@ -300,8 +300,8 @@ private: // convert encoding into a HTML standard, or encoding->getCString if not // recognized static char* mapEncodingToHtml(GooString* encoding); - void doProcessLink(Link *link); - GooString* getLinkDest(Link *link,Catalog *catalog); + void doProcessLink(AnnotLink *link); + GooString* getLinkDest(AnnotLink *link,Catalog *catalog); void dumpMetaVars(FILE *); void doFrame(int firstPage); GBool newOutlineLevel(FILE *output, Object *node, Catalog* catalog, int level = 1); |