#include "stdafx.h" #include "MemoryUtils.h" #include "StringExt.h" #include "List.h" #include "Link.h" #include "PDFDocEncoding.h" #include "Outline.h" //------------------------------------------------------------------------------------------------------------------------------- // Outline //------------------------------------------------------------------------------------------------------------------------------- Outline::Outline(Object *pOutlineObject, XRef *pXref) { m_pItems = NULL; if ( !pOutlineObject->IsDict() ) { return; } Object oFirst, oLast; m_pItems = OutlineItem::ReadItemList( pOutlineObject->DictLookupAndCopy("First", &oFirst), pOutlineObject->DictLookupAndCopy("Last", &oLast), pXref); oFirst.Free(); oLast.Free(); } Outline::~Outline() { if ( m_pItems ) { DeleteCList( m_pItems, OutlineItem ); } } //------------------------------------------------------------------------------------------------------------------------------- // OutlineItem //------------------------------------------------------------------------------------------------------------------------------- OutlineItem::OutlineItem(Dict *pDict, XRef *pXref) { m_pXref = pXref; m_pTitle = NULL; m_pAction = NULL; m_pKids = NULL; Object oDictItem; if ( pDict->Search("Title", &oDictItem)->IsString() ) { StringExt *seTitle = oDictItem.GetString(); if ( (seTitle->GetAt(0) & 0xff) == 0xfe && (seTitle->GetAt(1) & 0xff) == 0xff ) { m_nTitleLen = (seTitle->GetLength() - 2) / 2; m_pTitle = (Unicode *)MemUtilsMallocArray( m_nTitleLen, sizeof(Unicode) ); for ( int nIndex = 0; nIndex < m_nTitleLen; ++nIndex ) { m_pTitle[nIndex] = ((seTitle->GetAt(2 + 2 * nIndex) & 0xff) << 8) | (seTitle->GetAt(3 + 2 * nIndex) & 0xff); } } else { m_nTitleLen = seTitle->GetLength(); m_pTitle = (Unicode *)MemUtilsMallocArray( m_nTitleLen, sizeof(Unicode) ); for ( int nIndex = 0; nIndex < m_nTitleLen; ++nIndex ) { m_pTitle[nIndex] = c_arrPDFDocEncoding[seTitle->GetAt(nIndex) & 0xff]; } } } else { m_nTitleLen = 0; } oDictItem.Free(); if ( !pDict->Search("Dest", &oDictItem)->IsNull() ) { m_pAction = LinkAction::ParseDestination(&oDictItem); } else { oDictItem.Free(); if ( !pDict->Search("A", &oDictItem)->IsNull() ) { m_pAction = LinkAction::ParseAction(&oDictItem); } } oDictItem.Free(); pDict->SearchAndCopy("First", &m_oFirstRef); pDict->SearchAndCopy("Last", &m_oLastRef); pDict->SearchAndCopy("Next", &m_oNextRef); m_bOpen = FALSE; if ( pDict->Search("Count", &oDictItem)->IsInt() ) { if ( oDictItem.GetInt() > 0 ) { m_bOpen = TRUE; } } oDictItem.Free(); } OutlineItem::~OutlineItem() { Close(); if ( m_pTitle ) { MemUtilsFree( m_pTitle ); } if ( m_pAction ) { delete m_pAction; } m_oFirstRef.Free(); m_oLastRef.Free(); m_oNextRef.Free(); } CList *OutlineItem::ReadItemList(Object *pFirstItemRef, Object *pLastItemRef, XRef *pXref) { CList *pItems = new CList(); Object *pCurItem = pFirstItemRef; while ( pCurItem->IsRef() ) { Object oTemp; if ( !pCurItem->Fetch(pXref, &oTemp)->IsDict() ) { oTemp.Free(); break; } OutlineItem *pItem = new OutlineItem( oTemp.GetDict(), pXref ); oTemp.Free(); pItems->Append( pItem ); if ( pCurItem->GetRef().nNum == pLastItemRef->GetRef().nNum && pCurItem->GetRef().nGen == pLastItemRef->GetRef().nGen ) { break; } pCurItem = &pItem->m_oNextRef; } return pItems; } void OutlineItem::Open() { if ( !m_pKids ) { m_pKids = ReadItemList( &m_oFirstRef, &m_oLastRef, m_pXref ); } } void OutlineItem::Close() { if ( m_pKids ) { DeleteCList( m_pKids, OutlineItem ); m_pKids = NULL; } }