Change the translation of the "Help" menu item to "?", so that the menu can be displa...
[reactos.git] / rosapps / smartpdf / poppler / poppler / Outline.cc
1 //========================================================================
2 //
3 // Outline.cc
4 //
5 // Copyright 2002-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <config.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include "goo/gmem.h"
16 #include "goo/GooString.h"
17 #include "goo/GooList.h"
18 #include "Link.h"
19 #include "PDFDocEncoding.h"
20 #include "Outline.h"
21 #include "UGooString.h"
22
23 //------------------------------------------------------------------------
24
25 Outline::Outline(Object *outlineObj, XRef *xref) {
26 Object first, last;
27
28 items = NULL;
29 if (!outlineObj->isDict()) {
30 return;
31 }
32 items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
33 outlineObj->dictLookupNF("Last", &last),
34 xref);
35 first.free();
36 last.free();
37 }
38
39 Outline::~Outline() {
40 if (items) {
41 deleteGooList(items, OutlineItem);
42 }
43 }
44
45 //------------------------------------------------------------------------
46
47 OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
48 Object obj1;
49 GooString *s;
50 int i;
51
52 xref = xrefA;
53 title = NULL;
54 action = NULL;
55 kids = NULL;
56
57 if (dict->lookup("Title", &obj1)->isString()) {
58 s = obj1.getString();
59 if ((s->getChar(0) & 0xff) == 0xfe &&
60 (s->getChar(1) & 0xff) == 0xff) {
61 titleLen = (s->getLength() - 2) / 2;
62 title = (Unicode *)gmallocn(titleLen, sizeof(Unicode));
63 for (i = 0; i < titleLen; ++i) {
64 title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
65 (s->getChar(3 + 2*i) & 0xff);
66 }
67 } else {
68 titleLen = s->getLength();
69 title = (Unicode *)gmallocn(titleLen, sizeof(Unicode));
70 for (i = 0; i < titleLen; ++i) {
71 title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
72 }
73 }
74 } else {
75 titleLen = 0;
76 }
77 obj1.free();
78
79 if (!dict->lookup("Dest", &obj1)->isNull()) {
80 action = LinkAction::parseDest(&obj1);
81 } else {
82 obj1.free();
83 if (!dict->lookup("A", &obj1)->isNull()) {
84 action = LinkAction::parseAction(&obj1);
85 }
86 }
87 obj1.free();
88
89 dict->lookupNF("First", &firstRef);
90 dict->lookupNF("Last", &lastRef);
91 dict->lookupNF("Next", &nextRef);
92
93 startsOpen = gFalse;
94 if (dict->lookup("Count", &obj1)->isInt()) {
95 if (obj1.getInt() > 0) {
96 startsOpen = gTrue;
97 }
98 }
99 obj1.free();
100 }
101
102 OutlineItem::~OutlineItem() {
103 close();
104 if (title) {
105 gfree(title);
106 }
107 if (action) {
108 delete action;
109 }
110 firstRef.free();
111 lastRef.free();
112 nextRef.free();
113 }
114
115 GooList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
116 XRef *xrefA) {
117 GooList *items;
118 OutlineItem *item;
119 Object obj;
120 Object *p;
121
122 items = new GooList();
123 p = firstItemRef;
124 while (p->isRef()) {
125 if (!p->fetch(xrefA, &obj)->isDict()) {
126 obj.free();
127 break;
128 }
129 item = new OutlineItem(obj.getDict(), xrefA);
130 obj.free();
131 items->append(item);
132 if (p->getRef().num == lastItemRef->getRef().num &&
133 p->getRef().gen == lastItemRef->getRef().gen) {
134 break;
135 }
136 p = &item->nextRef;
137 }
138
139 if (!items->getLength()) {
140 delete items;
141 items = NULL;
142 }
143
144 return items;
145 }
146
147 void OutlineItem::open() {
148 if (!kids) {
149 kids = readItemList(&firstRef, &lastRef, xref);
150 }
151 }
152
153 void OutlineItem::close() {
154 if (kids) {
155 deleteGooList(kids, OutlineItem);
156 kids = NULL;
157 }
158 }