upgraded to xpdf-3.01pl1
[swftools.git] / pdf2swf / xpdf / Outline.cc
1 //========================================================================
2 //
3 // Outline.cc
4 //
5 // Copyright 2002-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include "gmem.h"
16 #include "GString.h"
17 #include "GList.h"
18 #include "Link.h"
19 #include "PDFDocEncoding.h"
20 #include "Outline.h"
21
22 //------------------------------------------------------------------------
23
24 Outline::Outline(Object *outlineObj, XRef *xref) {
25   Object first, last;
26
27   items = NULL;
28   if (!outlineObj->isDict()) {
29     return;
30   }
31   items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
32                                     outlineObj->dictLookupNF("Last", &last),
33                                     xref);
34   first.free();
35   last.free();
36 }
37
38 Outline::~Outline() {
39   if (items) {
40     deleteGList(items, OutlineItem);
41   }
42 }
43
44 //------------------------------------------------------------------------
45
46 OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
47   Object obj1;
48   GString *s;
49   int i;
50
51   xref = xrefA;
52   title = NULL;
53   action = NULL;
54   kids = NULL;
55
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 *)gmallocn(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);
65       }
66     } else {
67       titleLen = s->getLength();
68       title = (Unicode *)gmallocn(titleLen, sizeof(Unicode));
69       for (i = 0; i < titleLen; ++i) {
70         title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
71       }
72     }
73   } else {
74     titleLen = 0;
75   }
76   obj1.free();
77
78   if (!dict->lookup("Dest", &obj1)->isNull()) {
79     action = LinkAction::parseDest(&obj1);
80   } else {
81     obj1.free();
82     if (!dict->lookup("A", &obj1)->isNull()) {
83       action = LinkAction::parseAction(&obj1);
84     }
85   }
86   obj1.free();
87
88   dict->lookupNF("First", &firstRef);
89   dict->lookupNF("Last", &lastRef);
90   dict->lookupNF("Next", &nextRef);
91
92   startsOpen = gFalse;
93   if (dict->lookup("Count", &obj1)->isInt()) {
94     if (obj1.getInt() > 0) {
95       startsOpen = gTrue;
96     }
97   }
98   obj1.free();
99 }
100
101 OutlineItem::~OutlineItem() {
102   close();
103   if (title) {
104     gfree(title);
105   }
106   if (action) {
107     delete action;
108   }
109   firstRef.free();
110   lastRef.free();
111   nextRef.free();
112 }
113
114 GList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
115                                  XRef *xrefA) {
116   GList *items;
117   OutlineItem *item;
118   Object obj;
119   Object *p;
120
121   items = new GList();
122   p = firstItemRef;
123   while (p->isRef()) {
124     if (!p->fetch(xrefA, &obj)->isDict()) {
125       obj.free();
126       break;
127     }
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;
134     }
135     p = &item->nextRef;
136   }
137   return items;
138 }
139
140 void OutlineItem::open() {
141   if (!kids) {
142     kids = readItemList(&firstRef, &lastRef, xref);
143   }
144 }
145
146 void OutlineItem::close() {
147   if (kids) {
148     deleteGList(kids, OutlineItem);
149     kids = NULL;
150   }
151 }