From a1eb5f31eaf59af24cef56445734c400228b70a9 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 6 Dec 2009 16:19:36 +0100 Subject: [PATCH 1/5] [annots] Refactor Annot::setColor to receive an AnnotColor Removes duplicated code since color arrays are already parsed in AnnotColor --- poppler/Annot.cc | 136 ++++++++++++++++++++++++++++-------------------------- poppler/Annot.h | 4 +- 2 files changed, 73 insertions(+), 67 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index dd360ec..78a6e77 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -632,23 +632,41 @@ AnnotColor::AnnotColor(double c, double m, double y, double k) { values[3] = k; } -AnnotColor::AnnotColor(Array *array) { +// If is +1, color is brightened; +// if is -1, color is darkened; +// otherwise color is not modified. +AnnotColor::AnnotColor(Array *array, int adjust) { + int i; + length = array->getLength(); if (length > 4) length = 4; - for (int i = 0; i < length; i++) { - Object obj1; + for (i = 0; i < length; i++) { + Object obj1; - if (array->get(i, &obj1)->isNum()) { - values[i] = obj1.getNum(); + if (array->get(i, &obj1)->isNum()) { + values[i] = obj1.getNum(); - if (values[i] < 0 || values[i] > 1) - values[i] = 0; - } else { + if (values[i] < 0 || values[i] > 1) values[i] = 0; - } - obj1.free(); + } else { + values[i] = 0; + } + obj1.free(); + } + + if (length == 4) { + adjust = -adjust; + } + if (adjust > 0) { + for (i = 0; i < length; ++i) { + values[i] = 0.5 * values[i] + 0.5; + } + } else if (adjust < 0) { + for (i = 0; i < length; ++i) { + values[i] = 0.5 * values[i]; + } } } @@ -1126,51 +1144,28 @@ Annot::~Annot() { oc.free(); } -// Set the current fill or stroke color, based on (which should -// have 1, 3, or 4 elements). If is +1, color is brightened; -// if is -1, color is darkened; otherwise color is not -// modified. -void Annot::setColor(Array *a, GBool fill, int adjust) { - Object obj1; - double color[4]; - int nComps, i; +void Annot::setColor(AnnotColor *color, GBool fill) { + const double *values = color->getValues(); - nComps = a->getLength(); - if (nComps > 4) { - nComps = 4; - } - for (i = 0; i < nComps && i < 4; ++i) { - if (a->get(i, &obj1)->isNum()) { - color[i] = obj1.getNum(); - } else { - color[i] = 0; - } - obj1.free(); - } - if (nComps == 4) { - adjust = -adjust; - } - if (adjust > 0) { - for (i = 0; i < nComps; ++i) { - color[i] = 0.5 * color[i] + 0.5; - } - } else if (adjust < 0) { - for (i = 0; i < nComps; ++i) { - color[i] = 0.5 * color[i]; - } - } - if (nComps == 4) { + switch (color->getSpace()) { + case AnnotColor::colorCMYK: appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n", - color[0], color[1], color[2], color[3], - fill ? 'k' : 'K'); - } else if (nComps == 3) { + values[0], values[1], values[2], values[3], + fill ? 'k' : 'K'); + break; + case AnnotColor::colorRGB: appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:s}\n", - color[0], color[1], color[2], - fill ? "rg" : "RG"); - } else { + values[0], values[1], values[2], + fill ? "rg" : "RG"); + break; + case AnnotColor::colorGray: appearBuf->appendf("{0:.2f} {1:c}\n", - color[0], - fill ? 'g' : 'G'); + values[0], + fill ? 'g' : 'G'); + break; + case AnnotColor::colorTransparent: + default: + break; } } @@ -2999,6 +2994,7 @@ void AnnotWidget::generateFieldAppearance() { GBool *selection; int dashLength, ff, quadding, comb, nOptions, topIdx, i, j; GBool modified; + AnnotColor aColor; if (widget == NULL || !widget->getField () || !widget->getField ()->getObj ()->isDict ()) return; @@ -3027,7 +3023,8 @@ void AnnotWidget::generateFieldAppearance() { if (mkDict) { if (mkDict->lookup("BG", &obj1)->isArray() && obj1.arrayGetLength() > 0) { - setColor(obj1.getArray(), gTrue, 0); + AnnotColor aColor = AnnotColor (obj1.getArray()); + setColor(&aColor, gTrue); appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n", rect->x2 - rect->x1, rect->y2 - rect->y1); } @@ -3075,19 +3072,23 @@ void AnnotWidget::generateFieldAppearance() { case AnnotBorder::borderSolid: case AnnotBorder::borderUnderlined: appearBuf->appendf("{0:.2f} w\n", w); - setColor(obj1.getArray(), gFalse, 0); + aColor = AnnotColor (obj1.getArray()); + setColor(&aColor, gFalse); drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse); break; case AnnotBorder::borderBeveled: case AnnotBorder::borderInset: appearBuf->appendf("{0:.2f} w\n", 0.5 * w); - setColor(obj1.getArray(), gFalse, 0); + aColor = AnnotColor (obj1.getArray()); + setColor(&aColor, gFalse); drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse); - setColor(obj1.getArray(), gFalse, - border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1); + aColor = AnnotColor (obj1.getArray(), + border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1); + setColor(&aColor, gFalse); drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w); - setColor(obj1.getArray(), gFalse, - border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1); + aColor = AnnotColor (obj1.getArray(), + border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1); + setColor(&aColor, gFalse); drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w); break; } @@ -3105,14 +3106,16 @@ void AnnotWidget::generateFieldAppearance() { // fall through to the solid case case AnnotBorder::borderSolid: appearBuf->appendf("{0:.2f} w\n", w); - setColor(obj1.getArray(), gFalse, 0); + aColor = AnnotColor (obj1.getArray()); + setColor(&aColor, gFalse); appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n", 0.5 * w, dx - w, dy - w); break; case AnnotBorder::borderBeveled: case AnnotBorder::borderInset: - setColor(obj1.getArray(), gTrue, - border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1); + aColor = AnnotColor (obj1.getArray(), + border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1); + setColor(&aColor, gTrue); appearBuf->append("0 0 m\n"); appearBuf->appendf("0 {0:.2f} l\n", dy); appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy); @@ -3120,8 +3123,9 @@ void AnnotWidget::generateFieldAppearance() { appearBuf->appendf("{0:.2f} {1:.2f} l\n", w, dy - w); appearBuf->appendf("{0:.2f} {0:.2f} l\n", w); appearBuf->append("f\n"); - setColor(obj1.getArray(), gTrue, - border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1); + aColor = AnnotColor (obj1.getArray(), + border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1); + setColor(&aColor, gTrue); appearBuf->append("0 0 m\n"); appearBuf->appendf("{0:.2f} 0 l\n", dx); appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy); @@ -3132,7 +3136,8 @@ void AnnotWidget::generateFieldAppearance() { break; case AnnotBorder::borderUnderlined: appearBuf->appendf("{0:.2f} w\n", w); - setColor(obj1.getArray(), gFalse, 0); + aColor = AnnotColor (obj1.getArray()); + setColor(&aColor, gFalse); appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx); break; } @@ -3195,7 +3200,8 @@ void AnnotWidget::generateFieldAppearance() { obj3.arrayGetLength() > 0) { dx = rect->x2 - rect->x1; dy = rect->y2 - rect->y1; - setColor(obj3.getArray(), gTrue, 0); + aColor = AnnotColor (obj1.getArray()); + setColor(&aColor, gTrue); drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy), gTrue); } diff --git a/poppler/Annot.h b/poppler/Annot.h index 3f3ed70..92ca1c6 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -290,7 +290,7 @@ public: AnnotColor(double gray); AnnotColor(double r, double g, double b); AnnotColor(double c, double m, double y, double k); - AnnotColor(Array *array); + AnnotColor(Array *array, int adjust = 0); AnnotColorSpace getSpace() const { return (AnnotColorSpace) length; } const double *getValues() const { return values; } @@ -533,7 +533,7 @@ private: protected: - void setColor(Array *a, GBool fill, int adjust); + void setColor(AnnotColor *color, GBool fill); 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); -- 1.6.3.3 From 30cd899904595aadb79ee8e313cd86d0a97fd65d Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 6 Dec 2009 16:40:14 +0100 Subject: [PATCH 2/5] [annot] Create appearance stream for Text Annotations when not defined Only for Note icon at the moment. See bug #23108. --- poppler/Annot.cc | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ poppler/Annot.h | 3 ++ 2 files changed, 83 insertions(+), 0 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 78a6e77..62d623a 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -900,6 +900,8 @@ void Annot::initialize(XRef *xrefA, Dict *dict, Catalog *catalog) { appearBuf = NULL; fontSize = 0; + appearance.initNull(); + //----- parse the rectangle rect = new PDFRectangle(); if (dict->lookup("Rect", &obj1)->isArray() && obj1.arrayGetLength() == 4) { @@ -1597,6 +1599,84 @@ void AnnotText::setIcon(GooString *new_icon) { update("Name", &obj1); } +void AnnotText::drawNote() { + appearBuf = new GooString (); + + appearBuf->append ("q\n"); + if (color) + setColor(color, gTrue); + else + appearBuf->append ("0.901961 0.670588 0.262745 rg\n"); + appearBuf->append ("0.768627 0.435294 0.133333 RG 0.999922 w\n" + "0 J\n" + "1 j\n" + "[] 0.0 d\n" + "4 M 6.5 45.5 m 30.562 45.5 l 31.969 45.023 39.527 39.621 41.5 35.875 c 41.5\n" + "2.5 l 6.5 2.5 l h\n" + "6.5 45.5 m B\n" + "0.541176 0.384314 0.141176 RG 1 w\n" + "0 j\n" + "10 38.5 m 15 38.5 m 18 38.5 m 20.906 38.5 m 26 38.5 m 10 36.5 m 15 36.5\n" + "m 17 36.5 m 21 36.5 m 25 36.5 m 27.844 36.5 m 10 34.531 m 14 34.5 m 19\n" + "34.5 m 22 34.5 m 26 34.5 m 30 34.5 m 10 32.5 m 15 32.5 m 20 32.5 m 22\n" + "32.5 m 27 32.5 m 31 32.5 m 10 30.5 m 13 30.5 m 10 26.531 m 14 26.5 m 19\n" + "26.5 m 22 26.5 m 25 26.5 m 27 26.5 m 30 26.5 m 10 24.5 m 15 24.5 m 18\n" + "24.5 m 20.906 24.5 m 27 24.5 m 31.719 24.5 m 10 22.5 m 14 22.5 m 19\n" + "22.5 m 21 22.5 m 26 22.5 m 31 22.5 m 10 20.5 m 15 20.5 m 20 20.5 m 22\n" + "20.5 m 27 20.5 m 30 20.5 m 32.156 20.5 m 10 18.5 m 14.062 18.5 m 17\n" + "18.5 m 20 18.5 m 25 18.5 m 28 18.5 m 10 14.531 m 14 14.5 m 19 14.5 m 22\n" + "14.5 m 25 14.5 m 27 14.5 m 30 14.5 m 10 12.5 m 15 12.5 m 18 12.5 m\n" + "19.281 12.5 m 22 12.5 m 24.156 12.5 m 27.844 12.5 m 10 10.5 m 15 10.5 m\n" + "20 10.5 m 24 10.5 m 27 10.5 m 31.156 10.5 m 10 8.5 m 15 8.5 m 17 8.5 m\n" + "20 8.5 m 25.156 8.5 m 25.156 8.5 m S\n"); + if (color) + setColor(color, gTrue); + else + appearBuf->append ("0.901961 0.670588 0.262745 rg\n"); + appearBuf->append ("0.768627 0.435294 0.133333 RG 1 j\n" + "30.5 36.5 m 41.441 36.5 l 39.863 39.023 32.961 44.633 30.5 45.375 c h\n" + "30.5 36.5 m B*\n" + "Q\n"); + +} + +void AnnotText::draw(Gfx *gfx, GBool printing) { + Object obj; + + if (!isVisible (printing)) + return; + + if (appearance.isNull()) { + if (!icon->cmp("Note")) + drawNote(); + + if (appearBuf) { + Object appearDict, obj1, obj2; + + appearDict.initDict(xref); + appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength())); + appearDict.dictSet("Subtype", obj1.initName("Form")); + obj1.initArray(xref); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(48)); + obj1.arrayAdd(obj2.initReal(48)); + appearDict.dictSet("BBox", &obj1); + + MemStream *appearStream = new MemStream(copyString(appearBuf->getCString()), 0, + appearBuf->getLength(), &appearDict); + appearance.initStream(appearStream); + delete appearBuf; + } + } + + // draw the appearance stream + appearance.fetch(xref, &obj); + gfx->drawAnnot(&obj, border, color, + rect->x1, rect->y1, rect->x2, rect->y2); + obj.free(); +} + //------------------------------------------------------------------------ // AnnotLink //------------------------------------------------------------------------ diff --git a/poppler/Annot.h b/poppler/Annot.h index 92ca1c6..c23ffda 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -670,6 +670,8 @@ public: AnnotText(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj); ~AnnotText(); + virtual void draw(Gfx *gfx, GBool printing); + // getters GBool getOpen() const { return open; } GooString *getIcon() const { return icon; } @@ -681,6 +683,7 @@ public: private: void initialize(XRef *xrefA, Catalog *catalog, Dict *dict); + void drawNote(); GBool open; // Open (Default false) GooString *icon; // Name (Default Note) -- 1.6.3.3 From 8b0497310f9f290ca6b9fba81faa2853612b22a2 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 6 Dec 2009 16:51:37 +0100 Subject: [PATCH 3/5] [annot] Create appearance stream for Line Annotations when not defined See bug #23108. --- poppler/Annot.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ poppler/Annot.h | 2 + 2 files changed, 64 insertions(+), 0 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 62d623a..f7e74ec 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -2083,6 +2083,68 @@ void AnnotLine::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) { obj1.free(); } +void AnnotLine::draw(Gfx *gfx, GBool printing) { + Object obj; + + if (!isVisible (printing)) + return; + + if (appearance.isNull()) { + 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()); + } + 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"); + appearBuf->append ("Q\n"); + + Object appearDict, obj1, obj2; + + appearDict.initDict(xref); + appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength())); + appearDict.dictSet("Subtype", obj1.initName("Form")); + obj1.initArray(xref); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(rect->x2 - rect->x1)); + obj1.arrayAdd(obj2.initReal(rect->y2 - rect->y1)); + appearDict.dictSet("BBox", &obj1); + + MemStream *appearStream = new MemStream(copyString(appearBuf->getCString()), 0, + appearBuf->getLength(), &appearDict); + appearance.initStream(appearStream); + 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(); +} + //------------------------------------------------------------------------ // AnnotTextMarkup //------------------------------------------------------------------------ diff --git a/poppler/Annot.h b/poppler/Annot.h index c23ffda..0189b6d 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -929,6 +929,8 @@ public: AnnotLine(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj); ~AnnotLine(); + virtual void draw(Gfx *gfx, GBool printing); + // getters AnnotLineEndingStyle getStartStyle() const { return startStyle; } AnnotLineEndingStyle getEndStyle() const { return endStyle; } -- 1.6.3.3 From 462390baa3814c9a8cfaee186b328fa02d34f804 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 6 Dec 2009 16:56:22 +0100 Subject: [PATCH 4/5] [annot] Create appearance stream for Geometry Annotations when not defined See bug #23108. --- poppler/Annot.cc | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ poppler/Annot.h | 2 + 2 files changed, 122 insertions(+), 0 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index f7e74ec..e610846 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -4030,6 +4030,126 @@ void AnnotGeometry::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) { } +void AnnotGeometry::draw(Gfx *gfx, GBool printing) { + Object obj; + + if (!isVisible (printing)) + return; + + if (appearance.isNull()) { + 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 (type == typeSquare) { + appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re\n", + border->getWidth() / 2.0, border->getWidth() / 2.0, + (rect->x2 - rect->x1) - border->getWidth(), + (rect->y2 - rect->y1) - border->getWidth()); + } else { + double width, height; + double b; + double x1, y1, x2, y2, x3, y3; + + width = rect->x2 - rect->x1; + height = rect->y2 - rect->y1; + b = border->getWidth() / 2.0; + + x1 = b; + y1 = height / 2.0; + appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y1); + + y1 += height / 4.0; + x2 = width / 4.0; + y2 = height - b; + x3 = width / 2.0; + y3 = y2; + appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", + x1, y1, x2, y2, x3, y3); + x2 = width - b; + y2 = y1; + x1 = x3 + (width / 4.0); + y1 = y3; + x3 = x2; + y3 = height / 2.0; + appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", + x1, y1, x2, y2, x3, y3); + + x2 = x1; + y2 = b; + x1 = x3; + y1 = height / 4.0; + x3 = width / 2.0; + y3 = b; + appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", + x1, y1, x2, y2, x3, y3); + + x2 = b; + y2 = y1; + x1 = width / 4.0; + y1 = b; + x3 = b; + y3 = height / 2.0; + appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", + x1, y1, x2, y2, x3, y3); + + } + + if (interiorColor) + appearBuf->append ("b\n"); + else + appearBuf->append ("S\n"); + appearBuf->append ("Q\n"); + + Object appearDict, obj1, obj2; + + appearDict.initDict(xref); + appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength())); + appearDict.dictSet("Subtype", obj1.initName("Form")); + obj1.initArray(xref); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(0)); + obj1.arrayAdd(obj2.initReal(rect->x2 - rect->x1)); + obj1.arrayAdd(obj2.initReal(rect->y2 - rect->y1)); + appearDict.dictSet("BBox", &obj1); + + MemStream *appearStream = new MemStream(copyString(appearBuf->getCString()), 0, + appearBuf->getLength(), &appearDict); + appearance.initStream(appearStream); + 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(); +} + //------------------------------------------------------------------------ // AnnotPolygon //------------------------------------------------------------------------ diff --git a/poppler/Annot.h b/poppler/Annot.h index 0189b6d..327beb0 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -1026,6 +1026,8 @@ public: AnnotGeometry(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj); ~AnnotGeometry(); + virtual void draw(Gfx *gfx, GBool printing); + // getters AnnotColor *getInteriorColor() const { return interiorColor; } AnnotBorderEffect *getBorderEffect() const { return borderEffect; } -- 1.6.3.3 From f24d510c6772fe96bef190f843468645a79fb973 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 6 Dec 2009 17:09:23 +0100 Subject: [PATCH 5/5] [annots] Use opacity when drawing Markup Annotations According to the spec: "The constant opacity value that shall be used in painting the annotation. This value shall apply to all visible elements of the annotation in its closed state (including its background and border) but not to the pop-up window that appears when the annotation is opened. The specified value shall not used if the annotation has an appearance stream in that case, the appearance stream shall specify any transparency. If no explicit appearance stream is defined for the annotation, it may be painted by implementation-dependent means that do not necessarily conform to the PDF imaging model; in this case, the effect of this entry is implementation-dependent as well." --- poppler/Annot.cc | 21 +++++++++++++++------ poppler/Gfx.cc | 9 ++++++++- poppler/Gfx.h | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index e610846..6e9f300 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -1270,7 +1270,7 @@ void Annot::draw(Gfx *gfx, GBool printing) { // draw the appearance stream appearance.fetch(xref, &obj); - gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, + gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, 1, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); } @@ -1642,11 +1642,14 @@ void AnnotText::drawNote() { void AnnotText::draw(Gfx *gfx, GBool printing) { Object obj; + double ca = 1; if (!isVisible (printing)) return; if (appearance.isNull()) { + ca = opacity; + if (!icon->cmp("Note")) drawNote(); @@ -1672,7 +1675,7 @@ void AnnotText::draw(Gfx *gfx, GBool printing) { // draw the appearance stream appearance.fetch(xref, &obj); - gfx->drawAnnot(&obj, border, color, + gfx->drawAnnot(&obj, border, color, ca, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); } @@ -1764,7 +1767,7 @@ void AnnotLink::draw(Gfx *gfx, GBool printing) { // draw the appearance stream appearance.fetch(xref, &obj); - gfx->drawAnnot(&obj, border, color, + gfx->drawAnnot(&obj, border, color, 1, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); } @@ -2085,11 +2088,14 @@ void AnnotLine::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) { void AnnotLine::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) @@ -2140,7 +2146,7 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) { // draw the appearance stream appearance.fetch(xref, &obj); - gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, + gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, ca, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); } @@ -3586,7 +3592,7 @@ void AnnotWidget::draw(Gfx *gfx, GBool printing) { gfx->pushResources(dict); delete dict; } - gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, + gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, 1, rect->x1, rect->y1, rect->x2, rect->y2); if (addDingbatsResource) { gfx->popResources(); @@ -4032,11 +4038,14 @@ void AnnotGeometry::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) { void AnnotGeometry::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) @@ -4145,7 +4154,7 @@ void AnnotGeometry::draw(Gfx *gfx, GBool printing) { // draw the appearance stream appearance.fetch(xref, &obj); - gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, + gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, ca, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); } diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 401b52e..706dcce 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -4546,7 +4546,7 @@ void Gfx::opMarkPoint(Object args[], int numArgs) { // misc //------------------------------------------------------------------------ -void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, +void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, double opacity, double xMin, double yMin, double xMax, double yMax) { Dict *dict, *resDict; Object matrixObj, bboxObj, resObj; @@ -4562,6 +4562,13 @@ void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, int dashLength; int i; + if (opacity != 1) { + state->setFillOpacity(opacity); + out->updateFillOpacity(state); + state->setStrokeOpacity(opacity); + out->updateStrokeOpacity(state); + } + //~ can we assume that we're in default user space? //~ (i.e., baseMatrix = ctm) diff --git a/poppler/Gfx.h b/poppler/Gfx.h index bb76260..ef1977a 100644 --- a/poppler/Gfx.h +++ b/poppler/Gfx.h @@ -155,7 +155,7 @@ public: // Display an annotation, given its appearance (a Form XObject), // border style, and bounding box (in default user space). - void drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, + void drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, double opacity, double xMin, double yMin, double xMax, double yMax); // Save graphics state. -- 1.6.3.3