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.
signature.asc
Description: Esta parte del mensaje está firmada digitalmente
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
