mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
166 lines
3.6 KiB
C++
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;
|
|
}
|
|
}
|