]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/Outline.cc
Import of Xpdf 2.01 for merge
[evince.git] / pdf / xpdf / Outline.cc
1 //========================================================================
2 //
3 // Outline.cc
4 //
5 // Copyright 2002 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;
26
27   items = NULL;
28   if (!outlineObj->isDict()) {
29     return;
30   }
31   items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
32                                     xref);
33   first.free();
34 }
35
36 Outline::~Outline() {
37   if (items) {
38     deleteGList(items, OutlineItem);
39   }
40 }
41
42 //------------------------------------------------------------------------
43
44 OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
45   Object obj1;
46   GString *s;
47   int i;
48
49   xref = xrefA;
50   title = NULL;
51   action = NULL;
52   kids = NULL;
53
54   if (dict->lookup("Title", &obj1)->isString()) {
55     s = obj1.getString();
56     if ((s->getChar(0) & 0xff) == 0xfe &&
57         (s->getChar(1) & 0xff) == 0xff) {
58       titleLen = (s->getLength() - 2) / 2;
59       title = (Unicode *)gmalloc(titleLen * sizeof(Unicode));
60       for (i = 0; i < titleLen; ++i) {
61         title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
62                    (s->getChar(3 + 2*i) & 0xff);
63       }
64     } else {
65       titleLen = s->getLength();
66       title = (Unicode *)gmalloc(titleLen * sizeof(Unicode));
67       for (i = 0; i < titleLen; ++i) {
68         title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
69       }
70     }
71   }
72   obj1.free();
73
74   if (!dict->lookup("Dest", &obj1)->isNull()) {
75     action = LinkAction::parseDest(&obj1);
76   } else {
77     obj1.free();
78     if (dict->lookup("A", &obj1)) {
79       action = LinkAction::parseAction(&obj1);
80     }
81   }
82   obj1.free();
83
84   dict->lookupNF("First", &firstRef);
85   dict->lookupNF("Next", &nextRef);
86
87   startsOpen = gFalse;
88   if (dict->lookup("Count", &obj1)->isInt()) {
89     if (obj1.getInt() > 0) {
90       startsOpen = gTrue;
91     }
92   }
93   obj1.free();
94 }
95
96 OutlineItem::~OutlineItem() {
97   close();
98   if (title) {
99     gfree(title);
100   }
101   if (action) {
102     delete action;
103   }
104   firstRef.free();
105   nextRef.free();
106 }
107
108 GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
109   GList *items;
110   OutlineItem *item;
111   Object obj;
112   Object *p;
113
114   items = new GList();
115   p = itemRef;
116   while (p->isRef()) {
117     if (!p->fetch(xrefA, &obj)->isDict()) {
118       obj.free();
119       break;
120     }
121     item = new OutlineItem(obj.getDict(), xrefA);
122     obj.free();
123     items->append(item);
124     p = &item->nextRef;
125   }
126   return items;
127 }
128
129 void OutlineItem::open() {
130   if (!kids) {
131     kids = readItemList(&firstRef, xref);
132   }
133 }
134
135 void OutlineItem::close() {
136   if (kids) {
137     deleteGList(kids, OutlineItem);
138     kids = NULL;
139   }
140 }