Outline.cpp
1//========================================================================
2//
3// Outline.cpp
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
24Outline::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
36Outline::~Outline() {
37 if (items) {
38 deleteGList(items, OutlineItem);
39 }
40}
41
42//------------------------------------------------------------------------
43
44OutlineItem::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
96OutlineItem::~OutlineItem() {
97 close();
98 if (title) {
99 delete title;
100 }
101 if (action) {
102 delete action;
103 }
104 firstRef.free();
105 nextRef.free();
106}
107
108GList *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
129void OutlineItem::open() {
130 if (!kids) {
131 kids = readItemList(&firstRef, xref);
132 }
133}
134
135void OutlineItem::close() {
136 if (kids) {
137 deleteGList(kids, OutlineItem);
138 kids = NULL;
139 }
140}