mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 07:23:34 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62550 954022d7-b5bf-4e40-9824-e11837661b57
919 lines
20 KiB
C++
919 lines
20 KiB
C++
#include <stddef.h>
|
||
#include <string.h>
|
||
#include "MemoryUtils.h"
|
||
#include "StringExt.h"
|
||
#include "Object.h"
|
||
#include "Array.h"
|
||
#include "Dict.h"
|
||
#include "Link.h"
|
||
|
||
namespace PdfReader
|
||
{
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkAction
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkAction *LinkAction::ParseDestination(Object *pObject)
|
||
{
|
||
LinkAction *pAction = new LinkGoTo(pObject);
|
||
|
||
if (!pAction->CheckValidate())
|
||
{
|
||
delete pAction;
|
||
return NULL;
|
||
}
|
||
return pAction;
|
||
}
|
||
|
||
LinkAction *LinkAction::ParseAction(Object *pObject, StringExt *seBaseURI)
|
||
{
|
||
LinkAction *pAction = NULL;
|
||
|
||
if (!pObject->IsDict())
|
||
{
|
||
// TO DO: Error "Bad annotation action"
|
||
return NULL;
|
||
}
|
||
|
||
// S (тип Action)
|
||
Object oType;
|
||
pObject->DictLookup("S", &oType);
|
||
|
||
// GoTo action
|
||
if (oType.IsName("GoTo"))
|
||
{
|
||
Object oD;
|
||
pObject->DictLookup("D", &oD);
|
||
pAction = new LinkGoTo(&oD);
|
||
oD.Free();
|
||
}
|
||
else if (oType.IsName("GoToR")) // GoToR action
|
||
{
|
||
Object oF, oD;
|
||
pObject->DictLookup("F", &oF);
|
||
pObject->DictLookup("D", &oD);
|
||
pAction = new LinkGoToR(&oF, &oD);
|
||
oF.Free();
|
||
oD.Free();
|
||
}
|
||
else if (oType.IsName("Launch")) // Launch action
|
||
{
|
||
pAction = new LinkLaunch(pObject);
|
||
}
|
||
else if (oType.IsName("URI")) // URI action
|
||
{
|
||
Object oURI;
|
||
pObject->DictLookup("URI", &oURI);
|
||
pAction = new LinkURI(&oURI, seBaseURI);
|
||
oURI.Free();
|
||
}
|
||
else if (oType.IsName("Named")) // Named action
|
||
{
|
||
Object oN;
|
||
pObject->DictLookup("N", &oN);
|
||
pAction = new LinkNamed(&oN);
|
||
oN.Free();
|
||
}
|
||
else if (oType.IsName("Movie")) // Movie action
|
||
{
|
||
Object oAnnot, oT;
|
||
pObject->DictLookupAndCopy("Annot", &oAnnot);
|
||
pObject->DictLookup("T", &oT);
|
||
pAction = new LinkMovie(&oAnnot, &oT);
|
||
oAnnot.Free();
|
||
oT.Free();
|
||
}
|
||
else if (oType.IsName()) // unknown action
|
||
{
|
||
pAction = new LinkUnknown(oType.GetName());
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Bad annotation action"
|
||
pAction = NULL;
|
||
}
|
||
|
||
oType.Free();
|
||
|
||
if (pAction && !pAction->CheckValidate())
|
||
{
|
||
delete pAction;
|
||
return NULL;
|
||
}
|
||
return pAction;
|
||
}
|
||
|
||
StringExt *LinkAction::GetFileSpecName(Object *pFileSpecObject)
|
||
{
|
||
StringExt *seName = NULL;
|
||
|
||
if (pFileSpecObject->IsString())
|
||
{
|
||
seName = pFileSpecObject->GetString()->Copy();
|
||
}
|
||
else if (pFileSpecObject->IsDict())
|
||
{
|
||
Object oTemp;
|
||
if (!pFileSpecObject->DictLookup("DOS", &oTemp)->IsString())
|
||
{
|
||
oTemp.Free();
|
||
pFileSpecObject->DictLookup("F", &oTemp);
|
||
}
|
||
if (oTemp.IsString())
|
||
{
|
||
seName = oTemp.GetString()->Copy();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Illegal file spec in link"
|
||
}
|
||
oTemp.Free();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Illegal file spec in link"
|
||
}
|
||
|
||
if (seName)
|
||
{
|
||
// Производим преобразования, связанные с формой записи путей
|
||
|
||
// "//...." --> "\...."
|
||
// "/x/...." --> "x:\...."
|
||
// "/server/share/...." --> "\\server\share\...."
|
||
|
||
int nCurIndex = 0;
|
||
if (seName->GetAt(0) == '/')
|
||
{
|
||
if (seName->GetLength() >= 2 && seName->GetAt(1) == '/')
|
||
{
|
||
seName->Delete(0);
|
||
nCurIndex = 0;
|
||
}
|
||
else if (seName->GetLength() >= 2 && ((seName->GetAt(1) >= 'a' && seName->GetAt(1) <= 'z') || (seName->GetAt(1) >= 'A' && seName->GetAt(1) <= 'Z')) && (seName->GetLength() == 2 || seName->GetAt(2) == '/'))
|
||
{
|
||
seName->SetAt(0, seName->GetAt(1));
|
||
seName->SetAt(1, ':');
|
||
nCurIndex = 2;
|
||
}
|
||
else
|
||
{
|
||
int nJ;
|
||
for (nJ = 2; nJ < seName->GetLength(); ++nJ)
|
||
{
|
||
if (seName->GetAt(nJ - 1) != '\\' && seName->GetAt(nJ) == '/')
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if (nJ < seName->GetLength())
|
||
{
|
||
seName->SetAt(0, '\\');
|
||
seName->Insert(0, '\\');
|
||
nCurIndex = 2;
|
||
}
|
||
}
|
||
}
|
||
for (; nCurIndex < seName->GetLength(); ++nCurIndex)
|
||
{
|
||
if (seName->GetAt(nCurIndex) == '/')
|
||
{
|
||
seName->SetAt(nCurIndex, '\\');
|
||
}
|
||
else if (seName->GetAt(nCurIndex) == '\\' && nCurIndex + 1 < seName->GetLength() && seName->GetAt(nCurIndex + 1) == '/')
|
||
{
|
||
seName->Delete(nCurIndex);
|
||
}
|
||
}
|
||
}
|
||
|
||
return seName;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkDest
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkDestination::LinkDestination(Array *pArray)
|
||
{
|
||
m_dLeft = m_dBottom = m_dRight = m_dTop = m_dZoom = 0;
|
||
m_bValidate = false;
|
||
|
||
if (pArray->GetCount() < 2)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
return;
|
||
}
|
||
|
||
Object oArrayItem;
|
||
pArray->GetCopy(0, &oArrayItem);
|
||
|
||
if (oArrayItem.IsInt())
|
||
{
|
||
m_nPageNum = oArrayItem.GetInt() + 1;
|
||
m_bPageIsRef = false;
|
||
}
|
||
else if (oArrayItem.IsRef())
|
||
{
|
||
m_oPageRef.nNum = oArrayItem.GetRefNum();
|
||
m_oPageRef.nGen = oArrayItem.GetRefGen();
|
||
m_bPageIsRef = true;
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Bad annotation destination"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
oArrayItem.Free();
|
||
|
||
// Destination type
|
||
pArray->Get(1, &oArrayItem);
|
||
|
||
if (oArrayItem.IsName("XYZ"))
|
||
{
|
||
m_eType = destXYZ;
|
||
Object oTemp;
|
||
if (pArray->GetCount() < 3)
|
||
{
|
||
m_bChangeLeft = false;
|
||
}
|
||
else
|
||
{
|
||
pArray->Get(2, &oTemp);
|
||
if (oTemp.IsNull())
|
||
{
|
||
m_bChangeLeft = false;
|
||
}
|
||
else if (oTemp.IsNum())
|
||
{
|
||
m_bChangeLeft = true;
|
||
m_dLeft = oTemp.GetNum();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
oTemp.Free();
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
oTemp.Free();
|
||
}
|
||
if (pArray->GetCount() < 4)
|
||
{
|
||
m_bChangeTop = false;
|
||
}
|
||
else
|
||
{
|
||
pArray->Get(3, &oTemp);
|
||
if (oTemp.IsNull())
|
||
{
|
||
m_bChangeTop = false;
|
||
}
|
||
else if (oTemp.IsNum())
|
||
{
|
||
m_bChangeTop = true;
|
||
m_dTop = oTemp.GetNum();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
oTemp.Free();
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
oTemp.Free();
|
||
}
|
||
if (pArray->GetCount() < 5)
|
||
{
|
||
m_bChangeZoom = false;
|
||
}
|
||
else
|
||
{
|
||
pArray->Get(4, &oTemp);
|
||
if (oTemp.IsNull())
|
||
{
|
||
m_bChangeZoom = false;
|
||
}
|
||
else if (oTemp.IsNum())
|
||
{
|
||
m_bChangeZoom = true;
|
||
m_dZoom = oTemp.GetNum();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
oTemp.Free();
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
oTemp.Free();
|
||
}
|
||
}
|
||
else if (oArrayItem.IsName("Fit"))
|
||
{
|
||
if (pArray->GetCount() < 2)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFit;
|
||
}
|
||
else if (oArrayItem.IsName("FitH"))
|
||
{
|
||
if (pArray->GetCount() < 3)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFitH;
|
||
|
||
Object oTemp;
|
||
if (!pArray->Get(2, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dTop = oTemp.GetNum();
|
||
oTemp.Free();
|
||
}
|
||
else if (oArrayItem.IsName("FitV"))
|
||
{
|
||
if (pArray->GetCount() < 3)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFitV;
|
||
|
||
Object oTemp;
|
||
if (!pArray->Get(2, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dLeft = oTemp.GetNum();
|
||
oTemp.Free();
|
||
}
|
||
else if (oArrayItem.IsName("FitR"))
|
||
{
|
||
if (pArray->GetCount() < 6)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFitR;
|
||
|
||
Object oTemp;
|
||
if (!pArray->Get(2, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dLeft = oTemp.GetNum();
|
||
oTemp.Free();
|
||
|
||
if (!pArray->Get(3, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dBottom = oTemp.GetNum();
|
||
oTemp.Free();
|
||
|
||
if (!pArray->Get(4, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dRight = oTemp.GetNum();
|
||
oTemp.Free();
|
||
|
||
if (!pArray->Get(5, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dTop = oTemp.GetNum();
|
||
oTemp.Free();
|
||
}
|
||
else if (oArrayItem.IsName("FitB"))
|
||
{
|
||
if (pArray->GetCount() < 2)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFitB;
|
||
}
|
||
else if (oArrayItem.IsName("FitBH"))
|
||
{
|
||
if (pArray->GetCount() < 3)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFitBH;
|
||
|
||
Object oTemp;
|
||
if (!pArray->Get(2, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dTop = oTemp.GetNum();
|
||
oTemp.Free();
|
||
}
|
||
else if (oArrayItem.IsName("FitBV"))
|
||
{
|
||
if (pArray->GetCount() < 3)
|
||
{
|
||
// TO DO: Error "Annotation destination array is too short"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
m_eType = destFitBV;
|
||
|
||
Object oTemp;
|
||
if (!pArray->Get(2, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation destination position"
|
||
m_eType = destFit;
|
||
}
|
||
m_dLeft = oTemp.GetNum();
|
||
oTemp.Free();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Unknown annotation destination type"
|
||
oArrayItem.Free();
|
||
return;
|
||
}
|
||
|
||
oArrayItem.Free();
|
||
m_bValidate = true;
|
||
return;
|
||
}
|
||
|
||
LinkDestination::LinkDestination(LinkDestination *pDest)
|
||
{
|
||
m_eType = pDest->m_eType;
|
||
m_bPageIsRef = pDest->m_bPageIsRef;
|
||
|
||
if (m_bPageIsRef)
|
||
m_oPageRef = pDest->m_oPageRef;
|
||
else
|
||
m_nPageNum = pDest->m_nPageNum;
|
||
|
||
m_dLeft = pDest->m_dLeft;
|
||
m_dBottom = pDest->m_dBottom;
|
||
m_dRight = pDest->m_dRight;
|
||
m_dTop = pDest->m_dTop;
|
||
m_dZoom = pDest->m_dZoom;
|
||
m_bChangeLeft = pDest->m_bChangeLeft;
|
||
m_bChangeTop = pDest->m_bChangeTop;
|
||
m_bChangeZoom = pDest->m_bChangeZoom;
|
||
m_bValidate = true;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkGoTo
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkGoTo::LinkGoTo(Object *pDestObject)
|
||
{
|
||
m_pDestination = NULL;
|
||
m_pNamedDestination = NULL;
|
||
|
||
if (pDestObject->IsName())
|
||
{
|
||
m_pNamedDestination = new StringExt(pDestObject->GetName());
|
||
}
|
||
else if (pDestObject->IsString())
|
||
{
|
||
m_pNamedDestination = pDestObject->GetString()->Copy();
|
||
}
|
||
else if (pDestObject->IsArray())
|
||
{
|
||
m_pDestination = new LinkDestination(pDestObject->GetArray());
|
||
if (!m_pDestination->CheckValidate())
|
||
{
|
||
delete m_pDestination;
|
||
m_pDestination = NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Illegal annotation destination"
|
||
}
|
||
}
|
||
|
||
LinkGoTo::~LinkGoTo()
|
||
{
|
||
if (m_pDestination)
|
||
delete m_pDestination;
|
||
if (m_pNamedDestination)
|
||
delete m_pNamedDestination;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkGoToR
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkGoToR::LinkGoToR(Object *pFileSpecObject, Object *pDestObject)
|
||
{
|
||
m_pDestination = NULL;
|
||
m_pNamedDestination = NULL;
|
||
|
||
m_seFileName = GetFileSpecName(pFileSpecObject);
|
||
|
||
if (pDestObject->IsName())
|
||
{
|
||
m_pNamedDestination = new StringExt(pDestObject->GetName());
|
||
}
|
||
else if (pDestObject->IsString())
|
||
{
|
||
m_pNamedDestination = pDestObject->GetString()->Copy();
|
||
}
|
||
else if (pDestObject->IsArray())
|
||
{
|
||
m_pDestination = new LinkDestination(pDestObject->GetArray());
|
||
if (!m_pDestination->CheckValidate())
|
||
{
|
||
delete m_pDestination;
|
||
m_pDestination = NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Illegal annotation destination"
|
||
}
|
||
}
|
||
|
||
LinkGoToR::~LinkGoToR()
|
||
{
|
||
if (m_seFileName)
|
||
delete m_seFileName;
|
||
if (m_pDestination)
|
||
delete m_pDestination;
|
||
if (m_pNamedDestination)
|
||
delete m_pNamedDestination;
|
||
}
|
||
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkLaunch
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkLaunch::LinkLaunch(Object *pActionObject)
|
||
{
|
||
m_seFileName = NULL;
|
||
m_pParameters = NULL;
|
||
|
||
if (pActionObject->IsDict())
|
||
{
|
||
Object oSpecObject;
|
||
if (!pActionObject->DictLookup("F", &oSpecObject)->IsNull())
|
||
{
|
||
m_seFileName = GetFileSpecName(&oSpecObject);
|
||
}
|
||
else
|
||
{
|
||
oSpecObject.Free();
|
||
if (pActionObject->DictLookup("Win", &oSpecObject)->IsDict())
|
||
{
|
||
Object oTemp;
|
||
oSpecObject.DictLookup("F", &oTemp);
|
||
m_seFileName = GetFileSpecName(&oTemp);
|
||
oTemp.Free();
|
||
if (oSpecObject.DictLookup("P", &oTemp)->IsString())
|
||
{
|
||
m_pParameters = oTemp.GetString()->Copy();
|
||
}
|
||
oTemp.Free();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Bad launch-type link action"
|
||
}
|
||
}
|
||
oSpecObject.Free();
|
||
}
|
||
}
|
||
|
||
LinkLaunch::~LinkLaunch()
|
||
{
|
||
if (m_seFileName)
|
||
delete m_seFileName;
|
||
if (m_pParameters)
|
||
delete m_pParameters;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkURI
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkURI::LinkURI(Object *pUriObject, StringExt *seBaseURI)
|
||
{
|
||
m_seURI = NULL;
|
||
if (pUriObject->IsString())
|
||
{
|
||
StringExt *seTempURI = pUriObject->GetString()->Copy();
|
||
if (seBaseURI && seBaseURI->GetLength() > 0)
|
||
{
|
||
int nCount = strcspn(seTempURI->GetBuffer(), "/:");
|
||
if (nCount == seTempURI->GetLength() || seTempURI->GetAt(nCount) == '/')
|
||
{
|
||
m_seURI = seBaseURI->Copy();
|
||
int nChar = m_seURI->GetAt(m_seURI->GetLength() - 1);
|
||
if (nChar == '/' || nChar == '?')
|
||
{
|
||
if (seTempURI->GetAt(0) == '/')
|
||
{
|
||
seTempURI->Delete(0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (seTempURI->GetAt(0) != '/')
|
||
{
|
||
m_seURI->Append('/');
|
||
}
|
||
}
|
||
m_seURI->Append(seTempURI);
|
||
delete seTempURI;
|
||
}
|
||
else
|
||
{
|
||
m_seURI = seTempURI;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_seURI = seTempURI;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Illegal URI-type link"
|
||
}
|
||
}
|
||
|
||
LinkURI::~LinkURI()
|
||
{
|
||
if (m_seURI)
|
||
delete m_seURI;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkNamed
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkNamed::LinkNamed(Object *pNameObject)
|
||
{
|
||
m_seName = NULL;
|
||
if (pNameObject->IsName())
|
||
{
|
||
m_seName = new StringExt(pNameObject->GetName());
|
||
}
|
||
}
|
||
|
||
LinkNamed::~LinkNamed()
|
||
{
|
||
if (m_seName)
|
||
{
|
||
delete m_seName;
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkMovie
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkMovie::LinkMovie(Object *pAnnotObject, Object *pTitleObject)
|
||
{
|
||
m_oAnnotRef.nNum = -1;
|
||
m_seTitle = NULL;
|
||
if (pAnnotObject->IsRef())
|
||
{
|
||
m_oAnnotRef = pAnnotObject->GetRef();
|
||
}
|
||
else if (pTitleObject->IsString())
|
||
{
|
||
m_seTitle = pTitleObject->GetString()->Copy();
|
||
}
|
||
else
|
||
{
|
||
// TO DO: Error "Movie action is missing both the Annot and T keys"
|
||
}
|
||
}
|
||
|
||
LinkMovie::~LinkMovie()
|
||
{
|
||
if (m_seTitle)
|
||
{
|
||
delete m_seTitle;
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// LinkUnknown
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
LinkUnknown::LinkUnknown(char *sAction)
|
||
{
|
||
m_seAction = new StringExt(sAction);
|
||
}
|
||
|
||
LinkUnknown::~LinkUnknown()
|
||
{
|
||
if (m_seAction)
|
||
delete m_seAction;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// Link
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
Link::Link(Dict *pDict, StringExt *seBaseURI)
|
||
{
|
||
m_pAction = NULL;
|
||
m_bValid = false;
|
||
|
||
// Rect
|
||
Object oDictItem;
|
||
if (!pDict->Search("Rect", &oDictItem)->IsArray())
|
||
{
|
||
// TO DO: Error "Annotation rectangle is wrong type"
|
||
oDictItem.Free();
|
||
return;
|
||
}
|
||
|
||
Object oTemp;
|
||
if (!oDictItem.ArrayGet(0, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation rectangle"
|
||
oTemp.Free();
|
||
oDictItem.Free();
|
||
return;
|
||
}
|
||
m_dLeft = oTemp.GetNum();
|
||
oTemp.Free();
|
||
|
||
if (!oDictItem.ArrayGet(1, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation rectangle"
|
||
oTemp.Free();
|
||
oDictItem.Free();
|
||
return;
|
||
}
|
||
m_dBottom = oTemp.GetNum();
|
||
oTemp.Free();
|
||
|
||
if (!oDictItem.ArrayGet(2, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation rectangle"
|
||
oTemp.Free();
|
||
oDictItem.Free();
|
||
return;
|
||
}
|
||
m_dRight = oTemp.GetNum();
|
||
oTemp.Free();
|
||
|
||
if (!oDictItem.ArrayGet(3, &oTemp)->IsNum())
|
||
{
|
||
// TO DO: Error "Bad annotation rectangle"
|
||
oTemp.Free();
|
||
oDictItem.Free();
|
||
return;
|
||
}
|
||
m_dTop = oTemp.GetNum();
|
||
oTemp.Free();
|
||
oDictItem.Free();
|
||
|
||
if (m_dLeft > m_dRight)
|
||
{
|
||
double dTemp = m_dLeft;
|
||
m_dLeft = m_dRight;
|
||
m_dRight = dTemp;
|
||
}
|
||
if (m_dBottom > m_dTop)
|
||
{
|
||
double dTemp = m_dBottom;
|
||
m_dBottom = m_dTop;
|
||
m_dTop = dTemp;
|
||
}
|
||
|
||
// Dest
|
||
if (!pDict->Search("Dest", &oDictItem)->IsNull())
|
||
{
|
||
m_pAction = LinkAction::ParseDestination(&oDictItem);
|
||
}
|
||
else // A (Action)
|
||
{
|
||
oDictItem.Free();
|
||
if (pDict->Search("A", &oDictItem)->IsDict())
|
||
{
|
||
m_pAction = LinkAction::ParseAction(&oDictItem, seBaseURI);
|
||
}
|
||
}
|
||
oDictItem.Free();
|
||
|
||
if (m_pAction)
|
||
{
|
||
m_bValid = true;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
Link::~Link()
|
||
{
|
||
if (m_pAction)
|
||
{
|
||
delete m_pAction;
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
// Links
|
||
//-------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
Links::Links(Object *pAnnots, StringExt *seBaseURI)
|
||
{
|
||
m_ppLinks = NULL;
|
||
m_nLinksCount = 0;
|
||
|
||
int nSize = 0;
|
||
|
||
if (pAnnots->IsArray())
|
||
{
|
||
for (int nIndex = 0; nIndex < pAnnots->ArrayGetLength(); ++nIndex)
|
||
{
|
||
Object oArrayItem;
|
||
if (pAnnots->ArrayGet(nIndex, &oArrayItem)->IsDict())
|
||
{
|
||
Object oTemp;
|
||
if (oArrayItem.DictLookup("Subtype", &oTemp)->IsName("Link"))
|
||
{
|
||
Link *pLink = new Link(oArrayItem.GetDict(), seBaseURI);
|
||
if (pLink->CheckValidate())
|
||
{
|
||
if (m_nLinksCount >= nSize)
|
||
{
|
||
nSize += 16;
|
||
m_ppLinks = (Link **)MemUtilsReallocArray(m_ppLinks, nSize, sizeof(Link *));
|
||
}
|
||
m_ppLinks[m_nLinksCount++] = pLink;
|
||
}
|
||
else
|
||
{
|
||
if (pLink)
|
||
delete pLink;
|
||
}
|
||
}
|
||
oTemp.Free();
|
||
}
|
||
oArrayItem.Free();
|
||
}
|
||
}
|
||
}
|
||
|
||
Links::~Links()
|
||
{
|
||
for (int nIndex = 0; nIndex < m_nLinksCount; ++nIndex)
|
||
{
|
||
if (m_ppLinks[nIndex])
|
||
delete m_ppLinks[nIndex];
|
||
}
|
||
MemUtilsFree(m_ppLinks);
|
||
}
|
||
|
||
LinkAction *Links::Find(double dX, double dY)
|
||
{
|
||
for (int nIndex = m_nLinksCount - 1; nIndex >= 0; --nIndex)
|
||
{
|
||
if (m_ppLinks[nIndex]->InRect(dX, dY))
|
||
{
|
||
return m_ppLinks[nIndex]->GetAction();
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
bool Links::OnLink(double dX, double dY)
|
||
{
|
||
for (int nIndex = 0; nIndex < m_nLinksCount; ++nIndex)
|
||
{
|
||
if (m_ppLinks[nIndex]->InRect(dX, dY))
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
} |