29LinkAction *LinkAction::parseDest(Object *obj) {
32 action =
new LinkGoTo(obj);
33 if (!action->isOk()) {
40LinkAction *LinkAction::parseAction(Object *obj, GString *baseURI) {
42 Object obj2, obj3, obj4;
45 error(-1,
"Bad annotation action");
49 obj->dictLookup(
"S", &obj2);
52 if (obj2.isName(
"GoTo")) {
53 obj->dictLookup(
"D", &obj3);
54 action =
new LinkGoTo(&obj3);
58 }
else if (obj2.isName(
"GoToR")) {
59 obj->dictLookup(
"F", &obj3);
60 obj->dictLookup(
"D", &obj4);
61 action =
new LinkGoToR(&obj3, &obj4);
66 }
else if (obj2.isName(
"Launch")) {
67 action =
new LinkLaunch(obj);
70 }
else if (obj2.isName(
"URI")) {
71 obj->dictLookup(
"URI", &obj3);
72 action =
new LinkURI(&obj3, baseURI);
76 }
else if (obj2.isName(
"Named")) {
77 obj->dictLookup(
"N", &obj3);
78 action =
new LinkNamed(&obj3);
82 }
else if (obj2.isName(
"Movie")) {
83 obj->dictLookupNF(
"Annot", &obj3);
84 obj->dictLookup(
"T", &obj4);
85 action =
new LinkMovie(&obj3, &obj4);
90 }
else if (obj2.isName()) {
91 action =
new LinkUnknown(obj2.getName());
95 error(-1,
"Bad annotation action");
101 if (action && !action->isOk()) {
108GString *LinkAction::getFileSpecName(Object *fileSpecObj) {
115 if (fileSpecObj->isString()) {
116 name = fileSpecObj->getString()->copy();
119 }
else if (fileSpecObj->isDict()) {
120 if (!fileSpecObj->dictLookup(
"Unix", &obj1)->isString()) {
122 fileSpecObj->dictLookup(
"F", &obj1);
125 name = obj1.getString()->copy();
127 error(-1,
"Illegal file spec in link");
132 error(-1,
"Illegal file spec in link");
142LinkDest::LinkDest(Array *a) {
146 left = bottom = right = top = zoom = 0;
150 if (a->getLength() < 2) {
151 error(-1,
"Annotation destination array has wrong length");
156 pageNum = obj1.getInt() + 1;
158 }
else if (obj1.isRef()) {
159 pageRef.num = obj1.getRefNum();
160 pageRef.gen = obj1.getRefGen();
163 error(-1,
"Bad annotation destination");
172 if (obj1.isName(
"XYZ")) {
173 if (a->getLength() != 5) {
174 error(-1,
"Annotation destination array has wrong length");
181 }
else if (obj2.isNum()) {
183 left = obj2.getNum();
185 error(-1,
"Bad annotation destination position");
192 }
else if (obj2.isNum()) {
196 error(-1,
"Bad annotation destination position");
203 }
else if (obj2.isNum()) {
205 zoom = obj2.getNum();
207 error(-1,
"Bad annotation destination position");
213 }
else if (obj1.isName(
"Fit")) {
214 if (a->getLength() != 2) {
215 error(-1,
"Annotation destination array has wrong length");
221 }
else if (obj1.isName(
"FitH")) {
222 if (a->getLength() != 3) {
223 error(-1,
"Annotation destination array has wrong length");
227 if (!a->get(2, &obj2)->isNum()) {
228 error(-1,
"Bad annotation destination position");
235 }
else if (obj1.isName(
"FitV")) {
236 if (a->getLength() != 3) {
237 error(-1,
"Annotation destination array has wrong length");
241 if (!a->get(2, &obj2)->isNum()) {
242 error(-1,
"Bad annotation destination position");
245 left = obj2.getNum();
249 }
else if (obj1.isName(
"FitR")) {
250 if (a->getLength() != 6) {
251 error(-1,
"Annotation destination array has wrong length");
255 if (!a->get(2, &obj2)->isNum()) {
256 error(-1,
"Bad annotation destination position");
259 left = obj2.getNum();
261 if (!a->get(3, &obj2)->isNum()) {
262 error(-1,
"Bad annotation destination position");
265 bottom = obj2.getNum();
267 if (!a->get(4, &obj2)->isNum()) {
268 error(-1,
"Bad annotation destination position");
271 right = obj2.getNum();
273 if (!a->get(5, &obj2)->isNum()) {
274 error(-1,
"Bad annotation destination position");
281 }
else if (obj1.isName(
"FitB")) {
282 if (a->getLength() != 2) {
283 error(-1,
"Annotation destination array has wrong length");
289 }
else if (obj1.isName(
"FitBH")) {
290 if (a->getLength() != 3) {
291 error(-1,
"Annotation destination array has wrong length");
295 if (!a->get(2, &obj2)->isNum()) {
296 error(-1,
"Bad annotation destination position");
303 }
else if (obj1.isName(
"FitBV")) {
304 if (a->getLength() != 3) {
305 error(-1,
"Annotation destination array has wrong length");
309 if (!a->get(2, &obj2)->isNum()) {
310 error(-1,
"Bad annotation destination position");
313 left = obj2.getNum();
318 error(-1,
"Unknown annotation destination type");
332LinkDest::LinkDest(LinkDest *dest) {
334 pageIsRef = dest->pageIsRef;
336 pageRef = dest->pageRef;
338 pageNum = dest->pageNum;
340 bottom = dest->bottom;
344 changeLeft = dest->changeLeft;
345 changeTop = dest->changeTop;
346 changeZoom = dest->changeZoom;
354LinkGoTo::LinkGoTo(Object *destObj) {
359 if (destObj->isName()) {
360 namedDest =
new GString(destObj->getName());
361 }
else if (destObj->isString()) {
362 namedDest = destObj->getString()->copy();
365 }
else if (destObj->isArray()) {
366 dest =
new LinkDest(destObj->getArray());
374 error(-1,
"Illegal annotation destination");
378LinkGoTo::~LinkGoTo() {
389LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
394 fileName = getFileSpecName(fileSpecObj);
397 if (destObj->isName()) {
398 namedDest =
new GString(destObj->getName());
399 }
else if (destObj->isString()) {
400 namedDest = destObj->getString()->copy();
403 }
else if (destObj->isArray()) {
404 dest =
new LinkDest(destObj->getArray());
412 error(-1,
"Illegal annotation destination");
416LinkGoToR::~LinkGoToR() {
430LinkLaunch::LinkLaunch(Object *actionObj) {
436 if (actionObj->isDict()) {
437 if (!actionObj->dictLookup(
"F", &obj1)->isNull()) {
438 fileName = getFileSpecName(&obj1);
442 if (actionObj->dictLookup(
"Win", &obj1)->isDict()) {
443 obj1.dictLookup(
"F", &obj2);
444 fileName = getFileSpecName(&obj2);
446 if (obj1.dictLookup(
"P", &obj2)->isString()) {
447 params = obj2.getString()->copy();
451 error(-1,
"Bad launch-type link action");
456 if (actionObj->dictLookup(
"Unix", &obj1)->isDict()) {
457 obj1.dictLookup(
"F", &obj2);
458 fileName = getFileSpecName(&obj2);
460 if (obj1.dictLookup(
"P", &obj2)->isString()) {
461 params = obj2.getString()->copy();
465 error(-1,
"Bad launch-type link action");
473LinkLaunch::~LinkLaunch() {
484LinkURI::LinkURI(Object *uriObj, GString *baseURI) {
490 if (uriObj->isString()) {
491 uri2 = uriObj->getString()->copy();
493 n = strcspn(uri2->getCString(),
"/:");
494 if (n == uri2->getLength() || uri2->getChar(n) ==
'/') {
495 uri = baseURI->copy();
496 c = uri->getChar(uri->getLength() - 1);
497 if (c ==
'/' || c ==
'?') {
498 if (uri2->getChar(0) ==
'/') {
502 if (uri2->getChar(0) !=
'/') {
515 error(-1,
"Illegal URI-type link");
528LinkNamed::LinkNamed(Object *nameObj) {
530 if (nameObj->isName()) {
531 name =
new GString(nameObj->getName());
535LinkNamed::~LinkNamed() {
545LinkMovie::LinkMovie(Object *annotObj, Object *titleObj) {
548 if (annotObj->isRef()) {
549 annotRef = annotObj->getRef();
550 }
else if (titleObj->isString()) {
551 title = titleObj->getString()->copy();
553 error(-1,
"Movie action is missing both the Annot and T keys");
557LinkMovie::~LinkMovie() {
567LinkUnknown::LinkUnknown(
char *actionA) {
568 action =
new GString(actionA);
571LinkUnknown::~LinkUnknown() {
579Link::Link(Dict *dict, GString *baseURI) {
587 if (!dict->lookup(
"Rect", &obj1)->isArray()) {
588 error(-1,
"Annotation rectangle is wrong type");
591 if (!obj1.arrayGet(0, &obj2)->isNum()) {
592 error(-1,
"Bad annotation rectangle");
597 if (!obj1.arrayGet(1, &obj2)->isNum()) {
598 error(-1,
"Bad annotation rectangle");
603 if (!obj1.arrayGet(2, &obj2)->isNum()) {
604 error(-1,
"Bad annotation rectangle");
609 if (!obj1.arrayGet(3, &obj2)->isNum()) {
610 error(-1,
"Bad annotation rectangle");
629 if (!dict->lookup(
"Border", &obj1)->isNull()) {
630 if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
631 if (obj1.arrayGet(2, &obj2)->isNum()) {
632 borderW = obj2.getNum();
634 error(-1,
"Bad annotation border");
642 if (!dict->lookup(
"Dest", &obj1)->isNull()) {
643 action = LinkAction::parseDest(&obj1);
648 if (dict->lookup(
"A", &obj1)->isDict()) {
649 action = LinkAction::parseAction(&obj1, baseURI);
676Links::Links(Object *annots, GString *baseURI) {
686 if (annots->isArray()) {
687 for (i = 0; i < annots->arrayGetLength(); ++i) {
688 if (annots->arrayGet(i, &obj1)->isDict()) {
689 if (obj1.dictLookup(
"Subtype", &obj2)->isName(
"Link")) {
690 link =
new Link(obj1.getDict(), baseURI);
692 if (numLinks >= size) {
694 links = (Link **)grealloc(links, size *
sizeof(Link *));
696 links[numLinks++] = link;
711 for (i = 0; i < numLinks; ++i)
716LinkAction *Links::find(
double x,
double y) {
719 for (i = numLinks - 1; i >= 0; --i) {
720 if (links[i]->inRect(x, y)) {
721 return links[i]->getAction();
727GBool Links::onLink(
double x,
double y) {
730 for (i = 0; i < numLinks; ++i) {
731 if (links[i]->inRect(x, y))