]> git.ipfire.org Git - thirdparty/cups.git/blame - pdftops/Outline.cxx
Merge changes from CUPS 1.4svn-r7199.
[thirdparty/cups.git] / pdftops / Outline.cxx
CommitLineData
ef416fc2 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 "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, 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
38Outline::~Outline() {
39 if (items) {
40 deleteGList(items, OutlineItem);
41 }
42}
43
44//------------------------------------------------------------------------
45
46OutlineItem::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
101OutlineItem::~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
114GList *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
140void OutlineItem::open() {
141 if (!kids) {
142 kids = readItemList(&firstRef, &lastRef, xref);
143 }
144}
145
146void OutlineItem::close() {
147 if (kids) {
148 deleteGList(kids, OutlineItem);
149 kids = NULL;
150 }
151}