📄 link.cc
字号:
//========================================================================//// Link.cc//// Copyright 1996-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stddef.h>#include <string.h>#include "gmem.h"#include "GString.h"#include "Error.h"#include "Object.h"#include "Array.h"#include "Dict.h"#include "Link.h"//------------------------------------------------------------------------// LinkAction//------------------------------------------------------------------------LinkAction *LinkAction::parseDest(Object *obj) { LinkAction *action; action = new LinkGoTo(obj); if (!action->isOk()) { delete action; return NULL; } return action;}LinkAction *LinkAction::parseAction(Object *obj, GString *baseURI) { LinkAction *action; Object obj2, obj3, obj4; if (!obj->isDict()) { error(-1, "Bad annotation action"); return NULL; } obj->dictLookup("S", &obj2); // GoTo action if (obj2.isName("GoTo")) { obj->dictLookup("D", &obj3); action = new LinkGoTo(&obj3); obj3.free(); // GoToR action } else if (obj2.isName("GoToR")) { obj->dictLookup("F", &obj3); obj->dictLookup("D", &obj4); action = new LinkGoToR(&obj3, &obj4); obj3.free(); obj4.free(); // Launch action } else if (obj2.isName("Launch")) { action = new LinkLaunch(obj); // URI action } else if (obj2.isName("URI")) { obj->dictLookup("URI", &obj3); action = new LinkURI(&obj3, baseURI); obj3.free(); // Named action } else if (obj2.isName("Named")) { obj->dictLookup("N", &obj3); action = new LinkNamed(&obj3); obj3.free(); // Movie action } else if (obj2.isName("Movie")) { obj->dictLookupNF("Annot", &obj3); obj->dictLookup("T", &obj4); action = new LinkMovie(&obj3, &obj4); obj3.free(); obj4.free(); // unknown action } else if (obj2.isName()) { action = new LinkUnknown(obj2.getName()); // action is missing or wrong type } else { error(-1, "Bad annotation action"); action = NULL; } obj2.free(); if (action && !action->isOk()) { delete action; return NULL; } return action;}GString *LinkAction::getFileSpecName(Object *fileSpecObj) { GString *name; Object obj1; name = NULL; // string if (fileSpecObj->isString()) { name = fileSpecObj->getString()->copy(); // dictionary } else if (fileSpecObj->isDict()) {#ifdef WIN32 if (!fileSpecObj->dictLookup("DOS", &obj1)->isString()) {#else if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) {#endif obj1.free(); fileSpecObj->dictLookup("F", &obj1); } if (obj1.isString()) { name = obj1.getString()->copy(); } else { error(-1, "Illegal file spec in link"); } obj1.free(); // error } else { error(-1, "Illegal file spec in link"); } // system-dependent path manipulation if (name) {#ifdef WIN32 int i, j; // "//...." --> "\...." // "/x/...." --> "x:\...." // "/server/share/...." --> "\\server\share\...." // convert escaped slashes to slashes and unescaped slashes to backslashes i = 0; if (name->getChar(0) == '/') { if (name->getLength() >= 2 && name->getChar(1) == '/') { name->del(0); i = 0; } else if (name->getLength() >= 2 && ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') || (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) && (name->getLength() == 2 || name->getChar(2) == '/')) { name->setChar(0, name->getChar(1)); name->setChar(1, ':'); i = 2; } else { for (j = 2; j < name->getLength(); ++j) { if (name->getChar(j-1) != '\\' && name->getChar(j) == '/') { break; } } if (j < name->getLength()) { name->setChar(0, '\\'); name->insert(0, '\\'); i = 2; } } } for (; i < name->getLength(); ++i) { if (name->getChar(i) == '/') { name->setChar(i, '\\'); } else if (name->getChar(i) == '\\' && i+1 < name->getLength() && name->getChar(i+1) == '/') { name->del(i); } }#else // no manipulation needed for Unix#endif } return name;}//------------------------------------------------------------------------// LinkDest//------------------------------------------------------------------------LinkDest::LinkDest(Array *a) { Object obj1, obj2; // initialize fields left = bottom = right = top = zoom = 0; ok = gFalse; // get page if (a->getLength() < 2) { error(-1, "Annotation destination array is too short"); return; } a->getNF(0, &obj1); if (obj1.isInt()) { pageNum = obj1.getInt() + 1; pageIsRef = gFalse; } else if (obj1.isRef()) { pageRef.num = obj1.getRefNum(); pageRef.gen = obj1.getRefGen(); pageIsRef = gTrue; } else { error(-1, "Bad annotation destination"); goto err2; } obj1.free(); // get destination type a->get(1, &obj1); // XYZ link if (obj1.isName("XYZ")) { kind = destXYZ; if (a->getLength() < 3) { changeLeft = gFalse; } else { 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(); } if (a->getLength() < 4) { changeTop = gFalse; } else { 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(); } if (a->getLength() < 5) { changeZoom = gFalse; } else { 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(); } // Fit link } else if (obj1.isName("Fit")) { 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 is too short"); goto err2; } kind = destFitH; if (!a->get(2, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } top = obj2.getNum(); obj2.free(); // FitV link } else if (obj1.isName("FitV")) { if (a->getLength() < 3) { error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitV; if (!a->get(2, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } left = obj2.getNum(); obj2.free(); // FitR link } else if (obj1.isName("FitR")) { if (a->getLength() < 6) { error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitR; if (!a->get(2, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } left = obj2.getNum(); obj2.free(); if (!a->get(3, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } bottom = obj2.getNum(); obj2.free(); if (!a->get(4, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } right = obj2.getNum(); obj2.free(); if (!a->get(5, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } top = obj2.getNum(); obj2.free(); // FitB link } else if (obj1.isName("FitB")) { 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 is too short"); goto err2; } kind = destFitBH; if (!a->get(2, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } top = obj2.getNum(); obj2.free(); // FitBV link } else if (obj1.isName("FitBV")) { if (a->getLength() < 3) { error(-1, "Annotation destination array is too short"); goto err2; } kind = destFitBV; if (!a->get(2, &obj2)->isNum()) { error(-1, "Bad annotation destination position"); kind = destFit; } left = obj2.getNum(); obj2.free(); // unknown link kind } else { error(-1, "Unknown annotation destination type"); goto err2; } obj1.free(); ok = gTrue; return; err1: obj2.free(); err2: obj1.free();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -