summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
committerKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
commitad547a6b5986815fda458221149728d9d9ab1d87 (patch)
tree16296910eb3eca724371474ea9aea3994dc69614 /Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
parent947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff)
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc186
1 files changed, 186 insertions, 0 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
new file mode 100644
index 00000000000..9593956f8d0
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
@@ -0,0 +1,186 @@
+//========================================================================
+//
+// Outline.cc
+//
+// Copyright 2002-2013 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "gmempp.h"
+#include "GString.h"
+#include "GList.h"
+#include "Error.h"
+#include "Link.h"
+#include "TextString.h"
+#include "Outline.h"
+
+//------------------------------------------------------------------------
+
+Outline::Outline(Object *outlineObj, XRef *xref) {
+ Object first, last;
+
+ items = NULL;
+ if (!outlineObj->isDict()) {
+ return;
+ }
+ outlineObj->dictLookupNF("First", &first);
+ outlineObj->dictLookupNF("Last", &last);
+ if (first.isRef() && last.isRef()) {
+ items = OutlineItem::readItemList(&first, &last, NULL, xref);
+ }
+ first.free();
+ last.free();
+}
+
+Outline::~Outline() {
+ if (items) {
+ deleteGList(items, OutlineItem);
+ }
+}
+
+//------------------------------------------------------------------------
+
+OutlineItem::OutlineItem(Object *itemRefA, Dict *dict,
+ OutlineItem *parentA, XRef *xrefA) {
+ Object obj1;
+
+ xref = xrefA;
+ title = NULL;
+ action = NULL;
+ kids = NULL;
+ parent = parentA;
+
+ if (dict->lookup("Title", &obj1)->isString()) {
+ title = new TextString(obj1.getString());
+ }
+ obj1.free();
+
+ if (!dict->lookup("Dest", &obj1)->isNull()) {
+ action = LinkAction::parseDest(&obj1);
+ } else {
+ obj1.free();
+ if (!dict->lookup("A", &obj1)->isNull()) {
+ action = LinkAction::parseAction(&obj1);
+ }
+ }
+ obj1.free();
+
+ itemRefA->copy(&itemRef);
+ dict->lookupNF("First", &firstRef);
+ dict->lookupNF("Last", &lastRef);
+ dict->lookupNF("Next", &nextRef);
+
+ startsOpen = gFalse;
+ if (dict->lookup("Count", &obj1)->isInt()) {
+ if (obj1.getInt() > 0) {
+ startsOpen = gTrue;
+ }
+ }
+ obj1.free();
+
+ pageNum = -1;
+}
+
+OutlineItem::~OutlineItem() {
+ close();
+ if (title) {
+ delete title;
+ }
+ if (action) {
+ delete action;
+ }
+ itemRef.free();
+ firstRef.free();
+ lastRef.free();
+ nextRef.free();
+}
+
+GList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
+ OutlineItem *parentA, XRef *xrefA) {
+ GList *items;
+ OutlineItem *item, *sibling;
+ Object obj;
+ Object *p;
+ OutlineItem *ancestor;
+ int i;
+
+ items = new GList();
+ if (!firstItemRef->isRef() || !lastItemRef->isRef()) {
+ return items;
+ }
+ p = firstItemRef;
+ do {
+ if (!p->fetch(xrefA, &obj)->isDict()) {
+ obj.free();
+ break;
+ }
+ item = new OutlineItem(p, obj.getDict(), parentA, xrefA);
+ obj.free();
+
+ // check for loops with parents
+ for (ancestor = parentA; ancestor; ancestor = ancestor->parent) {
+ if (p->getRefNum() == ancestor->itemRef.getRefNum() &&
+ p->getRefGen() == ancestor->itemRef.getRefGen()) {
+ error(errSyntaxError, -1, "Loop detected in outline");
+ break;
+ }
+ }
+ if (ancestor) {
+ delete item;
+ break;
+ }
+
+ // check for loops with siblings
+ for (i = 0; i < items->getLength(); ++i) {
+ sibling = (OutlineItem *)items->get(i);
+ if (p->getRefNum() == sibling->itemRef.getRefNum() &&
+ p->getRefGen() == sibling->itemRef.getRefGen()) {
+ error(errSyntaxError, -1, "Loop detected in outline");
+ break;
+ }
+ }
+ if (i < items->getLength()) {
+ delete item;
+ break;
+ }
+
+ items->append(item);
+ if (p->getRefNum() == lastItemRef->getRef().num &&
+ p->getRefGen() == lastItemRef->getRef().gen) {
+ break;
+ }
+ p = &item->nextRef;
+ if (!p->isRef()) {
+ break;
+ }
+ } while (p);
+ return items;
+}
+
+void OutlineItem::open() {
+ if (!kids) {
+ kids = readItemList(&firstRef, &lastRef, this, xref);
+ }
+}
+
+void OutlineItem::close() {
+ if (kids) {
+ deleteGList(kids, OutlineItem);
+ kids = NULL;
+ }
+}
+
+Unicode *OutlineItem::getTitle() {
+ return title ? title->getUnicode() : (Unicode *)NULL;
+}
+
+int OutlineItem::getTitleLength() {
+ return title ? title->getLength() : 0;
+}