]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/Link.cc
add GnomePrintJob to EvPrintJob constructor arguments.
[evince.git] / pdf / xpdf / Link.cc
index 0c3a86926203286ce8d81e22a0381af943243832..bfb41b7d80edc58970047c646874f1b42f410979 100644 (file)
@@ -2,7 +2,7 @@
 //
 // Link.cc
 //
-// Copyright 1996-2002 Glyph & Cog, LLC
+// Copyright 1996-2003 Glyph & Cog, LLC
 //
 //========================================================================
 
@@ -42,8 +42,9 @@ LinkAction *LinkAction::parseAction(Object *obj, GString *baseURI) {
   Object obj2, obj3, obj4;
 
   if (!obj->isDict()) {
-    error(-1, "Bad annotation action");
-    return NULL;
+      error(-1, "parseAction: Bad annotation action for URI '%s'",
+            baseURI ? baseURI->getCString() : "NULL");
+      return NULL;
   }
 
   obj->dictLookup("S", &obj2);
@@ -92,7 +93,8 @@ LinkAction *LinkAction::parseAction(Object *obj, GString *baseURI) {
 
   // action is missing or wrong type
   } else {
-    error(-1, "Bad annotation action");
+    error(-1, "parseAction: Unknown annotation action object: URI = '%s'",
+          baseURI ? baseURI->getCString() : "NULL");
     action = NULL;
   }
 
@@ -148,7 +150,7 @@ LinkDest::LinkDest(Array *a) {
 
   // get page
   if (a->getLength() < 2) {
-    error(-1, "Annotation destination array has wrong length");
+    error(-1, "Annotation destination array is too short");
     return;
   }
   a->getNF(0, &obj1);
@@ -219,16 +221,16 @@ LinkDest::LinkDest(Array *a) {
 
   // Fit link
   } else if (obj1.isName("Fit")) {
-    if (a->getLength() != 2) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 2) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFit;
 
   // FitH link
   } else if (obj1.isName("FitH")) {
-    if (a->getLength() != 3) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 3) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitH;
@@ -241,8 +243,8 @@ LinkDest::LinkDest(Array *a) {
 
   // FitV link
   } else if (obj1.isName("FitV")) {
-    if (a->getLength() != 3) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 3) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitV;
@@ -255,8 +257,8 @@ LinkDest::LinkDest(Array *a) {
 
   // FitR link
   } else if (obj1.isName("FitR")) {
-    if (a->getLength() != 6) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 6) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitR;
@@ -287,16 +289,16 @@ LinkDest::LinkDest(Array *a) {
 
   // FitB link
   } else if (obj1.isName("FitB")) {
-    if (a->getLength() != 2) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 2) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitB;
 
   // FitBH link
   } else if (obj1.isName("FitBH")) {
-    if (a->getLength() != 3) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 3) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitBH;
@@ -309,8 +311,8 @@ LinkDest::LinkDest(Array *a) {
 
   // FitBV link
   } else if (obj1.isName("FitBV")) {
-    if (a->getLength() != 3) {
-      error(-1, "Annotation destination array has wrong length");
+    if (a->getLength() < 3) {
+      error(-1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitBV;
@@ -580,14 +582,43 @@ LinkUnknown::~LinkUnknown() {
   delete action;
 }
 
+//------------------------------------------------------------------------
+// LinkBorderStyle
+//------------------------------------------------------------------------
+
+LinkBorderStyle::LinkBorderStyle(LinkBorderType typeA, double widthA,
+                                double *dashA, int dashLengthA,
+                                double rA, double gA, double bA) {
+  type = typeA;
+  width = widthA;
+  dash = dashA;
+  dashLength = dashLengthA;
+  r = rA;
+  g = gA;
+  b = bA;
+}
+
+LinkBorderStyle::~LinkBorderStyle() {
+  if (dash) {
+    gfree(dash);
+  }
+}
+
 //------------------------------------------------------------------------
 // Link
 //------------------------------------------------------------------------
 
 Link::Link(Dict *dict, GString *baseURI) {
-  Object obj1, obj2;
+  Object obj1, obj2, obj3;
+  LinkBorderType borderType;
+  double borderWidth;
+  double *borderDash;
+  int borderDashLength;
+  double borderR, borderG, borderB;
   double t;
+  int i;
 
+  borderStyle = NULL;
   action = NULL;
   ok = gFalse;
 
@@ -632,19 +663,92 @@ Link::Link(Dict *dict, GString *baseURI) {
     y2 = t;
   }
 
-  // get border
-  borderW = 1;
-  if (!dict->lookup("Border", &obj1)->isNull()) {
-    if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
-      if (obj1.arrayGet(2, &obj2)->isNum()) {
-       borderW = obj2.getNum();
-      } else {
-       error(-1, "Bad annotation border");
+  // get the border style info
+  borderType = linkBorderSolid;
+  borderWidth = 1;
+  borderDash = NULL;
+  borderDashLength = 0;
+  borderR = 0;
+  borderG = 0;
+  borderB = 1;
+  if (dict->lookup("BS", &obj1)->isDict()) {
+    if (obj1.dictLookup("S", &obj2)->isName()) {
+      if (obj2.isName("S")) {
+       borderType = linkBorderSolid;
+      } else if (obj2.isName("D")) {
+       borderType = linkBorderDashed;
+      } else if (obj2.isName("B")) {
+       borderType = linkBorderEmbossed;
+      } else if (obj2.isName("I")) {
+       borderType = linkBorderEngraved;
+      } else if (obj2.isName("U")) {
+       borderType = linkBorderUnderlined;
+      }
+    }
+    obj2.free();
+    if (obj1.dictLookup("W", &obj2)->isNum()) {
+      borderWidth = obj2.getNum();
+    }
+    obj2.free();
+    if (obj1.dictLookup("D", &obj2)->isArray()) {
+      borderDashLength = obj2.arrayGetLength();
+      borderDash = (double *)gmalloc(borderDashLength * sizeof(double));
+      for (i = 0; i < borderDashLength; ++i) {
+       if (obj2.arrayGet(i, &obj3)->isNum()) {
+         borderDash[i] = obj3.getNum();
+       } else {
+         borderDash[i] = 1;
+       }
+       obj3.free();
+      }
+    }
+    obj2.free();
+  } else {
+    obj1.free();
+    if (dict->lookup("Border", &obj1)->isArray()) {
+      if (obj1.arrayGetLength() >= 3) {
+       if (obj1.arrayGet(2, &obj2)->isNum()) {
+         borderWidth = obj2.getNum();
+       }
+       obj2.free();
+       if (obj1.arrayGetLength() >= 4) {
+         if (obj1.arrayGet(3, &obj2)->isArray()) {
+           borderType = linkBorderDashed;
+           borderDashLength = obj2.arrayGetLength();
+           borderDash = (double *)gmalloc(borderDashLength * sizeof(double));
+           for (i = 0; i < borderDashLength; ++i) {
+             if (obj2.arrayGet(i, &obj3)->isNum()) {
+               borderDash[i] = obj3.getNum();
+             } else {
+               borderDash[i] = 1;
+             }
+             obj3.free();
+           }
+         }
+         obj2.free();
+       }
       }
-      obj2.free();
     }
   }
   obj1.free();
+  if (dict->lookup("C", &obj1)->isArray() && obj1.arrayGetLength() == 3) {
+    if (obj1.arrayGet(0, &obj2)->isNum()) {
+      borderR = obj2.getNum();
+    }
+    obj1.free();
+    if (obj1.arrayGet(1, &obj2)->isNum()) {
+      borderG = obj2.getNum();
+    }
+    obj1.free();
+    if (obj1.arrayGet(2, &obj2)->isNum()) {
+      borderB = obj2.getNum();
+    }
+    obj1.free();
+  }
+  obj1.free();
+  borderStyle = new LinkBorderStyle(borderType, borderWidth,
+                                   borderDash, borderDashLength,
+                                   borderR, borderG, borderB);
 
   // look for destination
   if (!dict->lookup("Dest", &obj1)->isNull()) {
@@ -673,8 +777,12 @@ Link::Link(Dict *dict, GString *baseURI) {
 }
 
 Link::~Link() {
-  if (action)
+  if (borderStyle) {
+    delete borderStyle;
+  }
+  if (action) {
     delete action;
+  }
 }
 
 //------------------------------------------------------------------------