source: trunk/poppler/mypoppler/poppler/Outline.cc @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 3.3 KB
Line 
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
25Outline::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
39Outline::~Outline() {
40  if (items) {
41    deleteGooList(items, OutlineItem);
42  }
43}
44
45//------------------------------------------------------------------------
46
47OutlineItem::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
102OutlineItem::~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
115GooList *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
147void OutlineItem::open() {
148  if (!kids) {
149    kids = readItemList(&firstRef, &lastRef, xref);
150  }
151}
152
153void OutlineItem::close() {
154  if (kids) {
155    deleteGooList(kids, OutlineItem);
156    kids = NULL;
157  }
158}
Note: See TracBrowser for help on using the repository browser.