1 //========================================================================
5 // Copyright 2002-2003 Glyph & Cog, LLC
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
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>
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
23 //========================================================================
27 #ifdef USE_GCC_PRAGMAS
28 #pragma implementation
32 #include "goo/GooString.h"
33 #include "goo/GooList.h"
36 #include "PDFDocEncoding.h"
39 //------------------------------------------------------------------------
41 Outline::Outline(Object
*outlineObj
, XRef
*xref
) {
45 if (!outlineObj
->isDict()) {
48 items
= OutlineItem::readItemList(outlineObj
->dictLookupNF("First", &first
),
49 outlineObj
->dictLookupNF("Last", &last
),
57 deleteGooList(items
, OutlineItem
);
61 //------------------------------------------------------------------------
63 OutlineItem::OutlineItem(Dict
*dict
, XRef
*xrefA
) {
73 if (dict
->lookup("Title", &obj1
)->isString()) {
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);
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];
95 if (!dict
->lookup("Dest", &obj1
)->isNull()) {
96 action
= LinkAction::parseDest(&obj1
);
99 if (!dict
->lookup("A", &obj1
)->isNull()) {
100 action
= LinkAction::parseAction(&obj1
);
105 dict
->lookupNF("First", &firstRef
);
106 dict
->lookupNF("Last", &lastRef
);
107 dict
->lookupNF("Next", &nextRef
);
110 if (dict
->lookup("Count", &obj1
)->isInt()) {
111 if (obj1
.getInt() > 0) {
118 OutlineItem::~OutlineItem() {
131 GooList
*OutlineItem::readItemList(Object
*firstItemRef
, Object
*lastItemRef
,
139 if (!lastItemRef
->isRef())
142 items
= new GooList();
144 alreadyRead
= (char *)gmalloc(xrefA
->getNumObjects());
145 memset(alreadyRead
, 0, xrefA
->getNumObjects());
149 (p
->getRefNum() >= 0) &&
150 (p
->getRefNum() < xrefA
->getNumObjects()) &&
151 !alreadyRead
[p
->getRefNum()]) {
152 if (!p
->fetch(xrefA
, &obj
)->isDict()) {
156 alreadyRead
[p
->getRefNum()] = 1;
157 item
= new OutlineItem(obj
.getDict(), xrefA
);
160 if (p
->getRef().num
== lastItemRef
->getRef().num
&&
161 p
->getRef().gen
== lastItemRef
->getRef().gen
) {
169 if (!items
->getLength()) {
177 void OutlineItem::open() {
179 kids
= readItemList(&firstRef
, &lastRef
, xref
);
183 void OutlineItem::close() {
185 deleteGooList(kids
, OutlineItem
);