From c41c048d04c89fee62bbd327eb8c3af60a1b1866 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?I=C3=B1igo=20Mart=C3=ADnez?= Date: Mon, 10 Dec 2007 16:24:38 +0100 Subject: [PATCH] Prepare code to Annotation Subtype support. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Signed-off-by: Iñigo Martínez --- glib/poppler-page.cc | 11 +--- poppler/Annot.cc | 160 ++++++++++++++++++++++++++++++++++++-------------- poppler/Annot.h | 54 ++++++++++++++--- poppler/Form.cc | 6 ++- 4 files changed, 167 insertions(+), 64 deletions(-) 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(); -- 1.5.2.5