X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=pdf%2Fxpdf%2FLink.cc;h=bfb41b7d80edc58970047c646874f1b42f410979;hb=5932479cc8c371a385616b5909df558a091b7111;hp=b16563a925de3957cb3dc6a87995e45fbcf06117;hpb=64676031423465996e83c4a685290f0c3d97a249;p=evince.git diff --git a/pdf/xpdf/Link.cc b/pdf/xpdf/Link.cc index b16563a9..bfb41b7d 100644 --- a/pdf/xpdf/Link.cc +++ b/pdf/xpdf/Link.cc @@ -2,7 +2,7 @@ // // Link.cc // -// Copyright 1996-2002 Glyph & Cog, LLC +// Copyright 1996-2003 Glyph & Cog, LLC // //======================================================================== @@ -42,8 +42,9 @@ LinkAction *LinkAction::parseAction(Object *obj, GString *baseURI) { Object obj2, obj3, obj4; if (!obj->isDict()) { - error(-1, "Bad annotation action"); - return NULL; + error(-1, "parseAction: Bad annotation action for URI '%s'", + baseURI ? baseURI->getCString() : "NULL"); + return NULL; } obj->dictLookup("S", &obj2); @@ -92,7 +93,8 @@ LinkAction *LinkAction::parseAction(Object *obj, GString *baseURI) { // action is missing or wrong type } else { - error(-1, "Bad annotation action"); + error(-1, "parseAction: Unknown annotation action object: URI = '%s'", + baseURI ? baseURI->getCString() : "NULL"); action = NULL; } @@ -148,7 +150,7 @@ LinkDest::LinkDest(Array *a) { // get page if (a->getLength() < 2) { - error(-1, "Annotation destination array has wrong length"); + error(-1, "Annotation destination array is too short"); return; } a->getNF(0, &obj1); @@ -170,57 +172,65 @@ LinkDest::LinkDest(Array *a) { // XYZ link if (obj1.isName("XYZ")) { - if (a->getLength() != 5) { - error(-1, "Annotation destination array has wrong length"); - goto err2; - } kind = destXYZ; - a->get(2, &obj2); - if (obj2.isNull()) { + if (a->getLength() < 3) { changeLeft = gFalse; - } else if (obj2.isNum()) { - changeLeft = gTrue; - left = obj2.getNum(); } else { - error(-1, "Bad annotation destination position"); - goto err1; + a->get(2, &obj2); + if (obj2.isNull()) { + changeLeft = gFalse; + } else if (obj2.isNum()) { + changeLeft = gTrue; + left = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); } - obj2.free(); - a->get(3, &obj2); - if (obj2.isNull()) { + if (a->getLength() < 4) { changeTop = gFalse; - } else if (obj2.isNum()) { - changeTop = gTrue; - top = obj2.getNum(); } else { - error(-1, "Bad annotation destination position"); - goto err1; + a->get(3, &obj2); + if (obj2.isNull()) { + changeTop = gFalse; + } else if (obj2.isNum()) { + changeTop = gTrue; + top = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); } - obj2.free(); - a->get(4, &obj2); - if (obj2.isNull()) { + if (a->getLength() < 5) { changeZoom = gFalse; - } else if (obj2.isNum()) { - changeZoom = gTrue; - zoom = obj2.getNum(); } else { - error(-1, "Bad annotation destination position"); - goto err1; + a->get(4, &obj2); + if (obj2.isNull()) { + changeZoom = gFalse; + } else if (obj2.isNum()) { + changeZoom = gTrue; + zoom = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); } - obj2.free(); // Fit link } else if (obj1.isName("Fit")) { - if (a->getLength() != 2) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 2) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFit; // FitH link } else if (obj1.isName("FitH")) { - if (a->getLength() != 3) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitH; @@ -233,8 +243,8 @@ LinkDest::LinkDest(Array *a) { // FitV link } else if (obj1.isName("FitV")) { - if (a->getLength() != 3) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitV; @@ -247,8 +257,8 @@ LinkDest::LinkDest(Array *a) { // FitR link } else if (obj1.isName("FitR")) { - if (a->getLength() != 6) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 6) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitR; @@ -279,16 +289,16 @@ LinkDest::LinkDest(Array *a) { // FitB link } else if (obj1.isName("FitB")) { - if (a->getLength() != 2) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 2) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitB; // FitBH link } else if (obj1.isName("FitBH")) { - if (a->getLength() != 3) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitBH; @@ -301,8 +311,8 @@ LinkDest::LinkDest(Array *a) { // FitBV link } else if (obj1.isName("FitBV")) { - if (a->getLength() != 3) { - error(-1, "Annotation destination array has wrong length"); + if (a->getLength() < 3) { + error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitBV; @@ -572,14 +582,43 @@ LinkUnknown::~LinkUnknown() { delete action; } +//------------------------------------------------------------------------ +// LinkBorderStyle +//------------------------------------------------------------------------ + +LinkBorderStyle::LinkBorderStyle(LinkBorderType typeA, double widthA, + double *dashA, int dashLengthA, + double rA, double gA, double bA) { + type = typeA; + width = widthA; + dash = dashA; + dashLength = dashLengthA; + r = rA; + g = gA; + b = bA; +} + +LinkBorderStyle::~LinkBorderStyle() { + if (dash) { + gfree(dash); + } +} + //------------------------------------------------------------------------ // Link //------------------------------------------------------------------------ Link::Link(Dict *dict, GString *baseURI) { - Object obj1, obj2; + Object obj1, obj2, obj3; + LinkBorderType borderType; + double borderWidth; + double *borderDash; + int borderDashLength; + double borderR, borderG, borderB; double t; + int i; + borderStyle = NULL; action = NULL; ok = gFalse; @@ -624,19 +663,92 @@ Link::Link(Dict *dict, GString *baseURI) { y2 = t; } - // get border - borderW = 1; - if (!dict->lookup("Border", &obj1)->isNull()) { - if (obj1.isArray() && obj1.arrayGetLength() >= 3) { - if (obj1.arrayGet(2, &obj2)->isNum()) { - borderW = obj2.getNum(); - } else { - error(-1, "Bad annotation border"); + // get the border style info + borderType = linkBorderSolid; + 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 = linkBorderSolid; + } else if (obj2.isName("D")) { + borderType = linkBorderDashed; + } else if (obj2.isName("B")) { + borderType = linkBorderEmbossed; + } else if (obj2.isName("I")) { + borderType = linkBorderEngraved; + } else if (obj2.isName("U")) { + borderType = linkBorderUnderlined; + } + } + obj2.free(); + if (obj1.dictLookup("W", &obj2)->isNum()) { + borderWidth = obj2.getNum(); + } + obj2.free(); + if (obj1.dictLookup("D", &obj2)->isArray()) { + borderDashLength = obj2.arrayGetLength(); + borderDash = (double *)gmalloc(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 = linkBorderDashed; + borderDashLength = obj2.arrayGetLength(); + borderDash = (double *)gmalloc(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(); + } } - obj2.free(); } } obj1.free(); + 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(); + borderStyle = new LinkBorderStyle(borderType, borderWidth, + borderDash, borderDashLength, + borderR, borderG, borderB); // look for destination if (!dict->lookup("Dest", &obj1)->isNull()) { @@ -665,8 +777,12 @@ Link::Link(Dict *dict, GString *baseURI) { } Link::~Link() { - if (action) + if (borderStyle) { + delete borderStyle; + } + if (action) { delete action; + } } //------------------------------------------------------------------------