From c48d2f28916b5fdaf9c2e4434d7031c3eb4ded65 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?I=C3=B1igo=20Mart=C3=ADnez?= <inigomartinez@gmail.com>
Date: Sun, 30 Dec 2007 19:37:18 +0100
Subject: [PATCH] Improved AnnotLink support.
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Iñigo Martínez <inigomartinez@gmail.com>
---
 poppler/Annot.cc |  116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 poppler/Annot.h  |   51 ++++++++++++++++++++++++
 2 files changed, 167 insertions(+), 0 deletions(-)

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index da6cca9..0cb7641 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -82,6 +82,22 @@ AnnotExternalDataType parseAnnotExternalData(Dict* dict) {
 }
 
 //------------------------------------------------------------------------
+// AnnotQuadPoints
+//------------------------------------------------------------------------
+
+AnnotQuadPoints::AnnotQuadPoints(double x1, double y1, double x2, double y2,
+    double x3, double y3, double x4, double y4) {
+  this->x1 = x1;
+  this->y1 = y1;
+  this->x2 = x2;
+  this->y2 = y2;
+  this->x3 = x3;
+  this->y3 = y3;
+  this->x4 = x4;
+  this->y4 = y4;
+}
+
+//------------------------------------------------------------------------
 // AnnotBorder
 //------------------------------------------------------------------------
 AnnotBorder::AnnotBorder() {
@@ -1975,6 +1991,106 @@ AnnotLink::AnnotLink(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog,
     Annot(xrefA, acroForm, dict, catalog, obj) {
 
   type = typeLink;
+  initialize (xrefA, catalog, dict);
+}
+
+AnnotLink::~AnnotLink() {
+  /*
+  if (actionDict)
+    delete actionDict;
+
+  if (uriAction)
+    delete uriAction;
+  */
+  if(quadrilaterals) {
+    for(int i = 0; i < quadrilateralsLength; i++)
+      delete quadrilaterals[i];
+
+    gfree (quadrilaterals);
+  }
+}
+
+void AnnotLink::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
+  Object obj1;
+  /*
+  if (dict->lookup("A", &obj1)->isDict()) {
+    actionDict = NULL;
+  } else {
+    actionDict = NULL;
+  }
+  obj1.free();
+  */
+  if (dict->lookup("H", &obj1)->isName()) {
+    GooString *effect = new GooString(obj1.getName());
+
+    if (!effect->cmp("N")) {
+      linkEffect = effectNone;
+    } else if (!effect->cmp("I")) {
+      linkEffect = effectInvert;
+    } else if (!effect->cmp("O")) {
+      linkEffect = effectOutline;
+    } else if (!effect->cmp("P")) {
+      linkEffect = effectPush;
+    } else {
+      linkEffect = effectInvert;
+    }
+    delete effect;
+  } else {
+    linkEffect = effectInvert;
+  }
+  obj1.free();
+  /*
+  if (dict->lookup("PA", &obj1)->isDict()) {
+    uriAction = NULL;
+  } else {
+    uriAction = NULL;
+  }
+  obj1.free();
+  */
+  /*
+   * TODO:
+   * QuadPoints should be ignored if any coordinate in the array lies outside
+   * the region specified by Rect.
+   */
+  if(dict->lookup("QuadPoints", &obj1)->isArray()) {
+    quadrilateralsLength = obj1.arrayGetLength();
+    if((quadrilateralsLength % 8) == 0) {
+      Object obj2;
+
+      quadrilaterals = (AnnotQuadPoints **) gmallocn
+        ((quadrilateralsLength / 8), sizeof(AnnotQuadPoints *));
+      for(int i = 0; i < quadrilateralsLength; i += 8) {
+        double x1, y1, x2, y2, x3, y3, x4, y4;
+
+        (obj1.arrayGet(i, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 1), &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 2), &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 3), &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 4), &obj2)->isNum() ? x3 = obj2.getNum() : x3 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 5), &obj2)->isNum() ? y3 = obj2.getNum() : y3 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 6), &obj2)->isNum() ? x4 = obj2.getNum() : x4 = 0);
+        obj2.free();
+        (obj1.arrayGet((i + 7), &obj2)->isNum() ? y4 = obj2.getNum() : y4 = 0);
+        obj2.free();
+
+        quadrilaterals[i / 8] =
+          new AnnotQuadPoints(x1, y1, x2, y2, x3, y3, x4, y4);
+      }
+      quadrilateralsLength /= 8;
+    } else {
+      quadrilaterals = NULL;
+      quadrilateralsLength = 0;
+    }
+  } else {
+    quadrilaterals = NULL;
+  }
+  obj1.free();
 }
 
 //------------------------------------------------------------------------
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 7456160..16a907d 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -28,6 +28,29 @@ enum AnnotExternalDataType {
 };
 
 //------------------------------------------------------------------------
+// AnnotQuadPoints
+//------------------------------------------------------------------------
+
+class AnnotQuadPoints {
+public:
+  
+  AnnotQuadPoints(double x1, double y1, double x2, double y2, double x3,
+      double y3, double x4, double y4);
+
+  double getX1() const { return x1; }
+  double getY1() const { return y1; }
+  double getX2() const { return x2; }
+  double getY2() const { return y2; }
+  double getX3() const { return x3; }
+  double getY3() const { return y3; }
+  double getX4() const { return x4; }
+  double getY4() const { return y4; }
+
+protected:
+  double x1, y1, x2, y2, x3, y3, x4, y4;
+};
+
+//------------------------------------------------------------------------
 // AnnotBorder
 //------------------------------------------------------------------------
 
@@ -410,7 +433,35 @@ private:
 class AnnotLink: public Annot {
 public:
 
+  enum AnnotLinkEffect {
+    effectNone,     // N
+    effectInvert,   // I
+    effectOutline,  // O
+    effectPush      // P
+  };
+
   AnnotLink(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
+  virtual ~AnnotLink();
+
+  // getters
+  Dict *getActionDict() const { return actionDict; }
+  // getDest
+  AnnotLinkEffect getLinkEffect() const { return linkEffect; }
+  Dict *getUriAction() const { return uriAction; }
+  AnnotQuadPoints **getQuadrilaterals() const { return quadrilaterals; }
+  int getQuadrilateralsLength() const { return quadrilateralsLength; }
+
+protected:
+
+  void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
+
+  Dict *actionDict;                 // A
+  //Dest
+  AnnotLinkEffect linkEffect;       // H          (Default I)
+  Dict *uriAction;                  // PA
+
+  AnnotQuadPoints **quadrilaterals; // QuadPoints
+  int quadrilateralsLength;
 };
 
 //------------------------------------------------------------------------
-- 
1.5.3.7

