diff options
author | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
---|---|---|
committer | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
commit | c6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch) | |
tree | 1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc | |
parent | 07ee7222e389b0777456b427a55c22d0e6ffd267 (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.cc | 1443 |
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; -} |