Files
core/ASCOfficePDFReader/Annot.cpp

1796 lines
44 KiB
C++
Raw Blame History

#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include "MemoryUtils.h"
#include "List.h"
#include "Object.h"
#include "Catalog.h"
#include "Graphics.h"
#include "GFont.h"
#include "Lexer.h"
#include "Annot.h"
//-------------------------------------------------------------------------------------------------------------------------------
#define annotFlagHidden 0x0002
#define annotFlagPrint 0x0004
#define annotFlagNoView 0x0020
#define fieldFlagReadOnly 0x00000001
#define fieldFlagRequired 0x00000002
#define fieldFlagNoExport 0x00000004
#define fieldFlagMultiline 0x00001000
#define fieldFlagPassword 0x00002000
#define fieldFlagNoToggleToOff 0x00004000
#define fieldFlagRadio 0x00008000
#define fieldFlagPushbutton 0x00010000
#define fieldFlagCombo 0x00020000
#define fieldFlagEdit 0x00040000
#define fieldFlagSort 0x00080000
#define fieldFlagFileSelect 0x00100000
#define fieldFlagMultiSelect 0x00200000
#define fieldFlagDoNotSpellCheck 0x00400000
#define fieldFlagDoNotScroll 0x00800000
#define fieldFlagComb 0x01000000
#define fieldFlagRichText 0x02000000
#define fieldFlagRadiosInUnison 0x02000000
#define fieldFlagCommitOnSelChange 0x04000000
#define fieldQuadLeft 0
#define fieldQuadCenter 1
#define fieldQuadRight 2
//-------------------------------------------------------------------------------------------------------------------------------
// AnnotBorderStyle
//-------------------------------------------------------------------------------------------------------------------------------
AnnotBorderStyle::AnnotBorderStyle(AnnotBorderType eType, double dWidth, double *pDash, int nDashLength, double dR, double dG, double dB)
{
m_eType = eType;
m_dWidth = dWidth;
m_pDash = pDash;
m_nDashLength = nDashLength;
m_dR = dR;
m_dG = dG;
m_dB = dB;
}
AnnotBorderStyle::~AnnotBorderStyle()
{
MemUtilsFree( m_pDash );
}
//-------------------------------------------------------------------------------------------------------------------------------
// Annot
//-------------------------------------------------------------------------------------------------------------------------------
Annot::Annot(GlobalParams *pGlobalParams, XRef *pXref, Dict *pAcroForm, Dict *pDict, Ref *pRef)
{
m_pGlobalParams = pGlobalParams;
m_bValid = TRUE;
m_pXref = pXref;
m_oRef = *pRef;
m_seType = NULL;
m_seAppBuffer = NULL;
m_pBorderStyle = NULL;
// SubType
Object oDictItem;
if ( pDict->Search("Subtype", &oDictItem)->IsName() )
{
m_seType = new StringExt( oDictItem.GetName() );
}
oDictItem.Free();
// Rect
if ( pDict->Search("Rect", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 4 )
{
Object oTemp;
m_dMinX = m_dMinY = m_dMaxX = m_dMaxY = 0;
if ( oDictItem.ArrayGet( 0, &oTemp)->IsNum() )
{
m_dMinX = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.ArrayGet( 1, &oTemp)->IsNum() )
{
m_dMinY = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.ArrayGet( 2, &oTemp)->IsNum() )
{
m_dMaxX = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.ArrayGet( 3, &oTemp)->IsNum() )
{
m_dMaxY = oTemp.GetNum();
}
oTemp.Free();
if ( m_dMinX > m_dMaxX )
{
double dTemp = m_dMinX;
m_dMinX = m_dMaxX;
m_dMaxX = dTemp;
}
if ( m_dMinY > m_dMaxY )
{
double dTemp = m_dMinY;
m_dMinY = m_dMaxY;
m_dMaxY = dTemp;
}
}
else
{
// TO DO: Error "Bad bounding box for annotation"
m_bValid = FALSE;
}
oDictItem.Free();
// F (flags)
if ( pDict->Search("F", &oDictItem)->IsInt() )
{
m_nFlags = oDictItem.GetInt();
}
else
{
m_nFlags = 0;
}
oDictItem.Free();
//Border style
AnnotBorderType eBorderType = annotBorderSolid;
double dBorderWidth = 1;
double *pBorderDash = NULL;
int nBorderDashLength = 0;
double dBorderR = 0;
double dBorderG = 0;
double dBorderB = 1;
if ( pDict->Search("BS", &oDictItem)->IsDict() )
{
Object oTemp;
if ( oDictItem.DictLookup("S", &oTemp)->IsName() )
{
if ( oTemp.IsName("S") )
{
eBorderType = annotBorderSolid;
}
else if ( oTemp.IsName("D") )
{
eBorderType = annotBorderDashed;
}
else if ( oTemp.IsName("B") )
{
eBorderType = annotBorderBeveled;
}
else if ( oTemp.IsName("I") )
{
eBorderType = annotBorderInset;
}
else if ( oTemp.IsName("U") )
{
eBorderType = annotBorderUnderlined;
}
}
oTemp.Free();
if ( oDictItem.DictLookup("W", &oTemp)->IsNum() )
{
dBorderWidth = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.DictLookup("D", &oTemp)->IsArray() )
{
nBorderDashLength = oTemp.ArrayGetLength();
pBorderDash = (double *)MemUtilsMallocArray( nBorderDashLength, sizeof(double) );
for ( int nIndex = 0; nIndex < nBorderDashLength; ++nIndex )
{
Object oArrayItem;
if ( oTemp.ArrayGet( nIndex, &oArrayItem)->IsNum() )
{
pBorderDash[nIndex] = oArrayItem.GetNum();
}
else
{
pBorderDash[nIndex] = 1;
}
oArrayItem.Free();
}
}
oTemp.Free();
}
else
{
oDictItem.Free();
if ( pDict->Search("Border", &oDictItem)->IsArray() )
{
Object oTemp;
if ( oDictItem.ArrayGetLength() >= 3 )
{
if ( oDictItem.ArrayGet( 2, &oTemp)->IsNum() )
{
dBorderWidth = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.ArrayGetLength() >= 4 )
{
if ( oDictItem.ArrayGet( 3, &oTemp)->IsArray() )
{
eBorderType = annotBorderDashed;
nBorderDashLength = oTemp.ArrayGetLength();
pBorderDash = (double *)MemUtilsMallocArray( nBorderDashLength, sizeof(double) );
for ( int nIndex = 0; nIndex < nBorderDashLength; ++nIndex )
{
Object oArrayItem;
if ( oTemp.ArrayGet( nIndex, &oArrayItem)->IsNum() )
{
pBorderDash[nIndex] = oArrayItem.GetNum();
}
else
{
pBorderDash[nIndex] = 1;
}
oArrayItem.Free();
}
}
else
{
dBorderWidth = 0;
}
oTemp.Free();
}
}
}
}
oDictItem.Free();
// C (border color)
// TO DO: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> 0, 1, 3, 4
if ( pDict->Search("C", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 3 )
{
Object oTemp;
if ( oDictItem.ArrayGet(0, &oTemp)->IsNum() )
{
dBorderR = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.ArrayGet(1, &oTemp)->IsNum() )
{
dBorderG = oTemp.GetNum();
}
oTemp.Free();
if ( oDictItem.ArrayGet(2, &oTemp)->IsNum() )
{
dBorderB = oTemp.GetNum();
}
oTemp.Free();
}
oDictItem.Free();
m_pBorderStyle = new AnnotBorderStyle( eBorderType, dBorderWidth, pBorderDash, nBorderDashLength, dBorderR, dBorderG, dBorderB);
// AP (appereance)
Object oAP;
if ( pDict->Search("AP", &oAP)->IsDict() )
{
Object oAS;
if ( pDict->Search("AS", &oAS)->IsName() )
{
Object oItem;
if ( oAP.DictLookup("N", &oItem)->IsDict() )
{
Object oTemp;
if ( oItem.DictLookupAndCopy( oAS.GetName(), &oTemp)->IsRef() )
{
oTemp.Copy(&m_oAppearance);
m_bValid = TRUE;
}
else
{
oTemp.Free();
if ( oItem.DictLookupAndCopy("Off", &oTemp)->IsRef() )
{
oTemp.Copy(&m_oAppearance);
}
}
oTemp.Free();
}
oItem.Free();
}
else
{
Object oItem;
if ( oAP.DictLookupAndCopy("N", &oItem)->IsRef() )
{
oItem.Copy(&m_oAppearance);
}
oItem.Free();
}
oAS.Free();
}
oAP.Free();
}
Annot::~Annot()
{
if ( m_seType )
{
delete m_seType;
}
m_oAppearance.Free();
if ( m_seAppBuffer )
{
delete m_seAppBuffer;
}
if ( m_pBorderStyle )
{
delete m_pBorderStyle;
}
}
void Annot::GenerateFieldAppearance(Dict *pField, Dict *pAnnot, Dict *pAcroForm)
{
// <20><><EFBFBD> Annotation <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Widget
if ( m_seType->Compare("Widget") )
{
return;
}
m_seAppBuffer = new StringExt();
// Appearance characteristics (MK) dictionary
Object oMKObject;
Dict *pMKDict;
if ( pAnnot->Search("MK", &oMKObject)->IsDict() )
{
pMKDict = oMKObject.GetDict();
}
else
{
pMKDict = NULL;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> (BackGround)
Object oDictItem;
if ( pMKDict )
{
if ( pMKDict->Search("BG", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() > 0 )
{
SetColor( oDictItem.GetArray(), TRUE, 0 );
m_seAppBuffer->AppendFormat("0 0 {0:.2f} {1:.2f} re f\n", m_dMaxX - m_dMinX, m_dMaxY - m_dMinY);
}
oDictItem.Free();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
// FT (File Type)
Object oFTobject;
FieldLookup( pField, "FT", &oFTobject);
// Ff (Filed flags)
int nFiledFlags = 0;
if ( FieldLookup( pField, "Ff", &oDictItem)->IsInt() )
{
nFiledFlags = oDictItem.GetInt();
}
else
{
nFiledFlags = 0;
}
oDictItem.Free();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
if ( pMKDict )
{
double dWidth = m_pBorderStyle->GetWidth();
if ( dWidth > 0 )
{
// BC (Border Color), <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> BG
pMKDict->Search("BC", &oDictItem);
if ( !(oDictItem.IsArray() && oDictItem.ArrayGetLength() > 0) )
{
pMKDict->Search("BG", &oDictItem);
}
if ( oDictItem.IsArray() && oDictItem.ArrayGetLength() > 0 )
{
double dDx = m_dMaxX - m_dMinX;
double dDy = m_dMaxY - m_dMinY;
double *pDash;
int nDashLength = 0;
Object oTemp;
BOOL bHasCaption = pMKDict->Search("CA", &oTemp)->IsString();
oTemp.Free();
if ( oFTobject.IsName("Btn") && ( nFiledFlags & fieldFlagRadio ) && !bHasCaption )
{
double dRad = 0.5 * (dDx < dDy ? dDx : dDy);
switch ( m_pBorderStyle->GetType() )
{
case annotBorderDashed:
m_seAppBuffer->Append("[");
m_pBorderStyle->GetDash( &pDash, &nDashLength );
for ( int nIndex = 0; nIndex < nDashLength; ++nIndex )
{
m_seAppBuffer->AppendFormat(" {0:.2f}", pDash[nIndex]);
}
m_seAppBuffer->Append("] 0 d\n");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
case annotBorderSolid:
case annotBorderUnderlined:
m_seAppBuffer->AppendFormat("{0:.2f} w\n", dWidth);
SetColor( oDictItem.GetArray(), FALSE, 0);
DrawCircle( 0.5 * dDx, 0.5 * dDy, dRad - 0.5 * dWidth, FALSE);
break;
case annotBorderBeveled:
case annotBorderInset:
m_seAppBuffer->AppendFormat("{0:.2f} w\n", 0.5 * dWidth);
SetColor( oDictItem.GetArray(), FALSE, 0);
DrawCircle( 0.5 * dDx, 0.5 * dDy, dRad - 0.25 * dWidth, FALSE);
SetColor( oDictItem.GetArray(), FALSE, m_pBorderStyle->GetType() == annotBorderBeveled ? 1 : -1);
DrawCircleTopLeft( 0.5 * dDx, 0.5 * dDy, dRad - 0.75 * dWidth);
SetColor( oDictItem.GetArray(), FALSE, m_pBorderStyle->GetType() == annotBorderBeveled ? -1 : 1);
DrawCircleBottomRight(0.5 * dDx, 0.5 * dDy, dRad - 0.75 * dWidth);
break;
}
}
else
{
switch ( m_pBorderStyle->GetType() )
{
case annotBorderDashed:
m_seAppBuffer->Append("[");
m_pBorderStyle->GetDash( &pDash, &nDashLength );
for ( int nIndex = 0; nIndex < nDashLength; ++nIndex )
{
m_seAppBuffer->AppendFormat(" {0:.2f}", pDash[nIndex]);
}
m_seAppBuffer->Append("] 0 d\n");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
case annotBorderSolid:
m_seAppBuffer->AppendFormat("{0:.2f} w\n", dWidth);
SetColor( oDictItem.GetArray(), FALSE, 0);
m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n", 0.5 * dWidth, dDx - dWidth, dDy - dWidth);
break;
case annotBorderBeveled:
case annotBorderInset:
SetColor( oDictItem.GetArray(), TRUE, m_pBorderStyle->GetType() == annotBorderBeveled ? 1 : -1);
m_seAppBuffer->Append("0 0 m\n");
m_seAppBuffer->AppendFormat("0 {0:.2f} l\n", dDy);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx, dDy);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx - dWidth, dDy - dWidth);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dWidth, dDy - dWidth);
m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} l\n", dWidth);
m_seAppBuffer->Append("f\n");
SetColor( oDictItem.GetArray(), TRUE, m_pBorderStyle->GetType() == annotBorderBeveled ? -1 : 1);
m_seAppBuffer->Append("0 0 m\n");
m_seAppBuffer->AppendFormat("{0:.2f} 0 l\n", dDx);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx, dDy);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx - dWidth, dDy - dWidth);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx - dWidth, dWidth);
m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} l\n", dWidth);
m_seAppBuffer->Append("f\n");
break;
case annotBorderUnderlined:
m_seAppBuffer->AppendFormat("{0:.2f} w\n", dWidth);
SetColor( oDictItem.GetArray(), FALSE, 0);
m_seAppBuffer->AppendFormat("0 0 m {0:.2f} 0 l s\n", dDx);
break;
}
m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n", dWidth, dDx - 2 * dWidth, dDy - 2 * dWidth);
}
}
oDictItem.Free();
}
}
// DR
Object oDRobject;
pAcroForm->Search("DR", &oDRobject);
// Font dictionary
GrFontDict *pFontDict;
if ( oDRobject.IsDict() && oDRobject.DictLookup("Font", &oDictItem)->IsDict() )
{
pFontDict = new GrFontDict( m_pXref, NULL, oDictItem.GetDict(), m_pGlobalParams );
}
else
{
pFontDict = NULL;
}
oDictItem.Free();
// DA (Default appereance string)
StringExt *seDA;
if ( FieldLookup( pField, "DA", &oDictItem )->IsNull() )
{
oDictItem.Free();
pAcroForm->Search("DA", &oDictItem);
}
if ( oDictItem.IsString() )
{
seDA = oDictItem.GetString()->Copy();
}
else
{
seDA = NULL;
}
oDictItem.Free();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Filed
if ( oFTobject.IsName("Btn") )
{
StringExt *seCaption = NULL;
if ( pMKDict )
{
if ( pMKDict->Search("CA", &oDictItem)->IsString() )
{
seCaption = oDictItem.GetString()->Copy();
}
oDictItem.Free();
}
// Radio button
if ( nFiledFlags & fieldFlagRadio )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Caption, <20><><EFBFBD><EFBFBD> <20><><EFBFBD> AP
if ( FieldLookup( pField, "V", &oDictItem )->IsName() )
{
Object oAppStream;
if ( pAnnot->Search("AS", &oAppStream)->IsName( oDictItem.GetName() ) )
{
if ( seCaption )
{
DrawText( seCaption, seDA, pFontDict, FALSE, 0, fieldQuadCenter, FALSE, TRUE);
}
else
{
if ( pMKDict )
{
Object oTemp;
if ( pMKDict->Search("BC", &oTemp)->IsArray() && oTemp.ArrayGetLength() > 0 )
{
double dDx = m_dMaxX - m_dMinX;
double dDy = m_dMaxY - m_dMinY;
SetColor( oTemp.GetArray(), TRUE, 0 );
DrawCircle( 0.5 * dDx, 0.5 * dDy, 0.2 * (dDx < dDy ? dDx : dDy), TRUE);
}
oTemp.Free();
}
}
}
oAppStream.Free();
}
oDictItem.Free();
}
else if ( nFiledFlags & fieldFlagPushbutton ) // PushButton
{
if ( seCaption )
{
DrawText( seCaption, seDA, pFontDict, FALSE, 0, fieldQuadCenter, FALSE, FALSE);
}
}
else // CheckBox
{
// "Yes" - <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, "off" - <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if ( FieldLookup( pField, "V", &oDictItem )->IsName("Yes") )
{
if ( !seCaption )
{
seCaption = new StringExt("3"); // ZapfDingbats checkmark
}
DrawText( seCaption, seDA, pFontDict, FALSE, 0, fieldQuadCenter, FALSE, TRUE);
}
oDictItem.Free();
}
if ( seCaption )
{
delete seCaption;
}
}
else if ( oFTobject.IsName("Tx") )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Object oValue;
if ( FieldLookup( pField, "V", &oValue )->IsString() )
{
Object oTemp;
int nQuadding = 0;
if ( FieldLookup( pField, "Q", &oTemp )->IsInt() )
{
nQuadding = oTemp.GetInt();
}
else
{
nQuadding = fieldQuadLeft;
}
oTemp.Free();
int nComb = 0;
if ( nFiledFlags & fieldFlagComb )
{
if ( FieldLookup( pField, "MaxLen", &oTemp )->IsInt())
{
nComb = oTemp.GetInt();
}
oTemp.Free();
}
DrawText( oValue.GetString(), seDA, pFontDict, nFiledFlags & fieldFlagMultiline, nComb, nQuadding, TRUE, FALSE);
}
oValue.Free();
}
else if ( oFTobject.IsName("Ch") )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int nQuadding = 0;
Object oTemp;
if ( FieldLookup( pField, "Q", &oTemp )->IsInt() )
{
nQuadding = oTemp.GetInt();
}
else
{
nQuadding = fieldQuadLeft;
}
oTemp.Free();
// ComboBox
if ( nFiledFlags & fieldFlagCombo )
{
Object oValue;
if ( FieldLookup( pField, "V", &oValue)->IsString() )
{
DrawText( oValue.GetString(), seDA, pFontDict, FALSE, 0, nQuadding, TRUE, FALSE);
//~ Acrobat draws a popup icon on the right side
}
oValue.Free();
}
else // ListBox
{
Object oOptions;
if ( pField->Search("Opt", &oOptions)->IsArray() )
{
int nOptionsCount = oOptions.ArrayGetLength();
// Option text
StringExt **ppText = (StringExt **)MemUtilsMallocArray(nOptionsCount, sizeof(StringExt *));
for ( int nIndex = 0; nIndex < nOptionsCount; ++nIndex )
{
ppText[nIndex] = NULL;
Object oTemp;
oOptions.ArrayGet( nIndex, &oTemp );
if ( oTemp.IsString() )
{
ppText[nIndex] = oTemp.GetString()->Copy();
}
else if ( oTemp.IsArray() && oTemp.ArrayGetLength() == 2 )
{
Object oArrayItem;
if ( oTemp.ArrayGet( 1, &oArrayItem)->IsString() )
{
ppText[nIndex] = oArrayItem.GetString()->Copy();
}
oArrayItem.Free();
}
oTemp.Free();
if ( !ppText[nIndex] )
{
ppText[nIndex] = new StringExt();
}
}
// Selected option(s)
BOOL *pSelection = (BOOL *)MemUtilsMallocArray( nOptionsCount, sizeof(BOOL));
//~ need to use the I field in addition to the V field
Object oValue;
FieldLookup( pField, "V", &oValue);
for ( int nIndex = 0; nIndex < nOptionsCount; ++nIndex )
{
pSelection[nIndex] = FALSE;
if ( oValue.IsString() )
{
if ( !oValue.GetString()->Compare( ppText[nIndex] ) )
{
pSelection[nIndex] = TRUE;
}
}
else if ( oValue.IsArray() )
{
for ( int nJ = 0; nJ < oValue.ArrayGetLength(); ++nJ )
{
Object oTemp;
if ( oValue.ArrayGet( nJ, &oTemp)->IsString() && !oTemp.GetString()->Compare( ppText[nIndex] ) )
{
pSelection[nIndex] = TRUE;
}
oTemp.Free();
}
}
}
oValue.Free();
// TI (Top Index)
int nTopIndex = 0;
if ( pField->Search("TI", &oValue)->IsInt() )
{
nTopIndex = oValue.GetInt();
}
else
{
nTopIndex = 0;
}
oValue.Free();
DrawListBox( ppText, pSelection, nOptionsCount, nTopIndex, seDA, pFontDict, nQuadding);
for ( int nIndex = 0; nIndex < nOptionsCount; ++nIndex )
{
delete ppText[nIndex];
}
MemUtilsFree( ppText );
MemUtilsFree( pSelection );
}
oOptions.Free();
}
}
else if ( oFTobject.IsName("Sig") )
{
//~unimp
}
else
{
// TO DO: Error "Unknown field type"
}
if ( seDA )
{
delete seDA;
}
// Appearance stream dictionary
Object oAppearanceDict;
oAppearanceDict.InitDict( m_pXref );
oAppearanceDict.DictAdd(CopyString("Length"), oDictItem.InitInt(m_seAppBuffer->GetLength()));
oAppearanceDict.DictAdd(CopyString("Subtype"), oDictItem.InitName("Form"));
oDictItem.InitArray( m_pXref );
Object oTemp;
oDictItem.ArrayAdd( oTemp.InitReal(0) );
oDictItem.ArrayAdd( oTemp.InitReal(0) );
oDictItem.ArrayAdd( oTemp.InitReal(m_dMaxX - m_dMinX) );
oDictItem.ArrayAdd( oTemp.InitReal(m_dMaxY - m_dMinY) );
oAppearanceDict.DictAdd(CopyString("BBox"), &oDictItem);
// Resource dictionary
if ( oDRobject.IsDict() )
{
oAppearanceDict.DictAdd(CopyString("Resources"), oDRobject.Copy(&oDictItem));
}
oDRobject.Free();
// Appearance stream
MemoryStream *pAppearStream = new MemoryStream( m_seAppBuffer->GetBuffer(), 0, m_seAppBuffer->GetLength(), &oAppearanceDict);
m_oAppearance.Free();
m_oAppearance.InitStream( pAppearStream );
if ( pFontDict )
{
delete pFontDict;
}
oFTobject.Free();
oMKObject.Free();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <pArray> (<28> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 1, 3, <20><><EFBFBD> 4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>). <20><><EFBFBD><EFBFBD> <nAdjust> <20><><EFBFBD><EFBFBD><EFBFBD> +1, <20><><EFBFBD><EFBFBD> color is <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <nAdjust> <20><><EFBFBD><EFBFBD><EFBFBD>
// -1, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
void Annot::SetColor(Array *pArray, BOOL bFill, int nAdjust)
{
double arrColor[4];
int nComponentsCount = pArray->GetCount();
if ( nComponentsCount > 4 )
{
nComponentsCount = 4;
}
for ( int nIndex = 0; nIndex < nComponentsCount && nIndex < 4; ++nIndex )
{
Object oTemp;
if ( pArray->Get( nIndex, &oTemp)->IsNum() )
{
arrColor[nIndex] = oTemp.GetNum();
}
else
{
arrColor[nIndex] = 0;
}
oTemp.Free();
}
if ( 4 == nComponentsCount )
{
nAdjust = -nAdjust;
}
if ( nAdjust > 0 )
{
for ( int nIndex = 0; nIndex < nComponentsCount; ++nIndex )
{
arrColor[nIndex] = 0.5 * arrColor[nIndex] + 0.5;
}
}
else if ( nAdjust < 0 )
{
for ( int nIndex = 0; nIndex < nComponentsCount; ++nIndex )
{
arrColor[nIndex] = 0.5 * arrColor[nIndex];
}
}
if ( 4 == nComponentsCount )
{
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n", arrColor[0], arrColor[1], arrColor[2], arrColor[3], bFill ? 'k' : 'K');
}
else if ( 3 == nComponentsCount )
{
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:s}\n", arrColor[0], arrColor[1], arrColor[2], bFill ? "rg" : "RG");
}
else
{
m_seAppBuffer->AppendFormat("{0:.2f} {1:c}\n", arrColor[0], bFill ? 'g' : 'G');
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> Field.
void Annot::DrawText(StringExt *seText, StringExt *seDA, GrFontDict *pFontDict, BOOL bMultiline, int nComb, int nQuadding, BOOL bTextField, BOOL bForceZapfDingbats)
{
CList *pListDA;
StringExt *seToken;
double dX, dY, dWidth;
int i, j, k, nChar;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Default Appearance string
int nTfPos = -1, nTmPos = -1;
if ( seDA )
{
pListDA = new CList();
i = 0;
while ( i < seDA->GetLength() )
{
while ( i < seDA->GetLength() && Lexer::IsSpace( seDA->GetAt(i) ) )
{
++i;
}
if ( i < seDA->GetLength() )
{
for ( j = i + 1; j < seDA->GetLength() && !Lexer::IsSpace(seDA->GetAt(j) ); ++j) ;
pListDA->Append(new StringExt(seDA, i, j - i));
i = j;
}
}
for ( i = 2; i < pListDA->GetLength(); ++i )
{
if ( i >= 2 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tf") )
{
nTfPos = i - 2;
}
else if ( i >= 6 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tm") )
{
nTmPos = i - 6;
}
}
}
else
{
pListDA = NULL;
}
// ZapfDingbats
if ( bForceZapfDingbats )
{
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTfPos );
if ( seToken->Compare("/ZaDb") )
{
seToken->Clear();
seToken->Append("/ZaDb");
}
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GrFont *pFont = NULL;
double dFontSize = 0;
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTfPos );
if ( seToken->GetLength() >= 1 && seToken->GetAt(0) == '/' )
{
if ( !pFontDict || !(pFont = pFontDict->Search(seToken->GetBuffer() + 1) ) )
{
// TO DO: Error "Unknown font in field's DA string"
}
}
else
{
// TO DO: Error "Invalid font name in 'Tf' operator in field's DA string"
}
seToken = (StringExt *)pListDA->GetByIndex( nTfPos + 1 );
dFontSize = atof( seToken->GetBuffer());
}
else
{
// TO DO: Error "Missing 'Tf' operator in field's DA string"
}
// Border Width
double dBorderWidth = m_pBorderStyle->GetWidth();
if ( bTextField )
{
m_seAppBuffer->Append("/Tx BMC\n");
}
m_seAppBuffer->Append("q\n");
m_seAppBuffer->Append("BT\n");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
if ( bMultiline )
{
// <20><><EFBFBD><EFBFBD><EFBFBD> nComb <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double dWMax = m_dMaxX - m_dMinX - 2 * dBorderWidth - 4;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
if ( 0 == dFontSize )
{
for ( dFontSize = 20; dFontSize > 1; --dFontSize )
{
dY = m_dMaxY - m_dMinY;
double dMaxLineWidth = 0;
i = 0;
while ( i < seText->GetLength() )
{
GetNextLine( seText, i, pFont, dFontSize, dWMax, &j, &dWidth, &k);
if ( dWidth > dMaxLineWidth )
{
dMaxLineWidth = dWidth;
}
i = k;
dY -= dFontSize;
}
if ( dY >= 0.33 * dFontSize )
{
break;
}
}
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTfPos + 1 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dFontSize);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Y
// (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Td)
dY = m_dMaxY - m_dMinY;
// Font Matrix
if ( nTmPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 4);
seToken->Clear();
seToken->Append('0');
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 5);
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dY);
}
// <20><><EFBFBD><EFBFBD><EFBFBD> DA-string
if ( pListDA )
{
for (i = 0; i < pListDA->GetLength(); ++i)
{
m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(i))->Append(' ');
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD> Font Matrix (<28><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20> DA-string)
if ( nTmPos < 0 )
{
m_seAppBuffer->AppendFormat("1 0 0 1 0 {0:.2f} Tm\n", dY);
}
i = 0;
double dPrevX = 0;
while ( i < seText->GetLength() )
{
GetNextLine( seText, i, pFont, dFontSize, dWMax, &j, &dWidth, &k);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
switch ( nQuadding )
{
case fieldQuadLeft:
default:
dX = dBorderWidth + 2;
break;
case fieldQuadCenter:
dX = (m_dMaxX - m_dMinX - dWidth) / 2;
break;
case fieldQuadRight:
dX = m_dMaxX - m_dMinX - dBorderWidth - 2 - dWidth;
break;
}
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} Td\n", dX - dPrevX, -dFontSize);
m_seAppBuffer->Append('(');
for (; i < j; ++i)
{
nChar = seText->GetAt(i) & 0xff;
if ( nChar == '(' || nChar == ')' || nChar == '\\' )
{
m_seAppBuffer->Append('\\');
m_seAppBuffer->Append(nChar);
}
else if ( nChar < 0x20 || nChar >= 0x80 )
{
m_seAppBuffer->AppendFormat("\\{0:03o}", nChar);
}
else
{
m_seAppBuffer->Append(nChar);
}
}
m_seAppBuffer->Append(") Tj\n");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
i = k;
dPrevX = dX;
}
}
else // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
{
if ( nComb > 0 )
{
dWidth = (m_dMaxX - m_dMinX - 2 * dBorderWidth) / nComb;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
if ( 0 == dFontSize )
{
dFontSize = m_dMaxY - m_dMinY - 2 * dBorderWidth;
if ( dWidth < dFontSize )
{
dFontSize = dWidth;
}
dFontSize = floor(dFontSize);
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTfPos + 1 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dFontSize);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
switch ( nQuadding )
{
case fieldQuadLeft:
default:
dX = dBorderWidth + 2;
break;
case fieldQuadCenter:
dX = dBorderWidth + 2 + 0.5 * (nComb - seText->GetLength()) * dWidth;
break;
case fieldQuadRight:
dX = dBorderWidth + 2 + (nComb - seText->GetLength()) * dWidth;
break;
}
dY = 0.5 * (m_dMaxY - m_dMinY) - 0.4 * dFontSize;
// Font Matrix
if ( nTmPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 4 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dX);
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 5 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dY);
}
// DA-string
if ( pListDA )
{
for (i = 0; i < pListDA->GetLength(); ++i)
{
m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(i))->Append(' ');
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD> Font Matrix (<28><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20> DA-string)
if ( nTmPos < 0 )
{
m_seAppBuffer->AppendFormat("1 0 0 1 {0:.2f} {1:.2f} Tm\n", dX, dY);
}
// write the text string
//~ this should center (instead of left-justify) each character within
//~ its comb cell
for ( i = 0; i < seText->GetLength(); ++i )
{
if ( i > 0 )
{
m_seAppBuffer->AppendFormat("{0:.2f} 0 Td\n", dWidth);
}
m_seAppBuffer->Append('(');
nChar = seText->GetAt(i) & 0xff;
if ( nChar == '(' || nChar == ')' || nChar == '\\' )
{
m_seAppBuffer->Append('\\');
m_seAppBuffer->Append(nChar);
}
else if ( nChar < 0x20 || nChar >= 0x80 )
{
m_seAppBuffer->AppendFormat("{0:.2f} 0 Td\n", dWidth);
}
else
{
m_seAppBuffer->Append(nChar);
}
m_seAppBuffer->Append(") Tj\n");
}
}
else // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (non-comb)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( pFont && !pFont->IsCIDFont() )
{
dWidth = 0;
for ( i = 0; i < seText->GetLength(); ++i )
{
dWidth += ( (Gr8BitFont *)pFont )->GetWidth( seText->GetAt(i) );
}
}
else
{
dWidth = seText->GetLength() * 0.5;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
if ( 0 == dFontSize )
{
dFontSize = m_dMaxY - m_dMinY - 2 * dBorderWidth;
double dTempFontSize = (m_dMaxX - m_dMinX - 4 - 2 * dBorderWidth) / dWidth;
if ( dTempFontSize < dFontSize )
{
dFontSize = dTempFontSize;
}
dFontSize = floor(dFontSize);
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTfPos + 1 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dFontSize);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dWidth *= dFontSize;
switch ( nQuadding )
{
case fieldQuadLeft:
default:
dX = dBorderWidth + 2;
break;
case fieldQuadCenter:
dX = (m_dMaxX - m_dMinX - dWidth) / 2;
break;
case fieldQuadRight:
dX = m_dMaxX - m_dMinX - dBorderWidth - 2 - dWidth;
break;
}
dY = 0.5 * (m_dMaxY - m_dMinY) - 0.4 * dFontSize;
// Font Matrix
if ( nTmPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 4 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dX);
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 5 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dY);
}
// DA-string
if ( pListDA )
{
for ( i = 0; i < pListDA->GetLength(); ++i)
{
m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(i))->Append(' ');
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD> Font Matrix (<28><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20> DA-string)
if ( nTmPos < 0 )
{
m_seAppBuffer->AppendFormat("1 0 0 1 {0:.2f} {1:.2f} Tm\n", dX, dY);
}
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
m_seAppBuffer->Append('(');
for ( i = 0; i < seText->GetLength(); ++i )
{
nChar = seText->GetAt(i) & 0xff;
if ( nChar == '(' || nChar == ')' || nChar == '\\' )
{
m_seAppBuffer->Append('\\');
m_seAppBuffer->Append(nChar);
}
else if ( nChar < 0x20 || nChar >= 0x80 )
{
m_seAppBuffer->AppendFormat("\\{0:03o}", nChar);
}
else
{
m_seAppBuffer->Append(nChar);
}
}
m_seAppBuffer->Append(") Tj\n");
}
}
m_seAppBuffer->Append("ET\n");
m_seAppBuffer->Append("Q\n");
if ( bTextField )
{
m_seAppBuffer->Append("EMC\n");
}
if ( pListDA )
{
DeleteCList( pListDA, StringExt);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> Field.
void Annot::DrawListBox(StringExt **ppText, BOOL *pSelection, int nOptionsCount, int nTopIndex, StringExt *seDA, GrFontDict *pFontDict, BOOL bQuadding)
{
CList *pListDA;
StringExt *seToken;
int i, j;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Default appearance string
int nTfPos = -1, nTmPos = -1;
if ( seDA )
{
pListDA = new CList();
i = 0;
while ( i < seDA->GetLength() )
{
while ( i < seDA->GetLength() && Lexer::IsSpace(seDA->GetAt(i)) )
{
++i;
}
if ( i < seDA->GetLength() )
{
for (j = i + 1; j < seDA->GetLength() && !Lexer::IsSpace(seDA->GetAt(j)); ++j) ;
pListDA->Append(new StringExt(seDA, i, j - i));
i = j;
}
}
for ( i = 2; i < pListDA->GetLength(); ++i )
{
if ( i >= 2 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tf") )
{
nTfPos = i - 2;
}
else if ( i >= 6 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tm") )
{
nTmPos = i - 6;
}
}
}
else
{
pListDA = NULL;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GrFont *pFont = NULL;
double dFontSize = 0;
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex(nTfPos);
if ( seToken->GetLength() >= 1 && seToken->GetAt(0) == '/' )
{
if ( !pFontDict || !(pFont = pFontDict->Search(seToken->GetBuffer() + 1)) )
{
// TO DO: Error "Unknown font in field's DA string"
}
}
else
{
// TO DO: Error "Invalid font name in 'Tf' operator in field's DA string"
}
seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1);
dFontSize = atof(seToken->GetBuffer());
}
else
{
// TO DO: Error "Missing 'Tf' operator in field's DA string"
}
// Border width
double dBorder = m_pBorderStyle->GetWidth();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
double dWidth = 0;
if ( 0 == dFontSize )
{
double dMaxW = 0;
for ( i = 0; i < nOptionsCount; ++i )
{
if ( pFont && !pFont->IsCIDFont() )
{
dWidth = 0;
for ( j = 0; j < ppText[i]->GetLength(); ++j )
{
dWidth += ((Gr8BitFont *)pFont)->GetWidth(ppText[i]->GetAt(j));
}
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dWidth = ppText[i]->GetLength() * 0.5;
}
if ( dWidth > dMaxW )
{
dMaxW = dWidth;
}
}
dFontSize = m_dMaxY - m_dMinY - 2 * dBorder;
double dFontSize2 = (m_dMaxX - m_dMinX - 4 - 2 * dBorder) / dMaxW;
if ( dFontSize2 < dFontSize )
{
dFontSize = dFontSize2;
}
dFontSize = floor(dFontSize);
if ( nTfPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1);
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dFontSize);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
double dY = m_dMaxY - m_dMinY - 1.1 * dFontSize;
for ( i = nTopIndex; i < nOptionsCount; ++i )
{
m_seAppBuffer->Append("q\n");
// Background
if ( pSelection[i] )
{
m_seAppBuffer->Append("0 g f\n");
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re f\n", dBorder, dY - 0.2 * dFontSize, m_dMaxX - m_dMinX - 2 * dBorder, 1.1 * dFontSize);
}
m_seAppBuffer->Append("BT\n");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( pFont && !pFont->IsCIDFont() )
{
dWidth = 0;
for ( j = 0; j < ppText[i]->GetLength(); ++j )
{
dWidth += ((Gr8BitFont *)pFont)->GetWidth(ppText[i]->GetAt(j));
}
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dWidth = ppText[i]->GetLength() * 0.5;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double dX = 0;
dWidth *= dFontSize;
switch ( bQuadding )
{
case fieldQuadLeft:
default:
dX = dBorder + 2;
break;
case fieldQuadCenter:
dX = (m_dMaxX - m_dMinX - dWidth) / 2;
break;
case fieldQuadRight:
dX = m_dMaxX - m_dMinX - dBorder - 2 - dWidth;
break;
}
// Font Matrix
if ( nTmPos >= 0 )
{
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 4 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dX);
seToken = (StringExt *)pListDA->GetByIndex( nTmPos + 5 );
seToken->Clear();
seToken->AppendFormat("{0:.2f}", dY);
}
// DA string
if ( pListDA )
{
for (j = 0; j < pListDA->GetLength(); ++j)
{
m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(j))->Append(' ');
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD> Font Matrix (<28><><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DA-string)
if ( nTmPos < 0 )
{
m_seAppBuffer->AppendFormat("1 0 0 1 {0:.2f} {1:.2f} Tm\n", dX, dY);
}
if ( pSelection[i] )
{
m_seAppBuffer->Append("1 g\n");
}
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
m_seAppBuffer->Append('(');
for ( j = 0; j < ppText[i]->GetLength(); ++j )
{
int nChar = ppText[i]->GetAt(j) & 0xff;
if ( nChar == '(' || nChar == ')' || nChar == '\\' )
{
m_seAppBuffer->Append('\\');
m_seAppBuffer->Append(nChar);
}
else if ( nChar < 0x20 || nChar >= 0x80 )
{
m_seAppBuffer->AppendFormat("\\{0:03o}", nChar);
}
else
{
m_seAppBuffer->Append(nChar);
}
}
m_seAppBuffer->Append(") Tj\n");
m_seAppBuffer->Append("ET\n");
m_seAppBuffer->Append("Q\n");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dY -= 1.1 * dFontSize;
}
if ( pListDA )
{
DeleteCList( pListDA, StringExt );
}
}
void Annot::GetNextLine(StringExt *seText, int nStart, GrFont *pFont, double dFontSize, double dMaxW, int *pEnd, double *pWidth, int *pNext)
{
double dWidth = 0, dTempWidth;
int j, k;
for ( j = nStart; j < seText->GetLength() && dWidth <= dMaxW; ++j )
{
int nChar = seText->GetAt(j) & 0xff;
if ( nChar == 0x0a || nChar == 0x0d )
{
break;
}
if ( pFont && !pFont->IsCIDFont() )
{
dTempWidth = ((Gr8BitFont *)pFont)->GetWidth(nChar) * dFontSize;
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dTempWidth = 0.5 * dFontSize;
}
dWidth += dTempWidth;
}
if ( dWidth > dMaxW )
{
for ( k = j; k > nStart && seText->GetAt(k - 1) != ' '; --k );
for ( ; k > nStart && seText->GetAt(k - 1) == ' '; --k );
if ( k > nStart )
{
j = k;
}
if ( j == nStart )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
j = nStart + 1;
}
}
*pEnd = j;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dWidth = 0;
for ( k = nStart; k < j; ++k )
{
if ( pFont && !pFont->IsCIDFont() )
{
dTempWidth = ((Gr8BitFont *)pFont)->GetWidth(seText->GetAt(k)) * dFontSize;
}
else
{
dTempWidth = 0.5 * dFontSize;
}
dWidth += dTempWidth;
}
*pWidth = dWidth;
while (j < seText->GetLength() && seText->GetAt(j) == ' ')
{
++j;
}
if ( j < seText->GetLength() && seText->GetAt(j) == 0x0d )
{
++j;
}
if ( j < seText->GetLength() && seText->GetAt(j) == 0x0a )
{
++j;
}
*pNext = j;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
// = (4 * (sqrt(2) - 1) / 3) * r
#define Kappa 0.55228475
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>. (dX, dY) - <20><><EFBFBD><EFBFBD><EFBFBD>, dRad - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// bFill - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
void Annot::DrawCircle(double dX, double dY, double dRad, BOOL bFill)
{
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} m\n", dX + dRad, dY);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + dRad, dY + Kappa * dRad, dX + Kappa * dRad, dY + dRad, dX, dY + dRad);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - Kappa * dRad, dY + dRad, dX - dRad, dY + Kappa * dRad, dX - dRad, dY );
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - dRad, dY - Kappa * dRad, dX - Kappa * dRad, dY - dRad, dX, dY - dRad);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + Kappa * dRad, dY - dRad, dX + dRad, dY - Kappa * dRad, dX + dRad, dY );
m_seAppBuffer->Append( bFill ? "f\n" : "s\n" );
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>. (dX, dY) - <20><><EFBFBD><EFBFBD><EFBFBD>, dRad - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
void Annot::DrawCircleTopLeft(double dX, double dY, double dRad)
{
double dRad2 = dRad / sqrt(2.0);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} m\n", dX + dRad2, dY + dRad2);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + (1 - Kappa) * dRad2, dY + (1 + Kappa) * dRad2, dX - (1 - Kappa) * dRad2, dY + (1 + Kappa) * dRad2, dX - dRad2, dY + dRad2);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - (1 + Kappa) * dRad2, dY + (1 - Kappa) * dRad2, dX - (1 + Kappa) * dRad2, dY - (1 - Kappa) * dRad2, dX - dRad2, dY - dRad2);
m_seAppBuffer->Append("S\n");
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>. (dX, dY) - <20><><EFBFBD><EFBFBD><EFBFBD>, dRad - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
void Annot::DrawCircleBottomRight(double dX, double dY, double dRad)
{
double dRad2 = dRad / sqrt(2.0);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} m\n", dX - dRad2, dY - dRad2);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - (1 - Kappa) * dRad2, dY - (1 + Kappa) * dRad2, dX + (1 - Kappa) * dRad2, dY - (1 + Kappa) * dRad2, dX + dRad2, dY - dRad2);
m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + (1 + Kappa) * dRad2, dY - (1 - Kappa) * dRad2, dX + (1 + Kappa) * dRad2, dY + (1 - Kappa) * dRad2, dX + dRad2, dY + dRad2);
m_seAppBuffer->Append("S\n");
}
Object *Annot::FieldLookup(Dict *pField, char *sKey, Object *pObject)
{
Dict *pDict = pField;
if ( !pDict->Search(sKey, pObject)->IsNull() )
{
return pObject;
}
pObject->Free();
Object oParent;
if ( pDict->Search("Parent", &oParent)->IsDict() )
{
FieldLookup( oParent.GetDict(), sKey, pObject);
}
else
{
pObject->InitNull();
}
oParent.Free();
return pObject;
}
void Annot::Draw(Graphics *pGraphics, BOOL bPrinting)
{
// Flags
if ( (m_nFlags & annotFlagHidden) || (bPrinting && !(m_nFlags & annotFlagPrint)) || (!bPrinting && (m_nFlags & annotFlagNoView)) )
{
return;
}
// Appearance stream
BOOL bIsLink = m_seType && !m_seType->Compare("Link");
Object oTemp;
m_oAppearance.Fetch( m_pXref, &oTemp);
pGraphics->DrawAnnotation( &oTemp, (bIsLink ? m_pBorderStyle : (AnnotBorderStyle *)NULL), m_dMinX, m_dMinY, m_dMaxX, m_dMaxY);
oTemp.Free();
}
//-------------------------------------------------------------------------------------------------------------------------------
// Annots
//-------------------------------------------------------------------------------------------------------------------------------
Annots::Annots(GlobalParams *pGlobalParams, XRef *pXref, Catalog *pCatalog, Object *pAnnotsObject)
{
m_pGlobalParams = pGlobalParams;
Annot *pAnnot = NULL;
Ref oRef;
m_ppAnnots = NULL;
int nSize = 0;
m_nAnnotsCount = 0;
Dict *pAcroForm = (pCatalog->GetAcroForm()->IsDict() ? pCatalog->GetAcroForm()->GetDict() : NULL);
if ( pAnnotsObject->IsArray() )
{
for ( int nIndex = 0; nIndex < pAnnotsObject->ArrayGetLength(); ++nIndex )
{
Object oTemp;
if ( pAnnotsObject->ArrayGetCopy(nIndex, &oTemp)->IsRef() )
{
oRef = oTemp.GetRef();
oTemp.Free();
pAnnotsObject->ArrayGet(nIndex, &oTemp);
}
else
{
oRef.nNum = oRef.nGen = -1;
}
if ( oTemp.IsDict() )
{
pAnnot = new Annot( m_pGlobalParams, pXref, pAcroForm, oTemp.GetDict(), &oRef );
if ( pAnnot->CheckValidation() )
{
if ( m_nAnnotsCount >= nSize )
{
nSize += 16;
m_ppAnnots = (Annot **)MemUtilsReallocArray(m_ppAnnots, nSize, sizeof(Annot *));
}
m_ppAnnots[m_nAnnotsCount++] = pAnnot;
}
else
{
delete pAnnot;
}
}
oTemp.Free();
}
}
}
Annots::~Annots()
{
for ( int nIndex = 0; nIndex < m_nAnnotsCount; ++nIndex )
{
delete m_ppAnnots[nIndex];
}
MemUtilsFree( m_ppAnnots );
}
void Annots::GenerateAppearances(Dict *pAcroForm)
{
Ref oRef;
Object oField;
if ( pAcroForm->Search("Fields", &oField)->IsArray() )
{
for ( int nIndex = 0; nIndex < oField.ArrayGetLength(); ++nIndex )
{
Object oItem;
if ( oField.ArrayGetCopy(nIndex, &oItem)->IsRef() )
{
oRef = oItem.GetRef();
oItem.Free();
oField.ArrayGet(nIndex, &oItem);
}
else
{
oRef.nNum = oRef.nGen = -1;
}
if ( oItem.IsDict() )
{
ScanFieldAppearances( oItem.GetDict(), &oRef, NULL, pAcroForm);
}
oItem.Free();
}
}
oField.Free();
}
void Annots::ScanFieldAppearances(Dict *pNode, Ref *pRef, Dict *pParent, Dict *pAcroForm)
{
Annot *pAnnot = NULL;
Ref oRef2;
Object oNodeItem;
if ( pNode->Search("Kids", &oNodeItem)->IsArray() )
{
for ( int nIndex = 0; nIndex < oNodeItem.ArrayGetLength(); ++nIndex )
{
Object oTemp;
if ( oNodeItem.ArrayGetCopy(nIndex, &oTemp)->IsRef() )
{
oRef2 = oTemp.GetRef();
oTemp.Free();
oNodeItem.ArrayGet(nIndex, &oTemp);
}
else
{
oRef2.nNum = oRef2.nGen = -1;
}
if ( oTemp.IsDict() )
{
ScanFieldAppearances( oTemp.GetDict(), &oRef2, pNode, pAcroForm);
}
oTemp.Free();
}
oNodeItem.Free();
return;
}
oNodeItem.Free();
if ( (pAnnot = FindAnnot(pRef)) )
{
pNode->SearchAndCopy("Parent", &oNodeItem);
if ( !pParent || !oNodeItem.IsNull() )
{
pAnnot->GenerateFieldAppearance( pNode, pNode, pAcroForm );
}
else
{
pAnnot->GenerateFieldAppearance( pParent, pNode, pAcroForm );
}
oNodeItem.Free();
}
}
Annot *Annots::FindAnnot(Ref *pRef)
{
for ( int nIndex = 0; nIndex < m_nAnnotsCount; ++nIndex)
{
if ( m_ppAnnots[nIndex]->Match(pRef) )
{
return m_ppAnnots[nIndex];
}
}
return NULL;
}