upgrade to xpdf 3.00.
[swftools.git] / pdf2swf / xpdf / Outline.cc
blob04891f3c309e7ea06b2f311989e4d78c504a05e7
1 //========================================================================
2 //
3 // Outline.cc
4 //
5 // Copyright 2002-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
9 #include <aconf.h>
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
15 #include "gmem.h"
16 #include "GString.h"
17 #include "GList.h"
18 #include "Link.h"
19 #include "PDFDocEncoding.h"
20 #include "Outline.h"
22 //------------------------------------------------------------------------
24 Outline::Outline(Object *outlineObj, XRef *xref) {
25 Object first, last;
27 items = NULL;
28 if (!outlineObj->isDict()) {
29 return;
31 items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
32 outlineObj->dictLookupNF("Last", &last),
33 xref);
34 first.free();
35 last.free();
38 Outline::~Outline() {
39 if (items) {
40 deleteGList(items, OutlineItem);
44 //------------------------------------------------------------------------
46 OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
47 Object obj1;
48 GString *s;
49 int i;
51 xref = xrefA;
52 title = NULL;
53 action = NULL;
54 kids = NULL;
56 if (dict->lookup("Title", &obj1)->isString()) {
57 s = obj1.getString();
58 if ((s->getChar(0) & 0xff) == 0xfe &&
59 (s->getChar(1) & 0xff) == 0xff) {
60 titleLen = (s->getLength() - 2) / 2;
61 title = (Unicode *)gmalloc(titleLen * sizeof(Unicode));
62 for (i = 0; i < titleLen; ++i) {
63 title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
64 (s->getChar(3 + 2*i) & 0xff);
66 } else {
67 titleLen = s->getLength();
68 title = (Unicode *)gmalloc(titleLen * sizeof(Unicode));
69 for (i = 0; i < titleLen; ++i) {
70 title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
73 } else {
74 titleLen = 0;
76 obj1.free();
78 if (!dict->lookup("Dest", &obj1)->isNull()) {
79 action = LinkAction::parseDest(&obj1);
80 } else {
81 obj1.free();
82 if (dict->lookup("A", &obj1)) {
83 action = LinkAction::parseAction(&obj1);
86 obj1.free();
88 dict->lookupNF("First", &firstRef);
89 dict->lookupNF("Last", &lastRef);
90 dict->lookupNF("Next", &nextRef);
92 startsOpen = gFalse;
93 if (dict->lookup("Count", &obj1)->isInt()) {
94 if (obj1.getInt() > 0) {
95 startsOpen = gTrue;
98 obj1.free();
101 OutlineItem::~OutlineItem() {
102 close();
103 if (title) {
104 gfree(title);
106 if (action) {
107 delete action;
109 firstRef.free();
110 lastRef.free();
111 nextRef.free();
114 GList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
115 XRef *xrefA) {
116 GList *items;
117 OutlineItem *item;
118 Object obj;
119 Object *p;
121 items = new GList();
122 p = firstItemRef;
123 while (p->isRef()) {
124 if (!p->fetch(xrefA, &obj)->isDict()) {
125 obj.free();
126 break;
128 item = new OutlineItem(obj.getDict(), xrefA);
129 obj.free();
130 items->append(item);
131 if (p->getRef().num == lastItemRef->getRef().num &&
132 p->getRef().gen == lastItemRef->getRef().gen) {
133 break;
135 p = &item->nextRef;
137 return items;
140 void OutlineItem::open() {
141 if (!kids) {
142 kids = readItemList(&firstRef, &lastRef, xref);
146 void OutlineItem::close() {
147 if (kids) {
148 deleteGList(kids, OutlineItem);
149 kids = NULL;