Back to index

tetex-bin  3.0
Outline.cc
Go to the documentation of this file.
00001 //========================================================================
00002 //
00003 // Outline.cc
00004 //
00005 // Copyright 2002-2003 Glyph & Cog, LLC
00006 //
00007 //========================================================================
00008 
00009 #include <aconf.h>
00010 
00011 #ifdef USE_GCC_PRAGMAS
00012 #pragma implementation
00013 #endif
00014 
00015 #include "gmem.h"
00016 #include "GString.h"
00017 #include "GList.h"
00018 #include "Link.h"
00019 #include "PDFDocEncoding.h"
00020 #include "Outline.h"
00021 
00022 //------------------------------------------------------------------------
00023 
00024 Outline::Outline(Object *outlineObj, XRef *xref) {
00025   Object first, last;
00026 
00027   items = NULL;
00028   if (!outlineObj->isDict()) {
00029     return;
00030   }
00031   items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
00032                                 outlineObj->dictLookupNF("Last", &last),
00033                                 xref);
00034   first.free();
00035   last.free();
00036 }
00037 
00038 Outline::~Outline() {
00039   if (items) {
00040     deleteGList(items, OutlineItem);
00041   }
00042 }
00043 
00044 //------------------------------------------------------------------------
00045 
00046 OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
00047   Object obj1;
00048   GString *s;
00049   int i;
00050 
00051   xref = xrefA;
00052   title = NULL;
00053   action = NULL;
00054   kids = NULL;
00055 
00056   if (dict->lookup("Title", &obj1)->isString()) {
00057     s = obj1.getString();
00058     if ((s->getChar(0) & 0xff) == 0xfe &&
00059        (s->getChar(1) & 0xff) == 0xff) {
00060       titleLen = (s->getLength() - 2) / 2;
00061       title = (Unicode *)gmalloc(titleLen * sizeof(Unicode));
00062       for (i = 0; i < titleLen; ++i) {
00063        title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
00064                   (s->getChar(3 + 2*i) & 0xff);
00065       }
00066     } else {
00067       titleLen = s->getLength();
00068       title = (Unicode *)gmalloc(titleLen * sizeof(Unicode));
00069       for (i = 0; i < titleLen; ++i) {
00070        title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
00071       }
00072     }
00073   } else {
00074     titleLen = 0;
00075   }
00076   obj1.free();
00077 
00078   if (!dict->lookup("Dest", &obj1)->isNull()) {
00079     action = LinkAction::parseDest(&obj1);
00080   } else {
00081     obj1.free();
00082     if (dict->lookup("A", &obj1)) {
00083       action = LinkAction::parseAction(&obj1);
00084     }
00085   }
00086   obj1.free();
00087 
00088   dict->lookupNF("First", &firstRef);
00089   dict->lookupNF("Last", &lastRef);
00090   dict->lookupNF("Next", &nextRef);
00091 
00092   startsOpen = gFalse;
00093   if (dict->lookup("Count", &obj1)->isInt()) {
00094     if (obj1.getInt() > 0) {
00095       startsOpen = gTrue;
00096     }
00097   }
00098   obj1.free();
00099 }
00100 
00101 OutlineItem::~OutlineItem() {
00102   close();
00103   if (title) {
00104     gfree(title);
00105   }
00106   if (action) {
00107     delete action;
00108   }
00109   firstRef.free();
00110   lastRef.free();
00111   nextRef.free();
00112 }
00113 
00114 GList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
00115                              XRef *xrefA) {
00116   GList *items;
00117   OutlineItem *item;
00118   Object obj;
00119   Object *p;
00120 
00121   items = new GList();
00122   p = firstItemRef;
00123   while (p->isRef()) {
00124     if (!p->fetch(xrefA, &obj)->isDict()) {
00125       obj.free();
00126       break;
00127     }
00128     item = new OutlineItem(obj.getDict(), xrefA);
00129     obj.free();
00130     items->append(item);
00131     if (p->getRef().num == lastItemRef->getRef().num &&
00132        p->getRef().gen == lastItemRef->getRef().gen) {
00133       break;
00134     }
00135     p = &item->nextRef;
00136   }
00137   return items;
00138 }
00139 
00140 void OutlineItem::open() {
00141   if (!kids) {
00142     kids = readItemList(&firstRef, &lastRef, xref);
00143   }
00144 }
00145 
00146 void OutlineItem::close() {
00147   if (kids) {
00148     deleteGList(kids, OutlineItem);
00149     kids = NULL;
00150   }
00151 }