Hi:

I have changed again the last patch with the required changes and synced
it with the git head.

I have tried it with some annot testing PDF documents I have around and
everything looks like is working correctly, but I have some (more)
things I have notes about thought.

1. When the dash numbers in the arrays are wrong, poppler old code does
give them 1 value, but reading the pdf reference there is this:

"Note that no dash phase is specified; the phase is assumed to be 0."

So I have assumed that it should have 0, so I have changed it. There are
some error handling I don't know have to handle too, so I have added a
TODO comment to do it later.

2. When handling the colors, poppler old code does default red and green
to 0 but blue to 1. There is nothing about that in the reference. My
code does default all colors to 0, as it does support more color spaces,
maybe I shoudl change it but, where are those 'magic' numbers come
from ?

I think I should do some testing with Acrobat Reader to test everything.
How do you do those testings ? How do you know what values does use
Acrobat once it detects a wrong object/value ?

As always any comment is welcome.
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 2e09848..832d2e9 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -60,6 +60,189 @@
 #define bezierCircle 0.55228475
 
 //------------------------------------------------------------------------
+// AnnotBorder
+//------------------------------------------------------------------------
+ 
+AnnotBorder::~AnnotBorder() { 
+  if (dash)
+    gfree (dash); 
+}
+  
+//------------------------------------------------------------------------
+// AnnotBorderArray
+//------------------------------------------------------------------------
+
+AnnotBorderArray::AnnotBorderArray() {
+  horizontalCorner = 0;
+  verticalCorner = 0;
+  width = 1;
+  dashLength = 0;
+  dash = NULL;
+  style = borderSolid;
+}
+
+AnnotBorderArray::AnnotBorderArray(Array *array) {
+  Object obj1;
+  int arrayLength = array->getLength();
+
+  if (arrayLength >= 3) {
+    // implementation note 81 in Appendix H.
+    /*
+    if(array->get(0, &obj1)->isNum())
+      horizontalCorner = obj1.getNum();
+    obj1.free();
+
+    if(array->get(1, &obj1)->isNum())
+      verticalCorner = obj1.getNum();
+    obj1.free();
+    */
+    if(array->get(2, &obj1)->isNum())
+      width = obj1.getNum();
+    obj1.free();
+
+    // TODO: check not all zero ? (Line Dash Pattern Page 217 PDF 8.1)
+    if(arrayLength > 3) {
+      style = borderDashed;
+      dashLength = array->getLength() - 3;
+      dash = (double *) gmallocn (dashLength, sizeof (double));
+
+      for(int i = 0; i < dashLength && i < DASH_LIMIT; i++) {
+
+        if(array->get((i + 3), &obj1)->isNum()) {
+          dash[i] = obj1.getNum();
+
+          if (dash[i] < 0)
+            dash[i] = 0;
+
+        } else {
+          dash[i] = 0;
+        }
+        obj1.free();
+      }
+    }
+  }
+}
+
+//------------------------------------------------------------------------
+// AnnotBorderBS
+//------------------------------------------------------------------------
+
+AnnotBorderBS::AnnotBorderBS() {
+  width = 1;
+  dashLength = 0;
+  dash = NULL;
+  style = borderSolid;
+}
+
+AnnotBorderBS::AnnotBorderBS(Dict *dict) {
+  Object obj1, obj2;
+
+  // acroread 8 seems to need both W and S entries for
+  // any border to be drawn, even though the spec
+  // doesn't claim anything of that sort. We follow
+  // that behaviour by veryifying both entries exist
+  // otherwise we set the borderWidth to 0
+  // --jrmuizel
+  dict->lookup("W", &obj1);
+  dict->lookup("S", &obj2);
+  if (obj1.isNum() && obj2.isName()) {
+    GooString *styleName = new GooString(obj2.getName());
+
+    width = obj1.getNum();
+
+    if(!styleName->cmp("S")) {
+      style = borderSolid;
+    } else if(!styleName->cmp("D")) {
+      style = borderDashed;
+    } else if(!styleName->cmp("B")) {
+      style = borderBeveled;
+    } else if(!styleName->cmp("I")) {
+      style = borderInset;
+    } else if(!styleName->cmp("U")) {
+      style = borderUnderlined;
+    } else {
+      style = borderSolid;
+    }
+    delete styleName;
+  } else {
+    width = 0;
+  }
+  obj2.free();
+  obj1.free();
+
+  // TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
+  if (dict->lookup("D", &obj1)->isArray()) {
+    dashLength = obj1.arrayGetLength();
+    dash = (double *) gmallocn (dashLength, sizeof (double));
+
+    for(int i = 0; i < dashLength; i++) {
+      Object obj2;
+
+      if(obj1.arrayGet(i, &obj2)->isNum()) {
+        dash[i] = obj2.getNum();
+
+        if(dash[i] < 0)
+          dash[i] = 0;
+      } else {
+        dash[i] = 0;
+      }
+      obj2.free();
+    }
+  } else {
+    dashLength = 1;
+    dash = (double *) gmallocn (dashLength, sizeof (double));
+    dash[0] = 3;
+  }
+  obj1.free();
+}
+
+//------------------------------------------------------------------------
+// AnnotColor
+//------------------------------------------------------------------------
+
+AnnotColor::AnnotColor() {
+  length = 0;
+  values = NULL;
+}
+
+AnnotColor::AnnotColor(Array *array) {
+  // TODO: check what Acrobat does in the case of having more than 5 numbers.
+  if (array->getLength() < 5) {
+    length = array->getLength();
+    values = (double *) gmallocn (length, sizeof(double));
+
+    for(int i = 0; i < length; i++) {  
+      Object obj1;
+
+      if(array->get(i, &obj1)->isNum()) {
+        values[i] = obj1.getNum();
+
+        if (values[i] < 0 || values[i] > 1)
+          values[i] = 0;
+      } else {
+        values[i] = 0;
+      }
+      obj1.free();
+    }
+  }
+}
+
+AnnotColor::AnnotColorSpace AnnotColor::getSpace() {
+  return (AnnotColor::AnnotColorSpace) length;
+}
+
+double AnnotColor::getValue(int i) {
+  if(i >= 0 && i < length) 
+    return values[i];
+  return 0;
+}
+
+AnnotColor::~AnnotColor() {
+  if(values)
+    gfree (values);
+}
+
+//------------------------------------------------------------------------
 // AnnotBorderStyle
 //------------------------------------------------------------------------
 
@@ -99,11 +282,6 @@ Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog* catalog) {
 
 void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog) {
   Object apObj, asObj, obj1, obj2, obj3;
-  AnnotBorderType borderType;
-  double borderWidth;
-  double *borderDash;
-  int borderDashLength;
-  double borderR, borderG, borderB;
   double t;
 
   ok = gTrue;
@@ -112,7 +290,6 @@ void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog
   fontSize = 0;
   type = NULL;
   widget = NULL;
-  borderStyle = NULL;
 
   //----- get the FormWidget
   if (hasRef) {
@@ -220,104 +397,26 @@ void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog
   obj3.free();
 
   //----- parse the border style
-
-  borderType = annotBorderSolid;
-  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 = annotBorderSolid;
-      } else if (obj2.isName("D")) {
-        borderType = annotBorderDashed;
-      } else if (obj2.isName("B")) {
-        borderType = annotBorderBeveled;
-      } else if (obj2.isName("I")) {
-        borderType = annotBorderInset;
-      } else if (obj2.isName("U")) {
-        borderType = annotBorderUnderlined;
-      }
-    }
-    if (obj1.dictLookup("W", &obj3)->isNum()) {
-      borderWidth = obj3.getNum();
-    }
-    // acroread 8 seems to need both W and S entries for
-    // any border to be drawn, even though the spec
-    // doesn't claim anything of that sort. We follow
-    // that behaviour by veryifying both entries exist
-    // otherwise we set the borderWidth to 0
-    // --jrmuizel
-    if (!obj2.isName() || !obj3.isNum()) {
-      borderWidth = 0;
-    }
-    obj3.free();
-    obj2.free();
-    if (obj1.dictLookup("D", &obj2)->isArray()) {
-      borderDashLength = obj2.arrayGetLength();
-      borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
-      for (int i = 0; i < borderDashLength; ++i) {
-        if (obj2.arrayGet(i, &obj3)->isNum()) {
-          borderDash[i] = obj3.getNum();
-        } else {
-          borderDash[i] = 1;
-        }
-        obj3.free();
-      }
-    }
-    obj2.free();
+    border = new AnnotBorderBS(obj1.getDict());
   } 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 = annotBorderDashed;
-            borderDashLength = obj2.arrayGetLength();
-            borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
-            for (int i = 0; i < borderDashLength; ++i) {
-              if (obj2.arrayGet(i, &obj3)->isNum()) {
-                borderDash[i] = obj3.getNum();
-              } else {
-                borderDash[i] = 1;
-              }
-              obj3.free();
-            }
-          } else {
-            // Adobe draws no border at all if the last element is of
-            // the wrong type.
-            borderWidth = 0;
-          }
-        }
-      }
-    }
-    obj1.free();
+
+    if (dict->lookup("Border", &obj1)->isArray())
+      border = new AnnotBorderArray(obj1.getArray());
+    else
+      // Adobe draws no border at all if the last element is of
+      // the wrong type.
+      border = NULL;
   }
-  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();
+
+  if (dict->lookup("C", &obj1)->isArray()) {
+    color = new AnnotColor(obj1.getArray());
+  } else {
+    color = NULL;
   }
   obj1.free();
-  borderStyle = new AnnotBorderStyle(borderType, borderWidth,
-      borderDash, borderDashLength,
-      borderR, borderG, borderB);
 }
 
 void Annot::readArrayNum(Object *pdfArray, int key, double *value) {
@@ -342,9 +441,11 @@ Annot::~Annot() {
     delete appearBuf;
   }
 
-  if (borderStyle) {
-    delete borderStyle;
-  }
+  if (border)
+    delete border;
+
+  if (color)
+    delete color;
 }
 
 void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
@@ -409,8 +510,8 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
   obj1.free();
 
   // draw the border
-  if (mkDict) {
-    w = borderStyle->getWidth();
+  if (mkDict && border) {
+    w = border->getWidth();
     if (w > 0) {
       mkDict->lookup("BC", &obj1);
       if (!(obj1.isArray() && obj1.arrayGetLength() > 0)) {
@@ -425,55 +526,57 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
         obj2.free();
         if (ftObj.isName("Btn") && (ff & fieldFlagRadio) && !hasCaption) {
           r = 0.5 * (dx < dy ? dx : dy);
-          switch (borderStyle->getType()) {
-            case annotBorderDashed:
+          switch (border->getStyle()) {
+            case AnnotBorder::borderDashed:
               appearBuf->append("[");
-              borderStyle->getDash(&dash, &dashLength);
+              dashLength = border->getDashLength();
+              dash = border->getDash();
               for (i = 0; i < dashLength; ++i) {
                 appearBuf->appendf(" {0:.2f}", dash[i]);
               }
               appearBuf->append("] 0 d\n");
               // fall through to the solid case
-            case annotBorderSolid:
-            case annotBorderUnderlined:
+            case AnnotBorder::borderSolid:
+            case AnnotBorder::borderUnderlined:
               appearBuf->appendf("{0:.2f} w\n", w);
               setColor(obj1.getArray(), gFalse, 0);
               drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse);
               break;
-            case annotBorderBeveled:
-            case annotBorderInset:
+            case AnnotBorder::borderBeveled:
+            case AnnotBorder::borderInset:
               appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
               setColor(obj1.getArray(), gFalse, 0);
               drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse);
               setColor(obj1.getArray(), gFalse,
-                  borderStyle->getType() == annotBorderBeveled ? 1 : -1);
+                  border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
               drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
               setColor(obj1.getArray(), gFalse,
-                  borderStyle->getType() == annotBorderBeveled ? -1 : 1);
+                  border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
               drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w);
               break;
           }
 
         } else {
-          switch (borderStyle->getType()) {
-            case annotBorderDashed:
+          switch (border->getStyle()) {
+            case AnnotBorder::borderDashed:
               appearBuf->append("[");
-              borderStyle->getDash(&dash, &dashLength);
+              dashLength = border->getDashLength();
+              dash = border->getDash();
               for (i = 0; i < dashLength; ++i) {
                 appearBuf->appendf(" {0:.2f}", dash[i]);
               }
               appearBuf->append("] 0 d\n");
               // fall through to the solid case
-            case annotBorderSolid:
+            case AnnotBorder::borderSolid:
               appearBuf->appendf("{0:.2f} w\n", w);
               setColor(obj1.getArray(), gFalse, 0);
               appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n",
                   0.5 * w, dx - w, dy - w);
               break;
-            case annotBorderBeveled:
-            case annotBorderInset:
+            case AnnotBorder::borderBeveled:
+            case AnnotBorder::borderInset:
               setColor(obj1.getArray(), gTrue,
-                  borderStyle->getType() == annotBorderBeveled ? 1 : -1);
+                  border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
               appearBuf->append("0 0 m\n");
               appearBuf->appendf("0 {0:.2f} l\n", dy);
               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
@@ -482,7 +585,7 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
               appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
               appearBuf->append("f\n");
               setColor(obj1.getArray(), gTrue,
-                  borderStyle->getType() == annotBorderBeveled ? -1 : 1);
+                  border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
               appearBuf->append("0 0 m\n");
               appearBuf->appendf("{0:.2f} 0 l\n", dx);
               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
@@ -491,7 +594,7 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
               appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
               appearBuf->append("f\n");
               break;
-            case annotBorderUnderlined:
+            case AnnotBorder::borderUnderlined:
               appearBuf->appendf("{0:.2f} w\n", w);
               setColor(obj1.getArray(), gFalse, 0);
               appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx);
@@ -831,7 +934,7 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
   GooList *daToks;
   GooString *tok;
   GfxFont *font;
-  double fontSize, fontSize2, border, x, xPrev, y, w, w2, wMax;
+  double fontSize, fontSize2, borderWidth, x, xPrev, y, w, w2, wMax;
   int tfPos, tmPos, i, j, k;
 
   //~ if there is no MK entry, this should use the existing content stream,
@@ -899,7 +1002,7 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
   }
 
   // get the border width
-  border = borderStyle->getWidth();
+  borderWidth = border->getWidth();
 
   // setup
   if (txField) {
@@ -911,7 +1014,7 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
   if (multiline) {
     // note: the comb flag is ignored in multiline mode
 
-    wMax = xMax - xMin - 2 * border - 4;
+    wMax = xMax - xMin - 2 * borderWidth - 4;
 
     // compute font autosize
     if (fontSize == 0) {
@@ -977,13 +1080,13 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
       switch (quadding) {
         case fieldQuadLeft:
         default:
-          x = border + 2;
+          x = borderWidth + 2;
           break;
         case fieldQuadCenter:
           x = (xMax - xMin - w) / 2;
           break;
         case fieldQuadRight:
-          x = xMax - xMin - border - 2 - w;
+          x = xMax - xMin - borderWidth - 2 - w;
           break;
       }
 
@@ -1005,11 +1108,11 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
     // comb formatting
     if (comb > 0) {
       // compute comb spacing
-      w = (xMax - xMin - 2 * border) / comb;
+      w = (xMax - xMin - 2 * borderWidth) / comb;
 
       // compute font autosize
       if (fontSize == 0) {
-        fontSize = yMax - yMin - 2 * border;
+        fontSize = yMax - yMin - 2 * borderWidth;
         if (w < fontSize) {
           fontSize = w;
         }
@@ -1025,13 +1128,13 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
       switch (quadding) {
         case fieldQuadLeft:
         default:
-          x = border + 2;
+          x = borderWidth + 2;
           break;
         case fieldQuadCenter:
-          x = border + 2 + 0.5 * (comb - text->getLength()) * w;
+          x = borderWidth + 2 + 0.5 * (comb - text->getLength()) * w;
           break;
         case fieldQuadRight:
-          x = border + 2 + (comb - text->getLength()) * w;
+          x = borderWidth + 2 + (comb - text->getLength()) * w;
           break;
       }
       y = 0.5 * (yMax - yMin) - 0.4 * fontSize;
@@ -1086,8 +1189,8 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
 
       // compute font autosize
       if (fontSize == 0) {
-        fontSize = yMax - yMin - 2 * border;
-        fontSize2 = (xMax - xMin - 4 - 2 * border) / w;
+        fontSize = yMax - yMin - 2 * borderWidth;
+        fontSize2 = (xMax - xMin - 4 - 2 * borderWidth) / w;
         if (fontSize2 < fontSize) {
           fontSize = fontSize2;
         }
@@ -1104,13 +1207,13 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
       switch (quadding) {
         case fieldQuadLeft:
         default:
-          x = border + 2;
+          x = borderWidth + 2;
           break;
         case fieldQuadCenter:
           x = (xMax - xMin - w) / 2;
           break;
         case fieldQuadRight:
-          x = xMax - xMin - border - 2 - w;
+          x = xMax - xMin - borderWidth - 2 - w;
           break;
       }
       y = 0.5 * (yMax - yMin) - 0.4 * fontSize;
@@ -1161,7 +1264,7 @@ void Annot::drawListBox(GooString **text, GBool *selection,
   GooList *daToks;
   GooString *tok;
   GfxFont *font;
-  double fontSize, fontSize2, border, x, y, w, wMax;
+  double fontSize, fontSize2, borderWidth, x, y, w, wMax;
   int tfPos, tmPos, i, j;
 
   //~ if there is no MK entry, this should use the existing content stream,
@@ -1218,7 +1321,7 @@ void Annot::drawListBox(GooString **text, GBool *selection,
   }
 
   // get the border width
-  border = borderStyle->getWidth();
+  borderWidth = border->getWidth();
 
   // compute font autosize
   if (fontSize == 0) {
@@ -1237,8 +1340,8 @@ void Annot::drawListBox(GooString **text, GBool *selection,
         wMax = w;
       }
     }
-    fontSize = yMax - yMin - 2 * border;
-    fontSize2 = (xMax - xMin - 4 - 2 * border) / wMax;
+    fontSize = yMax - yMin - 2 * borderWidth;
+    fontSize2 = (xMax - xMin - 4 - 2 * borderWidth) / wMax;
     if (fontSize2 < fontSize) {
       fontSize = fontSize2;
     }
@@ -1259,9 +1362,9 @@ void Annot::drawListBox(GooString **text, GBool *selection,
     if (selection[i]) {
       appearBuf->append("0 g f\n");
       appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re f\n",
-          border,
+          borderWidth,
           y - 0.2 * fontSize,
-          xMax - xMin - 2 * border,
+          xMax - xMin - 2 * borderWidth,
           1.1 * fontSize);
     }
 
@@ -1284,13 +1387,13 @@ void Annot::drawListBox(GooString **text, GBool *selection,
     switch (quadding) {
       case fieldQuadLeft:
       default:
-        x = border + 2;
+        x = borderWidth + 2;
         break;
       case fieldQuadCenter:
         x = (xMax - xMin - w) / 2;
         break;
       case fieldQuadRight:
-        x = xMax - xMin - border - 2 - w;
+        x = xMax - xMin - borderWidth - 2 - w;
         break;
     }
 
@@ -1494,7 +1597,7 @@ void Annot::draw(Gfx *gfx, GBool printing) {
   // draw the appearance stream
   isLink = type && !type->cmp("Link");
   appearance.fetch(xref, &obj);
-  gfx->drawAnnot(&obj, isLink ? borderStyle : (AnnotBorderStyle *)NULL,
+  gfx->drawAnnot(&obj, isLink ? border : (AnnotBorder *)NULL, color,
       xMin, yMin, xMax, yMax);
   obj.free();
 }
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 50f5bfb..424938b 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -20,6 +20,97 @@ class CharCodeToUnicode;
 class GfxFont;
 class GfxFontDict;
 class FormWidget;
+class PDFRectangle;
+
+//------------------------------------------------------------------------
+// AnnotBorder
+//------------------------------------------------------------------------
+
+class AnnotBorder {
+public:
+  enum AnnotBorderStyle {
+    borderSolid,      // Solid
+    borderDashed,     // Dashed
+    borderBeveled,    // Beveled
+    borderInset,      // Inset
+    borderUnderlined, // Underlined
+  };
+	  
+  virtual ~AnnotBorder();
+
+  virtual double getWidth() { return width; }
+  virtual int getDashLength() { return dashLength; }
+  virtual double *getDash() { return dash; }
+  virtual AnnotBorderStyle getStyle() { return style; }
+
+protected:
+  double width;
+  int dashLength;
+  double *dash;
+  AnnotBorderStyle style;
+};
+
+//------------------------------------------------------------------------
+// AnnotBorderArray
+//------------------------------------------------------------------------
+
+class AnnotBorderArray: public AnnotBorder {
+public:
+  AnnotBorderArray();
+  AnnotBorderArray(Array *array);
+
+  virtual double getHorizontalCorner() { return horizontalCorner; }
+  virtual double getVerticalCorner() { return verticalCorner; }
+
+protected:
+  static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
+  double horizontalCorner;          // (Default 0)
+  double verticalCorner;            // (Default 0)
+  // double width;                  // (Default 1)  (inherited from AnnotBorder)
+};
+
+//------------------------------------------------------------------------
+// AnnotBorderBS
+//------------------------------------------------------------------------
+
+class AnnotBorderBS: public AnnotBorder {
+public:
+  
+  AnnotBorderBS();
+  AnnotBorderBS(Dict *dict);
+
+private:
+  // double width;           // W  (Default 1)   (inherited from AnnotBorder)
+  // AnnotBorderStyle style; // S  (Default S)   (inherited from AnnotBorder)
+  // double *dash;           // D  (Default [3]) (inherited from AnnotBorder)
+};
+
+//------------------------------------------------------------------------
+// AnnotColor
+//------------------------------------------------------------------------
+
+class AnnotColor {
+public:
+
+  enum AnnotColorSpace {
+    colorTransparent = 0,
+    colorGray        = 1,
+    colorRGB         = 3,
+    colorCMYK        = 4
+  };
+  
+  AnnotColor();
+  AnnotColor(Array *array);
+  ~AnnotColor();
+
+  AnnotColorSpace getSpace();
+  double getValue(int i);
+
+private:
+
+  double *values;
+  int length;
+};
 
 //------------------------------------------------------------------------
 // AnnotBorderStyle
@@ -75,8 +166,6 @@ public:
   Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
   GBool textField() { return isTextField; }
 
-  AnnotBorderStyle *getBorderStyle () { return borderStyle; }
-
   GBool match(Ref *refA)
     { return ref.num == refA->num && ref.gen == refA->gen; }
 
@@ -88,7 +177,9 @@ public:
   double getFontSize() { return fontSize; }
 
   GooString *getType() { return type; }
-
+  AnnotBorder *getBorder() { return border; }
+  AnnotColor *getColor() { return color; }
+  
 private:
   void setColor(Array *a, GBool fill, int adjust);
   void drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
@@ -120,7 +211,8 @@ private:
   Guint flags;
   double xMin, yMin,		// annotation rectangle
          xMax, yMax;
-  AnnotBorderStyle *borderStyle;
+  AnnotBorder *border;          // Border, BS
+  AnnotColor *color;            // C
   double fontSize; 
   GBool ok;
   GBool regen, isTextField;
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 163b340..db5fe5d 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -4060,7 +4060,7 @@ void Gfx::opMarkPoint(Object args[], int numArgs) {
 // misc
 //------------------------------------------------------------------------
 
-void Gfx::drawAnnot(Object *str, AnnotBorderStyle *borderStyle,
+void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor,
 		    double xMin, double yMin, double xMax, double yMax) {
   Dict *dict, *resDict;
   Object matrixObj, bboxObj, resObj;
@@ -4182,13 +4182,19 @@ void Gfx::drawAnnot(Object *str, AnnotBorderStyle *borderStyle,
   }
 
   // draw the border
-  if (borderStyle && borderStyle->getWidth() > 0) {
+  if (border && border->getWidth() > 0) {
     if (state->getStrokeColorSpace()->getMode() != csDeviceRGB) {
       state->setStrokePattern(NULL);
       state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
       out->updateStrokeColorSpace(state);
     }
-    borderStyle->getColor(&r, &g, &b);
+    if (aColor && (aColor->getSpace() == AnnotColor::colorRGB)) {
+      r = aColor->getValue(0);
+      g = aColor->getValue(1);
+      b = aColor->getValue(2);
+    } else {
+      r = g = b = 0;
+    };
     color.c[0] = dblToCol(r);
     color.c[1] = dblToCol(g);
     color.c[2] = dblToCol(b);
@@ -4201,10 +4207,11 @@ void Gfx::drawAnnot(Object *str, AnnotBorderStyle *borderStyle,
     y = (baseMatrix[0] + baseMatrix[2]) * ictm[1] +
         (baseMatrix[1] + baseMatrix[3]) * ictm[3];
     x = sqrt(0.5 * (x * x + y * y));
-    state->setLineWidth(x * borderStyle->getWidth());
+    state->setLineWidth(x * border->getWidth());
     out->updateLineWidth(state);
-    borderStyle->getDash(&dash, &dashLength);
-    if (borderStyle->getType() == annotBorderDashed && dashLength > 0) {
+    dashLength = border->getDashLength();
+    dash = border->getDash();
+    if (border->getStyle() == AnnotBorder::borderDashed && dashLength > 0) {
       dash2 = (double *)gmallocn(dashLength, sizeof(double));
       for (i = 0; i < dashLength; ++i) {
 	dash2[i] = x * dash[i];
@@ -4216,7 +4223,7 @@ void Gfx::drawAnnot(Object *str, AnnotBorderStyle *borderStyle,
     state->clearPath();
     state->moveTo(annotX0, out->upsideDown() ? annotY1 : annotY0);
     state->lineTo(annotX1, out->upsideDown() ? annotY1 : annotY0);
-    if (borderStyle->getType() != annotBorderUnderlined) {
+    if (border->getStyle() != AnnotBorder::borderUnderlined) {
       state->lineTo(annotX1, out->upsideDown() ? annotY0 : annotY1);
       state->lineTo(annotX0, out->upsideDown() ? annotY0 : annotY1);
       state->closePath();
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index 28d8a3d..2c86105 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -41,7 +41,8 @@ struct GfxColor;
 class GfxColorSpace;
 class Gfx;
 class PDFRectangle;
-class AnnotBorderStyle;
+class AnnotBorder;
+class AnnotColor;
 
 //------------------------------------------------------------------------
 
@@ -128,7 +129,7 @@ public:
 
   // Display an annotation, given its appearance (a Form XObject),
   // border style, and bounding box (in default user space).
-  void drawAnnot(Object *str, AnnotBorderStyle *borderStyle,
+  void drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor,
 		 double xMin, double yMin, double xMax, double yMax);
 
   // Save graphics state.

Attachment: signature.asc
Description: Esta parte del mensaje está firmada digitalmente

_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to