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

Last change on this file since 461 was 271, checked in by Eugene Romanenko, 13 years ago

PDF plugin: Poppler library updated to version 0.10.5

File size: 4.3 KB
Line 
1//========================================================================
2//
3// Outline.cc
4//
5// Copyright 2002-2003 Glyph & Cog, LLC
6//
7//========================================================================
8
9//========================================================================
10//
11// Modified under the Poppler project - http://poppler.freedesktop.org
12//
13// All changes made under the Poppler project to this file are licensed
14// under GPL version 2 or later
15//
16// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
17// Copyright (C) 2008 Albert Astals Cid <aacid@kde.org>
18// Copyright (C) 2009 Nick Jones <nick.jones@network-box.com>
19//
20// To see a description of the changes please see the Changelog file that
21// came with your tarball or type make ChangeLog if you are building from git
22//
23//========================================================================
24
25#include <config.h>
26
27#ifdef USE_GCC_PRAGMAS
28#pragma implementation
29#endif
30
31#include "goo/gmem.h"
32#include "goo/GooString.h"
33#include "goo/GooList.h"
34#include "XRef.h"
35#include "Link.h"
36#include "PDFDocEncoding.h"
37#include "Outline.h"
38
39//------------------------------------------------------------------------
40
41Outline::Outline(Object *outlineObj, XRef *xref) {
42  Object first, last;
43
44  items = NULL;
45  if (!outlineObj->isDict()) {
46    return;
47  }
48  items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
49                                    outlineObj->dictLookupNF("Last", &last),
50                                    xref);
51  first.free();
52  last.free();
53}
54
55Outline::~Outline() {
56  if (items) {
57    deleteGooList(items, OutlineItem);
58  }
59}
60
61//------------------------------------------------------------------------
62
63OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
64  Object obj1;
65  GooString *s;
66  int i;
67
68  xref = xrefA;
69  title = NULL;
70  action = NULL;
71  kids = NULL;
72
73  if (dict->lookup("Title", &obj1)->isString()) {
74    s = obj1.getString();
75    if ((s->getChar(0) & 0xff) == 0xfe &&
76        (s->getChar(1) & 0xff) == 0xff) {
77      titleLen = (s->getLength() - 2) / 2;
78      title = (Unicode *)gmallocn(titleLen, sizeof(Unicode));
79      for (i = 0; i < titleLen; ++i) {
80        title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
81                   (s->getChar(3 + 2*i) & 0xff);
82      }
83    } else {
84      titleLen = s->getLength();
85      title = (Unicode *)gmallocn(titleLen, sizeof(Unicode));
86      for (i = 0; i < titleLen; ++i) {
87        title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
88      }
89    }
90  } else {
91    titleLen = 0;
92  }
93  obj1.free();
94
95  if (!dict->lookup("Dest", &obj1)->isNull()) {
96    action = LinkAction::parseDest(&obj1);
97  } else {
98      obj1.free();
99    if (!dict->lookup("A", &obj1)->isNull()) {
100        action = LinkAction::parseAction(&obj1);
101  }
102  }
103  obj1.free();
104
105  dict->lookupNF("First", &firstRef);
106  dict->lookupNF("Last", &lastRef);
107  dict->lookupNF("Next", &nextRef);
108
109  startsOpen = gFalse;
110  if (dict->lookup("Count", &obj1)->isInt()) {
111    if (obj1.getInt() > 0) {
112      startsOpen = gTrue;
113    }
114  }
115  obj1.free();
116}
117
118OutlineItem::~OutlineItem() {
119  close();
120  if (title) {
121    gfree(title);
122  }
123  if (action) {
124    delete action;
125  }
126  firstRef.free();
127  lastRef.free();
128  nextRef.free();
129}
130
131GooList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
132                                 XRef *xrefA) {
133  GooList *items;
134  char* alreadyRead;
135  OutlineItem *item;
136  Object obj;
137  Object *p;
138
139  if (!lastItemRef->isRef())
140    return NULL;
141
142  items = new GooList();
143
144  alreadyRead = (char *)gmalloc(xrefA->getNumObjects());
145  memset(alreadyRead, 0, xrefA->getNumObjects());
146
147  p = firstItemRef;
148  while (p->isRef() && 
149         (p->getRefNum() >= 0) && 
150         (p->getRefNum() < xrefA->getNumObjects()) && 
151         !alreadyRead[p->getRefNum()]) {
152    if (!p->fetch(xrefA, &obj)->isDict()) {
153      obj.free();
154      break;
155    }
156    alreadyRead[p->getRefNum()] = 1;
157    item = new OutlineItem(obj.getDict(), xrefA);
158    obj.free();
159    items->append(item);
160    if (p->getRef().num == lastItemRef->getRef().num &&
161        p->getRef().gen == lastItemRef->getRef().gen) {
162      break;
163    }
164    p = &item->nextRef;
165  }
166
167  gfree(alreadyRead);
168
169  if (!items->getLength()) {
170    delete items;
171    items = NULL;
172  }
173
174  return items;
175}
176
177void OutlineItem::open() {
178  if (!kids) {
179    kids = readItemList(&firstRef, &lastRef, xref);
180  }
181}
182
183void OutlineItem::close() {
184  if (kids) {
185    deleteGooList(kids, OutlineItem);
186    kids = NULL;
187  }
188}
Note: See TracBrowser for help on using the repository browser.