[poppler] 6 commits - glib/poppler-page.cc poppler/Annot.cc poppler/Annot.h poppler/Form.cc poppler/Gfx.cc poppler/Gfx.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Thu Dec 13 15:13:42 PST 2007
glib/poppler-page.cc | 11
poppler/Annot.cc | 1003 ++++++++++++++++++++++++++++++++++++++-------------
poppler/Annot.h | 311 ++++++++++++++-
poppler/Form.cc | 6
poppler/Gfx.cc | 21 -
poppler/Gfx.h | 5
6 files changed, 1077 insertions(+), 280 deletions(-)
New commits:
commit 0fb42a2f557d5ec83b42326eb6b0be41622ca328
Author: Iñigo MartÃnez <inigomartinez at gmail.com>
Date: Wed Dec 12 01:02:31 2007 +0100
Changed getters to const
Signed-off-by: Iñigo MartÃnez <inigomartinez at gmail.com>
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 3d1a7eb..70b8409 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -124,7 +124,7 @@ AnnotBorderArray::AnnotBorderArray(Array *array) {
// TODO: check not all zero ? (Line Dash Pattern Page 217 PDF 8.1)
if(arrayLength > 3) {
- bool correct = true;
+ GBool correct = gTrue;
int tempLength = array->getLength() - 3;
double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
@@ -134,10 +134,10 @@ AnnotBorderArray::AnnotBorderArray(Array *array) {
tempDash[i] = obj1.getNum();
if (tempDash[i] < 0)
- correct = false;
+ correct = gFalse;
} else {
- correct = false;
+ correct = gFalse;
}
obj1.free();
}
@@ -147,7 +147,7 @@ AnnotBorderArray::AnnotBorderArray(Array *array) {
dash = tempDash;
style = borderDashed;
} else {
- delete tempDash;
+ gfree (tempDash);
}
}
}
@@ -202,7 +202,7 @@ AnnotBorderBS::AnnotBorderBS(Dict *dict) {
// TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
if (dict->lookup("D", &obj1)->isArray()) {
- bool correct = true;
+ GBool correct = gTrue;
int tempLength = obj1.arrayGetLength();
double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
@@ -213,9 +213,9 @@ AnnotBorderBS::AnnotBorderBS(Dict *dict) {
tempDash[i] = obj2.getNum();
if(tempDash[i] < 0)
- correct = false;
+ correct = gFalse;
} else {
- correct = false;
+ correct = gFalse;
}
obj2.free();
}
@@ -225,7 +225,7 @@ AnnotBorderBS::AnnotBorderBS(Dict *dict) {
dash = tempDash;
style = borderDashed;
} else {
- delete tempDash;
+ gfree (tempDash);
}
} else {
@@ -267,11 +267,11 @@ AnnotColor::AnnotColor(Array *array) {
}
}
-AnnotColor::AnnotColorSpace AnnotColor::getSpace() {
+AnnotColor::AnnotColorSpace AnnotColor::getSpace() const {
return (AnnotColor::AnnotColorSpace) length;
}
-double AnnotColor::getValue(int i) {
+double AnnotColor::getValue(int i) const {
if(i >= 0 && i < length)
return values[i];
return 0;
@@ -310,10 +310,10 @@ AnnotBorderStyle::~AnnotBorderStyle() {
Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog* catalog, Object *obj) {
if (obj->isRef()) {
- hasRef = true;
+ hasRef = gTrue;
ref = obj->getRef();
} else {
- hasRef = false;
+ hasRef = gFalse;
}
flags = flagUnknown;
type = typeUnknown;
@@ -1848,7 +1848,7 @@ AnnotText::AnnotText(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog,
initialize (xrefA, catalog, dict);
}
-void AnnotText::setModified(GooString* date) {
+void AnnotText::setModified(GooString *date) {
if(date) {
delete modified;
modified = new GooString(date);
@@ -1912,7 +1912,7 @@ void AnnotText::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
} else {
state = stateUnknown;
}
-
+
delete stateName;
} else {
state = stateUnknown;
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 09faec3..a08ff96 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -43,10 +43,10 @@ public:
virtual ~AnnotBorder();
- virtual double getWidth() { return width; }
- virtual int getDashLength() { return dashLength; }
- virtual double *getDash() { return dash; }
- virtual AnnotBorderStyle getStyle() { return style; }
+ virtual double getWidth() const { return width; }
+ virtual int getDashLength() const { return dashLength; }
+ virtual double *getDash() const { return dash; }
+ virtual AnnotBorderStyle getStyle() const { return style; }
protected:
double width;
@@ -64,8 +64,8 @@ public:
AnnotBorderArray();
AnnotBorderArray(Array *array);
- virtual double getHorizontalCorner() { return horizontalCorner; }
- virtual double getVerticalCorner() { return verticalCorner; }
+ virtual double getHorizontalCorner() const { return horizontalCorner; }
+ virtual double getVerticalCorner() const { return verticalCorner; }
protected:
static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
@@ -108,8 +108,8 @@ public:
AnnotColor(Array *array);
~AnnotColor();
- AnnotColorSpace getSpace();
- double getValue(int i);
+ AnnotColorSpace getSpace() const;
+ double getValue(int i) const;
private:
@@ -222,19 +222,19 @@ public:
double getFontSize() { return fontSize; }
// getters
- AnnotSubtype getType() { return type; }
- PDFRectangle *getRect() { return rect; }
- GooString *getContents() { return contents; }
- Dict *getPageDict() { return pageDict; }
- GooString *getName() { return name; }
- GooString *getModified() { return modified; }
- Guint getFlags() { return flags; }
- /*Dict *getAppearDict() { return appearDict; }*/
- GooString *getAppearState() { return appearState; }
- AnnotBorder *getBorder() { return border; }
- AnnotColor *getColor() { return color; }
- int getTreeKey() { return treeKey; }
- Dict *getOptionalContent() { return optionalContent; }
+ AnnotSubtype getType() const { return type; }
+ PDFRectangle *getRect() const { return rect; }
+ GooString *getContents() const { return contents; }
+ Dict *getPageDict() const { return pageDict; }
+ GooString *getName() const { return name; }
+ GooString *getModified() const { return modified; }
+ Guint getFlags() const { return flags; }
+ /*Dict *getAppearDict() const { return appearDict; }*/
+ GooString *getAppearState() const { return appearState; }
+ AnnotBorder *getBorder() const { return border; }
+ AnnotColor *getColor() const { return color; }
+ int getTreeKey() const { return treeKey; }
+ Dict *getOptionalContent() const { return optionalContent; }
private:
void setColor(Array *a, GBool fill, int adjust);
@@ -298,14 +298,14 @@ public:
AnnotPopup(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
virtual ~AnnotPopup();
- Dict *getParent() { return parent; }
- bool getOpen() { return open; }
+ Dict *getParent() const { return parent; }
+ GBool getOpen() const { return open; }
protected:
void initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
Dict *parent; // Parent
- bool open; // Open
+ GBool open; // Open
};
//------------------------------------------------------------------------
@@ -323,15 +323,15 @@ public:
virtual ~AnnotMarkup();
// getters
- GooString *getLabel() { return label; }
- AnnotPopup *getPopup() { return popup; }
- double getOpacity() { return opacity; }
+ GooString *getLabel() const { return label; }
+ AnnotPopup *getPopup() const { return popup; }
+ double getOpacity() const { return opacity; }
// getRC
- GooString *getDate() { return date; }
- Dict *getInReplyTo() { return inReplyTo; }
- GooString *getSubject() { return subject; }
- AnnotMarkupReplyType getReplyTo() { return replyTo; }
- AnnotExternalDataType getExData() { return exData; }
+ GooString *getDate() const { return date; }
+ Dict *getInReplyTo() const { return inReplyTo; }
+ GooString *getSubject() const { return subject; }
+ AnnotMarkupReplyType getReplyTo() const { return replyTo; }
+ AnnotExternalDataType getExData() const { return exData; }
protected:
GooString *label; // T (Default autor)
@@ -383,9 +383,9 @@ public:
AnnotText(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
// getters
- bool getOpen() { return open; }
- AnnotTextIcon getIcon() { return icon; }
- AnnotTextState getState() { return state; }
+ GBool getOpen() const { return open; }
+ AnnotTextIcon getIcon() const { return icon; }
+ AnnotTextState getState() const { return state; }
// setters
void setModified(GooString *date);
@@ -394,7 +394,7 @@ private:
void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
- bool open; // Open (Default false)
+ GBool open; // Open (Default false)
AnnotTextIcon icon; // Name (Default Note)
AnnotTextState state; // State (Default Umarked if
// StateModel Marked
commit 29d39a8ae120e6045a16a7aa0944c36560b42508
Author: Iñigo MartÃnez <inigomartinez at gmail.com>
Date: Mon Dec 10 17:56:44 2007 +0100
AnnotText support.
Signed-off-by: Iñigo MartÃnez <inigomartinez at gmail.com>
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 96dc8fe..3d1a7eb 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -1837,6 +1837,127 @@ void AnnotMarkup::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *c
}
//------------------------------------------------------------------------
+// AnnotText
+//------------------------------------------------------------------------
+
+AnnotText::AnnotText(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj) :
+ Annot(xrefA, acroForm, dict, catalog, obj), AnnotMarkup(xref, acroForm, dict, catalog, obj) {
+
+ type = typeText;
+ flags |= flagNoZoom & flagNoRotate;
+ initialize (xrefA, catalog, dict);
+}
+
+void AnnotText::setModified(GooString* date) {
+ if(date) {
+ delete modified;
+ modified = new GooString(date);
+ }
+}
+
+void AnnotText::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
+ Object obj1;
+
+ if (dict->lookup("Open", &obj1)->isBool())
+ open = obj1.getBool();
+ else
+ open = gFalse;
+ obj1.free();
+
+ if (dict->lookup("Name", &obj1)->isName()) {
+ GooString *iconName = new GooString(obj1.getName());
+
+ if(!iconName->cmp("Comment")) {
+ icon = iconComment;
+ } else if(!iconName->cmp("Key")) {
+ icon = iconKey;
+ } else if(!iconName->cmp("Help")) {
+ icon = iconHelp;
+ } else if(!iconName->cmp("NewParagraph")) {
+ icon = iconNewParagraph;
+ } else if(!iconName->cmp("Paragraph")) {
+ icon = iconParagraph;
+ } else if(!iconName->cmp("Insert")) {
+ icon = iconInsert;
+ } else {
+ icon = iconNote;
+ }
+ delete iconName;
+ } else {
+ icon = iconNote;
+ }
+ obj1.free();
+
+ if (dict->lookup("StateModel", &obj1)->isString()) {
+ Object obj2;
+ GooString *modelName = obj1.getString();
+
+ if (dict->lookup("State", &obj2)->isString()) {
+ GooString *stateName = obj2.getString();
+
+ if(!stateName->cmp("Marked")) {
+ state = stateMarked;
+ } else if(!stateName->cmp("Unmarked")) {
+ state = stateUnmarked;
+ } else if(!stateName->cmp("Accepted")) {
+ state = stateAccepted;
+ } else if(!stateName->cmp("Rejected")) {
+ state = stateRejected;
+ } else if(!stateName->cmp("Cancelled")) {
+ state = stateCancelled;
+ } else if(!stateName->cmp("Completed")) {
+ state = stateCompleted;
+ } else if(!stateName->cmp("None")) {
+ state = stateNone;
+ } else {
+ state = stateUnknown;
+ }
+
+ delete stateName;
+ } else {
+ state = stateUnknown;
+ }
+ obj2.free();
+
+ if(!modelName->cmp("Marked")) {
+ switch (state) {
+ case stateUnknown:
+ state = stateMarked;
+ break;
+ case stateAccepted:
+ case stateRejected:
+ case stateCancelled:
+ case stateCompleted:
+ case stateNone:
+ state = stateUnknown;
+ break;
+ default:
+ break;
+ }
+ } else if(!modelName->cmp("Review")) {
+ switch (state) {
+ case stateUnknown:
+ state = stateNone;
+ break;
+ case stateMarked:
+ case stateUnmarked:
+ state = stateUnknown;
+ break;
+ default:
+ break;
+ }
+ } else {
+ state = stateUnknown;
+ }
+
+ delete modelName;
+ } else {
+ state = stateUnknown;
+ }
+ obj1.free();
+}
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
@@ -1886,7 +2007,7 @@ Annot *Annots::createAnnot(XRef *xref, Dict *acroForm, Dict* dict, Catalog *cata
GooString *typeName = new GooString(obj1.getName());
if (!typeName->cmp("Text")) {
- annot = new Annot(xref, acroForm, dict, catalog, obj);
+ annot = new AnnotText(xref, acroForm, dict, catalog, obj);
} else if(!typeName->cmp("Link")) {
annot = new Annot(xref, acroForm, dict, catalog, obj);
} else if(!typeName->cmp("FreeText")) {
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 18416c5..09faec3 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -40,7 +40,7 @@ public:
borderInset, // Inset
borderUnderlined, // Underlined
};
-
+
virtual ~AnnotBorder();
virtual double getWidth() { return width; }
@@ -80,7 +80,7 @@ protected:
class AnnotBorderBS: public AnnotBorder {
public:
-
+
AnnotBorderBS();
AnnotBorderBS(Dict *dict);
@@ -103,7 +103,7 @@ public:
colorRGB = 3,
colorCMYK = 4
};
-
+
AnnotColor();
AnnotColor(Array *array);
~AnnotColor();
@@ -285,7 +285,7 @@ protected:
GBool ok;
GBool regen, isTextField;
GBool isMultiline, isListbox;
-
+
bool hasRef;
};
@@ -295,7 +295,6 @@ protected:
class AnnotPopup: public Annot {
public:
-
AnnotPopup(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
virtual ~AnnotPopup();
@@ -303,9 +302,8 @@ public:
bool getOpen() { return open; }
protected:
-
void initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
-
+
Dict *parent; // Parent
bool open; // Open
};
@@ -336,7 +334,6 @@ public:
AnnotExternalDataType getExData() { return exData; }
protected:
-
GooString *label; // T (Default autor)
AnnotPopup *popup; // Popup
double opacity; // CA (Default 1.0)
@@ -351,11 +348,60 @@ protected:
AnnotExternalDataType exData; // ExData
private:
-
void initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
};
//------------------------------------------------------------------------
+// AnnotText
+//------------------------------------------------------------------------
+
+class AnnotText: public Annot, public AnnotMarkup {
+public:
+ enum AnnotTextIcon {
+ iconComment, // Comment
+ iconKey, // Key
+ iconNote, // Note
+ iconHelp, // Help
+ iconNewParagraph, // NewParagraph
+ iconParagraph, // Paragraph
+ iconInsert // Insert
+ };
+
+ enum AnnotTextState {
+ stateUnknown,
+ // Marked state model
+ stateMarked, // Marked
+ stateUnmarked, // Unmarked
+ // Review state model
+ stateAccepted, // Accepted
+ stateRejected, // Rejected
+ stateCancelled, // Cancelled
+ stateCompleted, // Completed
+ stateNone // None
+ };
+
+ AnnotText(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
+
+ // getters
+ bool getOpen() { return open; }
+ AnnotTextIcon getIcon() { return icon; }
+ AnnotTextState getState() { return state; }
+
+ // setters
+ void setModified(GooString *date);
+
+private:
+
+ void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
+
+ bool open; // Open (Default false)
+ AnnotTextIcon icon; // Name (Default Note)
+ AnnotTextState state; // State (Default Umarked if
+ // StateModel Marked
+ // None if StareModel Review)
+};
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
@@ -375,7 +421,6 @@ public:
// to a form field.
void generateAppearances(Dict *acroForm);
-
private:
Annot* createAnnot(XRef *xref, Dict *acroForm, Dict* dict, Catalog *catalog, Object *obj);
void scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
commit 2acecde458122bd67487cc302478befa78bf6fbe
Author: Iñigo MartÃnez <inigomartinez at gmail.com>
Date: Mon Dec 10 16:45:46 2007 +0100
AnnotMarkup support.
Signed-off-by: Iñigo MartÃnez <inigomartinez at gmail.com>
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 7ba7510..96dc8fe 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -60,6 +60,27 @@
// = (4 * (sqrt(2) - 1) / 3) * r
#define bezierCircle 0.55228475
+AnnotExternalDataType parseAnnotExternalData(Dict* dict) {
+ Object obj1;
+ AnnotExternalDataType type;
+
+ if (dict->lookup("Subtype", &obj1)->isName()) {
+ GooString *typeName = new GooString(obj1.getName());
+
+ if(!typeName->cmp("Markup3D")) {
+ type = annotExternalDataMarkup3D;
+ } else {
+ type = annotExternalDataMarkupUnknown;
+ }
+ delete typeName;
+ } else {
+ type = annotExternalDataMarkupUnknown;
+ }
+ obj1.free();
+
+ return type;
+}
+
//------------------------------------------------------------------------
// AnnotBorder
//------------------------------------------------------------------------
@@ -1722,6 +1743,100 @@ void AnnotPopup::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *ca
}
//------------------------------------------------------------------------
+// AnnotMarkup
+//------------------------------------------------------------------------
+
+AnnotMarkup::AnnotMarkup(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj) {
+ initialize(xrefA, acroForm, dict, catalog, obj);
+}
+
+AnnotMarkup::~AnnotMarkup() {
+ if (label)
+ delete label;
+
+ if (popup)
+ delete popup;
+
+ if (date)
+ delete date;
+
+ if (inReplyTo)
+ delete inReplyTo;
+
+ if (subject)
+ delete subject;
+}
+
+void AnnotMarkup::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj) {
+ Object obj1;
+
+ if (dict->lookup("T", &obj1)->isString()) {
+ label = obj1.getString()->copy();
+ } else {
+ label = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("Popup", &obj1)->isDict()) {
+ popup = new AnnotPopup(xrefA, acroForm, obj1.getDict(), catalog, obj);
+ } else {
+ popup = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("CA", &obj1)->isNum()) {
+ opacity = obj1.getNum();
+ } else {
+ opacity = 1.0;
+ }
+ obj1.free();
+
+ if (dict->lookup("CreationDate", &obj1)->isString()) {
+ date = obj1.getString()->copy();
+ } else {
+ date = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("IRT", &obj1)->isDict()) {
+ inReplyTo = obj1.getDict();
+ } else {
+ inReplyTo = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("Subj", &obj1)->isString()) {
+ subject = obj1.getString()->copy();
+ } else {
+ subject = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("RT", &obj1)->isName()) {
+ GooString *replyName = new GooString(obj1.getName());
+
+ if(!replyName->cmp("R")) {
+ replyTo = replyTypeR;
+ } else if(!replyName->cmp("Group")) {
+ replyTo = replyTypeGroup;
+ } else {
+ replyTo = replyTypeR;
+ }
+ delete replyName;
+ } else {
+ replyTo = replyTypeR;
+ }
+ obj1.free();
+
+ if (dict->lookup("ExData", &obj1)->isDict()) {
+ exData = parseAnnotExternalData(obj1.getDict());
+ } else {
+ exData = annotExternalDataMarkupUnknown;
+ }
+ obj1.free();
+}
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 26611d2..18416c5 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -22,6 +22,11 @@ class GfxFontDict;
class FormWidget;
class PDFRectangle;
+enum AnnotExternalDataType {
+ annotExternalDataMarkupUnknown,
+ annotExternalDataMarkup3D // Markup3D
+};
+
//------------------------------------------------------------------------
// AnnotBorder
//------------------------------------------------------------------------
@@ -252,6 +257,7 @@ private:
void initialize (XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
+protected:
// required data
AnnotSubtype type; // Annotation type
PDFRectangle *rect; // Rect
@@ -305,6 +311,51 @@ protected:
};
//------------------------------------------------------------------------
+// AnnotMarkup
+//------------------------------------------------------------------------
+
+class AnnotMarkup {
+public:
+ enum AnnotMarkupReplyType {
+ replyTypeR, // R
+ replyTypeGroup // Group
+ };
+
+ AnnotMarkup(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
+ virtual ~AnnotMarkup();
+
+ // getters
+ GooString *getLabel() { return label; }
+ AnnotPopup *getPopup() { return popup; }
+ double getOpacity() { return opacity; }
+ // getRC
+ GooString *getDate() { return date; }
+ Dict *getInReplyTo() { return inReplyTo; }
+ GooString *getSubject() { return subject; }
+ AnnotMarkupReplyType getReplyTo() { return replyTo; }
+ AnnotExternalDataType getExData() { return exData; }
+
+protected:
+
+ GooString *label; // T (Default autor)
+ AnnotPopup *popup; // Popup
+ double opacity; // CA (Default 1.0)
+ // RC
+ GooString *date; // CreationDate
+ Dict *inReplyTo; // IRT
+ GooString *subject; // Subj
+ AnnotMarkupReplyType replyTo; // RT (Default R)
+ // this object is overrided by the custom intent fields defined in some
+ // annotation types.
+ //GooString *intent; // IT
+ AnnotExternalDataType exData; // ExData
+
+private:
+
+ void initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
+};
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
commit 1f8c1fe34e04688d2ba200f1166cfdd1ffe563f0
Author: Iñigo MartÃnez <inigomartinez at gmail.com>
Date: Mon Dec 10 16:34:01 2007 +0100
AnnotPopup support.
Signed-off-by: Iñigo MartÃnez <inigomartinez at gmail.com>
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 48f3248..7ba7510 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -1686,6 +1686,40 @@ void Annot::draw(Gfx *gfx, GBool printing) {
obj.free();
}
+//------------------------------------------------------------------------
+// AnnotPopup
+//------------------------------------------------------------------------
+
+AnnotPopup::AnnotPopup(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj) :
+ Annot(xrefA, acroForm, dict, catalog, obj) {
+ type = typePopup;
+ initialize(xrefA, acroForm, dict, catalog);
+}
+
+AnnotPopup::~AnnotPopup() {
+ /*
+ if (parent)
+ delete parent;
+ */
+}
+
+void AnnotPopup::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog) {
+ Object obj1;
+ /*
+ if(dict->lookup("Parent", &obj1)->isDict()) {
+ parent = NULL;
+ } else {
+ parent = NULL;
+ }
+ obj1.free();
+ */
+ if(dict->lookup("Open", &obj1)->isBool()) {
+ open = obj1.getBool();
+ } else {
+ open = gFalse;
+ }
+ obj1.free();
+}
//------------------------------------------------------------------------
// Annots
diff --git a/poppler/Annot.h b/poppler/Annot.h
index bdd8839..26611d2 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -284,6 +284,27 @@ private:
};
//------------------------------------------------------------------------
+// AnnotPopup
+//------------------------------------------------------------------------
+
+class AnnotPopup: public Annot {
+public:
+
+ AnnotPopup(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
+ virtual ~AnnotPopup();
+
+ Dict *getParent() { return parent; }
+ bool getOpen() { return open; }
+
+protected:
+
+ void initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
+
+ Dict *parent; // Parent
+ bool open; // Open
+};
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
commit 6c83e06fb2eb77d0dbefd1ebfbcac3e5f0cbb622
Author: Iñigo MartÃnez <inigomartinez at gmail.com>
Date: Mon Dec 10 16:24:38 2007 +0100
Prepare code to Annotation Subtype support.
Signed-off-by: Iñigo MartÃnez <inigomartinez at gmail.com>
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 34098f9..13d639a 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -409,16 +409,7 @@ poppler_page_copy_to_pixbuf(PopplerPage *page,
static GBool
poppler_print_annot_cb (Annot *annot, void *user_data)
{
- GooString *annot_type;
-
- annot_type = annot->getType ();
- if (!annot_type)
- return gFalse;
-
- if (annot_type->cmp ("Widget") == 0)
- return gTrue;
-
- return gFalse;
+ return (annot->getType() == Annot::typeWidget);
}
#if defined (HAVE_CAIRO)
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 54527c0..48f3248 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -88,7 +88,7 @@ AnnotBorderArray::AnnotBorderArray(Array *array) {
if (arrayLength >= 3) {
// implementation note 81 in Appendix H.
- /*
+
if(array->get(0, &obj1)->isNum())
horizontalCorner = obj1.getNum();
obj1.free();
@@ -96,30 +96,38 @@ AnnotBorderArray::AnnotBorderArray(Array *array) {
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));
+ bool correct = true;
+ int tempLength = array->getLength() - 3;
+ double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
- for(int i = 0; i < dashLength && i < DASH_LIMIT; i++) {
+ for(int i = 0; i < tempLength && i < DASH_LIMIT && correct; i++) {
if(array->get((i + 3), &obj1)->isNum()) {
- dash[i] = obj1.getNum();
+ tempDash[i] = obj1.getNum();
- if (dash[i] < 0)
- dash[i] = 0;
+ if (tempDash[i] < 0)
+ correct = false;
} else {
- dash[i] = 0;
+ correct = false;
}
obj1.free();
}
+
+ if (correct) {
+ dashLength = tempLength;
+ dash = tempDash;
+ style = borderDashed;
+ } else {
+ delete tempDash;
+ }
}
}
}
@@ -173,22 +181,32 @@ AnnotBorderBS::AnnotBorderBS(Dict *dict) {
// 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));
+ bool correct = true;
+ int tempLength = obj1.arrayGetLength();
+ double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
- for(int i = 0; i < dashLength; i++) {
+ for(int i = 0; i < tempLength && correct; i++) {
Object obj2;
if(obj1.arrayGet(i, &obj2)->isNum()) {
- dash[i] = obj2.getNum();
+ tempDash[i] = obj2.getNum();
- if(dash[i] < 0)
- dash[i] = 0;
+ if(tempDash[i] < 0)
+ correct = false;
} else {
- dash[i] = 0;
+ correct = false;
}
obj2.free();
}
+
+ if (correct) {
+ dashLength = tempLength;
+ dash = tempDash;
+ style = borderDashed;
+ } else {
+ delete tempDash;
+ }
+
} else {
dashLength = 1;
dash = (double *) gmallocn (dashLength, sizeof (double));
@@ -269,17 +287,15 @@ AnnotBorderStyle::~AnnotBorderStyle() {
// Annot
//------------------------------------------------------------------------
-Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, const Ref& aref, Catalog* catalog)
-{
- hasRef = true;
- ref = aref;
- flags = flagUnknown;
- initialize (xrefA, acroForm, dict, catalog);
-}
-
-Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog* catalog) {
- hasRef = false;
+Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog* catalog, Object *obj) {
+ if (obj->isRef()) {
+ hasRef = true;
+ ref = obj->getRef();
+ } else {
+ hasRef = false;
+ }
flags = flagUnknown;
+ type = typeUnknown;
initialize (xrefA, acroForm, dict, catalog);
}
@@ -290,7 +306,6 @@ void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog
xref = xrefA;
appearBuf = NULL;
fontSize = 0;
- type = NULL;
widget = NULL;
//----- get the FormWidget
@@ -300,12 +315,6 @@ void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog
if (form)
widget = form->findWidgetByRef (ref);
}
-
- //----- parse the type
- if (dict->lookup("Subtype", &obj1)->isName()) {
- type = new GooString(obj1.getName());
- }
- obj1.free();
//----- parse the rectangle
rect = new PDFRectangle();
@@ -507,9 +516,6 @@ Annot::~Annot() {
if (modified)
delete modified;
- if (type) {
- delete type;
- }
appearance.free();
if (appearBuf) {
delete appearBuf;
@@ -543,7 +549,7 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
GBool modified;
// must be a Widget annotation
- if (type->cmp("Widget")) {
+ if (type == typeWidget) {
return;
}
@@ -1665,7 +1671,6 @@ void Annot::drawCircleBottomRight(double cx, double cy, double r) {
void Annot::draw(Gfx *gfx, GBool printing) {
Object obj;
- GBool isLink;
// check the flags
if ((flags & annotFlagHidden) ||
@@ -1675,9 +1680,8 @@ void Annot::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
- isLink = type && !type->cmp("Link");
appearance.fetch(xref, &obj);
- gfx->drawAnnot(&obj, isLink ? border : (AnnotBorder *)NULL, color,
+ gfx->drawAnnot(&obj, (type == typeLink) ? border : (AnnotBorder *)NULL, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
}
@@ -1707,10 +1711,8 @@ Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) {
//form widget
Object obj2;
if (annotsObj->arrayGet(i, &obj1)->isDict()) {
- if (annotsObj->arrayGetNF(i, &obj2)->isRef())
- annot = new Annot(xref, acroForm, obj1.getDict(), obj2.getRef(), catalog);
- else
- annot = new Annot(xref, acroForm, obj1.getDict(), catalog);
+ annotsObj->arrayGetNF(i, &obj2);
+ annot = createAnnot (xref, acroForm, obj1.getDict(), catalog, &obj2);
if (annot->isOk()) {
if (nAnnots >= size) {
size += 16;
@@ -1727,6 +1729,74 @@ Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) {
}
}
+Annot *Annots::createAnnot(XRef *xref, Dict *acroForm, Dict* dict, Catalog *catalog, Object *obj) {
+ Annot *annot;
+ Object obj1;
+
+ if (dict->lookup("Subtype", &obj1)->isName()) {
+ GooString *typeName = new GooString(obj1.getName());
+
+ if (!typeName->cmp("Text")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Link")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("FreeText")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Line")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Square")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Circle")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Polygon")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("PolyLine")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Highlight")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Underline")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Squiggly")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("StrikeOut")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Stamp")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Caret")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Ink")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("FileAttachment")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Sound")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Movie")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Widget")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Screen")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("PrinterMark")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("TrapNet")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("Watermark")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else if(!typeName->cmp("3D")) {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ } else {
+ annot = new Annot(xref, acroForm, dict, catalog, obj);
+ }
+
+ delete typeName;
+ } else {
+ annot = NULL;
+ }
+ obj1.free();
+
+ return annot;
+}
+
void Annots::generateAppearances(Dict *acroForm) {
Object obj1, obj2;
Ref ref;
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 64181e6..bdd8839 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -168,13 +168,40 @@ public:
flagLockedContents = 0x0200
};
- Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
- Annot(XRef *xrefA, Dict *acroForm, Dict *dict, const Ref& aref, Catalog *catalog);
- ~Annot();
+ enum AnnotSubtype {
+ typeUnknown, // 0
+ typeText, // Text 1
+ typeLink, // Link 2
+ typeFreeText, // FreeText 3
+ typeLine, // Line 4
+ typeSquare, // Square 5
+ typeCircle, // Circle 6
+ typePolygon, // Polygon 7
+ typePolyLine, // PolyLine 8
+ typeHighlight, // Highlight 9
+ typeUnderline, // Underline 10
+ typeSquiggly, // Squiggly 11
+ typeStrikeOut, // StrikeOut 12
+ typeStamp, // Stamp 13
+ typeCaret, // Caret 14
+ typeInk, // Ink 15
+ typePopup, // Popup 16
+ typeFileAttachment, // FileAttachment 17
+ typeSound, // Sound 18
+ typeMovie, // Movie 19
+ typeWidget, // Widget 20
+ typeScreen, // Screen 21
+ typePrinterMark, // PrinterMark 22
+ typeTrapNet, // TrapNet 23
+ typeWatermark, // Watermark 24
+ type3D // 3D 25
+ };
+
+ Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog, Object *obj);
+ virtual ~Annot();
GBool isOk() { return ok; }
void draw(Gfx *gfx, GBool printing);
-
// Get appearance object.
Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
GBool textField() { return isTextField; }
@@ -189,11 +216,21 @@ public:
double getFontSize() { return fontSize; }
- GooString *getType() { return type; }
+ // getters
+ AnnotSubtype getType() { return type; }
PDFRectangle *getRect() { return rect; }
+ GooString *getContents() { return contents; }
+ Dict *getPageDict() { return pageDict; }
+ GooString *getName() { return name; }
+ GooString *getModified() { return modified; }
+ Guint getFlags() { return flags; }
+ /*Dict *getAppearDict() { return appearDict; }*/
+ GooString *getAppearState() { return appearState; }
AnnotBorder *getBorder() { return border; }
AnnotColor *getColor() { return color; }
-
+ int getTreeKey() { return treeKey; }
+ Dict *getOptionalContent() { return optionalContent; }
+
private:
void setColor(Array *a, GBool fill, int adjust);
void drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
@@ -216,7 +253,8 @@ private:
void initialize (XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
// required data
- PDFRectangle *rect; // Rect
+ AnnotSubtype type; // Annotation type
+ PDFRectangle *rect; // Rect
// optional data
GooString *contents; // Contents
@@ -234,7 +272,6 @@ private:
XRef *xref; // the xref table for this PDF file
Ref ref; // object ref identifying this annotation
FormWidget *widget; // FormWidget object for this annotation
- GooString *type; // annotation type
GooString *appearBuf;
AnnotBorder *border; // Border, BS
AnnotColor *color; // C
@@ -268,6 +305,7 @@ public:
private:
+ Annot* createAnnot(XRef *xref, Dict *acroForm, Dict* dict, Catalog *catalog, Object *obj);
void scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
Dict *acroForm);
Annot *findAnnot(Ref *ref);
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 5cb4b87..a0fcfa1 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -1213,8 +1213,12 @@ FormPageWidgets::FormPageWidgets (XRef *xrefA, Object* annots, unsigned int page
//create a temporary Annot to get the font size
Object obj2;
if (annots->arrayGet(i, &obj2)->isDict()) {
- Annot* ann = new Annot(xref, NULL ,obj2.getDict(), NULL);
+ Annot *ann;
+ Object obj3;
+ annots->arrayGetNF(i, &obj3);
+ ann = new Annot(xref, NULL ,obj2.getDict(), NULL, &obj3);
tmp->setFontSize(ann->getFontSize());
+ obj3.free();
delete ann;
}
obj2.free();
commit fa0bb5bbea5bf2769c8b3084f78770b7781002eb
Author: Iñigo MartÃnez <inigomartinez at gmail.com>
Date: Mon Dec 10 15:41:38 2007 +0100
Various Annot improvements
Signed-off-by: Iñigo MartÃnez <inigomartinez at gmail.com>
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 2e09848..54527c0 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -26,6 +26,7 @@
#include "CharCodeToUnicode.h"
#include "Form.h"
#include "Error.h"
+#include "Page.h"
#define annotFlagHidden 0x0002
#define annotFlagPrint 0x0004
@@ -60,6 +61,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
//------------------------------------------------------------------------
@@ -88,23 +272,19 @@ AnnotBorderStyle::~AnnotBorderStyle() {
Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, const Ref& aref, Catalog* catalog)
{
hasRef = true;
- ref = aref;
+ ref = aref;
+ flags = flagUnknown;
initialize (xrefA, acroForm, dict, catalog);
}
Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog* catalog) {
hasRef = false;
+ flags = flagUnknown;
initialize (xrefA, acroForm, dict, 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;
xref = xrefA;
@@ -112,7 +292,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) {
@@ -129,47 +308,74 @@ void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog
obj1.free();
//----- parse the rectangle
+ rect = new PDFRectangle();
+ if (dict->lookup("Rect", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
+ Object obj2;
+ (obj1.arrayGet(0, &obj2)->isNum() ? rect->x1 = obj2.getNum() : rect->x1 = 0);
+ obj2.free();
+ (obj1.arrayGet(1, &obj2)->isNum() ? rect->y1 = obj2.getNum() : rect->y1 = 0);
+ obj2.free();
+ (obj1.arrayGet(2, &obj2)->isNum() ? rect->x2 = obj2.getNum() : rect->x2 = 1);
+ obj2.free();
+ (obj1.arrayGet(3, &obj2)->isNum() ? rect->y2 = obj2.getNum() : rect->y2 = 1);
+ obj2.free();
- if (dict->lookup("Rect", &obj1)->isArray() &&
- obj1.arrayGetLength() == 4) {
- readArrayNum(&obj1, 0, &xMin);
- readArrayNum(&obj1, 1, &yMin);
- readArrayNum(&obj1, 2, &xMax);
- readArrayNum(&obj1, 3, &yMax);
- if (ok) {
- if (xMin > xMax) {
- t = xMin; xMin = xMax; xMax = t;
- }
- if (yMin > yMax) {
- t = yMin; yMin = yMax; yMax = t;
- }
- } else {
- xMin = yMin = 0;
- xMax = yMax = 1;
- error(-1, "Bad bounding box for annotation");
- ok = gFalse;
+ if (rect->x1 > rect->x2) {
+ double t = rect->x1;
+ rect->x1 = rect->x2;
+ rect->x2 = t;
+ }
+
+ if (rect->y1 > rect->y2) {
+ double t = rect->y1;
+ rect->y1 = rect->y2;
+ rect->y2 = t;
}
} else {
- xMin = yMin = 0;
- xMax = yMax = 1;
+ rect->x1 = rect->y1 = 0;
+ rect->x2 = rect->y2 = 1;
error(-1, "Bad bounding box for annotation");
ok = gFalse;
}
obj1.free();
-
+
+ if (dict->lookup("Contents", &obj1)->isString()) {
+ contents = obj1.getString()->copy();
+ } else {
+ contents = NULL;
+ }
+ obj1.free();
+
+ /* TODO: Page Object indirect reference (should be parsed ?)
+ if (dict->lookup("P", &obj1)->isDict()) {
+ pageDict = NULL;
+ } else {
+ pageDict = NULL;
+ }
+ obj1.free();
+ */
+
+ if (dict->lookup("NM", &obj1)->isString()) {
+ name = obj1.getString()->copy();
+ } else {
+ name = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("M", &obj1)->isString()) {
+ modified = obj1.getString()->copy();
+ } else {
+ modified = NULL;
+ }
+ obj1.free();
+
//----- get the flags
if (dict->lookup("F", &obj1)->isInt()) {
- flags = obj1.getInt();
+ flags |= obj1.getInt();
} else {
- flags = 0;
+ flags = flagUnknown;
}
- obj1.free ();
-
- //check for hidden annot
- if (flags & 0x2)
- hidden = true;
- else
- hidden = false;
+ obj1.free();
// check if field apperances need to be regenerated
// Only text or choice fields needs to have appearance regenerated
@@ -185,139 +391,92 @@ void Annot::initialize(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog
obj1.free();
}
}
+ obj3.free();
+
+ if (dict->lookup("AP", &obj1)->isDict()) {
+ Object obj2;
+
+ if (dict->lookup("AS", &obj2)->isName()) {
+ Object obj3;
- if (dict->lookup("AP", &apObj)->isDict()) {
- if (dict->lookup("AS", &asObj)->isName()) {
- if (apObj.dictLookup("N", &obj1)->isDict()) {
- if (obj1.dictLookupNF(asObj.getName(), &obj2)->isRef()) {
- obj2.copy(&appearance);
- ok = gTrue;
- } else {
- obj2.free();
- if (obj1.dictLookupNF("Off", &obj2)->isRef()) {
- obj2.copy(&appearance);
- ok = gTrue;
- } else
- regen = gTrue;
- }
- obj2.free();
+ appearState = new GooString(obj2.getName());
+ if (obj1.dictLookup("N", &obj3)->isDict()) {
+ Object obj4;
+
+ if (obj3.dictLookupNF(appearState->getCString(), &obj4)->isRef()) {
+ obj4.copy(&appearance);
+ } else {
+ obj4.free();
+ if (obj3.dictLookupNF("Off", &obj4)->isRef()) {
+ obj4.copy(&appearance);
+ } else
+ regen = gTrue;
+ }
+ obj4.free();
}
- obj1.free();
+ obj3.free();
} else {
- if (apObj.dictLookupNF("N", &obj1)->isRef()) {
- obj1.copy(&appearance);
- ok = gTrue;
+ obj2.free();
+
+ appearState = NULL;
+ if (obj1.dictLookupNF("N", &obj2)->isRef()) {
+ obj2.copy(&appearance);
} else
regen = gTrue;
- obj1.free();
}
- asObj.free();
+ obj2.free();
} else {
+ appearState = NULL;
// If field doesn't have an AP we'll have to generate it
regen = gTrue;
}
- apObj.free();
- obj3.free();
+ obj1.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();
+
+ if (dict->lookup("StructParent", &obj1)->isInt()) {
+ treeKey = obj1.getInt();
+ } else {
+ treeKey = 0;
}
obj1.free();
- borderStyle = new AnnotBorderStyle(borderType, borderWidth,
- borderDash, borderDashLength,
- borderR, borderG, borderB);
+
+ /* TODO: optional content should be parsed
+ if (dict->lookup("OC", &obj1)->isDict()) {
+ optionalContent = NULL;
+ } else {
+ optionalContent = NULL;
+ }
+ obj1.free();
+ */
+}
+
+double Annot::getXMin() {
+ return rect->x1;
+}
+
+double Annot::getYMin() {
+ return rect->y1;
}
void Annot::readArrayNum(Object *pdfArray, int key, double *value) {
@@ -334,6 +493,20 @@ void Annot::readArrayNum(Object *pdfArray, int key, double *value) {
}
Annot::~Annot() {
+ delete rect;
+
+ if (contents)
+ delete contents;
+
+ if (pageDict)
+ delete pageDict;
+
+ if(name)
+ delete name;
+
+ if (modified)
+ delete modified;
+
if (type) {
delete type;
}
@@ -342,9 +515,17 @@ Annot::~Annot() {
delete appearBuf;
}
- if (borderStyle) {
- delete borderStyle;
- }
+ if(appearState)
+ delete appearState;
+
+ if (border)
+ delete border;
+
+ if (color)
+ delete color;
+
+ if (optionalContent)
+ delete optionalContent;
}
void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
@@ -392,7 +573,7 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
obj1.arrayGetLength() > 0) {
setColor(obj1.getArray(), gTrue, 0);
appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n",
- xMax - xMin, yMax - yMin);
+ rect->x2 - rect->x1, rect->y2 - rect->y1);
}
obj1.free();
}
@@ -409,71 +590,73 @@ 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)) {
mkDict->lookup("BG", &obj1);
}
if (obj1.isArray() && obj1.arrayGetLength() > 0) {
- dx = xMax - xMin;
- dy = yMax - yMin;
+ dx = rect->x2 - rect->x1;
+ dy = rect->y2 - rect->y1;
// radio buttons with no caption have a round border
hasCaption = mkDict->lookup("CA", &obj2)->isString();
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 +665,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 +674,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);
@@ -554,8 +737,8 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
if (mkDict) {
if (mkDict->lookup("BC", &obj3)->isArray() &&
obj3.arrayGetLength() > 0) {
- dx = xMax - xMin;
- dy = yMax - yMin;
+ dx = rect->x2 - rect->x1;
+ dy = rect->y2 - rect->y1;
setColor(obj3.getArray(), gTrue, 0);
drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy),
gTrue);
@@ -704,8 +887,8 @@ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
obj1.initArray(xref);
obj1.arrayAdd(obj2.initReal(0));
obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(xMax - xMin));
- obj1.arrayAdd(obj2.initReal(yMax - yMin));
+ obj1.arrayAdd(obj2.initReal(rect->x2 - rect->x1));
+ obj1.arrayAdd(obj2.initReal(rect->y2 - rect->y1));
appearDict.dictAdd(copyString("BBox"), &obj1);
// set the resource dictionary
@@ -831,7 +1014,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 +1082,7 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
}
// get the border width
- border = borderStyle->getWidth();
+ borderWidth = border->getWidth();
// setup
if (txField) {
@@ -911,12 +1094,12 @@ 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 = rect->x2 - rect->x1 - 2 * borderWidth - 4;
// compute font autosize
if (fontSize == 0) {
for (fontSize = 20; fontSize > 1; --fontSize) {
- y = yMax - yMin;
+ y = rect->y2 - rect->y1;
w2 = 0;
i = 0;
while (i < text->getLength()) {
@@ -942,7 +1125,7 @@ void Annot::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
// starting y coordinate
// (note: each line of text starts with a Td operator that moves
// down a line)
- y = yMax - yMin;
+ y = rect->y2 - rect->y1;
// set the font matrix
if (tmPos >= 0) {
@@ -977,13 +1160,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;
+ x = (rect->x2 - rect->x1 - w) / 2;
break;
case fieldQuadRight:
- x = xMax - xMin - border - 2 - w;
+ x = rect->x2 - rect->x1 - borderWidth - 2 - w;
break;
}
@@ -1005,11 +1188,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 = (rect->x2 - rect->x1 - 2 * borderWidth) / comb;
// compute font autosize
if (fontSize == 0) {
- fontSize = yMax - yMin - 2 * border;
+ fontSize = rect->y2 - rect->y1 - 2 * borderWidth;
if (w < fontSize) {
fontSize = w;
}
@@ -1025,16 +1208,16 @@ 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;
+ y = 0.5 * (rect->y2 - rect->y1) - 0.4 * fontSize;
// set the font matrix
if (tmPos >= 0) {
@@ -1086,8 +1269,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 = rect->y2 - rect->y1 - 2 * borderWidth;
+ fontSize2 = (rect->x2 - rect->x1 - 4 - 2 * borderWidth) / w;
if (fontSize2 < fontSize) {
fontSize = fontSize2;
}
@@ -1104,16 +1287,16 @@ 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;
+ x = (rect->x2 - rect->x1 - w) / 2;
break;
case fieldQuadRight:
- x = xMax - xMin - border - 2 - w;
+ x = rect->x2 - rect->x1 - borderWidth - 2 - w;
break;
}
- y = 0.5 * (yMax - yMin) - 0.4 * fontSize;
+ y = 0.5 * (rect->y2 - rect->y1) - 0.4 * fontSize;
// set the font matrix
if (tmPos >= 0) {
@@ -1161,7 +1344,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 +1401,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 +1420,8 @@ void Annot::drawListBox(GooString **text, GBool *selection,
wMax = w;
}
}
- fontSize = yMax - yMin - 2 * border;
- fontSize2 = (xMax - xMin - 4 - 2 * border) / wMax;
+ fontSize = rect->y2 - rect->y1 - 2 * borderWidth;
+ fontSize2 = (rect->x2 - rect->x1 - 4 - 2 * borderWidth) / wMax;
if (fontSize2 < fontSize) {
fontSize = fontSize2;
}
@@ -1250,7 +1433,7 @@ void Annot::drawListBox(GooString **text, GBool *selection,
}
}
// draw the text
- y = yMax - yMin - 1.1 * fontSize;
+ y = rect->y2 - rect->y1 - 1.1 * fontSize;
for (i = topIdx; i < nOptions; ++i) {
// setup
appearBuf->append("q\n");
@@ -1259,9 +1442,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,
+ rect->x2 - rect->x1 - 2 * borderWidth,
1.1 * fontSize);
}
@@ -1284,13 +1467,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;
+ x = (rect->x2 - rect->x1 - w) / 2;
break;
case fieldQuadRight:
- x = xMax - xMin - border - 2 - w;
+ x = rect->x2 - rect->x1 - borderWidth - 2 - w;
break;
}
@@ -1494,8 +1677,8 @@ 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,
- xMin, yMin, xMax, yMax);
+ gfx->drawAnnot(&obj, isLink ? border : (AnnotBorder *)NULL, color,
+ rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
}
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 50f5bfb..64181e6 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
@@ -63,6 +154,19 @@ private:
class Annot {
public:
+ enum AnnotFlag {
+ flagUnknown = 0x0000,
+ flagInvisible = 0x0001,
+ flagHidden = 0x0002,
+ flagPrint = 0x0004,
+ flagNoZoom = 0x0008,
+ flagNoRotate = 0x0010,
+ flagNoView = 0x0020,
+ flagReadOnly = 0x0040,
+ flagLocked = 0x0080,
+ flagToggleNoView = 0x0100,
+ flagLockedContents = 0x0200
+ };
Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
Annot(XRef *xrefA, Dict *acroForm, Dict *dict, const Ref& aref, Catalog *catalog);
@@ -75,20 +179,21 @@ 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; }
void generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm);
- double getXMin() { return xMin; }
- double getYMin() { return yMin; }
+ double getXMin();
+ double getYMin();
double getFontSize() { return fontSize; }
GooString *getType() { return type; }
-
+ PDFRectangle *getRect() { return rect; }
+ 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,
@@ -110,24 +215,35 @@ private:
void initialize (XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
+ // required data
+ PDFRectangle *rect; // Rect
+
+ // optional data
+ GooString *contents; // Contents
+ Dict *pageDict; // P
+ GooString *name; // NM
+ GooString *modified; // M
+ Guint flags; // F (must be a 32 bit unsigned int)
+ //Dict *appearDict; // AP (should be correctly parsed)
+ Object appearance; // a reference to the Form XObject stream
+ // for the normal appearance
+ GooString *appearState; // AS
+ int treeKey; // Struct Parent;
+ Dict *optionalContent; // OC
+
XRef *xref; // the xref table for this PDF file
Ref ref; // object ref identifying this annotation
FormWidget *widget; // FormWidget object for this annotation
GooString *type; // annotation type
- Object appearance; // a reference to the Form XObject stream
- // for the normal appearance
GooString *appearBuf;
- 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;
GBool isMultiline, isListbox;
bool hasRef;
- bool hidden;
};
//------------------------------------------------------------------------
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 78bb640..037f1ac 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.
More information about the poppler
mailing list