]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/Outline.cc
add a FIXME. We should probably not allocate a bookmark object every time
[evince.git] / pdf / xpdf / Outline.cc
index 256d38d4ba7ca62988f71a2cb14cb9c0baafce64..b7e064586a6e9b7d49db6fa7253c54fbd74aabfb 100644 (file)
@@ -2,7 +2,7 @@
 //
 // Outline.cc
 //
-// Copyright 2002 Glyph & Cog, LLC
+// Copyright 2002-2003 Glyph & Cog, LLC
 //
 //========================================================================
 
 //------------------------------------------------------------------------
 
 Outline::Outline(Object *outlineObj, XRef *xref) {
-  Object first;
+  Object first, last;
 
   items = NULL;
   if (!outlineObj->isDict()) {
     return;
   }
   items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
+                                   outlineObj->dictLookupNF("Last", &last),
                                    xref);
   first.free();
+  last.free();
 }
 
 Outline::~Outline() {
@@ -42,7 +44,7 @@ Outline::~Outline() {
 //------------------------------------------------------------------------
 
 OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
-  Object obj1;
+  Object obj1, obj2;
   GString *s;
   int i;
 
@@ -68,20 +70,23 @@ OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
        title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
       }
     }
+  } else {
+    titleLen = 0;
   }
   obj1.free();
 
   if (!dict->lookup("Dest", &obj1)->isNull()) {
     action = LinkAction::parseDest(&obj1);
   } else {
-    obj1.free();
-    if (dict->lookup("A", &obj1)) {
-      action = LinkAction::parseAction(&obj1);
-    }
+      obj1.free();
+      dict->lookup("A", &obj1);
+      if (!obj1.isNull())
+        action = LinkAction::parseAction(&obj1);
   }
   obj1.free();
 
   dict->lookupNF("First", &firstRef);
+  dict->lookupNF("Last", &lastRef);
   dict->lookupNF("Next", &nextRef);
 
   startsOpen = gFalse;
@@ -96,23 +101,25 @@ OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
 OutlineItem::~OutlineItem() {
   close();
   if (title) {
-    delete title;
+    gfree(title);
   }
   if (action) {
     delete action;
   }
   firstRef.free();
+  lastRef.free();
   nextRef.free();
 }
 
-GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
+GList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
+                                XRef *xrefA) {
   GList *items;
   OutlineItem *item;
   Object obj;
   Object *p;
 
   items = new GList();
-  p = itemRef;
+  p = firstItemRef;
   while (p->isRef()) {
     if (!p->fetch(xrefA, &obj)->isDict()) {
       obj.free();
@@ -121,6 +128,10 @@ GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
     item = new OutlineItem(obj.getDict(), xrefA);
     obj.free();
     items->append(item);
+    if (p->getRef().num == lastItemRef->getRef().num &&
+       p->getRef().gen == lastItemRef->getRef().gen) {
+      break;
+    }
     p = &item->nextRef;
   }
   return items;
@@ -128,7 +139,7 @@ GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
 
 void OutlineItem::open() {
   if (!kids) {
-    kids = readItemList(&firstRef, xref);
+    kids = readItemList(&firstRef, &lastRef, xref);
   }
 }