[poppler] 10 commits - poppler/Annot.cc poppler/Annot.h poppler/FontInfo.cc poppler/GlobalParams.cc poppler/Page.h poppler/PSOutputDev.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Sun Apr 8 07:52:47 PDT 2012


 poppler/Annot.cc        |  599 ++++++++++++++++++++++++++++++++++++++++++------
 poppler/Annot.h         |   47 +++
 poppler/FontInfo.cc     |   11 
 poppler/GlobalParams.cc |    3 
 poppler/PSOutputDev.cc  |   12 
 poppler/Page.h          |    2 
 6 files changed, 581 insertions(+), 93 deletions(-)

New commits:
commit 3d4985f14e54ddcc64ea654b23e931b7e6acfbdc
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Sat Apr 7 11:28:36 2012 +0200

    Do not trust the rect of AnnotTextMarkup when drawing

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index a2ced1f..53d71ed 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -93,10 +93,6 @@
 // = (4 * (sqrt(2) - 1) / 3) * r
 #define bezierCircle 0.55228475
 
-// Ensures that x is between the limits set by low and high.
-// If low is greater than high the result is undefined.
-#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
-
 AnnotLineEndingStyle parseAnnotLineEndingStyle(GooString *string) {
   if (string != NULL) {
     if (!string->cmp("Square")) {
@@ -361,10 +357,7 @@ AnnotQuadrilaterals::AnnotQuadrilaterals(Array *array, PDFRectangle *rect) {
       for (int j = 0; j < 8; j++) {
         Object obj;
         if (array->get(i * 8 + j, &obj)->isNum()) {
-          if (j % 2 == 1)
-	    quadArray[j] = CLAMP (obj.getNum(), rect->y1, rect->y2);
-          else
-	    quadArray[j] = CLAMP (obj.getNum(), rect->x1, rect->x2);
+          quadArray[j] = obj.getNum();
         } else {
             correct = gFalse;
 	    obj.free();
@@ -3292,6 +3285,16 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
     appearBuf = new GooString ();
     appearBuf->append ("q\n");
 
+    /* Adjust BBox */
+    delete appearBBox;
+    appearBBox = new AnnotAppearanceBBox(rect);
+    for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
+      appearBBox->extendTo (quadrilaterals->getX1(i) - rect->x1, quadrilaterals->getY1(i) - rect->y1);
+      appearBBox->extendTo (quadrilaterals->getX2(i) - rect->x1, quadrilaterals->getY2(i) - rect->y1);
+      appearBBox->extendTo (quadrilaterals->getX3(i) - rect->x1, quadrilaterals->getY3(i) - rect->y1);
+      appearBBox->extendTo (quadrilaterals->getX4(i) - rect->x1, quadrilaterals->getY4(i) - rect->y1);
+    }
+
     switch (type) {
     case typeUnderline:
       if (color) {
@@ -3366,6 +3369,7 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
       if (color)
         setColor(color, gTrue);
 
+      double biggestBorder = 0;
       for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
         double x1, y1, x2, y2, x3, y3, x4, y4;
 	double h4;
@@ -3380,6 +3384,10 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
 	y4 = quadrilaterals->getY4(i);
 	h4 = fabs(y1 - y3) / 4.0;
 
+	if (h4 > biggestBorder) {
+	  biggestBorder = h4;
+	}
+
 	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
 	appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
 			    x3 - h4, y3 + h4, x1 - h4, y1 - h4, x1, y1);
@@ -3388,16 +3396,17 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
 			    x2 + h4, y2 - h4, x4 + h4, y4 + h4, x4, y4);
 	appearBuf->append ("f\n");
       }
+      appearBBox->setBorderWidth(biggestBorder);
       break;
     }
     appearBuf->append ("Q\n");
 
     Object aStream, resDict;
     double bbox[4];
-    bbox[0] = rect->x1;
-    bbox[1] = rect->y1;
-    bbox[2] = rect->x2;
-    bbox[3] = rect->y2;
+    bbox[0] = appearBBox->getPageXMin();
+    bbox[1] = appearBBox->getPageYMin();
+    bbox[2] = appearBBox->getPageXMax();
+    bbox[3] = appearBBox->getPageYMax();
     createForm(bbox, gTrue, NULL, &aStream);
     delete appearBuf;
 
@@ -3418,8 +3427,14 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
 
   // draw the appearance stream
   appearance.fetch(xref, &obj);
-  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
-		 rect->x1, rect->y1, rect->x2, rect->y2);
+  if (appearBBox) {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+                   appearBBox->getPageXMax(), appearBBox->getPageYMax());
+  } else {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   rect->x1, rect->y1, rect->x2, rect->y2);
+  }
   obj.free();
 }
 
commit c6296cd8c1ca398beac20f1e88c87b9082386247
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Sat Apr 7 00:30:54 2012 +0200

    Do not trust the rect of AnnotLine, AnnotPolygon and AnnotInk when drawing

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 60419b2..a2ced1f 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -965,6 +965,59 @@ AnnotAppearanceCharacs::~AnnotAppearanceCharacs() {
 }
 
 //------------------------------------------------------------------------
+// AnnotAppearanceBBox
+//------------------------------------------------------------------------
+
+AnnotAppearanceBBox::AnnotAppearanceBBox(PDFRectangle *rect) {
+  origX = rect->x1;
+  origY = rect->y1;
+  borderWidth = 0;
+
+  // Initially set the same size as rect
+  minX = 0;
+  minY = 0;
+  maxX = rect->x2 - rect->x1;
+  maxY = rect->y2 - rect->y1;
+}
+
+void AnnotAppearanceBBox::extendTo(double x, double y) {
+  if (x < minX) {
+    minX = x;
+  } else if (x > maxX) {
+    maxX = x;
+  }
+  if (y < minY) {
+    minY = y;
+  } else if (y > maxY) {
+    maxY = y;
+  }
+}
+
+void AnnotAppearanceBBox::getBBoxRect(double bbox[4]) const {
+  Object obj2;
+  bbox[0] = minX - borderWidth;
+  bbox[1] = minY - borderWidth;
+  bbox[2] = maxX + borderWidth;
+  bbox[3] = maxY + borderWidth;
+}
+
+double AnnotAppearanceBBox::getPageXMin() const {
+  return origX + minX - borderWidth;
+}
+
+double AnnotAppearanceBBox::getPageYMin() const {
+  return origY + minY - borderWidth;
+}
+
+double AnnotAppearanceBBox::getPageXMax() const {
+  return origX + maxX + borderWidth;
+}
+
+double AnnotAppearanceBBox::getPageYMax() const {
+  return origY + maxY + borderWidth;
+}
+
+//------------------------------------------------------------------------
 // Annot
 //------------------------------------------------------------------------
 
@@ -1023,6 +1076,7 @@ void Annot::initialize(PDFDoc *docA, Dict *dict) {
   doc = docA;
   xref = doc->getXRef();
   appearStreams = NULL;
+  appearBBox = NULL;
   appearState = NULL;
   appearBuf = NULL;
   fontSize = 0;
@@ -1315,6 +1369,9 @@ void Annot::setAppearanceState(const char *state) {
   delete appearState;
   appearState = new GooString(state);
 
+  delete appearBBox;
+  appearBBox = NULL;
+
   Object obj1;
   obj1.initName(state);
   update ("AS", &obj1);
@@ -1388,6 +1445,7 @@ Annot::~Annot() {
     delete modified;
 
   delete appearStreams;
+  delete appearBBox;
   appearance.free();
 
   if (appearState)
@@ -2975,17 +3033,8 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
   if (!isVisible (printing))
     return;
 
-  /* Some documents like pdf_commenting_new.pdf,
-   * have y1 = y2 but line_width > 0, acroread
-   * renders the lines in such cases even though
-   * the annot bbox is empty. We adjust the bbox here
-   * to avoid having an empty bbox so that lines
-   * are rendered
-   */
-  if (rect->y1 == rect->y2)
-    rect->y2 += border ? border->getWidth() : 1;
-
   if (appearance.isNull()) {
+    appearBBox = new AnnotAppearanceBBox(rect);
     ca = opacity;
 
     appearBuf = new GooString ();
@@ -3011,6 +3060,7 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
         break;
       }
       appearBuf->appendf("{0:.2f} w\n", border->getWidth());
+      appearBBox->setBorderWidth(border->getWidth());
     }
 
     const double x1 = coord1->getX();
@@ -3035,9 +3085,11 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
     // Draw main segment
     matr.transform (0, leaderLineLength, &tx, &ty);
     appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
+    appearBBox->extendTo (tx, ty);
 
     matr.transform (main_len, leaderLineLength, &tx, &ty);
     appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
+    appearBBox->extendTo (tx, ty);
 
     // TODO: Line ending, caption
 
@@ -3047,23 +3099,25 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
     if (ll_len != 0) {
       matr.transform (0, 0, &tx, &ty);
       appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
+      appearBBox->extendTo (tx, ty);
 
       matr.transform (0, sign*ll_len, &tx, &ty);
       appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
+      appearBBox->extendTo (tx, ty);
 
       matr.transform (main_len, 0, &tx, &ty);
       appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
+      appearBBox->extendTo (tx, ty);
 
       matr.transform (main_len, sign*ll_len, &tx, &ty);
       appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
+      appearBBox->extendTo (tx, ty);
     }
 
     appearBuf->append ("Q\n");
 
     double bbox[4];
-    bbox[0] = bbox[1] = 0;
-    bbox[2] = rect->x2 - rect->x1;
-    bbox[3] = rect->y2 - rect->y1;
+    appearBBox->getBBoxRect(bbox);
     if (ca == 1) {
       createForm(bbox, gFalse, NULL, &appearance);
     } else {
@@ -3081,8 +3135,14 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
 
   // draw the appearance stream
   appearance.fetch(xref, &obj);
-  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
-		 rect->x1, rect->y1, rect->x2, rect->y2);
+  if (appearBBox) {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+                   appearBBox->getPageXMax(), appearBBox->getPageYMax());
+  } else {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   rect->x1, rect->y1, rect->x2, rect->y2);
+  }
   obj.free();
 }
 
@@ -5272,6 +5332,7 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
     return;
 
   if (appearance.isNull()) {
+    appearBBox = new AnnotAppearanceBBox(rect);
     ca = opacity;
 
     appearBuf = new GooString ();
@@ -5299,6 +5360,7 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
         break;
       }
       appearBuf->appendf("{0:.2f} w\n", border->getWidth());
+      appearBBox->setBorderWidth(border->getWidth());
     }
 
     if (interiorColor) {
@@ -5307,9 +5369,11 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
 
     if (vertices->getCoordsLength() != 0) {
       appearBuf->appendf ("{0:.2f} {1:.2f} m\n", vertices->getX(0) - rect->x1, vertices->getY(0) - rect->y1);
+      appearBBox->extendTo (vertices->getX(0) - rect->x1, vertices->getY(0) - rect->y1);
 
       for (int i = 1; i < vertices->getCoordsLength(); ++i) {
         appearBuf->appendf ("{0:.2f} {1:.2f} l\n", vertices->getX(i) - rect->x1, vertices->getY(i) - rect->y1);
+        appearBBox->extendTo (vertices->getX(i) - rect->x1, vertices->getY(i) - rect->y1);
       }
 
       if (type == typePolygon) {
@@ -5326,9 +5390,7 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
     appearBuf->append ("Q\n");
 
     double bbox[4];
-    bbox[0] = bbox[1] = 0;
-    bbox[2] = rect->x2 - rect->x1;
-    bbox[3] = rect->y2 - rect->y1;
+    appearBBox->getBBoxRect(bbox);
     if (ca == 1) {
       createForm(bbox, gFalse, NULL, &appearance);
     } else {
@@ -5346,8 +5408,14 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
 
   // draw the appearance stream
   appearance.fetch(xref, &obj);
-  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
-                 rect->x1, rect->y1, rect->x2, rect->y2);
+  if (appearBBox) {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+                   appearBBox->getPageXMax(), appearBBox->getPageYMax());
+  } else {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   rect->x1, rect->y1, rect->x2, rect->y2);
+  }
   obj.free();
 }
 
@@ -5501,6 +5569,7 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) {
     return;
 
   if (appearance.isNull()) {
+    appearBBox = new AnnotAppearanceBBox(rect);
     ca = opacity;
 
     appearBuf = new GooString ();
@@ -5512,15 +5581,18 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) {
 
     if (border) {
       appearBuf->appendf("{0:.2f} w\n", border->getWidth());
+      appearBBox->setBorderWidth(border->getWidth());
     }
 
     for (int i = 0; i < inkListLength; ++i) {
       const AnnotPath * path = inkList[i];
       if (path->getCoordsLength() != 0) {
         appearBuf->appendf ("{0:.2f} {1:.2f} m\n", path->getX(0) - rect->x1, path->getY(0) - rect->y1);
+        appearBBox->extendTo (path->getX(0) - rect->x1, path->getY(0) - rect->y1);
 
         for (int j = 1; j < path->getCoordsLength(); ++j) {
           appearBuf->appendf ("{0:.2f} {1:.2f} l\n", path->getX(j) - rect->x1, path->getY(j) - rect->y1);
+          appearBBox->extendTo (path->getX(j) - rect->x1, path->getY(j) - rect->y1);
         }
 
         appearBuf->append ("S\n");
@@ -5530,9 +5602,7 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) {
     appearBuf->append ("Q\n");
 
     double bbox[4];
-    bbox[0] = bbox[1] = 0;
-    bbox[2] = rect->x2 - rect->x1;
-    bbox[3] = rect->y2 - rect->y1;
+    appearBBox->getBBoxRect(bbox);
     if (ca == 1) {
       createForm(bbox, gFalse, NULL, &appearance);
     } else {
@@ -5550,8 +5620,14 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) {
 
   // draw the appearance stream
   appearance.fetch(xref, &obj);
-  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
-                 rect->x1, rect->y1, rect->x2, rect->y2);
+  if (appearBBox) {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+                   appearBBox->getPageXMax(), appearBBox->getPageYMax());
+  } else {
+    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                   rect->x1, rect->y1, rect->x2, rect->y2);
+  }
   obj.free();
 }
 
diff --git a/poppler/Annot.h b/poppler/Annot.h
index cfa2365..2e64ac9 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -435,6 +435,32 @@ protected:
 };
 
 //------------------------------------------------------------------------
+// AnnotAppearanceBBox
+//------------------------------------------------------------------------
+
+class AnnotAppearanceBBox
+{
+public:
+  AnnotAppearanceBBox(PDFRectangle *init);
+
+  void setBorderWidth(double w) { borderWidth = w; }
+
+  // The following functions operate on coords relative to [origX origY]
+  void extendTo(double x, double y);
+  void getBBoxRect(double bbox[4]) const;
+
+  // Get boundaries in page coordinates
+  double getPageXMin() const;
+  double getPageYMin() const;
+  double getPageXMax() const;
+  double getPageYMax() const;
+
+private:
+  double origX, origY, borderWidth;
+  double minX, minY, maxX, maxY;
+};
+
+//------------------------------------------------------------------------
 // Annot
 //------------------------------------------------------------------------
 
@@ -593,6 +619,7 @@ protected:
   AnnotAppearance *appearStreams;   // AP
   Object appearance;     // a reference to the Form XObject stream
                          //   for the normal appearance
+  AnnotAppearanceBBox *appearBBox;  // BBox of generated appearance
   GooString *appearState;           // AS
   int treeKey;                      // Struct Parent;
   Object oc;                        // OC
commit 503620ae74d719da52e3374725e490c62f7be7a3
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Thu Mar 29 19:07:05 2012 +0200

    Do not recreate Annots when writing to PS, Export poppler-generated Annot appearance resource dict
    
    1) With previous code each Annot object was reconstructed from the pdf object when
    writing to PS, leading to the fact that writeDocSetup couldn't see the
    generated appearance.
    This patch makes writeDocSetup use the same Annots object returned by
    Page::getAnnots.
    
    2) This patch also enables each Annot subtype to control the exported
    resources. AnnotFreeText uses this new method to export font information.
    
    3) Comment fixed in Page.h: Page::getAnnots does *not* give away ownership, in
    fact the returned object is destroyed by ~Page.

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index e1fd5d8..60419b2 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -1552,6 +1552,25 @@ void Annot::createResourcesDict(const char *formName, Object *formStream,
   resDict->dictSet("XObject", &formDict);
 }
 
+Object *Annot::getAppearanceResDict(Object *dest) {
+  Object obj1, obj2;
+
+  dest->initNull(); // Default value
+
+  // Fetch appearance's resource dict (if any)
+  appearance.fetch(xref, &obj1);
+  if (obj1.isStream()) {
+    obj1.streamGetDict()->lookup("Resources", &obj2);
+    if (obj2.isDict()) {
+      obj2.copy(dest);
+    }
+    obj2.free();
+  }
+  obj1.free();
+
+  return dest;
+}
+
 GBool Annot::isVisible(GBool printing) {
   // check the flags
   if ((flags & flagHidden) ||
@@ -2682,6 +2701,15 @@ void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
   obj.free();
 }
 
+// Before retrieving the res dict, regenerate the appearance stream if needed,
+// because AnnotFreeText::draw needs to store font info in the res dict
+Object *AnnotFreeText::getAppearanceResDict(Object *dest) {
+  if (appearance.isNull()) {
+    generateFreeTextAppearance();
+  }
+  return Annot::getAppearanceResDict(dest);
+}
+
 //------------------------------------------------------------------------
 // AnnotLine
 //------------------------------------------------------------------------
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 5f0d4c4..cfa2365 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -492,8 +492,8 @@ public:
   void decRefCnt();
 
   virtual void draw(Gfx *gfx, GBool printing);
-  // Get appearance object.
-  Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
+  // Get the resource dict of the appearance stream
+  virtual Object *getAppearanceResDict(Object *dest);
 
   GBool match(Ref *refA)
     { return ref.num == refA->num && ref.gen == refA->gen; }
@@ -842,6 +842,7 @@ public:
   ~AnnotFreeText();
 
   virtual void draw(Gfx *gfx, GBool printing);
+  virtual Object *getAppearanceResDict(Object *dest);
 
   void setAppearanceString(GooString *new_string);
   void setQuadding(AnnotFreeTextQuadding new_quadding);
diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
index 2a90c1e..4f30f05 100644
--- a/poppler/FontInfo.cc
+++ b/poppler/FontInfo.cc
@@ -11,6 +11,7 @@
 // Copyright (C) 2010, 2012 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2010 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2011 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2012 Fabio D'Urso <fabiodurso at hotmail.it>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -53,7 +54,7 @@ GooList *FontInfoScanner::scan(int nPages) {
   Page *page;
   Dict *resDict;
   Annots *annots;
-  Object obj1, obj2;
+  Object obj1;
   int lastPage;
 
   if (currentPage > doc->getNumPages()) {
@@ -76,12 +77,8 @@ GooList *FontInfoScanner::scan(int nPages) {
     }
     annots = page->getAnnots();
     for (int i = 0; i < annots->getNumAnnots(); ++i) {
-      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
-	obj1.streamGetDict()->lookup("Resources", &obj2);
-	if (obj2.isDict()) {
-	  scanFonts(obj2.getDict(), result);
-	}
-	obj2.free();
+      if (annots->getAnnot(i)->getAppearanceResDict(&obj1)->isDict()) {
+        scanFonts(obj1.getDict(), result);
       }
       obj1.free();
     }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 232c750..157b4b7 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1553,19 +1553,13 @@ void PSOutputDev::writeDocSetup(PDFDoc *doc, Catalog *catalog,
     if ((resDict = page->getResourceDict())) {
       setupResources(resDict);
     }
-    annots = new Annots(doc, page->getAnnots(&obj1));
-    obj1.free();
+    annots = page->getAnnots();
     for (i = 0; i < annots->getNumAnnots(); ++i) {
-      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
-	obj1.streamGetDict()->lookup("Resources", &obj2);
-	if (obj2.isDict()) {
-	  setupResources(obj2.getDict());
-	}
-	obj2.free();
+      if (annots->getAnnot(i)->getAppearanceResDict(&obj1)->isDict()) {
+        setupResources(obj1.getDict());
       }
       obj1.free();
     }
-    delete annots;
   }
   if ((acroForm = catalog->getAcroForm()) && acroForm->isDict()) {
     if (acroForm->dictLookup("DR", &obj1)->isDict()) {
diff --git a/poppler/Page.h b/poppler/Page.h
index a1722a4..9dea41c 100644
--- a/poppler/Page.h
+++ b/poppler/Page.h
@@ -178,7 +178,7 @@ public:
   // Return a list of links.
   Links *getLinks();
 
-  // Return a list of annots. Ownership is transferred to the caller.
+  // Return a list of annots. It will be valid until the page is destroyed
   Annots *getAnnots();
 
   // Get contents.
commit 2733504890333b0925d95e01310726d11fed44d8
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Fri Mar 23 20:54:58 2012 +0100

    Basic AnnotFreeText rendering (hardcoded font, WinAnsi characters only)
    
    This patch also moves layoutText and writeString from AnnotWidget to Annot

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 9013eed..e1fd5d8 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -2549,6 +2549,139 @@ void AnnotFreeText::setIntent(AnnotFreeTextIntent new_intent) {
   update ("IT", &obj1);
 }
 
+static GfxFont * createAnnotDrawFont(XRef * xref, Object *fontResDict)
+{
+  Ref dummyRef = { -1, -1 };
+
+  Object baseFontObj, subtypeObj, encodingObj;
+  baseFontObj.initName("Helvetica");
+  subtypeObj.initName("Type0");
+  encodingObj.initName("WinAnsiEncoding");
+
+  Object fontDictObj;
+  Dict *fontDict = new Dict(xref);
+  fontDict->decRef();
+  fontDict->add(copyString("BaseFont"), &baseFontObj);
+  fontDict->add(copyString("Subtype"), &subtypeObj);
+  fontDict->add(copyString("Encoding"), &encodingObj);
+  fontDictObj.initDict(fontDict);
+
+  Object fontsDictObj;
+  Dict *fontsDict = new Dict(xref);
+  fontsDict->decRef();
+  fontsDict->add(copyString("AnnotDrawFont"), &fontDictObj);
+  fontsDictObj.initDict(fontsDict);
+
+  Dict *dict = new Dict(xref);
+  dict->add(copyString("Font"), &fontsDictObj);
+
+  fontResDict->initDict(dict);
+  return GfxFont::makeFont(xref, "AnnotDrawFont", dummyRef, fontDict);
+}
+
+void AnnotFreeText::generateFreeTextAppearance()
+{
+  double ca = opacity;
+
+  appearBuf = new GooString ();
+  appearBuf->append ("q\n");
+  if (color) {
+    setColor(color, gTrue);
+  }
+
+  // Main segment length
+  const double width = rect->x2 - rect->x1;
+  const double height = rect->y2 - rect->y1;
+
+  // Parse text size from appearance string (TODO: other properties)
+  double fontsize = 0;
+  GooString * da = appearanceString;
+  if (da) {
+    GooList * daToks = new GooList();
+    int j, i = 0;
+    while (i < da->getLength()) {
+      while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
+        ++i;
+      }
+      if (i < da->getLength()) {
+        for (j = i + 1; j < da->getLength() && !Lexer::isSpace(da->getChar(j)); ++j) {
+        }
+        daToks->append(new GooString(da, i, j - i));
+        i = j;
+      }
+    }
+    for (i = 2; i < daToks->getLength(); ++i) {
+      if (!((GooString *)daToks->get(i))->cmp("Tf")) {
+        GooString * tok = (GooString *)daToks->get(i - 1);
+        fontsize = gatof(tok->getCString());
+        break;
+      }
+    }
+    deleteGooList(daToks, GooString);
+  }
+  if (fontsize <= 0) {
+    fontsize = 10; // Default value
+  }
+
+  // Draw box and setup clipping
+  appearBuf->appendf ("[] 0 d 1 w 0 G 0 0 {0:.2f} {1:.2f} re b\n", width, height);
+  appearBuf->appendf ("2 0 {0:.2f} {1:.2f} re W n\n", width-4, height);
+
+  // Set font state
+  appearBuf->appendf ("0 g BT 1 0 0 1 2 {0:.2f} Tm\n", height);
+  appearBuf->appendf ("{0:.2f} TL /AnnotDrawFont {0:.2f} Tf\n", fontsize);
+
+  Object fontResDict;
+  GfxFont *font = createAnnotDrawFont(xref, &fontResDict);
+
+  int i = 0;
+  while (i < contents->getLength()) {
+    GooString out;
+    layoutText(contents, &out, &i, font, NULL, 0, NULL, gFalse);
+    writeString(&out, appearBuf);
+    appearBuf->append("'\n");
+  }
+
+  font->decRefCnt();
+  appearBuf->append ("ET Q\n");
+
+  double bbox[4];
+  bbox[0] = bbox[1] = 0;
+  bbox[2] = rect->x2 - rect->x1;
+  bbox[3] = rect->y2 - rect->y1;
+
+  if (ca == 1) {
+    createForm(bbox, gFalse, &fontResDict, &appearance);
+  } else {
+    Object aStream, resDict;
+
+    createForm(bbox, gTrue, &fontResDict, &aStream);
+    delete appearBuf;
+
+    appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
+    createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
+    createForm(bbox, gFalse, &resDict, &appearance);
+  }
+  delete appearBuf;
+}
+
+void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
+  Object obj;
+
+  if (!isVisible (printing))
+    return;
+
+  if (appearance.isNull()) {
+    generateFreeTextAppearance();
+  }
+
+  // draw the appearance stream
+  appearance.fetch(xref, &obj);
+  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                 rect->x1, rect->y1, rect->x2, rect->y2);
+  obj.free();
+}
+
 //------------------------------------------------------------------------
 // AnnotLine
 //------------------------------------------------------------------------
@@ -3308,7 +3441,7 @@ void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) {
 // TODO: Handle surrogate pairs in UTF-16.
 //       Should be able to generate output for any CID-keyed font.
 //       Doesn't handle vertical fonts--should it?
-void AnnotWidget::layoutText(GooString *text, GooString *outBuf, int *i,
+void Annot::layoutText(GooString *text, GooString *outBuf, int *i,
                              GfxFont *font, double *width, double widthLimit,
                              int *charCount, GBool noReencode)
 {
@@ -3502,7 +3635,7 @@ void AnnotWidget::layoutText(GooString *text, GooString *outBuf, int *i,
 
 // Copy the given string to appearBuf, adding parentheses around it and
 // escaping characters as appropriate.
-void AnnotWidget::writeString(GooString *str, GooString *appearBuf)
+void Annot::writeString(GooString *str, GooString *appearBuf)
 {
   char c;
   int i;
diff --git a/poppler/Annot.h b/poppler/Annot.h
index a01361f..5f0d4c4 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -563,6 +563,10 @@ protected:
   void drawCircle(double cx, double cy, double r, GBool fill);
   void drawCircleTopLeft(double cx, double cy, double r);
   void drawCircleBottomRight(double cx, double cy, double r);
+  void layoutText(GooString *text, GooString *outBuf, int *i, GfxFont *font,
+		  double *width, double widthLimit, int *charCount,
+		  GBool noReencode);
+  void writeString(GooString *str, GooString *appearBuf);
   void createForm(double *bbox, GBool transparencyGroup, Object *resDict, Object *aStream);
   void createResourcesDict(const char *formName, Object *formStream, const char *stateName,
 			   double opacity, const char *blendMode, Object *resDict);
@@ -837,6 +841,8 @@ public:
   AnnotFreeText(PDFDoc *docA, Dict *dict, Object *obj);
   ~AnnotFreeText();
 
+  virtual void draw(Gfx *gfx, GBool printing);
+
   void setAppearanceString(GooString *new_string);
   void setQuadding(AnnotFreeTextQuadding new_quadding);
   void setStyleString(GooString *new_string);
@@ -857,6 +863,7 @@ public:
 protected:
 
   void initialize(PDFDoc *docA, Dict *dict);
+  void generateFreeTextAppearance();
 
   // required
   GooString *appearanceString;      // DA
@@ -1242,10 +1249,6 @@ private:
 		GBool password=false);
   void drawListBox(FormFieldChoice *fieldChoice,
 		   GooString *da, GfxResources *resources, int quadding);
-  void layoutText(GooString *text, GooString *outBuf, int *i, GfxFont *font,
-		  double *width, double widthLimit, int *charCount,
-		  GBool noReencode);
-  void writeString(GooString *str, GooString *appearBuf);
 
   Form *form;
   FormField *field;                       // FormField object for this annotation
commit 3023a59c0a1a5974b232f6f8cb629eabb6797616
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Sun Mar 25 22:04:11 2012 +0200

    AnnotTextMarkup rendering improvements
    
    1) FIX: Wrong coords in typeUnderline and typeStrikeout
    2) Implementation of typeSquiggly
    3) FIX: Form creation is common to all markup types

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 9ed22bf..9013eed 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -3065,42 +3065,40 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
     return;
 
   if (appearance.isNull() || type == typeHighlight) {
+    GBool blendMultiply = gTrue;
     ca = opacity;
 
     appearBuf = new GooString ();
+    appearBuf->append ("q\n");
 
     switch (type) {
     case typeUnderline:
       if (color) {
         setColor(color, gFalse);
-	setColor(color, gTrue);
       }
+      appearBuf->append ("[] 0 d 1 w\n");
 
       for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
         double x1, x2, y3;
-	double x, y;
 
 	x1 = quadrilaterals->getX1(i);
 	x2 = quadrilaterals->getX2(i);
 	y3 = quadrilaterals->getY3(i);
 
-	x = x1 - rect->x1;
-	y = y3 - rect->y1;
-	appearBuf->append ("[]0 d 2 w\n");
-	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x, y);
-	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x + (x2 - x1), y);
+	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y3);
+	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x2, y3);
 	appearBuf->append ("S\n");
       }
       break;
     case typeStrikeOut:
       if (color) {
         setColor(color, gFalse);
-	setColor(color, gTrue);
       }
+      blendMultiply = gFalse;
+      appearBuf->append ("[] 0 d 1 w\n");
 
       for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
         double x1, y1, x2, y3;
-	double x, y;
 	double h2;
 
 	x1 = quadrilaterals->getX1(i);
@@ -3109,16 +3107,37 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
 	y3 = quadrilaterals->getY3(i);
 	h2 = (y1 - y3) / 2.0;
 
-	x = x1 - rect->x1;
-	y = (y3 - rect->y1) + h2;
-	appearBuf->append ("[]0 d 2 w\n");
-	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x, y);
-	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x + (x2 - x1), y);
+	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y3+h2);
+	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x2, y3+h2);
 	appearBuf->append ("S\n");
       }
       break;
     case typeSquiggly:
-      // TODO
+      if (color) {
+        setColor(color, gFalse);
+      }
+      appearBuf->append ("[] 0 d 1 w\n");
+
+      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
+        double x1, y1, x2, y3;
+        double h6;
+
+        x1 = quadrilaterals->getX1(i);
+        y1 = quadrilaterals->getY1(i);
+        x2 = quadrilaterals->getX2(i);
+        y3 = quadrilaterals->getY3(i);
+        h6 = (y1 - y3) / 6.0;
+
+        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y3+h6);
+        bool down = false;
+        do {
+          down = !down; // Zigzag line
+          x1 += 2;
+          appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x1, y3 + (down ? 0 : h6));
+        } while (x1 < x2);
+        appearBuf->append ("S\n");
+      }
+      break;
     default:
     case typeHighlight:
       appearance.free();
@@ -3138,7 +3157,7 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
 	y3 = quadrilaterals->getY3(i);
 	x4 = quadrilaterals->getX4(i);
 	y4 = quadrilaterals->getY4(i);
-	h4 = abs(y1 - y3) / 4.0;
+	h4 = fabs(y1 - y3) / 4.0;
 
 	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
 	appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
@@ -3148,31 +3167,32 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
 			    x2 + h4, y2 - h4, x4 + h4, y4 + h4, x4, y4);
 	appearBuf->append ("f\n");
       }
+      break;
+    }
+    appearBuf->append ("Q\n");
 
-      Object aStream, resDict;
-      double bbox[4];
-      bbox[0] = rect->x1;
-      bbox[1] = rect->y1;
-      bbox[2] = rect->x2;
-      bbox[3] = rect->y2;
-      createForm(bbox, gTrue, NULL, &aStream);
+    Object aStream, resDict;
+    double bbox[4];
+    bbox[0] = rect->x1;
+    bbox[1] = rect->y1;
+    bbox[2] = rect->x2;
+    bbox[3] = rect->y2;
+    createForm(bbox, gTrue, NULL, &aStream);
+    delete appearBuf;
+
+    appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
+    createResourcesDict("Fm0", &aStream, "GS0", 1, blendMultiply ? "Multiply" : NULL, &resDict);
+    if (ca == 1) {
+      createForm(bbox, gFalse, &resDict, &appearance);
+    } else {
+      createForm(bbox, gTrue, &resDict, &aStream);
       delete appearBuf;
 
       appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
-      createResourcesDict("Fm0", &aStream, "GS0", 1, "Multiply", &resDict);
-      if (ca == 1) {
-        createForm(bbox, gFalse, &resDict, &appearance);
-      } else {
-        createForm(bbox, gTrue, &resDict, &aStream);
-	delete appearBuf;
-
-	appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
-	createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
-	createForm(bbox, gFalse, &resDict, &appearance);
-      }
-      delete appearBuf;
-      break;
+      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
+      createForm(bbox, gFalse, &resDict, &appearance);
     }
+    delete appearBuf;
   }
 
   // draw the appearance stream
commit 8927ddc448edc016043107e88e3bc3b2b8b03269
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Thu Mar 22 17:33:01 2012 +0100

    Improvements to AnnotLine::draw

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 6d42be1..9ed22bf 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -2851,10 +2851,52 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
       }
       appearBuf->appendf("{0:.2f} w\n", border->getWidth());
     }
-    appearBuf->appendf ("{0:.2f} {1:.2f} m\n", coord1->getX() - rect->x1, coord1->getY() - rect->y1);
-    appearBuf->appendf ("{0:.2f} {1:.2f} l\n", coord2->getX() - rect->x1, coord2->getY() - rect->y1);
-    // TODO: Line ending, caption, leader lines
-    appearBuf->append ("S\n");
+
+    const double x1 = coord1->getX();
+    const double y1 = coord1->getY();
+    const double x2 = coord2->getX();
+    const double y2 = coord2->getY();
+
+    // Main segment length
+    const double main_len = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
+
+    // Main segment becomes positive x direction, coord1 becomes (0,0)
+    Matrix matr;
+    const double angle = atan2(y2 - y1, x2 - x1);
+    matr.m[0] = matr.m[3] = cos(angle);
+    matr.m[1] = sin(angle);
+    matr.m[2] = -matr.m[1];
+    matr.m[4] = x1-rect->x1;
+    matr.m[5] = y1-rect->y1;
+
+    double tx, ty;
+
+    // Draw main segment
+    matr.transform (0, leaderLineLength, &tx, &ty);
+    appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
+
+    matr.transform (main_len, leaderLineLength, &tx, &ty);
+    appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
+
+    // TODO: Line ending, caption
+
+    // Draw leader lines
+    double ll_len = fabs(leaderLineLength) + leaderLineExtension;
+    double sign = leaderLineLength >= 0 ? 1 : -1;
+    if (ll_len != 0) {
+      matr.transform (0, 0, &tx, &ty);
+      appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
+
+      matr.transform (0, sign*ll_len, &tx, &ty);
+      appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
+
+      matr.transform (main_len, 0, &tx, &ty);
+      appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
+
+      matr.transform (main_len, sign*ll_len, &tx, &ty);
+      appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
+    }
+
     appearBuf->append ("Q\n");
 
     double bbox[4];
commit bd7a40fd0312c753d1871558b566376304f1ff35
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Wed Mar 21 22:48:05 2012 +0100

    AnnotInk rendering

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 2868efd..6d42be1 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -5270,6 +5270,68 @@ void AnnotInk::setInkList(AnnotPath **paths, int n_paths) {
   annotObj.dictSet ("InkList", &obj1);
 }
 
+void AnnotInk::draw(Gfx *gfx, GBool printing) {
+  Object obj;
+  double ca = 1;
+
+  if (!isVisible (printing))
+    return;
+
+  if (appearance.isNull()) {
+    ca = opacity;
+
+    appearBuf = new GooString ();
+    appearBuf->append ("q\n");
+
+    if (color) {
+      setColor(color, gFalse);
+    }
+
+    if (border) {
+      appearBuf->appendf("{0:.2f} w\n", border->getWidth());
+    }
+
+    for (int i = 0; i < inkListLength; ++i) {
+      const AnnotPath * path = inkList[i];
+      if (path->getCoordsLength() != 0) {
+        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", path->getX(0) - rect->x1, path->getY(0) - rect->y1);
+
+        for (int j = 1; j < path->getCoordsLength(); ++j) {
+          appearBuf->appendf ("{0:.2f} {1:.2f} l\n", path->getX(j) - rect->x1, path->getY(j) - rect->y1);
+        }
+
+        appearBuf->append ("S\n");
+      }
+    }
+
+    appearBuf->append ("Q\n");
+
+    double bbox[4];
+    bbox[0] = bbox[1] = 0;
+    bbox[2] = rect->x2 - rect->x1;
+    bbox[3] = rect->y2 - rect->y1;
+    if (ca == 1) {
+      createForm(bbox, gFalse, NULL, &appearance);
+    } else {
+      Object aStream, resDict;
+
+      createForm(bbox, gTrue, NULL, &aStream);
+      delete appearBuf;
+
+      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
+      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
+      createForm(bbox, gFalse, &resDict, &appearance);
+    }
+    delete appearBuf;
+  }
+
+  // draw the appearance stream
+  appearance.fetch(xref, &obj);
+  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                 rect->x1, rect->y1, rect->x2, rect->y2);
+  obj.free();
+}
+
 //------------------------------------------------------------------------
 // AnnotFileAttachment
 //------------------------------------------------------------------------
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 299eaa7..a01361f 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -1120,6 +1120,8 @@ public:
   AnnotInk(PDFDoc *docA, Dict *dict, Object *obj);
   ~AnnotInk();
 
+  virtual void draw(Gfx *gfx, GBool printing);
+
   void setInkList(AnnotPath **paths, int n_paths);
 
   // getters
commit 6a8794abe639db8284db079e028cbcd66e138884
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Wed Mar 21 22:33:13 2012 +0100

    AnnotPolygon rendering

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 6e8b355..2868efd 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -5041,6 +5041,93 @@ void AnnotPolygon::setIntent(AnnotPolygonIntent new_intent) {
   update ("IT", &obj1);
 }
 
+void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
+  Object obj;
+  double ca = 1;
+
+  if (!isVisible (printing))
+    return;
+
+  if (appearance.isNull()) {
+    ca = opacity;
+
+    appearBuf = new GooString ();
+    appearBuf->append ("q\n");
+
+    if (color) {
+      setColor(color, gFalse);
+    }
+
+    if (border) {
+      int i, dashLength;
+      double *dash;
+
+      switch (border->getStyle()) {
+      case AnnotBorder::borderDashed:
+        appearBuf->append("[");
+        dashLength = border->getDashLength();
+        dash = border->getDash();
+        for (i = 0; i < dashLength; ++i)
+          appearBuf->appendf(" {0:.2f}", dash[i]);
+        appearBuf->append(" ] 0 d\n");
+        break;
+      default:
+        appearBuf->append("[] 0 d\n");
+        break;
+      }
+      appearBuf->appendf("{0:.2f} w\n", border->getWidth());
+    }
+
+    if (interiorColor) {
+      setColor(interiorColor, gTrue);
+    }
+
+    if (vertices->getCoordsLength() != 0) {
+      appearBuf->appendf ("{0:.2f} {1:.2f} m\n", vertices->getX(0) - rect->x1, vertices->getY(0) - rect->y1);
+
+      for (int i = 1; i < vertices->getCoordsLength(); ++i) {
+        appearBuf->appendf ("{0:.2f} {1:.2f} l\n", vertices->getX(i) - rect->x1, vertices->getY(i) - rect->y1);
+      }
+
+      if (type == typePolygon) {
+        if (interiorColor && interiorColor->getSpace() != AnnotColor::colorTransparent) {
+          appearBuf->append ("b\n");
+        } else {
+          appearBuf->append ("s\n");
+        }
+      } else {
+        appearBuf->append ("S\n");
+      }
+    }
+
+    appearBuf->append ("Q\n");
+
+    double bbox[4];
+    bbox[0] = bbox[1] = 0;
+    bbox[2] = rect->x2 - rect->x1;
+    bbox[3] = rect->y2 - rect->y1;
+    if (ca == 1) {
+      createForm(bbox, gFalse, NULL, &appearance);
+    } else {
+      Object aStream, resDict;
+
+      createForm(bbox, gTrue, NULL, &aStream);
+      delete appearBuf;
+
+      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
+      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
+      createForm(bbox, gFalse, &resDict, &appearance);
+    }
+    delete appearBuf;
+  }
+
+  // draw the appearance stream
+  appearance.fetch(xref, &obj);
+  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+                 rect->x1, rect->y1, rect->x2, rect->y2);
+  obj.free();
+}
+
 //------------------------------------------------------------------------
 // AnnotCaret
 //------------------------------------------------------------------------
diff --git a/poppler/Annot.h b/poppler/Annot.h
index b196e51..299eaa7 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -1045,6 +1045,8 @@ public:
   AnnotPolygon(PDFDoc *docA, Dict *dict, Object *obj);
   ~AnnotPolygon();
 
+  virtual void draw(Gfx *gfx, GBool printing);
+
   void setType(AnnotSubtype new_type); // typePolygon or typePolyLine
   void setVertices(AnnotPath *path);
   void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end);
commit f389c50458079f24164b1c12b1151c8617485acb
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Wed Mar 21 21:12:59 2012 +0100

    Do not fill AnnotGeometry with transparent color
    
    Previously it was filled with black.

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index caa13c5..6e8b355 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -4812,7 +4812,7 @@ void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
 
       }
 
-      if (interiorColor)
+      if (interiorColor && interiorColor->getSpace() != AnnotColor::colorTransparent)
         appearBuf->append ("b\n");
       else
         appearBuf->append ("S\n");
commit c63cc22dd82f827305ad57f241ad49998f2a1c23
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sun Apr 8 12:28:17 2012 +0200

    Remove extra copy() (memleak)

diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 662f8f9..811a120 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -15,7 +15,7 @@
 //
 // Copyright (C) 2005 Martin Kretzschmar <martink at gnome.org>
 // Copyright (C) 2005, 2006 Kristian Høgsberg <krh at redhat.com>
-// Copyright (C) 2005, 2007-2010 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2005, 2007-2010, 2012 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2005 Jonathan Blandford <jrb at redhat.com>
 // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff at infidigm.net>
 // Copyright (C) 2006 Takashi Iwai <tiwai at suse.de>
@@ -1184,7 +1184,6 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
   GooString *path = NULL;
   GooString *fontName = font->getName();
   if (!fontName) return NULL;
-  fontName = fontName->copy();
   lockGlobalParams;
 
   if ((fi = sysFonts->find(fontName, font->isFixedWidth(), gTrue))) {


More information about the poppler mailing list