Files
core/ASCOfficePDFReader/Outline.cpp

166 lines
3.6 KiB
C++

#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;
}
}