summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc1443
1 files changed, 0 insertions, 1443 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
deleted file mode 100644
index d7229a2fe86..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
+++ /dev/null
@@ -1,1443 +0,0 @@
-//========================================================================
-//
-// Annot.cc
-//
-// Copyright 2000-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <stdlib.h>
-#include <math.h>
-#include "gmem.h"
-#include "gmempp.h"
-#include "GList.h"
-#include "Error.h"
-#include "Object.h"
-#include "Catalog.h"
-#include "Gfx.h"
-#include "GfxFont.h"
-#include "Lexer.h"
-#include "PDFDoc.h"
-#include "OptionalContent.h"
-#include "AcroForm.h"
-#include "BuiltinFontTables.h"
-#include "FontEncodingTables.h"
-#include "Annot.h"
-
-// the MSVC math.h doesn't define this
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-//------------------------------------------------------------------------
-
-#define annotFlagHidden 0x0002
-#define annotFlagPrint 0x0004
-#define annotFlagNoView 0x0020
-
-// distance of Bezier control point from center for circle approximation
-// = (4 * (sqrt(2) - 1) / 3) * r
-#define bezierCircle 0.55228475
-
-#define lineEndSize1 6
-#define lineEndSize2 10
-#define lineArrowAngle (M_PI / 6)
-
-//------------------------------------------------------------------------
-// AnnotBorderStyle
-//------------------------------------------------------------------------
-
-AnnotBorderStyle::AnnotBorderStyle(AnnotBorderType typeA, double widthA,
- double *dashA, int dashLengthA,
- double *colorA, int nColorCompsA) {
- type = typeA;
- width = widthA;
- dash = dashA;
- dashLength = dashLengthA;
- color[0] = colorA[0];
- color[1] = colorA[1];
- color[2] = colorA[2];
- color[3] = colorA[3];
- nColorComps = nColorCompsA;
-}
-
-AnnotBorderStyle::~AnnotBorderStyle() {
- if (dash) {
- gfree(dash);
- }
-}
-
-//------------------------------------------------------------------------
-// Annot
-//------------------------------------------------------------------------
-
-Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA) {
- Object apObj, asObj, obj1, obj2, obj3;
- AnnotBorderType borderType;
- double borderWidth;
- double *borderDash;
- int borderDashLength;
- double borderColor[4];
- int nBorderColorComps;
- double t;
- int i;
-
- ok = gTrue;
- doc = docA;
- xref = doc->getXRef();
- ref = *refA;
- type = NULL;
- appearanceState = NULL;
- appearBuf = NULL;
- borderStyle = NULL;
-
- //----- parse the type
-
- if (dict->lookup("Subtype", &obj1)->isName()) {
- type = new GString(obj1.getName());
- }
- obj1.free();
-
- //----- parse the rectangle
-
- if (dict->lookup("Rect", &obj1)->isArray() &&
- obj1.arrayGetLength() == 4) {
- xMin = yMin = xMax = yMax = 0;
- if (obj1.arrayGet(0, &obj2)->isNum()) {
- xMin = obj2.getNum();
- }
- obj2.free();
- if (obj1.arrayGet(1, &obj2)->isNum()) {
- yMin = obj2.getNum();
- }
- obj2.free();
- if (obj1.arrayGet(2, &obj2)->isNum()) {
- xMax = obj2.getNum();
- }
- obj2.free();
- if (obj1.arrayGet(3, &obj2)->isNum()) {
- yMax = obj2.getNum();
- }
- obj2.free();
- if (xMin > xMax) {
- t = xMin; xMin = xMax; xMax = t;
- }
- if (yMin > yMax) {
- t = yMin; yMin = yMax; yMax = t;
- }
- } else {
- error(errSyntaxError, -1, "Bad bounding box for annotation");
- ok = gFalse;
- }
- obj1.free();
-
- //----- parse the flags
-
- if (dict->lookup("F", &obj1)->isInt()) {
- flags = obj1.getInt();
- } else {
- flags = 0;
- }
- obj1.free();
-
- //----- parse the border style
-
- borderType = annotBorderSolid;
- borderWidth = 1;
- borderDash = NULL;
- borderDashLength = 0;
- nBorderColorComps = 3;
- borderColor[0] = 0;
- borderColor[1] = 0;
- borderColor[2] = 1;
- borderColor[3] = 0;
- 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;
- }
- }
- obj2.free();
- if (obj1.dictLookup("W", &obj2)->isNum()) {
- borderWidth = obj2.getNum();
- }
- obj2.free();
- if (obj1.dictLookup("D", &obj2)->isArray()) {
- borderDashLength = obj2.arrayGetLength();
- borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
- for (i = 0; i < borderDashLength; ++i) {
- if (obj2.arrayGet(i, &obj3)->isNum()) {
- borderDash[i] = obj3.getNum();
- } else {
- borderDash[i] = 1;
- }
- obj3.free();
- }
- }
- obj2.free();
- } 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 (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;
- }
- obj2.free();
- }
- } else {
- // an empty Border array also means "no border"
- borderWidth = 0;
- }
- }
- }
- obj1.free();
- if (dict->lookup("C", &obj1)->isArray() &&
- (obj1.arrayGetLength() == 1 ||
- obj1.arrayGetLength() == 3 ||
- obj1.arrayGetLength() == 4)) {
- nBorderColorComps = obj1.arrayGetLength();
- for (i = 0; i < nBorderColorComps; ++i) {
- if (obj1.arrayGet(i, &obj2)->isNum()) {
- borderColor[i] = obj2.getNum();
- } else {
- borderColor[i] = 0;
- }
- obj2.free();
- }
- }
- obj1.free();
- borderStyle = new AnnotBorderStyle(borderType, borderWidth,
- borderDash, borderDashLength,
- borderColor, nBorderColorComps);
-
- //----- get the appearance state
-
- dict->lookup("AP", &apObj);
- dict->lookup("AS", &asObj);
- if (asObj.isName()) {
- appearanceState = new GString(asObj.getName());
- } else if (apObj.isDict()) {
- apObj.dictLookup("N", &obj1);
- if (obj1.isDict() && obj1.dictGetLength() == 1) {
- appearanceState = new GString(obj1.dictGetKey(0));
- }
- obj1.free();
- }
- if (!appearanceState) {
- appearanceState = new GString("Off");
- }
- asObj.free();
-
- //----- get the annotation appearance
-
- if (apObj.isDict()) {
- apObj.dictLookup("N", &obj1);
- apObj.dictLookupNF("N", &obj2);
- if (obj1.isDict()) {
- if (obj1.dictLookupNF(appearanceState->getCString(), &obj3)->isRef()) {
- obj3.copy(&appearance);
- }
- obj3.free();
- } else if (obj2.isRef()) {
- obj2.copy(&appearance);
- }
- obj1.free();
- obj2.free();
- }
- apObj.free();
-
- //----- get the optional content entry
-
- dict->lookupNF("OC", &ocObj);
-}
-
-Annot::~Annot() {
- if (type) {
- delete type;
- }
- if (appearanceState) {
- delete appearanceState;
- }
- appearance.free();
- if (appearBuf) {
- delete appearBuf;
- }
- if (borderStyle) {
- delete borderStyle;
- }
- ocObj.free();
-}
-
-void Annot::generateAnnotAppearance() {
- Object obj;
-
- appearance.fetch(doc->getXRef(), &obj);
- if (!obj.isStream()) {
- if (type) {
- if (!type->cmp("Line")) {
- generateLineAppearance();
- } else if (!type->cmp("PolyLine")) {
- generatePolyLineAppearance();
- } else if (!type->cmp("Polygon")) {
- generatePolygonAppearance();
- } else if (!type->cmp("FreeText")) {
- generateFreeTextAppearance();
- }
- }
- }
- obj.free();
-}
-
-//~ this doesn't draw the caption
-void Annot::generateLineAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
- MemStream *appearStream;
- double x1, y1, x2, y2, dx, dy, len, w;
- double lx1, ly1, lx2, ly2;
- double tx1, ty1, tx2, ty2;
- double ax1, ay1, ax2, ay2;
- double bx1, by1, bx2, by2;
- double leaderLen, leaderExtLen, leaderOffLen;
- AnnotLineEndType lineEnd1, lineEnd2;
- GBool fill;
-
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
- appearBuf = new GString();
-
- //----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
- gfxStateDict.initDict(doc->getXRef());
- gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
- appearBuf->append("/GS1 gs\n");
- }
- obj1.free();
-
- //----- set line style, colors
- setLineStyle(borderStyle, &w);
- setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps());
- fill = gFalse;
- if (annotObj.dictLookup("IC", &obj1)->isArray()) {
- if (setFillColor(&obj1)) {
- fill = gTrue;
- }
- }
- obj1.free();
-
- //----- get line properties
- if (annotObj.dictLookup("L", &obj1)->isArray() &&
- obj1.arrayGetLength() == 4) {
- if (obj1.arrayGet(0, &obj2)->isNum()) {
- x1 = obj2.getNum();
- } else {
- obj2.free();
- obj1.free();
- goto err1;
- }
- obj2.free();
- if (obj1.arrayGet(1, &obj2)->isNum()) {
- y1 = obj2.getNum();
- } else {
- obj2.free();
- obj1.free();
- goto err1;
- }
- obj2.free();
- if (obj1.arrayGet(2, &obj2)->isNum()) {
- x2 = obj2.getNum();
- } else {
- obj2.free();
- obj1.free();
- goto err1;
- }
- obj2.free();
- if (obj1.arrayGet(3, &obj2)->isNum()) {
- y2 = obj2.getNum();
- } else {
- obj2.free();
- obj1.free();
- goto err1;
- }
- obj2.free();
- } else {
- obj1.free();
- goto err1;
- }
- obj1.free();
- lineEnd1 = lineEnd2 = annotLineEndNone;
- if (annotObj.dictLookup("LE", &obj1)->isArray() &&
- obj1.arrayGetLength() == 2) {
- lineEnd1 = parseLineEndType(obj1.arrayGet(0, &obj2));
- obj2.free();
- lineEnd2 = parseLineEndType(obj1.arrayGet(1, &obj2));
- obj2.free();
- }
- obj1.free();
- if (annotObj.dictLookup("LL", &obj1)->isNum()) {
- leaderLen = obj1.getNum();
- } else {
- leaderLen = 0;
- }
- obj1.free();
- if (annotObj.dictLookup("LLE", &obj1)->isNum()) {
- leaderExtLen = obj1.getNum();
- } else {
- leaderExtLen = 0;
- }
- obj1.free();
- if (annotObj.dictLookup("LLO", &obj1)->isNum()) {
- leaderOffLen = obj1.getNum();
- } else {
- leaderOffLen = 0;
- }
- obj1.free();
-
- //----- compute positions
- x1 -= xMin;
- y1 -= yMin;
- x2 -= xMin;
- y2 -= yMin;
- dx = x2 - x1;
- dy = y2 - y1;
- len = sqrt(dx*dx + dy*dy);
- if (len > 0) {
- dx /= len;
- dy /= len;
- }
- if (leaderLen != 0) {
- ax1 = x1 + leaderOffLen * dy;
- ay1 = y1 - leaderOffLen * dx;
- lx1 = ax1 + leaderLen * dy;
- ly1 = ay1 - leaderLen * dx;
- bx1 = lx1 + leaderExtLen * dy;
- by1 = ly1 - leaderExtLen * dx;
- ax2 = x2 + leaderOffLen * dy;
- ay2 = y2 - leaderOffLen * dx;
- lx2 = ax2 + leaderLen * dy;
- ly2 = ay2 - leaderLen * dx;
- bx2 = lx2 + leaderExtLen * dy;
- by2 = ly2 - leaderExtLen * dx;
- } else {
- lx1 = x1;
- ly1 = y1;
- lx2 = x2;
- ly2 = y2;
- ax1 = ay1 = ax2 = ay2 = 0; // make gcc happy
- bx1 = by1 = bx2 = by2 = 0;
- }
- adjustLineEndpoint(lineEnd1, lx1, ly1, dx, dy, w, &tx1, &ty1);
- adjustLineEndpoint(lineEnd2, lx2, ly2, -dx, -dy, w, &tx2, &ty2);
-
- //----- draw leaders
- if (leaderLen != 0) {
- appearBuf->appendf("{0:.4f} {1:.4f} m {2:.4f} {3:.4f} l\n",
- ax1, ay1, bx1, by1);
- appearBuf->appendf("{0:.4f} {1:.4f} m {2:.4f} {3:.4f} l\n",
- ax2, ay2 , bx2, by2);
- }
-
- //----- draw the line
- appearBuf->appendf("{0:.4f} {1:.4f} m {2:.4f} {3:.4f} l\n",
- tx1, ty1, tx2, ty2);
- appearBuf->append("S\n");
-
- //----- draw the arrows
- if (borderStyle->getType() == annotBorderDashed) {
- appearBuf->append("[] 0 d\n");
- }
- drawLineArrow(lineEnd1, lx1, ly1, dx, dy, w, fill);
- drawLineArrow(lineEnd2, lx2, ly2, -dx, -dy, w, fill);
-
- //----- build the appearance stream dictionary
- appearDict.initDict(doc->getXRef());
- appearDict.dictAdd(copyString("Length"),
- obj1.initInt(appearBuf->getLength()));
- appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
- obj1.initArray(doc->getXRef());
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(xMax - xMin));
- obj1.arrayAdd(obj2.initReal(yMax - yMin));
- appearDict.dictAdd(copyString("BBox"), &obj1);
- if (gfxStateDict.isDict()) {
- obj1.initDict(doc->getXRef());
- obj2.initDict(doc->getXRef());
- obj2.dictAdd(copyString("GS1"), &gfxStateDict);
- obj1.dictAdd(copyString("ExtGState"), &obj2);
- appearDict.dictAdd(copyString("Resources"), &obj1);
- }
-
- //----- build the appearance stream
- appearStream = new MemStream(appearBuf->getCString(), 0,
- appearBuf->getLength(), &appearDict);
- appearance.free();
- appearance.initStream(appearStream);
-
- err1:
- annotObj.free();
-}
-
-//~ this doesn't handle line ends (arrows)
-void Annot::generatePolyLineAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
- MemStream *appearStream;
- double x1, y1, w;
- int i;
-
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
- appearBuf = new GString();
-
- //----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
- gfxStateDict.initDict(doc->getXRef());
- gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
- appearBuf->append("/GS1 gs\n");
- }
- obj1.free();
-
- //----- set line style, colors
- setLineStyle(borderStyle, &w);
- setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps());
- // fill = gFalse;
- // if (annotObj.dictLookup("IC", &obj1)->isArray()) {
- // if (setFillColor(&obj1)) {
- // fill = gTrue;
- // }
- // }
- // obj1.free();
-
- //----- draw line
- if (!annotObj.dictLookup("Vertices", &obj1)->isArray()) {
- obj1.free();
- goto err1;
- }
- for (i = 0; i+1 < obj1.arrayGetLength(); i += 2) {
- if (!obj1.arrayGet(i, &obj2)->isNum()) {
- obj2.free();
- obj1.free();
- goto err1;
- }
- x1 = obj2.getNum();
- obj2.free();
- if (!obj1.arrayGet(i+1, &obj2)->isNum()) {
- obj2.free();
- obj1.free();
- goto err1;
- }
- y1 = obj2.getNum();
- obj2.free();
- x1 -= xMin;
- y1 -= yMin;
- if (i == 0) {
- appearBuf->appendf("{0:.4f} {1:.4f} m\n", x1, y1);
- } else {
- appearBuf->appendf("{0:.4f} {1:.4f} l\n", x1, y1);
- }
- }
- appearBuf->append("S\n");
- obj1.free();
-
- //----- build the appearance stream dictionary
- appearDict.initDict(doc->getXRef());
- appearDict.dictAdd(copyString("Length"),
- obj1.initInt(appearBuf->getLength()));
- appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
- obj1.initArray(doc->getXRef());
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(xMax - xMin));
- obj1.arrayAdd(obj2.initReal(yMax - yMin));
- appearDict.dictAdd(copyString("BBox"), &obj1);
- if (gfxStateDict.isDict()) {
- obj1.initDict(doc->getXRef());
- obj2.initDict(doc->getXRef());
- obj2.dictAdd(copyString("GS1"), &gfxStateDict);
- obj1.dictAdd(copyString("ExtGState"), &obj2);
- appearDict.dictAdd(copyString("Resources"), &obj1);
- }
-
- //----- build the appearance stream
- appearStream = new MemStream(appearBuf->getCString(), 0,
- appearBuf->getLength(), &appearDict);
- appearance.free();
- appearance.initStream(appearStream);
-
- err1:
- annotObj.free();
-}
-
-void Annot::generatePolygonAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
- MemStream *appearStream;
- double x1, y1;
- int i;
-
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
- appearBuf = new GString();
-
- //----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
- gfxStateDict.initDict(doc->getXRef());
- gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
- appearBuf->append("/GS1 gs\n");
- }
- obj1.free();
-
- //----- set fill color
- if (!annotObj.dictLookup("IC", &obj1)->isArray() ||
- !setFillColor(&obj1)) {
- obj1.free();
- goto err1;
- }
- obj1.free();
-
- //----- fill polygon
- if (!annotObj.dictLookup("Vertices", &obj1)->isArray()) {
- obj1.free();
- goto err1;
- }
- for (i = 0; i+1 < obj1.arrayGetLength(); i += 2) {
- if (!obj1.arrayGet(i, &obj2)->isNum()) {
- obj2.free();
- obj1.free();
- goto err1;
- }
- x1 = obj2.getNum();
- obj2.free();
- if (!obj1.arrayGet(i+1, &obj2)->isNum()) {
- obj2.free();
- obj1.free();
- goto err1;
- }
- y1 = obj2.getNum();
- obj2.free();
- x1 -= xMin;
- y1 -= yMin;
- if (i == 0) {
- appearBuf->appendf("{0:.4f} {1:.4f} m\n", x1, y1);
- } else {
- appearBuf->appendf("{0:.4f} {1:.4f} l\n", x1, y1);
- }
- }
- appearBuf->append("f\n");
- obj1.free();
-
- //----- build the appearance stream dictionary
- appearDict.initDict(doc->getXRef());
- appearDict.dictAdd(copyString("Length"),
- obj1.initInt(appearBuf->getLength()));
- appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
- obj1.initArray(doc->getXRef());
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(xMax - xMin));
- obj1.arrayAdd(obj2.initReal(yMax - yMin));
- appearDict.dictAdd(copyString("BBox"), &obj1);
- if (gfxStateDict.isDict()) {
- obj1.initDict(doc->getXRef());
- obj2.initDict(doc->getXRef());
- obj2.dictAdd(copyString("GS1"), &gfxStateDict);
- obj1.dictAdd(copyString("ExtGState"), &obj2);
- appearDict.dictAdd(copyString("Resources"), &obj1);
- }
-
- //----- build the appearance stream
- appearStream = new MemStream(appearBuf->getCString(), 0,
- appearBuf->getLength(), &appearDict);
- appearance.free();
- appearance.initStream(appearStream);
-
- err1:
- annotObj.free();
-}
-
-//~ this doesn't handle rich text
-//~ this doesn't handle the callout
-//~ this doesn't handle the RD field
-void Annot::generateFreeTextAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
- Object resources, gsResources, fontResources, defaultFont;
- GString *text, *da;
- double lineWidth;
- int quadding, rot;
- MemStream *appearStream;
-
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
- appearBuf = new GString();
-
- //----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
- gfxStateDict.initDict(doc->getXRef());
- gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
- appearBuf->append("/GS1 gs\n");
- }
- obj1.free();
-
- //----- draw the text
- if (annotObj.dictLookup("Contents", &obj1)->isString()) {
- text = obj1.getString()->copy();
- } else {
- text = new GString();
- }
- obj1.free();
- if (annotObj.dictLookup("Q", &obj1)->isInt()) {
- quadding = obj1.getInt();
- } else {
- quadding = 0;
- }
- obj1.free();
- if (annotObj.dictLookup("DA", &obj1)->isString()) {
- da = obj1.getString()->copy();
- } else {
- da = new GString();
- }
- obj1.free();
- // the "Rotate" field is not defined in the PDF spec, but Acrobat
- // looks at it
- if (annotObj.dictLookup("Rotate", &obj1)->isInt()) {
- rot = obj1.getInt();
- } else {
- rot = 0;
- }
- obj1.free();
- drawText(text, da, quadding, 0, rot);
- delete text;
- delete da;
-
- //----- draw the border
- if (borderStyle->getWidth() != 0) {
- setLineStyle(borderStyle, &lineWidth);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re s\n",
- 0.5 * lineWidth, 0.5 * lineWidth,
- xMax - xMin - lineWidth, yMax - yMin - lineWidth);
- }
-
- //----- build the appearance stream dictionary
- appearDict.initDict(doc->getXRef());
- appearDict.dictAdd(copyString("Length"),
- obj1.initInt(appearBuf->getLength()));
- appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
- obj1.initArray(doc->getXRef());
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(xMax - xMin));
- obj1.arrayAdd(obj2.initReal(yMax - yMin));
- appearDict.dictAdd(copyString("BBox"), &obj1);
- resources.initDict(doc->getXRef());
- defaultFont.initDict(doc->getXRef());
- defaultFont.dictAdd(copyString("Type"), obj1.initName("Font"));
- defaultFont.dictAdd(copyString("Subtype"), obj1.initName("Type1"));
- defaultFont.dictAdd(copyString("BaseFont"), obj1.initName("Helvetica"));
- defaultFont.dictAdd(copyString("Encoding"), obj1.initName("WinAnsiEncoding"));
- fontResources.initDict(doc->getXRef());
- fontResources.dictAdd(copyString("xpdf_default_font"), &defaultFont);
- resources.dictAdd(copyString("Font"), &fontResources);
- if (gfxStateDict.isDict()) {
- gsResources.initDict(doc->getXRef());
- gsResources.dictAdd(copyString("GS1"), &gfxStateDict);
- resources.dictAdd(copyString("ExtGState"), &gsResources);
- }
- appearDict.dictAdd(copyString("Resources"), &resources);
-
- //----- build the appearance stream
- appearStream = new MemStream(appearBuf->getCString(), 0,
- appearBuf->getLength(), &appearDict);
- appearance.free();
- appearance.initStream(appearStream);
-
- annotObj.free();
-}
-
-void Annot::setLineStyle(AnnotBorderStyle *bs, double *lineWidth) {
- double *dash;
- double w;
- int dashLength, i;
-
- if ((w = borderStyle->getWidth()) <= 0) {
- w = 0.1;
- }
- *lineWidth = w;
- appearBuf->appendf("{0:.4f} w\n", w);
- // this treats beveled/inset/underline as solid
- if (borderStyle->getType() == annotBorderDashed) {
- borderStyle->getDash(&dash, &dashLength);
- appearBuf->append("[");
- for (i = 0; i < dashLength; ++i) {
- appearBuf->appendf(" {0:.4f}", dash[i]);
- }
- appearBuf->append("] 0 d\n");
- }
- appearBuf->append("0 j\n0 J\n");
-}
-
-void Annot::setStrokeColor(double *color, int nComps) {
- switch (nComps) {
- case 0:
- appearBuf->append("0 G\n");
- break;
- case 1:
- appearBuf->appendf("{0:.2f} G\n", color[0]);
- break;
- case 3:
- appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} RG\n",
- color[0], color[1], color[2]);
- break;
- case 4:
- appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} K\n",
- color[0], color[1], color[2], color[3]);
- break;
- }
-}
-
-GBool Annot::setFillColor(Object *colorObj) {
- Object obj;
- double color[4];
- int i;
-
- if (!colorObj->isArray()) {
- return gFalse;
- }
- for (i = 0; i < colorObj->arrayGetLength() && i < 4; ++i) {
- if (colorObj->arrayGet(i, &obj)->isNum()) {
- color[i] = obj.getNum();
- } else {
- color[i] = 0;
- }
- obj.free();
- }
- switch (colorObj->arrayGetLength()) {
- case 1:
- appearBuf->appendf("{0:.2f} g\n", color[0]);
- return gTrue;
- case 3:
- appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} rg\n",
- color[0], color[1], color[2]);
- return gTrue;
- case 4:
- appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.3f} k\n",
- color[0], color[1],
- color[2], color[3]);
- return gTrue;
- }
- return gFalse;
-}
-
-AnnotLineEndType Annot::parseLineEndType(Object *obj) {
- if (obj->isName("None")) {
- return annotLineEndNone;
- } else if (obj->isName("Square")) {
- return annotLineEndSquare;
- } else if (obj->isName("Circle")) {
- return annotLineEndCircle;
- } else if (obj->isName("Diamond")) {
- return annotLineEndDiamond;
- } else if (obj->isName("OpenArrow")) {
- return annotLineEndOpenArrow;
- } else if (obj->isName("ClosedArrow")) {
- return annotLineEndClosedArrow;
- } else if (obj->isName("Butt")) {
- return annotLineEndButt;
- } else if (obj->isName("ROpenArrow")) {
- return annotLineEndROpenArrow;
- } else if (obj->isName("RClosedArrow")) {
- return annotLineEndRClosedArrow;
- } else if (obj->isName("Slash")) {
- return annotLineEndSlash;
- } else {
- return annotLineEndNone;
- }
-}
-
-void Annot::adjustLineEndpoint(AnnotLineEndType lineEnd,
- double x, double y, double dx, double dy,
- double w, double *tx, double *ty) {
- switch (lineEnd) {
- case annotLineEndNone:
- w = 0;
- break;
- case annotLineEndSquare:
- w *= lineEndSize1;
- break;
- case annotLineEndCircle:
- w *= lineEndSize1;
- break;
- case annotLineEndDiamond:
- w *= lineEndSize1;
- break;
- case annotLineEndOpenArrow:
- w = 0;
- break;
- case annotLineEndClosedArrow:
- w *= lineEndSize2 * cos(lineArrowAngle);
- break;
- case annotLineEndButt:
- w = 0;
- break;
- case annotLineEndROpenArrow:
- w *= lineEndSize2 * cos(lineArrowAngle);
- break;
- case annotLineEndRClosedArrow:
- w *= lineEndSize2 * cos(lineArrowAngle);
- break;
- case annotLineEndSlash:
- w = 0;
- break;
- }
- *tx = x + w * dx;
- *ty = y + w * dy;
-}
-
-void Annot::drawLineArrow(AnnotLineEndType lineEnd,
- double x, double y, double dx, double dy,
- double w, GBool fill) {
- switch (lineEnd) {
- case annotLineEndNone:
- break;
- case annotLineEndSquare:
- w *= lineEndSize1;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + w*dx + 0.5*w*dy,
- y + w*dy - 0.5*w*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + 0.5*w*dy,
- y - 0.5*w*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x - 0.5*w*dy,
- y + 0.5*w*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + w*dx - 0.5*w*dy,
- y + w*dy + 0.5*w*dx);
- appearBuf->append(fill ? "b\n" : "s\n");
- break;
- case annotLineEndCircle:
- w *= lineEndSize1;
- drawCircle(x + 0.5*w*dx, y + 0.5*w*dy, 0.5*w, fill ? "b" : "s");
- break;
- case annotLineEndDiamond:
- w *= lineEndSize1;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n", x, y);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + 0.5*w*dx - 0.5*w*dy,
- y + 0.5*w*dy + 0.5*w*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + w*dx,
- y + w*dy);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + 0.5*w*dx + 0.5*w*dy,
- y + 0.5*w*dy - 0.5*w*dx);
- appearBuf->append(fill ? "b\n" : "s\n");
- break;
- case annotLineEndOpenArrow:
- w *= lineEndSize2;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + w*cos(lineArrowAngle)*dx + w*sin(lineArrowAngle)*dy,
- y + w*cos(lineArrowAngle)*dy - w*sin(lineArrowAngle)*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n", x, y);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + w*cos(lineArrowAngle)*dx - w*sin(lineArrowAngle)*dy,
- y + w*cos(lineArrowAngle)*dy + w*sin(lineArrowAngle)*dx);
- appearBuf->append("S\n");
- break;
- case annotLineEndClosedArrow:
- w *= lineEndSize2;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + w*cos(lineArrowAngle)*dx + w*sin(lineArrowAngle)*dy,
- y + w*cos(lineArrowAngle)*dy - w*sin(lineArrowAngle)*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n", x, y);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + w*cos(lineArrowAngle)*dx - w*sin(lineArrowAngle)*dy,
- y + w*cos(lineArrowAngle)*dy + w*sin(lineArrowAngle)*dx);
- appearBuf->append(fill ? "b\n" : "s\n");
- break;
- case annotLineEndButt:
- w *= lineEndSize1;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + 0.5*w*dy,
- y - 0.5*w*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x - 0.5*w*dy,
- y + 0.5*w*dx);
- appearBuf->append("S\n");
- break;
- case annotLineEndROpenArrow:
- w *= lineEndSize2;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + w*sin(lineArrowAngle)*dy,
- y - w*sin(lineArrowAngle)*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + w*cos(lineArrowAngle)*dx,
- y + w*cos(lineArrowAngle)*dy);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x - w*sin(lineArrowAngle)*dy,
- y + w*sin(lineArrowAngle)*dx);
- appearBuf->append("S\n");
- break;
- case annotLineEndRClosedArrow:
- w *= lineEndSize2;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + w*sin(lineArrowAngle)*dy,
- y - w*sin(lineArrowAngle)*dx);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x + w*cos(lineArrowAngle)*dx,
- y + w*cos(lineArrowAngle)*dy);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x - w*sin(lineArrowAngle)*dy,
- y + w*sin(lineArrowAngle)*dx);
- appearBuf->append(fill ? "b\n" : "s\n");
- break;
- case annotLineEndSlash:
- w *= lineEndSize1;
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- x + 0.5*w*cos(lineArrowAngle)*dy
- - 0.5*w*sin(lineArrowAngle)*dx,
- y - 0.5*w*cos(lineArrowAngle)*dx
- - 0.5*w*sin(lineArrowAngle)*dy);
- appearBuf->appendf("{0:.4f} {1:.4f} l\n",
- x - 0.5*w*cos(lineArrowAngle)*dy
- + 0.5*w*sin(lineArrowAngle)*dx,
- y + 0.5*w*cos(lineArrowAngle)*dx
- + 0.5*w*sin(lineArrowAngle)*dy);
- appearBuf->append("S\n");
- break;
- }
-}
-
-// Draw an (approximate) circle of radius <r> centered at (<cx>, <cy>).
-// <cmd> is used to draw the circle ("f", "s", or "b").
-void Annot::drawCircle(double cx, double cy, double r, const char *cmd) {
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- cx + r, cy);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx + r, cy + bezierCircle * r,
- cx + bezierCircle * r, cy + r,
- cx, cy + r);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx - bezierCircle * r, cy + r,
- cx - r, cy + bezierCircle * r,
- cx - r, cy);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx - r, cy - bezierCircle * r,
- cx - bezierCircle * r, cy - r,
- cx, cy - r);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx + bezierCircle * r, cy - r,
- cx + r, cy - bezierCircle * r,
- cx + r, cy);
- appearBuf->appendf("{0:s}\n", cmd);
-}
-
-// Draw the top-left half of an (approximate) circle of radius <r>
-// centered at (<cx>, <cy>).
-void Annot::drawCircleTopLeft(double cx, double cy, double r) {
- double r2;
-
- r2 = r / sqrt(2.0);
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- cx + r2, cy + r2);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx + (1 - bezierCircle) * r2,
- cy + (1 + bezierCircle) * r2,
- cx - (1 - bezierCircle) * r2,
- cy + (1 + bezierCircle) * r2,
- cx - r2,
- cy + r2);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx - (1 + bezierCircle) * r2,
- cy + (1 - bezierCircle) * r2,
- cx - (1 + bezierCircle) * r2,
- cy - (1 - bezierCircle) * r2,
- cx - r2,
- cy - r2);
- appearBuf->append("S\n");
-}
-
-// Draw the bottom-right half of an (approximate) circle of radius <r>
-// centered at (<cx>, <cy>).
-void Annot::drawCircleBottomRight(double cx, double cy, double r) {
- double r2;
-
- r2 = r / sqrt(2.0);
- appearBuf->appendf("{0:.4f} {1:.4f} m\n",
- cx - r2, cy - r2);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx - (1 - bezierCircle) * r2,
- cy - (1 + bezierCircle) * r2,
- cx + (1 - bezierCircle) * r2,
- cy - (1 + bezierCircle) * r2,
- cx + r2,
- cy - r2);
- appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
- cx + (1 + bezierCircle) * r2,
- cy - (1 - bezierCircle) * r2,
- cx + (1 + bezierCircle) * r2,
- cy + (1 - bezierCircle) * r2,
- cx + r2,
- cy + r2);
- appearBuf->append("S\n");
-}
-
-void Annot::drawText(GString *text, GString *da, int quadding, double margin,
- int rot) {
- GString *text2, *tok;
- GList *daToks;
- const char *charName;
- double dx, dy, fontSize, fontSize2, x, y, w;
- Gushort charWidth;
- int tfPos, tmPos, i, j, c;
-
- // check for a Unicode string
- //~ this currently drops all non-Latin1 characters
- if (text->getLength() >= 2 &&
- text->getChar(0) == '\xfe' && text->getChar(1) == '\xff') {
- text2 = new GString();
- for (i = 2; i+1 < text->getLength(); i += 2) {
- c = ((text->getChar(i) & 0xff) << 8) + (text->getChar(i+1) & 0xff);
- if (c <= 0xff) {
- text2->append((char)c);
- } else {
- text2->append('?');
- }
- }
- } else {
- text2 = text;
- }
-
- // parse the default appearance string
- tfPos = tmPos = -1;
- if (da) {
- daToks = new GList();
- i = 0;
- while (i < da->getLength()) {
- while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
- ++i;
- }
- if (i < da->getLength()) {
- for (j = i + 1;
- j < da->getLength() && !Lexer::isSpace(da->getChar(j));
- ++j) ;
- daToks->append(new GString(da, i, j - i));
- i = j;
- }
- }
- for (i = 2; i < daToks->getLength(); ++i) {
- if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {
- tfPos = i - 2;
- } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) {
- tmPos = i - 6;
- }
- }
- } else {
- daToks = NULL;
- }
-
- // get the font and font size
- fontSize = 0;
- if (tfPos >= 0) {
- //~ where do we look up the font?
- tok = (GString *)daToks->get(tfPos);
- tok->clear();
- tok->append("/xpdf_default_font");
- tok = (GString *)daToks->get(tfPos + 1);
- fontSize = atof(tok->getCString());
- } else {
- error(errSyntaxError, -1,
- "Missing 'Tf' operator in annotation's DA string");
- daToks->append(new GString("/xpdf_default_font"));
- daToks->append(new GString("10"));
- daToks->append(new GString("Tf"));
- }
-
- // setup
- appearBuf->append("q\n");
- if (rot == 90) {
- appearBuf->appendf("0 1 -1 0 {0:.4f} 0 cm\n", xMax - xMin);
- dx = yMax - yMin;
- dy = xMax - xMin;
- } else if (rot == 180) {
- appearBuf->appendf("-1 0 0 -1 {0:.4f} {1:.4f} cm\n",
- xMax - xMin, yMax - yMin);
- dx = xMax - yMax;
- dy = yMax - yMin;
- } else if (rot == 270) {
- appearBuf->appendf("0 -1 1 0 0 {0:.4f} cm\n", yMax - yMin);
- dx = yMax - yMin;
- dy = xMax - xMin;
- } else { // assume rot == 0
- dx = xMax - xMin;
- dy = yMax - yMin;
- }
- appearBuf->append("BT\n");
-
- // compute string width
- //~ this assumes we're substituting Helvetica/WinAnsiEncoding for everything
- w = 0;
- for (i = 0; i < text2->getLength(); ++i) {
- charName = winAnsiEncoding[text->getChar(i) & 0xff];
- if (charName && builtinFonts[4].widths->getWidth(charName, &charWidth)) {
- w += charWidth;
- } else {
- w += 0.5;
- }
- }
-
- // compute font autosize
- if (fontSize == 0) {
- fontSize = dy - 2 * margin;
- fontSize2 = (dx - 2 * margin) / w;
- if (fontSize2 < fontSize) {
- fontSize = fontSize2;
- }
- fontSize = floor(fontSize);
- if (tfPos >= 0) {
- tok = (GString *)daToks->get(tfPos + 1);
- tok->clear();
- tok->appendf("{0:.4f}", fontSize);
- }
- }
-
- // compute text start position
- w *= fontSize;
- switch (quadding) {
- case 0:
- default:
- x = margin + 2;
- break;
- case 1:
- x = (dx - w) / 2;
- break;
- case 2:
- x = dx - margin - 2 - w;
- break;
- }
- y = 0.5 * dy - 0.4 * fontSize;
-
- // set the font matrix
- if (tmPos >= 0) {
- tok = (GString *)daToks->get(tmPos + 4);
- tok->clear();
- tok->appendf("{0:.4f}", x);
- tok = (GString *)daToks->get(tmPos + 5);
- tok->clear();
- tok->appendf("{0:.4f}", y);
- }
-
- // write the DA string
- if (daToks) {
- for (i = 0; i < daToks->getLength(); ++i) {
- appearBuf->append((GString *)daToks->get(i))->append(' ');
- }
- }
-
- // write the font matrix (if not part of the DA string)
- if (tmPos < 0) {
- appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", x, y);
- }
-
- // write the text string
- appearBuf->append('(');
- for (i = 0; i < text2->getLength(); ++i) {
- c = text2->getChar(i) & 0xff;
- if (c == '(' || c == ')' || c == '\\') {
- appearBuf->append('\\');
- appearBuf->append((char)c);
- } else if (c < 0x20 || c >= 0x80) {
- appearBuf->appendf("\\{0:03o}", c);
- } else {
- appearBuf->append((char)c);
- }
- }
- appearBuf->append(") Tj\n");
-
- // cleanup
- appearBuf->append("ET\n");
- appearBuf->append("Q\n");
-
- if (daToks) {
- deleteGList(daToks, GString);
- }
- if (text2 != text) {
- delete text2;
- }
-}
-
-void Annot::draw(Gfx *gfx, GBool printing) {
- GBool oc, isLink;
-
- // check the flags
- if ((flags & annotFlagHidden) ||
- (printing && !(flags & annotFlagPrint)) ||
- (!printing && (flags & annotFlagNoView))) {
- return;
- }
-
- // check the optional content entry
- if (doc->getOptionalContent()->evalOCObject(&ocObj, &oc) && !oc) {
- return;
- }
-
- // draw the appearance stream
- isLink = type && !type->cmp("Link");
- gfx->drawAnnot(&appearance, isLink ? borderStyle : (AnnotBorderStyle *)NULL,
- xMin, yMin, xMax, yMax);
-}
-
-Object *Annot::getObject(Object *obj) {
- if (ref.num >= 0) {
- xref->fetch(ref.num, ref.gen, obj);
- } else {
- obj->initNull();
- }
- return obj;
-}
-
-//------------------------------------------------------------------------
-// Annots
-//------------------------------------------------------------------------
-
-Annots::Annots(PDFDoc *docA, Object *annotsObj) {
- Annot *annot;
- Object obj1, obj2;
- Ref ref;
- GBool drawWidgetAnnots;
- int size;
- int i;
-
- doc = docA;
- annots = NULL;
- size = 0;
- nAnnots = 0;
-
- if (annotsObj->isArray()) {
- // Kludge: some PDF files define an empty AcroForm, but still
- // include Widget-type annotations -- in that case, we want to
- // draw the widgets (since the form code won't). This really
- // ought to look for Widget-type annotations that are not included
- // in any form field.
- drawWidgetAnnots = !doc->getCatalog()->getForm() ||
- doc->getCatalog()->getForm()->getNumFields() == 0;
- for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
- if (annotsObj->arrayGetNF(i, &obj1)->isRef()) {
- ref = obj1.getRef();
- obj1.free();
- annotsObj->arrayGet(i, &obj1);
- } else {
- ref.num = ref.gen = -1;
- }
- if (obj1.isDict()) {
- if (drawWidgetAnnots ||
- !obj1.dictLookup("Subtype", &obj2)->isName("Widget")) {
- annot = new Annot(doc, obj1.getDict(), &ref);
- if (annot->isOk()) {
- if (nAnnots >= size) {
- size += 16;
- annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
- }
- annots[nAnnots++] = annot;
- } else {
- delete annot;
- }
- }
- obj2.free();
- }
- obj1.free();
- }
- }
-}
-
-Annots::~Annots() {
- int i;
-
- for (i = 0; i < nAnnots; ++i) {
- delete annots[i];
- }
- gfree(annots);
-}
-
-Annot *Annots::find(double x, double y) {
- int i;
-
- for (i = nAnnots - 1; i >= 0; --i) {
- if (annots[i]->inRect(x, y)) {
- return annots[i];
- }
- }
- return NULL;
-}
-
-int Annots::findIdx(double x, double y) {
- int i;
-
- for (i = nAnnots - 1; i >= 0; --i) {
- if (annots[i]->inRect(x, y)) {
- return i;
- }
- }
- return -1;
-}
-
-void Annots::generateAnnotAppearances() {
- int i;
-
- for (i = 0; i < nAnnots; ++i) {
- annots[i]->generateAnnotAppearance();
- }
-}
-
-Annot *Annots::findAnnot(Ref *ref) {
- int i;
-
- for (i = 0; i < nAnnots; ++i) {
- if (annots[i]->match(ref)) {
- return annots[i];
- }
- }
- return NULL;
-}