diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-0.24.1/poppler/Outline.cc')
-rw-r--r-- | Build/source/libs/poppler/poppler-0.24.1/poppler/Outline.cc | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/Build/source/libs/poppler/poppler-0.24.1/poppler/Outline.cc b/Build/source/libs/poppler/poppler-0.24.1/poppler/Outline.cc new file mode 100644 index 00000000000..bd4e6d01b6d --- /dev/null +++ b/Build/source/libs/poppler/poppler-0.24.1/poppler/Outline.cc @@ -0,0 +1,188 @@ +//======================================================================== +// +// Outline.cc +// +// Copyright 2002-2003 Glyph & Cog, LLC +// +//======================================================================== + +//======================================================================== +// +// Modified under the Poppler project - http://poppler.freedesktop.org +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com> +// Copyright (C) 2008 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2009 Nick Jones <nick.jones@network-box.com> +// +// To see a description of the changes please see the Changelog file that +// came with your tarball or type make ChangeLog if you are building from git +// +//======================================================================== + +#include <config.h> + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "goo/gmem.h" +#include "goo/GooString.h" +#include "goo/GooList.h" +#include "XRef.h" +#include "Link.h" +#include "PDFDocEncoding.h" +#include "Outline.h" + +//------------------------------------------------------------------------ + +Outline::Outline(Object *outlineObj, XRef *xref) { + Object first, last; + + items = NULL; + if (!outlineObj->isDict()) { + return; + } + items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first), + outlineObj->dictLookupNF("Last", &last), + xref); + first.free(); + last.free(); +} + +Outline::~Outline() { + if (items) { + deleteGooList(items, OutlineItem); + } +} + +//------------------------------------------------------------------------ + +OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) { + Object obj1; + GooString *s; + int i; + + xref = xrefA; + title = NULL; + action = NULL; + kids = NULL; + + if (dict->lookup("Title", &obj1)->isString()) { + s = obj1.getString(); + if ((s->getChar(0) & 0xff) == 0xfe && + (s->getChar(1) & 0xff) == 0xff) { + titleLen = (s->getLength() - 2) / 2; + title = (Unicode *)gmallocn(titleLen, sizeof(Unicode)); + for (i = 0; i < titleLen; ++i) { + title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) | + (s->getChar(3 + 2*i) & 0xff); + } + } else { + titleLen = s->getLength(); + title = (Unicode *)gmallocn(titleLen, sizeof(Unicode)); + for (i = 0; i < titleLen; ++i) { + title[i] = pdfDocEncoding[s->getChar(i) & 0xff]; + } + } + } else { + titleLen = 0; + } + 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(); + + 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(); +} + +OutlineItem::~OutlineItem() { + close(); + if (title) { + gfree(title); + } + if (action) { + delete action; + } + firstRef.free(); + lastRef.free(); + nextRef.free(); +} + +GooList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef, + XRef *xrefA) { + GooList *items; + char* alreadyRead; + OutlineItem *item; + Object obj; + Object *p; + + if (!lastItemRef->isRef()) + return NULL; + + items = new GooList(); + + alreadyRead = (char *)gmalloc(xrefA->getNumObjects()); + memset(alreadyRead, 0, xrefA->getNumObjects()); + + p = firstItemRef; + while (p->isRef() && + (p->getRefNum() >= 0) && + (p->getRefNum() < xrefA->getNumObjects()) && + !alreadyRead[p->getRefNum()]) { + if (!p->fetch(xrefA, &obj)->isDict()) { + obj.free(); + break; + } + alreadyRead[p->getRefNum()] = 1; + item = new OutlineItem(obj.getDict(), xrefA); + obj.free(); + items->append(item); + if (p->getRef().num == lastItemRef->getRef().num && + p->getRef().gen == lastItemRef->getRef().gen) { + break; + } + p = &item->nextRef; + } + + gfree(alreadyRead); + + if (!items->getLength()) { + delete items; + items = NULL; + } + + return items; +} + +void OutlineItem::open() { + if (!kids) { + kids = readItemList(&firstRef, &lastRef, xref); + } +} + +void OutlineItem::close() { + if (kids) { + deleteGooList(kids, OutlineItem); + kids = NULL; + } +} |