summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2011-03-01 10:56:40 +0100
committerCarlos Garcia Campos <carlosgc@gnome.org>2011-03-01 12:32:24 +0100
commit664865a2ddca9c20ac36a41aef52ebf12eab838d (patch)
tree35b8e56ca44eec26ae566696284754e4d3e9c4fd
parent1f6573e949aaba0eb0a4c2f9cd73d7ad45ba67be (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.cc2
-rw-r--r--glib/poppler-page.cc29
-rw-r--r--glib/poppler-private.h1
-rw-r--r--poppler/Annot.cc79
-rw-r--r--poppler/Annot.h24
-rw-r--r--poppler/ArthurOutputDev.cc4
-rw-r--r--poppler/ArthurOutputDev.h3
-rw-r--r--poppler/CairoOutputDev.cc3
-rw-r--r--poppler/CairoOutputDev.h6
-rw-r--r--poppler/FontInfo.cc4
-rw-r--r--poppler/Form.cc36
-rw-r--r--poppler/Form.h5
-rw-r--r--poppler/Link.cc124
-rw-r--r--poppler/Link.h43
-rw-r--r--poppler/OutputDev.h4
-rw-r--r--poppler/PDFDoc.cc4
-rw-r--r--poppler/Page.cc63
-rw-r--r--poppler/Page.h11
-rw-r--r--poppler/TextOutputDev.cc9
-rw-r--r--poppler/TextOutputDev.h10
-rw-r--r--qt4/src/poppler-link-extractor-private.h2
-rw-r--r--qt4/src/poppler-link-extractor.cc3
-rw-r--r--qt4/src/poppler-page.cc12
-rw-r--r--utils/HtmlOutputDev.cc7
-rw-r--r--utils/HtmlOutputDev.h4
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);