Files
DocumentServer-v-9.2.0/core/PdfFile/SrcWriter/Annotation.cpp
T
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

2559 lines
66 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "Annotation.h"
#include "Pages.h"
#include "Utils.h"
#include "ResourcesDictionary.h"
#include "FontCidTT.h"
#include "Streams.h"
#include "Image.h"
#include "../../DesktopEditor/common/File.h"
#ifndef BS_DEF_WIDTH
#define BS_DEF_WIDTH 1
#endif
namespace PdfWriter
{
const static char* c_sAnnotTypeNames[] =
{
"Text",
"Link",
"FreeText",
"Line",
"Square",
"Circle",
"Polygon",
"PolyLine",
"Highlight",
"Underline",
"Squiggly",
"StrikeOut",
"Stamp",
"Caret",
"Ink",
"Popup",
"FileAttachment",
"Sound",
"Movie",
"Widget",
"Screen",
"PrinterMark",
"TrapNet",
"Watermark",
"3D",
"Redact"
};
const static char* c_sAnnotIconNames[] =
{
"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"
};
const static char* c_sCheckBoxStyleNames[] =
{
"4", // Check
"8", // Cross
"u", // Diamond
"l", // Circle
"H", // Star
"n" // Square
};
void AddToVectorD(CDictObject* pObj, const std::string& sName, const std::vector<double>& arrV)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
pObj->Add(sName, pArray);
for (const double& dV : arrV)
pArray->Add(dV);
}
std::string AddLE(const BYTE& nLE)
{
std::string sValue;
ELineEndType eLE = ELineEndType(nLE);
switch (eLE)
{
case ELineEndType::Square: sValue = "Square"; break;
case ELineEndType::Circle: sValue = "Circle"; break;
case ELineEndType::Diamond: sValue = "Diamond"; break;
case ELineEndType::OpenArrow: sValue = "OpenArrow"; break;
case ELineEndType::ClosedArrow: sValue = "ClosedArrow"; break;
case ELineEndType::None: sValue = "None"; break;
case ELineEndType::Butt: sValue = "Butt"; break;
case ELineEndType::ROpenArrow: sValue = "ROpenArrow"; break;
case ELineEndType::RClosedArrow: sValue = "RClosedArrow"; break;
case ELineEndType::Slash: sValue = "Slash"; break;
}
return sValue;
}
void AddRD(CDictObject* pObj, const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
pObj->Add("RD", pArray);
pArray->Add(dRD1);
pArray->Add(dRD4);
pArray->Add(dRD3);
pArray->Add(dRD2);
}
std::string GetColor(const std::vector<double>& arr, bool bCaps, double dDiff = 0)
{
if (arr.empty())
return bCaps ? "1 G" : "1 g";
std::string sDA;
for (double dColoc : arr)
{
sDA.append(std::to_string(dColoc + dDiff));
sDA.append(" ");
}
if (arr.size() == 3)
sDA.append(bCaps ? "RG" : "rg");
else if (arr.size() == 4)
sDA.append(bCaps ? "K" : "k");
else if (arr.size() == 1)
sDA.append(bCaps ? "G" : "g");
return sDA;
}
std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0)
{
std::string sDA;
if (!pArr)
return sDA;
int nSize = pArr->GetCount();
for (int i = 0; i < nSize; ++i)
{
CObjectBase* pColor = pArr->Get(i);
float fColor = pColor->GetType() == object_type_REAL ? ((CRealObject*)pColor)->Get() : ((CNumberObject*)pColor)->Get();
sDA.append(std::to_string(fColor + dDiff));
sDA.append(" ");
}
if (nSize == 3)
sDA.append(bCAPS ? "RG" : "rg");
else if (nSize == 4)
sDA.append(bCAPS ? "K" : "k");
else if (nSize == 1)
sDA.append(bCAPS ? "G" : "g");
return sDA;
}
//----------------------------------------------------------------------------------------
// CAnnotation
//----------------------------------------------------------------------------------------
CAnnotation::CAnnotation(CXref* pXref, EAnnotType eType)
{
m_pAppearance = NULL;
m_pDocument = NULL;
m_pXref = pXref;
m_oBorder.bHave = false;
Add("Type", "Annot");
Add("Subtype", c_sAnnotTypeNames[(int)eType]);
// Для PDFA нужно, чтобы 0, 1, 4 биты были выключены, а второй включен
Add("F", 4);
}
void CAnnotation::SetRect(const TRect& oRect)
{
m_oRect = oRect;
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("Rect", pArray);
if (oRect.fTop < oRect.fBottom)
{
m_oRect.fTop = oRect.fBottom;
m_oRect.fBottom = oRect.fTop;
}
pArray->Add(m_oRect.fLeft);
pArray->Add(m_oRect.fBottom);
pArray->Add(m_oRect.fRight);
pArray->Add(m_oRect.fTop);
}
void CAnnotation::SetBorder(BYTE nType, double dWidth, const std::vector<double>& arrDash)
{
CDictObject* pBorderStyleDict = new CDictObject();
if (!pBorderStyleDict)
return;
Add("BS", pBorderStyleDict);
pBorderStyleDict->Add("Type", "Border");
pBorderStyleDict->Add("W", dWidth);
EBorderType eBT = EBorderType(nType);
if (EBorderType::Dashed == eBT)
AddToVectorD(pBorderStyleDict, "D", arrDash);
switch (eBT)
{
case EBorderType::Solid: pBorderStyleDict->Add("S", "S"); break;
case EBorderType::Dashed: pBorderStyleDict->Add("S", "D"); break;
case EBorderType::Beveled: pBorderStyleDict->Add("S", "B"); break;
case EBorderType::Inset: pBorderStyleDict->Add("S", "I"); break;
case EBorderType::Underline: pBorderStyleDict->Add("S", "U"); break;
}
m_oBorder.bHave = true;
m_oBorder.nType = EBorderType(nType);
m_oBorder.dWidth = dWidth;
m_oBorder.arrDash = arrDash;
}
void CAnnotation::SetAnnotFlag(const int& nAnnotFlag)
{
Add("F", nAnnotFlag);
}
void CAnnotation::SetPage(CPage* pPage, double dW, double dH, double dX, double dY)
{
Add("P", pPage);
m_dPageW = dW;
m_dPageH = dH;
m_dPageX = dX;
m_dPageY = dY;
}
void CAnnotation::SetBE(BYTE nType, const double& dBE)
{
CDictObject* pBEDict = new CDictObject();
if (!pBEDict)
return;
Add("BE", pBEDict);
pBEDict->Add("I", dBE);
std::string sValue;
switch (nType)
{
case 0:
{ sValue = "S"; break; }
case 1:
{ sValue = "C"; break; }
default: { return; }
}
pBEDict->Add("S", sValue.c_str());
}
void CAnnotation::SetContents(const std::wstring& wsText)
{
std::string sValue = U_TO_UTF8(wsText);
Add("Contents", new CStringObject(sValue.c_str(), true));
// TODO
Remove("RC");
}
void CAnnotation::SetNM(const std::wstring& wsNM)
{
std::string sValue = U_TO_UTF8(wsNM);
Add("NM", new CStringObject(sValue.c_str()));
}
void CAnnotation::SetLM(const std::wstring& wsLM)
{
std::string sValue = U_TO_UTF8(wsLM);
Add("M", new CStringObject(sValue.c_str()));
}
void CAnnotation::SetOUserID(const std::wstring& wsLM)
{
std::string sValue = U_TO_UTF8(wsLM);
Add("OUserID", new CStringObject(sValue.c_str()));
}
void CAnnotation::SetOMetadata(const std::wstring& wsOMetadata)
{
std::string sValue = U_TO_UTF8(wsOMetadata);
Add("OMetadata", new CStringObject(sValue.c_str(), true));
}
void CAnnotation::SetC(const std::vector<double>& arrC)
{
AddToVectorD(this, "C", arrC);
}
void CAnnotation::SetDocument(CDocument* pDocument)
{
m_pDocument = pDocument;
}
CDocument* CAnnotation::GetDocument()
{
return m_pDocument;
}
std::string CAnnotation::GetBorderDash()
{
std::string sRes = "[";
for (double dDash : m_oBorder.arrDash)
{
sRes.append(" ");
sRes.append(std::to_string(dDash));
}
sRes.append(" ] 0 d\012");
return sRes;
}
std::string CAnnotation::GetColorName(const std::string& sName, bool bCAPS)
{
std::string sRes;
CObjectBase* pObj = Get(sName);
if (pObj && pObj->GetType() == object_type_ARRAY)
{
sRes += GetColor(dynamic_cast<CArrayObject*>(pObj), bCAPS).c_str();
sRes += "\012";
}
return sRes;
}
CAnnotAppearanceObject* CAnnotation::StartAP(int nRotate)
{
m_pAppearance = new CAnnotAppearance(m_pXref, this);
if (!m_pAppearance)
return NULL;
Add("AP", m_pAppearance);
CResourcesDict* pResources = new CResourcesDict(m_pXref, false, false);
CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(pResources);
pNormal->Add("Resources", pResources);
return pNormal;
}
void CAnnotation::APFromFakePage()
{
if (!m_pAppearance)
return;
CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal();
pNormal->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop);
pNormal->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom);
}
//----------------------------------------------------------------------------------------
// CMarkupAnnotation
//----------------------------------------------------------------------------------------
CMarkupAnnotation::CMarkupAnnotation(CXref* pXref, EAnnotType eType) : CAnnotation(pXref, eType)
{
}
void CMarkupAnnotation::SetRT(BYTE nRT)
{
Add("RT", nRT ? "Group" : "R");
}
CPopupAnnotation* CMarkupAnnotation::CreatePopup()
{
CPopupAnnotation* pAnnot = new CPopupAnnotation(m_pXref);
m_pXref->Add(pAnnot);
Add("Popup", pAnnot);
pAnnot->SetOpen(false);
pAnnot->SetParentID(this);
pAnnot->SetAnnotFlag(28);
TRect oRect = m_oRect;
oRect.fLeft = m_dPageW - 100 - (oRect.fRight - oRect.fLeft);
oRect.fBottom -= 100;
oRect.fRight = m_dPageW;
pAnnot->SetRect(oRect);
return pAnnot;
}
void CMarkupAnnotation::SetCA(const double& dCA)
{
Add("CA", dCA);
}
void CMarkupAnnotation::SetT(const std::wstring& wsT)
{
std::string sValue = U_TO_UTF8(wsT);
if (!Get("T"))
Add("T", new CStringObject(sValue.c_str(), true));
}
void CMarkupAnnotation::SetRC(const std::wstring& wsRC)
{
std::string sValue = U_TO_UTF8(wsRC);
Add("RC", new CStringObject(sValue.c_str(), true));
}
void CMarkupAnnotation::SetCD(const std::wstring& wsCD)
{
std::string sValue = U_TO_UTF8(wsCD);
Add("CreationDate", new CStringObject(sValue.c_str()));
}
void CMarkupAnnotation::SetSubj(const std::wstring& wsSubj)
{
std::string sValue = U_TO_UTF8(wsSubj);
Add("Subj", new CStringObject(sValue.c_str(), true));
}
void CMarkupAnnotation::SetIRTID(CAnnotation* pAnnot)
{
Add("IRT", pAnnot);
}
void CMarkupAnnotation::RemoveAP()
{
Remove("AP");
}
//----------------------------------------------------------------------------------------
// CLinkAnnotation
//----------------------------------------------------------------------------------------
CLinkAnnotation::CLinkAnnotation(CXref* pXref, CDestination* pDestination) : CAnnotation(pXref, AnnotLink)
{
Add("Dest", (CObjectBase*)pDestination);
}
void CLinkAnnotation::SetBorderStyle(float fWidth, unsigned short nDashOn, unsigned short nDashOff)
{
fWidth = std::max(fWidth, 0.f);
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("Border", pArray);
pArray->Add(0);
pArray->Add(0);
pArray->Add(fWidth);
if (nDashOn && nDashOff)
{
CArrayObject* pDash = new CArrayObject();
if (!pDash)
return;
pArray->Add(pDash);
pDash->Add(nDashOn);
pDash->Add(nDashOff);
}
}
void CLinkAnnotation::SetHighlightMode(EAnnotHighlightMode eMode)
{
switch (eMode)
{
case AnnotNoHighlight: Add("H", "N"); break;
case AnnotInvertBorder: Add("H", "O"); break;
case AnnotDownAppearance: Add("H", "P"); break;
default: Remove("H"); break;
}
}
//----------------------------------------------------------------------------------------
// CTextAnnotation
//----------------------------------------------------------------------------------------
CTextAnnotation::CTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotText)
{
m_nName = 10;
Add("Name", "Comment");
}
void CTextAnnotation::SetOpen(bool bOpen)
{
Add("Open", new CBoolObject(bOpen));
}
void CTextAnnotation::SetName(BYTE nName)
{
m_nName = nName;
Add("Name", c_sAnnotIconNames[nName]);
}
void CTextAnnotation::SetState(BYTE nState)
{
std::string sValue;
switch (nState)
{
case 0:
{ sValue = "Marked"; break; }
case 1:
{ sValue = "Unmarked"; break; }
case 2:
{ sValue = "Accepted"; break; }
case 3:
{ sValue = "Rejected"; break; }
case 4:
{ sValue = "Cancelled"; break; }
case 5:
{ sValue = "Completed"; break; }
case 6:
{ sValue = "None"; break; }
default: { return; }
}
Add("State", new CStringObject(sValue.c_str()));
if (!Get("C"))
SetC({ 1.0, 0.8, 0.0 });
}
void CTextAnnotation::SetStateModel(BYTE nStateModel)
{
std::string sValue;
switch (nStateModel)
{
case 0:
{ sValue = "Marked"; break; }
case 1:
{ sValue = "Review"; break; }
default: { return; }
}
Add("StateModel", new CStringObject(sValue.c_str()));
}
void CTextAnnotation::SetAP()
{
std::string sColor = GetColor(dynamic_cast<CArrayObject*>(Get("C")), false);
CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this);
Add("AP", pAP);
CAnnotAppearanceObject* pN = pAP->GetNormal();
CAnnotAppearanceObject* pR = pAP->GetRollover();
switch (m_nName)
{
case 0:
{
pN->AddBBox(0, 0, 19, 19);
pN->DrawTextCheck(sColor);
pR->AddBBox(0, 0, 19, 19);
pR->DrawTextCheck(sColor);
break;
}
case 1:
{
pN->AddBBox(0, 0, 20, 20);
pN->DrawTextCheckmark();
pR->AddBBox(0, 0, 20, 20);
pR->DrawTextCheckmark();
break;
}
case 2:
{
pN->AddBBox(0, 0, 20, 20);
pN->DrawTextCircle(sColor);
pR->AddBBox(0, 0, 20, 20);
pR->DrawTextCircle(sColor);
break;
}
case 3:
{
pN->AddBBox(0, 0, 24, 24);
pN->DrawTextCommentN(sColor);
pR->AddBBox(0, 0, 24, 24);
pR->DrawTextCommentR(sColor);
break;
}
case 4:
{
pN->AddBBox(0, 0, 19, 19);
pN->DrawTextCross(sColor);
pR->AddBBox(0, 0, 19, 19);
pR->DrawTextCross(sColor);
break;
}
case 5:
{
pN->AddBBox(0, 0, 20, 20);
pN->DrawTextCrossHairs(sColor);
pR->AddBBox(0, 0, 20, 20);
pR->DrawTextCrossHairs(sColor);
break;
}
case 6:
{
pN->AddBBox(0, 0, 20, 20);
pN->DrawTextHelp(sColor);
pR->AddBBox(0, 0, 20, 20);
pR->DrawTextHelp(sColor);
break;
}
case 7:
{
pN->AddBBox(0, 0, 17, 20);
pN->DrawTextInsert(sColor);
pR->AddBBox(0, 0, 17, 20);
pR->DrawTextInsert(sColor);
break;
}
case 8:
{
pN->AddBBox(0, 0, 13, 18);
pN->DrawTextKey(sColor);
pR->AddBBox(0, 0, 13, 18);
pR->DrawTextKey(sColor);
break;
}
case 9:
{
pN->AddBBox(0, 0, 13, 20);
pN->DrawTextNewParagraph(sColor);
pR->AddBBox(0, 0, 13, 20);
pR->DrawTextNewParagraph(sColor);
break;
}
case 11:
{
pN->AddBBox(0, 0, 20, 20);
pN->DrawTextParagraph(sColor);
pR->AddBBox(0, 0, 20, 20);
pR->DrawTextParagraph(sColor);
break;
}
case 12:
{
pN->AddBBox(0, 0, 20, 20);
pN->DrawTextRightArrow(sColor);
pR->AddBBox(0, 0, 20, 20);
pR->DrawTextRightArrow(sColor);
break;
}
case 13:
{
pN->AddBBox(0, 0, 20, 17);
pN->DrawTextRightPointer(sColor);
pR->AddBBox(0, 0, 20, 17);
pR->DrawTextRightPointer(sColor);
break;
}
case 14:
{
pN->AddBBox(0, 0, 20, 19);
pN->DrawTextStar(sColor);
pR->AddBBox(0, 0, 20, 19);
pR->DrawTextStar(sColor);
break;
}
case 15:
{
pN->AddBBox(0, 0, 17, 20);
pN->DrawTextUpArrow(sColor);
pR->AddBBox(0, 0, 17, 20);
pR->DrawTextUpArrow(sColor);
break;
}
case 16:
{
pN->AddBBox(0, 0, 17, 17);
pN->DrawTextUpLeftArrow(sColor);
pR->AddBBox(0, 0, 17, 17);
pR->DrawTextUpLeftArrow(sColor);
break;
}
case 10:
default:
{
pN->AddBBox(0, 0, 18, 20);
pN->DrawTextNote(sColor);
pR->AddBBox(0, 0, 18, 20);
pR->DrawTextNote(sColor);
break;
}
}
}
//----------------------------------------------------------------------------------------
// CUriLinkAnnotation
//----------------------------------------------------------------------------------------
CUriLinkAnnotation::CUriLinkAnnotation(CXref* pXref, const char* sUri) : CAnnotation(pXref, AnnotLink)
{
CDictObject* pAction = new CDictObject();
if (!pAction)
return;
Add("A", pAction);
pAction->Add("Type", "Action");
pAction->Add("S", "URI");
pAction->Add("URI", new CStringObject(sUri));
}
//----------------------------------------------------------------------------------------
// CInkAnnotation
//----------------------------------------------------------------------------------------
CInkAnnotation::CInkAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotInk)
{
}
void CInkAnnotation::SetInkList(const std::vector< std::vector<double> >& arrInkList)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("InkList", pArray);
for (const std::vector<double>& arrInk : arrInkList)
{
CArrayObject* pArrayI = new CArrayObject();
pArray->Add(pArrayI);
for (int i = 0; i < arrInk.size(); ++i)
pArrayI->Add(i % 2 == 0 ? (arrInk[i] + m_dPageX) : (m_dPageH - arrInk[i]));
}
}
//----------------------------------------------------------------------------------------
// CLineAnnotation
//----------------------------------------------------------------------------------------
CLineAnnotation::CLineAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotLine), dL{0.0, 0.0, 0.0, 0.0}
{
m_nLE1 = ELineEndType::None;
m_nLE2 = ELineEndType::None;
}
void CLineAnnotation::SetCap(bool bCap)
{
Add("Open", new CBoolObject(bCap));
}
void CLineAnnotation::SetIT(BYTE nIT)
{
std::string sValue;
ELineIntentType eIT = ELineIntentType(nIT);
switch (eIT)
{
case ELineIntentType::LineDimension: sValue = "LineDimension"; break;
case ELineIntentType::LineArrow: sValue = "LineArrow"; break;
default: return;
}
Add("IT", sValue.c_str());
}
void CLineAnnotation::SetCP(BYTE nCP)
{
if (!Get("Open"))
return;
std::string sValue;
ECaptionPositioning eCP = ECaptionPositioning(nCP);
switch (eCP)
{
case ECaptionPositioning::Inline: sValue = "Inline"; break;
case ECaptionPositioning::Top: sValue = "Top"; break;
default: return;
}
Add("CP", sValue.c_str());
}
void CLineAnnotation::SetLL(const double& dLL)
{
Add("LL", dLL);
}
void CLineAnnotation::SetLLE(const double& dLLE)
{
Add("LLE", dLLE);
}
void CLineAnnotation::SetLLO(const double& dLLO)
{
Add("LLO", dLLO);
}
void CLineAnnotation::SetLE(BYTE nLE1, BYTE nLE2)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("LE", pArray);
pArray->Add(AddLE(nLE1).c_str());
pArray->Add(AddLE(nLE2).c_str());
m_nLE1 = ELineEndType(nLE1);
m_nLE2 = ELineEndType(nLE2);
}
void CLineAnnotation::SetL(const double& dL1, const double& dL2, const double& dL3, const double& dL4)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("L", pArray);
dL[0] = dL1 + m_dPageX;
dL[1] = m_dPageH - dL2;
dL[2] = dL3 + m_dPageX;
dL[3] = m_dPageH - dL4;
pArray->Add(dL[0]);
pArray->Add(dL[1]);
pArray->Add(dL[2]);
pArray->Add(dL[3]);
}
void CLineAnnotation::SetCO(const double& dCO1, const double& dCO2)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("CO", pArray);
pArray->Add(dCO1);
pArray->Add(dCO2);
}
void CLineAnnotation::SetIC(const std::vector<double>& arrIC)
{
AddToVectorD(this, "IC", arrIC);
}
void CLineAnnotation::SetAP()
{
CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this);
Add("AP", pAppearance);
CAnnotAppearanceObject* pNormal = pAppearance->GetNormal();
pNormal->DrawLine();
}
//----------------------------------------------------------------------------------------
// CPopupAnnotation
//----------------------------------------------------------------------------------------
CPopupAnnotation::CPopupAnnotation(CXref* pXref) : CAnnotation(pXref, AnnotPopup)
{
}
void CPopupAnnotation::SetOpen(bool bOpen)
{
Add("Open", new CBoolObject(bOpen));
}
void CPopupAnnotation::SetParentID(CAnnotation* pAnnot)
{
Add("Parent", pAnnot);
}
//----------------------------------------------------------------------------------------
// CFreeTextAnnotation
//----------------------------------------------------------------------------------------
CFreeTextAnnotation::CFreeTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotFreeText)
{
}
void CFreeTextAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector<double>& arrC)
{
if (!pFont)
return;
CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources();
const char* sFontName = pFieldsResources->GetFontName(pFont);
std::vector<double> _arrC = arrC;
if (arrC.empty())
_arrC = {0};
std::string sDA = GetColor(_arrC, false);
if (sFontName)
{
sDA.append(" /");
sDA.append(sFontName);
sDA.append(" ");
sDA.append(std::to_string(dFontSize));
sDA.append(" Tf");
}
Add("DA", new CStringObject(sDA.c_str()));
}
void CFreeTextAnnotation::SetQ(BYTE nQ)
{
Add("Q", (int)nQ);
}
void CFreeTextAnnotation::SetIT(BYTE nIT)
{
std::string sValue;
switch (nIT)
{
case 0:
{ sValue = "FreeText"; break; }
case 1:
{ sValue = "FreeTextCallout"; break; }
case 2:
{ sValue = "FreeTextTypeWriter"; break; }
default: { return; }
}
Add("IT", sValue.c_str());
}
void CFreeTextAnnotation::SetLE(BYTE nLE)
{
Add("LE", AddLE(nLE).c_str());
}
void CFreeTextAnnotation::SetRotate(int nRotate)
{
Add("Rotate", nRotate);
}
void CFreeTextAnnotation::SetDS(const std::wstring& wsDS)
{
std::string sValue = U_TO_UTF8(wsDS);
Add("DS", new CStringObject(sValue.c_str()));
}
void CFreeTextAnnotation::SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4)
{
AddRD(this, dRD1, dRD2, dRD3, dRD4);
}
void CFreeTextAnnotation::SetCL(const std::vector<double>& arrCL)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("CL", pArray);
for (int i = 0; i < arrCL.size(); ++i)
pArray->Add(i % 2 == 0 ? (arrCL[i] + m_dPageX) : (m_dPageH - arrCL[i]));
}
void CFreeTextAnnotation::SetIC(const std::vector<double>& arrIC)
{
SetC(arrIC);
}
//----------------------------------------------------------------------------------------
// CTextMarkupAnnotation
//----------------------------------------------------------------------------------------
CTextMarkupAnnotation::CTextMarkupAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotHighLight)
{
m_nSubtype = AnnotHighLight;
}
void CTextMarkupAnnotation::SetSubtype(BYTE nSubtype)
{
switch (nSubtype)
{
case 8:
{ m_nSubtype = AnnotHighLight; break; }
case 9:
{ m_nSubtype = AnnotUnderline; break; }
case 10:
{ m_nSubtype = AnnotSquiggly; break; }
default:
case 11:
{ m_nSubtype = AnnotStrikeOut; break; }
}
Add("Subtype", c_sAnnotTypeNames[(int)m_nSubtype]);
}
void CTextMarkupAnnotation::SetQuadPoints(const std::vector<double>& arrQuadPoints)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("QuadPoints", pArray);
for (int i = 0; i < arrQuadPoints.size(); ++i)
pArray->Add(i % 2 == 0 ? (arrQuadPoints[i] + m_dPageX) : (m_dPageH - arrQuadPoints[i]));
}
void CTextMarkupAnnotation::SetAP(const std::vector<double>& arrQuadPoints, const double& dCA)
{
CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this);
Add("AP", pAP);
CResourcesDict* pResources = new CResourcesDict(m_pXref, true, false);
CAnnotAppearanceObject* pN = pAP->GetNormal(pResources);
CStream* pStream = pN->GetStream();
pN->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop);
pN->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom);
CExtGrState* pExtGrState = m_pDocument->GetExtGState(dCA, dCA, m_nSubtype == AnnotHighLight ? blendmode_Multiply : blendmode_Unknown);
const char* sExtGrStateName = pResources->GetExtGrStateName(pExtGrState);
if (sExtGrStateName)
{
pStream->WriteEscapeName(sExtGrStateName);
pStream->WriteStr(" gs\012");
}
std::string sColor = GetColor(dynamic_cast<CArrayObject*>(Get("C")), m_nSubtype != AnnotHighLight);
pStream->WriteStr(sColor.c_str());
pStream->WriteChar('\012');
switch (m_nSubtype)
{
case AnnotHighLight:
{
pStream->WriteStr("1 w\012");
for (int i = 0; i < arrQuadPoints.size(); i += 8)
{
pStream->WriteReal(arrQuadPoints[i] + m_dPageX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - arrQuadPoints[i + 1]);
pStream->WriteStr(" m\012");
pStream->WriteReal(arrQuadPoints[i + 2] + m_dPageX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - arrQuadPoints[i + 3]);
pStream->WriteStr(" l\012");
pStream->WriteReal(arrQuadPoints[i + 6] + m_dPageX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - arrQuadPoints[i + 7]);
pStream->WriteStr(" l\012");
pStream->WriteReal(arrQuadPoints[i + 4] + m_dPageX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - arrQuadPoints[i + 5]);
pStream->WriteStr(" l\012f\012");
}
break;
}
case AnnotSquiggly:
case AnnotUnderline:
{
for (int i = 0; i < arrQuadPoints.size(); i += 8)
{
double dX = arrQuadPoints[i + 2] - arrQuadPoints[i];
double dY = arrQuadPoints[i + 3] - arrQuadPoints[i + 1];
double dAngle = atan2(dY, dX);
double dHeight = sqrt(pow(arrQuadPoints[i] - arrQuadPoints[i + 4], 2) + pow(arrQuadPoints[i + 1] - arrQuadPoints[i + 5], 2));
double dLineWidth = std::max(0.5, dHeight * 0.075);
double dIndentX = sin(dAngle) * dLineWidth * 1.9;
double dIndentY = cos(dAngle) * dLineWidth * 1.9;
pStream->WriteReal(dLineWidth);
pStream->WriteStr(" w\012");
pStream->WriteReal(arrQuadPoints[i + 4] + m_dPageX + dIndentX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - arrQuadPoints[i + 5] + dIndentY);
pStream->WriteStr(" m\012");
pStream->WriteReal(arrQuadPoints[i + 6] + m_dPageX + dIndentX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - arrQuadPoints[i + 7] + dIndentY);
pStream->WriteStr(" l\012S\012");
}
break;
}
case AnnotStrikeOut:
default:
{
for (int i = 0; i < arrQuadPoints.size(); i += 8)
{
double dX1 = arrQuadPoints[i] + (arrQuadPoints[i + 4] - arrQuadPoints[i]) / 2.0;
double dY1 = arrQuadPoints[i + 1] + (arrQuadPoints[i + 5] - arrQuadPoints[i + 1]) / 2.0;
double dX2 = arrQuadPoints[i + 2] + (arrQuadPoints[i + 6] - arrQuadPoints[i + 2]) / 2.0;
double dY2 = arrQuadPoints[i + 3] + (arrQuadPoints[i + 7] - arrQuadPoints[i + 3]) / 2.0;
double dHeight = sqrt(pow(arrQuadPoints[i] - arrQuadPoints[i + 4], 2) + pow(arrQuadPoints[i + 1] - arrQuadPoints[i + 5], 2));
double dLineWidth = std::max(0.5, dHeight * 0.075);
pStream->WriteReal(dLineWidth);
pStream->WriteStr(" w\012");
pStream->WriteReal(dX1 + m_dPageX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - dY1);
pStream->WriteStr(" m\012");
pStream->WriteReal(dX2 + m_dPageX);
pStream->WriteChar(' ');
pStream->WriteReal(m_dPageH - dY2);
pStream->WriteStr(" l\012S\012");
}
break;
}
}
}
//----------------------------------------------------------------------------------------
// CSquareCircleAnnotation
//----------------------------------------------------------------------------------------
CSquareCircleAnnotation::CSquareCircleAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotSquare)
{
m_nSubtype = AnnotSquare;
}
void CSquareCircleAnnotation::SetSubtype(BYTE nSubtype)
{
switch (nSubtype)
{
case 4:
{ m_nSubtype = AnnotSquare; break; }
default:
case 5:
{ m_nSubtype = AnnotCircle; break; }
}
Add("Subtype", c_sAnnotTypeNames[(int)m_nSubtype]);
}
void CSquareCircleAnnotation::SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4)
{
AddRD(this, dRD1, dRD2, dRD3, dRD4);
}
void CSquareCircleAnnotation::SetIC(const std::vector<double>& arrIC)
{
AddToVectorD(this, "IC", arrIC);
}
//----------------------------------------------------------------------------------------
// CPolygonLineAnnotation
//----------------------------------------------------------------------------------------
CPolygonLineAnnotation::CPolygonLineAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotPolygon)
{
m_nSubtype = AnnotPolygon;
}
void CPolygonLineAnnotation::SetIT(BYTE nIT)
{
std::string sValue;
switch (nIT)
{
case 0:
{ sValue = "PolygonCloud"; break; }
case 1:
{ sValue = "PolyLineDimension"; break; }
case 2:
{ sValue = "PolygonDimension"; break; }
default: { return; }
}
Add("IT", sValue.c_str());
}
void CPolygonLineAnnotation::SetSubtype(BYTE nSubtype)
{
switch (nSubtype)
{
case 6:
{ m_nSubtype = AnnotPolygon; break; }
default:
case 7:
{ m_nSubtype = AnnotPolyLine; break; }
}
Add("Subtype", c_sAnnotTypeNames[(int)m_nSubtype]);
}
void CPolygonLineAnnotation::SetLE(BYTE nLE1, BYTE nLE2)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("LE", pArray);
pArray->Add(AddLE(nLE1).c_str());
pArray->Add(AddLE(nLE2).c_str());
}
void CPolygonLineAnnotation::SetIC(const std::vector<double>& arrIC)
{
AddToVectorD(this, "IC", arrIC);
}
void CPolygonLineAnnotation::SetVertices(const std::vector<double>& arrVertices)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("Vertices", pArray);
for (int i = 0; i < arrVertices.size(); ++i)
pArray->Add(i % 2 == 0 ? (arrVertices[i] + m_dPageX) : (m_dPageH - arrVertices[i]));
}
//----------------------------------------------------------------------------------------
// CCaretAnnotation
//----------------------------------------------------------------------------------------
CCaretAnnotation::CCaretAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotCaret)
{
}
void CCaretAnnotation::SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4)
{
AddRD(this, dRD1, dRD2, dRD3, dRD4);
}
void CCaretAnnotation::SetSy(BYTE nSy)
{
std::string sValue;
switch (nSy)
{
case 0:
{ sValue = "P"; break; }
case 1:
{ sValue = "None"; break; }
default: { return; }
}
Add("IT", sValue.c_str());
}
//----------------------------------------------------------------------------------------
// CStampAnnotation
//----------------------------------------------------------------------------------------
CStampAnnotation::CStampAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotStamp), m_pAPStream(NULL)
{
}
void CStampAnnotation::SetRotate(double nRotate)
{
Add("Rotate", nRotate);
if (!m_pAPStream)
return;
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
double ca = cos(nRotate / 180.0 * M_PI);
double sa = sin(nRotate / 180.0 * M_PI);
m_pAPStream->Add("Matrix", pArray);
pArray->Add(ca);
pArray->Add(sa);
pArray->Add(-sa);
pArray->Add(ca);
pArray->Add(0);
pArray->Add(0);
}
void CStampAnnotation::SetName(const std::wstring& wsName)
{
std::string sValue = U_TO_UTF8(wsName);
Add("Name", sValue.c_str());
}
void CStampAnnotation::SetAPStream(CDictObject* pStream, bool bCopy)
{
if (bCopy)
{
CDictObject* pStreamNew = (CDictObject*)pStream->Copy();
CStream* pStr = new CMemoryStream();
pStreamNew->SetStream(m_pXref, pStr, true);
pStr->WriteStream(pStream->GetStream(), 0, NULL);
pStreamNew->SetFilter(STREAM_FILTER_FLATE_DECODE);
pStream = pStreamNew;
CDictObject* pAP = new PdfWriter::CDictObject();
Add("AP", pAP);
pAP->Add("N", pStreamNew);
}
m_pAPStream = pStream;
}
CDictObject* CStampAnnotation::GetAPStream()
{
return m_pAPStream;
}
//----------------------------------------------------------------------------------------
// CRedactAnnotation
//----------------------------------------------------------------------------------------
CRedactAnnotation::CRedactAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotRedact)
{
}
void CRedactAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector<double>& arrC)
{
const char* sFontName = NULL;
if (pFont)
{
CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources();
sFontName = pFieldsResources->GetFontName(pFont);
}
std::vector<double> _arrC = arrC;
if (arrC.empty())
_arrC = {0};
std::string sDA = GetColor(_arrC, false);
if (sFontName)
{
sDA.append(" /");
sDA.append(sFontName);
sDA.append(" ");
sDA.append(std::to_string(dFontSize));
sDA.append(" Tf");
}
Add("DA", new CStringObject(sDA.c_str()));
}
void CRedactAnnotation::SetRepeat(bool bRepeat)
{
Add("Repeat", bRepeat);
}
void CRedactAnnotation::SetQ(BYTE nQ)
{
Add("Q", (int)nQ);
}
void CRedactAnnotation::SetOverlayText(const std::wstring& wsOverlayText)
{
std::string sValue = U_TO_UTF8(wsOverlayText);
Add("OverlayText", new CStringObject(sValue.c_str(), true));
}
void CRedactAnnotation::SetIC(const std::vector<double>& arrIC)
{
AddToVectorD(this, "IC", arrIC);
}
void CRedactAnnotation::SetOC(const std::vector<double>& arrOC)
{
AddToVectorD(this, "OC", arrOC);
}
void CRedactAnnotation::SetQuadPoints(const std::vector<double>& arrQuadPoints)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("QuadPoints", pArray);
for (int i = 0; i < arrQuadPoints.size(); ++i)
pArray->Add(i % 2 == 0 ? (arrQuadPoints[i] + m_dPageX) : (m_dPageH - arrQuadPoints[i]));
}
//----------------------------------------------------------------------------------------
// CWidgetAnnotation
//----------------------------------------------------------------------------------------
CWidgetAnnotation::CWidgetAnnotation(CXref* pXref, EAnnotType eType) : CAnnotation(pXref, eType)
{
m_pMK = NULL;
m_pParent = NULL;
m_pAppearance = NULL;
m_pResources = NULL;
m_pFont = NULL;
m_dFontSizeAP = 0;
m_nParentID = 0;
m_nQ = 0;
m_dFontSize = 10.0;
m_bBold = false;
m_bItalic = false;
m_nSubtype = WidgetUnknown;
}
void CWidgetAnnotation::SetSubtype(BYTE nSubtype)
{
m_nSubtype = (EWidgetType)nSubtype;
}
void CWidgetAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const double& dFontSizeAP, const std::vector<double>& arrTC)
{
if (!pFont)
return;
CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources();
const char* sFontName = pFieldsResources->GetFontName(pFont);
std::string sDA = GetColor(arrTC, false);
if (sFontName)
{
sDA.append(" /");
sDA.append(sFontName);
sDA.append(" ");
sDA.append(std::to_string(dFontSize));
sDA.append(" Tf");
}
CDictObject* pOwner = GetObjOwnValue("DA");
if (pOwner)
pOwner->Remove("DA");
Add("DA", new CStringObject(sDA.c_str()));
m_arrTC = arrTC;
m_dFontSizeAP = dFontSizeAP;
}
void CWidgetAnnotation::SetFont(CFontCidTrueType* pFont, double dFontSize, bool bBold, bool bItalic)
{
m_pFont = pFont;
m_dFontSize = dFontSize;
m_bBold = bBold;
m_bItalic = bItalic;
}
CDictObject* CWidgetAnnotation::GetObjOwnValue(const std::string& sV)
{
if (Get(sV))
return this;
CDictObject* pParent = m_pParent;
while (pParent)
{
if (pParent->Get(sV))
return pParent;
CObjectBase* pParent2 = pParent->Get("Parent");
if (pParent2 && pParent2->GetType() == object_type_DICT)
pParent = (CDictObject*)pParent2;
else
return NULL;
}
return NULL;
}
CObjectBase* CWidgetAnnotation::GetObjValue(const std::string& sV)
{
CObjectBase* pRes = Get(sV);
if (pRes)
return pRes;
CDictObject* pParent = m_pParent;
while (pParent)
{
pRes = pParent->Get(sV);
if (pRes)
return pRes;
CObjectBase* pParent2 = pParent->Get("Parent");
if (pParent2 && pParent2->GetType() == object_type_DICT)
pParent = (CDictObject*)pParent2;
else
return NULL;
}
return NULL;
}
void CWidgetAnnotation::CheckMK()
{
if (!m_pMK)
{
CObjectBase* pMK = Get("MK");
if (pMK && pMK->GetType() == object_type_DICT)
{
m_pMK = (CDictObject*)pMK;
return;
}
m_pMK = new CDictObject();
Add("MK", m_pMK);
}
}
void CWidgetAnnotation::SetQ(BYTE nQ)
{
CDictObject* pOwner = GetObjOwnValue("Q");
if (!pOwner)
pOwner = this;
pOwner->Add("Q", (int)nQ);
m_nQ = nQ;
}
void CWidgetAnnotation::SetH(BYTE nH)
{
std::string sValue;
switch (nH)
{
case 0:
{ sValue = "N"; break; }
case 1:
{ sValue = "I"; break; }
case 2:
{ sValue = "P"; break; }
case 3:
{ sValue = "O"; break; }
default: { return; }
}
Add("H", sValue.c_str());
}
void CWidgetAnnotation::SetR(const int& nR)
{
CheckMK();
m_pMK->Add("R", nR);
}
void CWidgetAnnotation::SetFlag(const int& nFlag)
{
if (nFlag < 0)
return;
CDictObject* pOwner = GetObjOwnValue("Ff");
if (!pOwner)
pOwner = this;
pOwner->Add("Ff", nFlag);
}
void CWidgetAnnotation::SetParent(CDictObject* pParent)
{
if (!pParent)
return;
m_pParent = pParent;
Add("Parent", pParent);
}
void CWidgetAnnotation::SetParentID(int nParentID)
{
m_nParentID = nParentID;
}
void CWidgetAnnotation::SetMEOptions(const int& nMEOptions)
{
Add("MEOptions", nMEOptions);
}
void CWidgetAnnotation::SetTU(const std::wstring& wsTU)
{
std::string sValue = U_TO_UTF8(wsTU);
CDictObject* pOwner = GetObjOwnValue("TU");
if (!pOwner)
pOwner = this;
pOwner->Add("TU", new CStringObject(sValue.c_str(), true));
}
void CWidgetAnnotation::SetDS(const std::wstring& wsDS)
{
std::string sValue = U_TO_UTF8(wsDS);
CDictObject* pOwner = GetObjOwnValue("DS");
if (!pOwner)
pOwner = this;
pOwner->Add("DS", new CStringObject(sValue.c_str(), true));
}
void CWidgetAnnotation::SetDV(const std::wstring& wsDV)
{
std::string sValue = U_TO_UTF8(wsDV);
CDictObject* pOwner = GetObjOwnValue("DV");
if (!pOwner)
pOwner = this;
pOwner->Add("DV", new CStringObject(sValue.c_str(), true));
}
void CWidgetAnnotation::SetT(const std::wstring& wsT)
{
std::string sValue = U_TO_UTF8(wsT);
CDictObject* pOwner = GetObjOwnValue("T");
if (!pOwner)
pOwner = this;
pOwner->Add("T", new CStringObject(sValue.c_str(), true));
}
void CWidgetAnnotation::SetBC(const std::vector<double>& arrBC)
{
CheckMK();
AddToVectorD(m_pMK, "BC", arrBC);
}
void CWidgetAnnotation::SetBG(const std::vector<double>& arrBG)
{
CheckMK();
AddToVectorD(m_pMK, "BG", arrBG);
}
void CWidgetAnnotation::AddAction(CAction* pAction)
{
if (!pAction)
return;
if (pAction->m_sType == "A")
{
Add(pAction->m_sType.c_str(), pAction);
return;
}
CDictObject* pAA = (CDictObject*)Get("AA");
if (!pAA)
{
pAA = new CDictObject();
Add("AA", pAA);
}
pAA->Add(pAction->m_sType.c_str(), pAction);
}
void CWidgetAnnotation::SetDocument(CDocument* pDocument)
{
m_pDocument = pDocument;
m_pResources = m_pDocument->GetFieldsResources();
}
std::string CWidgetAnnotation::GetDAforAP(CFontDict* pFont)
{
const char* sFontName = m_pResources->GetFontName(pFont);
std::string sDA = GetColor(m_arrTC, false);
if (sFontName)
{
sDA.append(" /");
sDA.append(sFontName);
sDA.append(" ");
sDA.append(std::to_string(m_dFontSizeAP));
sDA.append(" Tf\012");
}
return sDA;
}
std::string CWidgetAnnotation::GetBGforAP(double dDiff, bool bCAPS)
{
if (m_pMK)
return GetColor(dynamic_cast<CArrayObject*>(m_pMK->Get("BG")), bCAPS, dDiff);
return "";
}
std::string CWidgetAnnotation::GetBCforAP()
{
if (m_pMK)
return GetColor(dynamic_cast<CArrayObject*>(m_pMK->Get("BC")), true);
return "";
}
int CWidgetAnnotation::GetR()
{
if (m_pMK)
{
CObjectBase* pObj = m_pMK->Get("R");
if (pObj && pObj->GetType() == object_type_NUMBER)
return ((CNumberObject*)pObj)->Get();
}
return 0;
}
bool CWidgetAnnotation::HaveBG()
{
if (!m_pMK)
return false;
CObjectBase* pObj = m_pMK->Get("BG");
return pObj && pObj->GetType() == object_type_ARRAY;
}
bool CWidgetAnnotation::HaveBC()
{
if (!m_pMK)
return false;
CObjectBase* pObj = m_pMK->Get("BC");
return pObj && pObj->GetType() == object_type_ARRAY;
}
void CWidgetAnnotation::SetEmptyAP()
{
if (!m_pAppearance)
m_pAppearance = new CAnnotAppearance(m_pXref, this);
Add("AP", m_pAppearance);
CAnnotAppearanceObject* pAppearance = m_pAppearance->GetNormal();
double dHeight = fabs(m_oRect.fTop - m_oRect.fBottom);
double dWidth = fabs(m_oRect.fRight - m_oRect.fLeft);
pAppearance->StartDraw(dWidth, dHeight);
pAppearance->EndDraw();
}
void CWidgetAnnotation::SetAP(const std::wstring& wsValue, unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts, double* pShifts)
{
if (!m_pAppearance)
m_pAppearance = new CAnnotAppearance(m_pXref, this);
Add("AP", m_pAppearance);
CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal();
pNormal->DrawSimpleText(wsValue, pCodes, unCount, m_pFont, m_dFontSize, dX, dY, 0, 0, 0, NULL, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop), ppFonts, pShifts);
}
CAnnotAppearanceObject* CWidgetAnnotation::StartAP(int nRotate)
{
CAnnotAppearanceObject* pNormal = CAnnotation::StartAP(nRotate);
m_pResources = dynamic_cast<CResourcesDict*>(pNormal->Get("Resources"));
double dW = fabs(m_oRect.fRight - m_oRect.fLeft);
double dH = fabs(m_oRect.fBottom - m_oRect.fTop);
if (nRotate == 0 || nRotate == 180)
pNormal->StartDrawText(m_pFont, m_dFontSize, 0, 0, 0, NULL, dW, dH);
else
pNormal->StartDrawText(m_pFont, m_dFontSize, 0, 0, 0, NULL, dH, dW);
pNormal->EndText();
if (nRotate == 0)
{
pNormal->AddBBox(0, 0, dW, dH);
pNormal->AddMatrix(1, 0, 0, 1, 0, 0);
}
if (nRotate == 90)
{
pNormal->AddBBox(0, 0, dH, dW);
pNormal->AddMatrix(0, 1, -1, 0, dW, 0);
}
else if (nRotate == 180)
{
pNormal->AddBBox(0, 0, dW, dH);
pNormal->AddMatrix(-1, 0, 0, -1, dW, dH);
}
else if (nRotate == 270)
{
pNormal->AddBBox(0, 0, dH, dW);
pNormal->AddMatrix(0, -1, 1, 0, 0, dH);
}
return pNormal;
}
void CWidgetAnnotation::AddLineToAP(const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, CFontCidTrueType** ppFonts, const double* pShifts)
{
if (!m_pAppearance)
return;
CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal();
pNormal->DrawTextLine(dX, dY, pCodes, unCodesCount, ppFonts, pShifts);
}
void CWidgetAnnotation::EndAP()
{
if (!m_pAppearance)
return;
CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal();
pNormal->EndDrawText();
}
//----------------------------------------------------------------------------------------
// CPushButtonWidget
//----------------------------------------------------------------------------------------
CPushButtonWidget::CPushButtonWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget)
{
m_pIF = NULL;
m_nI = -1;
m_nRI = -1;
m_nIX = -1;
m_nTP = 0;
m_nScaleType = 0;
m_bRespectBorders = false;
m_bConstantProportions = true;
m_dShiftX = 0.5;
m_dShiftY = 0.5;
}
void CPushButtonWidget::CheckIF()
{
CheckMK();
if (!m_pIF)
{
m_pIF = new CDictObject();
m_pMK->Add("IF", m_pIF);
}
}
void CPushButtonWidget::SetV(const std::wstring& wsV)
{
std::string sV = U_TO_UTF8(wsV);
CDictObject* pOwner = GetObjOwnValue("V");
if (!pOwner)
pOwner = this;
pOwner->Add("V", new CStringObject(sV.c_str(), true));
}
void CPushButtonWidget::SetS(BYTE nS)
{
m_bConstantProportions = !nS;
CheckIF();
std::string sValue;
switch (nS)
{
case 0:
{ sValue = "P"; break; }
case 1:
{ sValue = "A"; break; }
default: { return; }
}
m_pIF->Add("S", sValue.c_str());
}
void CPushButtonWidget::SetTP(BYTE nTP)
{
CheckMK();
m_pMK->Add("TP", (int)nTP);
m_nTP = nTP;
}
void CPushButtonWidget::SetSW(BYTE nSW)
{
m_nScaleType = nSW;
CheckIF();
std::string sValue;
switch (nSW)
{
case 0:
{ sValue = "A"; break; }
case 1:
{ sValue = "N"; break; }
case 2:
{ sValue = "B"; break; }
case 3:
{ sValue = "S"; break; }
default: { return; }
}
m_pIF->Add("SW", sValue.c_str());
}
void CPushButtonWidget::SetIFFlag(const int& nIFFlag)
{
CheckIF();
m_bRespectBorders = (nIFFlag & (1 << 4)) ? false : true;
m_pIF->Add("FB", !m_bRespectBorders);
}
void CPushButtonWidget::SetFlag(const int& nFlag)
{
if (nFlag < 0)
return;
int nFlags = nFlag;
nFlags |= (1 << 16);
CWidgetAnnotation::SetFlag(nFlags);
}
void CPushButtonWidget::SetI(const int& nI)
{
m_nI = nI;
}
void CPushButtonWidget::SetRI(const int& nRI)
{
m_nRI = nRI;
}
void CPushButtonWidget::SetIX(const int& nIX)
{
m_nIX = nIX;
}
void CPushButtonWidget::SetA(const double& dA1, const double& dA2)
{
m_dShiftX = dA1;
m_dShiftY = dA2;
CheckIF();
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
m_pIF->Add("A", pArray);
pArray->Add(dA1);
pArray->Add(dA2);
}
void CPushButtonWidget::SetCA(const std::wstring& wsCA)
{
CheckMK();
std::string sValue = U_TO_UTF8(wsCA);
m_pMK->Add("CA", new CStringObject(sValue.c_str(), true));
m_wsCA = wsCA;
}
void CPushButtonWidget::SetRC(const std::wstring& wsRC)
{
CheckMK();
std::string sValue = U_TO_UTF8(wsRC);
m_pMK->Add("RC", new CStringObject(sValue.c_str(), true));
m_wsRC = wsRC;
}
void CPushButtonWidget::SetAC(const std::wstring& wsAC)
{
CheckMK();
std::string sValue = U_TO_UTF8(wsAC);
m_pMK->Add("AC", new CStringObject(sValue.c_str(), true));
m_wsAC = wsAC;
}
void CPushButtonWidget::SetAP(CXObject* pForm, BYTE nAP, unsigned short* pCodes, unsigned int unCount, double dX, double dY, double dLineW, double dLineH, CFontCidTrueType** ppFonts, bool bNoAP)
{
if (!pForm && !pCodes)
{
CObjectBase* pAP = Get("AP");
if (pAP && pAP->GetType() == object_type_DICT)
{
CDictObject* pDAP = (CDictObject*)pAP;
std::string sAP = nAP == 0 ? "N" : (nAP == 1 ? "R" : "D");
pDAP->Remove(sAP);
}
if (m_pMK)
{
std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX");
m_pMK->Remove(sAP);
}
if (nAP != 0)
return;
}
if (!m_pAppearance)
{
m_pAppearance = new CAnnotAppearance(m_pXref, this);
CObjectBase* pAP = Get("AP");
if (pAP && pAP->GetType() == object_type_DICT)
{
CDictObject* pDAP = (CDictObject*)pAP;
CObjectBase* pAPi = pDAP->Get("N");
if (pAPi)
{
CProxyObject* pNewAPi = new CProxyObject(pAPi->Copy(), true);
pNewAPi->Get()->SetRef(pAPi->GetObjId(), pAPi->GetGenNo());
m_pAppearance->Add("N", pNewAPi);
}
pAPi = pDAP->Get("D");
if (pAPi)
{
CProxyObject* pNewAPi = new CProxyObject(pAPi->Copy(), true);
pNewAPi->Get()->SetRef(pAPi->GetObjId(), pAPi->GetGenNo());
m_pAppearance->Add("D", pNewAPi);
}
pAPi = pDAP->Get("R");
if (pAPi)
{
CProxyObject* pNewAPi = new CProxyObject(pAPi->Copy(), true);
pNewAPi->Get()->SetRef(pAPi->GetObjId(), pAPi->GetGenNo());
m_pAppearance->Add("R", pNewAPi);
}
}
}
if (bNoAP)
{
if (pForm)
{
CheckMK();
std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX");
m_pMK->Add(sAP, pForm);
}
else if (m_pMK)
{
std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX");
m_pMK->Remove(sAP);
}
return;
}
CAnnotAppearanceObject* pAppearance = NULL;
m_pResources = new CResourcesDict(NULL, true, false);
if (nAP == 0)
pAppearance = m_pAppearance->GetNormal(m_pResources);
else if (nAP == 1)
pAppearance = m_pAppearance->GetRollover(m_pResources);
else if (nAP == 2)
pAppearance = m_pAppearance->GetDown(m_pResources);
else
{
delete m_pResources;
m_pResources = m_pDocument->GetFieldsResources();
}
if (!pAppearance)
return;
Add("AP", m_pAppearance);
double dHeight = fabs(m_oRect.fTop - m_oRect.fBottom);
double dWidth = fabs(m_oRect.fRight - m_oRect.fLeft);
int nRotate = GetR();
if (nRotate == 0)
{
pAppearance->AddBBox(0, 0, dWidth, dHeight);
pAppearance->AddMatrix(1, 0, 0, 1, 0, 0);
}
if (nRotate == 90)
{
pAppearance->AddBBox(0, 0, dHeight, dWidth);
pAppearance->AddMatrix(0, 1, -1, 0, dWidth, 0);
}
else if (nRotate == 180)
{
pAppearance->AddBBox(0, 0, dWidth, dHeight);
pAppearance->AddMatrix(-1, 0, 0, -1, dWidth, dHeight);
}
else if (nRotate == 270)
{
pAppearance->AddBBox(0, 0, dHeight, dWidth);
pAppearance->AddMatrix(0, -1, 1, 0, 0, dHeight);
}
if (nRotate == 90 || nRotate == 270)
std::swap(dWidth, dHeight);
pAppearance->StartDraw(dWidth, dHeight);
if (pForm)
{
double dH = dHeight;
double dW = dWidth;
double dOriginW = pForm->GetWidth();
double dOriginH = pForm->GetHeight();
bool bNeedScale = (0 == m_nScaleType
|| (2 == m_nScaleType && (dOriginH > dH || dOriginW > dW))
|| (3 == m_nScaleType && dOriginH < dH && dOriginW < dW));
double dBorderSize = m_oBorder.dWidth;
if (m_oBorder.nType == EBorderType::Beveled || m_oBorder.nType == EBorderType::Inset)
dBorderSize *= 2;
double dDstW = dOriginW;
double dDstH = dOriginH;
double dDstX = 0;
double dDstY = 0;
if (m_nTP == 2)
{
dH -= (dLineH + dBorderSize);
dDstY += (dLineH + dBorderSize);
}
if (m_nTP == 3)
dH -= (dLineH + dBorderSize);
if (m_nTP == 4)
dW -= (dLineW + dBorderSize);
if (m_nTP == 5)
{
dW -= (dLineW + dBorderSize);
dDstX += (dLineW + dBorderSize);
}
if (m_bRespectBorders)
{
dDstX += 2 * dBorderSize;
dDstY += 2 * dBorderSize;
dH -= 4 * dBorderSize;
dW -= 4 * dBorderSize;
}
if (bNeedScale)
{
if (!m_bConstantProportions)
{
dDstH = dH;
dDstW = dW;
}
else
{
double dScaleKoef = fmin(dW / dOriginW, dH / dOriginH);
dDstW = dScaleKoef * dOriginW;
dDstH = dScaleKoef * dOriginH;
}
}
dDstX += (dW - dDstW) * m_dShiftX;
dDstY += (dH - dDstH) * m_dShiftY;
m_pResources->AddXObjectWithName(pForm->GetName().c_str(), pForm);
pAppearance->DrawPictureInline(dWidth, dHeight, pForm->GetName().c_str(), dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders);
CheckMK();
std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX");
m_pMK->Add(sAP, pForm);
}
else if (m_pMK)
{
std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX");
m_pMK->Remove(sAP);
}
if (pCodes)
{
pAppearance->StartText(m_pFont, m_dFontSize);
pAppearance->DrawTextLine(dX, dY, pCodes, unCount, ppFonts, NULL);
pAppearance->EndText();
}
pAppearance->EndDraw();
}
//----------------------------------------------------------------------------------------
// CCheckBoxWidget
//----------------------------------------------------------------------------------------
CCheckBoxWidget::CCheckBoxWidget(CXref* pXref, EWidgetType nSubtype) : CWidgetAnnotation(pXref, AnnotWidget)
{
m_nSubtype = nSubtype;
m_nStyle = ECheckBoxStyle::Circle;
m_pAP = NULL;
}
void CCheckBoxWidget::SetV(const std::wstring& wsV)
{
std::string sV = U_TO_UTF8(wsV);
CDictObject* pOwner = GetObjOwnValue("V");
if (!pOwner)
pOwner = this;
if (isdigit(sV[0]))
pOwner->Add("V", sV.c_str());
else
pOwner->Add("V", new CStringObject(sV.c_str(), true));
}
void CCheckBoxWidget::SetStyle(BYTE nStyle)
{
m_nStyle = ECheckBoxStyle(nStyle);
CheckMK();
m_pMK->Add("CA", new CStringObject(c_sCheckBoxStyleNames[(int)nStyle]));
}
void CCheckBoxWidget::SetAP_N_Yes(const std::wstring& wsAP_N_Yes)
{
std::string sValue = U_TO_UTF8(wsAP_N_Yes);
if (m_sAP_N_Yes.empty())
m_sAP_N_Yes = sValue;
if (m_pAP)
{
CDictObject* pDict = (CDictObject*)m_pAP->Get("N");
pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN());
pDict->Remove("Yes");
pDict = (CDictObject*)m_pAP->Get("D");
pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD());
pDict->Remove("Yes");
}
}
void CCheckBoxWidget::RenameAP_N_Yes(const std::wstring& wsAP_N_Yes)
{
std::string sValue = U_TO_UTF8(wsAP_N_Yes);
m_sAP_N_Yes = sValue;
if (m_pAP)
{
CDictObject* pDict = (CDictObject*)m_pAP->Get("N");
pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN());
pDict->Remove("Yes");
pDict = (CDictObject*)m_pAP->Get("D");
pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD());
pDict->Remove("Yes");
}
else
{
CObjectBase* pAPN = NULL;
CObjectBase* pAP = Get("AP");
if (pAP->GetType() == object_type_DICT)
pAPN = ((CDictObject*)pAP)->Get("N");
if (pAPN && pAPN->GetType() == object_type_DICT)
{
CDictObject* pDictAPN = (CDictObject*)pAPN;
std::map<std::string, CObjectBase*> mDict = pDictAPN->GetDict();
for (std::pair<std::string, CObjectBase*> it : mDict)
{
if (it.first != "Off" && it.first != m_sAP_N_Yes)
{
CObjectBase* pObject = it.second;
pDictAPN->Add(m_sAP_N_Yes, pObject->Copy());
pDictAPN->Remove(it.first);
break;
}
}
}
pAPN = NULL;
if (pAP->GetType() == object_type_DICT)
pAPN = ((CDictObject*)pAP)->Get("D");
if (pAPN && pAPN->GetType() == object_type_DICT)
{
CDictObject* pDictAPN = (CDictObject*)pAPN;
std::map<std::string, CObjectBase*> mDict = pDictAPN->GetDict();
for (std::pair<std::string, CObjectBase*> it : mDict)
{
if (it.first != "Off" && it.first != m_sAP_N_Yes)
{
CObjectBase* pObject = it.second;
pDictAPN->Add(m_sAP_N_Yes, pObject->Copy());
pDictAPN->Remove(it.first);
break;
}
}
}
}
}
bool CCheckBoxWidget::NeedAP_N_Yes()
{
return m_sAP_N_Yes.empty();
}
void CCheckBoxWidget::SetAP(int nRotate)
{
if (!m_pAP)
{
m_pAP = new CCheckBoxAnnotAppearance(m_pXref, this, m_sAP_N_Yes.empty() ? NULL : m_sAP_N_Yes.c_str());
Add("AP", m_pAP);
}
if (m_nStyle == ECheckBoxStyle::Circle && m_nSubtype == WidgetRadiobutton)
{
m_pAP->GetYesN()->DrawCheckBoxCircle(nRotate, true, true);
m_pAP->GetOffN()->DrawCheckBoxCircle(nRotate, false, true);
m_pAP->GetYesD()->DrawCheckBoxCircle(nRotate, true, false);
m_pAP->GetOffD()->DrawCheckBoxCircle(nRotate, false, false);
}
else
{
m_pAP->GetYesN()->DrawCheckBoxSquare(nRotate, true, true);
m_pAP->GetOffN()->DrawCheckBoxSquare(nRotate, false, true);
m_pAP->GetYesD()->DrawCheckBoxSquare(nRotate, true, false);
m_pAP->GetOffD()->DrawCheckBoxSquare(nRotate, false, false);
}
if (nRotate != 0)
{
double dW = fabs(m_oRect.fRight - m_oRect.fLeft);
double dH = fabs(m_oRect.fBottom - m_oRect.fTop);
if (nRotate == 90 || nRotate == 270)
{
m_pAP->GetYesN()->AddBBox(0, 0, dH, dW);
m_pAP->GetOffN()->AddBBox(0, 0, dH, dW);
m_pAP->GetYesD()->AddBBox(0, 0, dH, dW);
m_pAP->GetOffD()->AddBBox(0, 0, dH, dW);
}
if (nRotate == 90)
{
m_pAP->GetYesN()->AddMatrix(0, 1, -1, 0, dW, 0);
m_pAP->GetOffN()->AddMatrix(0, 1, -1, 0, dW, 0);
m_pAP->GetYesD()->AddMatrix(0, 1, -1, 0, dW, 0);
m_pAP->GetOffD()->AddMatrix(0, 1, -1, 0, dW, 0);
}
if (nRotate == 180)
{
m_pAP->GetYesN()->AddMatrix(-1, 0, 0, -1, dW, dH);
m_pAP->GetOffN()->AddMatrix(-1, 0, 0, -1, dW, dH);
m_pAP->GetYesD()->AddMatrix(-1, 0, 0, -1, dW, dH);
m_pAP->GetOffD()->AddMatrix(-1, 0, 0, -1, dW, dH);
}
if (nRotate == 270)
{
m_pAP->GetYesN()->AddMatrix(0, -1, 1, 0, 0, dH);
m_pAP->GetOffN()->AddMatrix(0, -1, 1, 0, 0, dH);
m_pAP->GetYesD()->AddMatrix(0, -1, 1, 0, 0, dH);
m_pAP->GetOffD()->AddMatrix(0, -1, 1, 0, 0, dH);
}
}
}
std::string CCheckBoxWidget::Yes()
{
std::string sName = m_sAP_N_Yes.empty() ? "Yes" : m_sAP_N_Yes;
Add("AS", sName.c_str());
if (!m_nParentID)
Add("V", sName.c_str());
return sName;
}
void CCheckBoxWidget::Off()
{
Add("AS", "Off");
if (!m_nParentID)
Add("V", "Off");
}
void CCheckBoxWidget::SwitchAP(const std::string& sV, int nI)
{
CObjectBase* pAP, *pAPN;
Add("AS", "Off");
CObjectBase* pObj = GetObjValue("Opt");
if (!m_sAP_N_Yes.empty() && pObj && pObj->GetType() == object_type_ARRAY)
{
if (m_pAP)
{
CDictObject* pDict = (CDictObject*)m_pAP->Get("N");
pDict->Remove(m_sAP_N_Yes);
pDict = (CDictObject*)m_pAP->Get("D");
pDict->Remove(m_sAP_N_Yes);
}
CArrayObject* pArr = (CArrayObject*)pObj;
for (int i = 0; i < pArr->GetCount(); ++i)
{
pObj = pArr->Get(i);
if (pObj->GetType() == object_type_ARRAY && ((CArrayObject*)pObj)->GetCount() > 0)
pObj = ((CArrayObject*)pObj)->Get(0);
if (pObj->GetType() == object_type_STRING)
{
CStringObject* pStr = (CStringObject*)pObj;
const BYTE* pBinary = pStr->GetString();
if (pStr->GetLength() == m_sAP_N_Yes.length() && !StrCmp((const char*)pBinary, m_sAP_N_Yes.c_str()))
{
m_sAP_N_Yes = std::to_string(i);
SetV(UTF8_TO_U(m_sAP_N_Yes));
break;
}
}
}
Add("AS", m_sAP_N_Yes.c_str());
if (nI >= 0 && m_pAP)
{
CDictObject* pDict = (CDictObject*)m_pAP->Get("N");
pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN());
pDict = (CDictObject*)m_pAP->Get("D");
pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD());
}
}
else if ((pAP = Get("AP")) && pAP->GetType() == object_type_DICT && (pAPN = ((CDictObject*)pAP)->Get("N")) && pAPN->GetType() == object_type_DICT && ((CDictObject*)pAPN)->Get(sV))
Add("AS", sV.c_str());
else if (nI >= 0 && m_pAP)
{
CDictObject* pDict = (CDictObject*)m_pAP->Get("N");
pDict->Add(std::to_string(nI), m_pAP->GetYesN());
pDict->Remove("Yes");
pDict = (CDictObject*)m_pAP->Get("D");
pDict->Add(std::to_string(nI), m_pAP->GetYesD());
pDict->Remove("Yes");
}
}
void CCheckBoxWidget::SetFlag(const int& nFlag)
{
if (nFlag < 0)
return;
int nFlags = nFlag;
if (nFlags & (1 << 15))
m_nSubtype = WidgetRadiobutton;
CWidgetAnnotation::SetFlag(nFlags);
}
std::string CCheckBoxWidget::GetTC(bool bCAPS)
{
std::string sDA = GetColor(m_arrTC, bCAPS);
if (sDA.empty())
sDA = bCAPS ? "0 G" : "0 g";
sDA += "\012";
return sDA;
}
//----------------------------------------------------------------------------------------
// CTextWidget
//----------------------------------------------------------------------------------------
CTextWidget::CTextWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget)
{
m_bAPV = false;
}
void CTextWidget::SetMaxLen(const int& nMaxLen)
{
if (nMaxLen > 0)
{
CDictObject* pOwner = GetObjOwnValue("MaxLen");
if (!pOwner)
pOwner = this;
pOwner->Add("MaxLen", nMaxLen);
}
}
void CTextWidget::SetV(const std::wstring& wsV)
{
m_sV = U_TO_UTF8(wsV);
CDictObject* pOwner = GetObjOwnValue("V");
if (!pOwner)
pOwner = this;
pOwner->Add("V", new CStringObject(m_sV.c_str(), true));
}
void CTextWidget::SetRV(const std::wstring& wsRV)
{
std::string sValue = U_TO_UTF8(wsRV);
CDictObject* pOwner = GetObjOwnValue("RV");
if (!pOwner)
pOwner = this;
pOwner->Add("RV", new CStringObject(sValue.c_str(), true));
}
bool CTextWidget::IsCombFlag()
{
int nFlags = 0;
CNumberObject* pFf = (CNumberObject*)GetObjValue("Ff");
if (pFf)
nFlags = pFf->Get();
return (nFlags & (1 << 24));
}
bool CTextWidget::IsMultiLine()
{
int nFlags = 0;
CNumberObject* pFf = (CNumberObject*)GetObjValue("Ff");
if (pFf)
nFlags = pFf->Get();
return (nFlags & (1 << 12));
}
unsigned int CTextWidget::GetMaxLen()
{
CNumberObject* oMaxLen = (CNumberObject*)GetObjValue("MaxLen");
return oMaxLen ? oMaxLen->Get() : 0;
}
//----------------------------------------------------------------------------------------
// CChoiceWidget
//----------------------------------------------------------------------------------------
CChoiceWidget::CChoiceWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget)
{
m_dHeight = 0;
m_nTI = -1;
m_bAPV = false;
}
void CChoiceWidget::SetFlag(const int& nFlag)
{
if (nFlag < 0)
return;
int nFlags = nFlag;
if (m_nSubtype == WidgetCombobox)
nFlags |= (1 << 17);
CDictObject* pOwner = GetObjOwnValue("Ff");
if (!pOwner)
pOwner = this;
else
{
int nFlags2 = ((CNumberObject*)(pOwner->Get("Ff")))->Get();
if (nFlags2 & (1 << 19))
nFlags |= (1 << 19);
}
pOwner->Add("Ff", nFlags);
}
void CChoiceWidget::SetTI(const int& nTI)
{
m_nTI = nTI;
CDictObject* pOwner = GetObjOwnValue("TI");
if (!pOwner)
pOwner = this;
pOwner->Add("TI", nTI);
}
void CChoiceWidget::SetV(const std::wstring& wsV)
{
std::string sValue = U_TO_UTF8(wsV);
CDictObject* pOwner = GetObjOwnValue("V");
if (!pOwner)
pOwner = this;
pOwner->Add("V", new CStringObject(sValue.c_str(), true));
}
void CChoiceWidget::SetI(const std::vector<int>& arrI)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
CDictObject* pOwner = GetObjOwnValue("I");
if (!pOwner)
pOwner = this;
pOwner->Add("I", pArray);
for (int i = 0; i < arrI.size(); ++i)
pArray->Add(arrI[i]);
}
void CChoiceWidget::SetV(const std::vector<std::wstring>& arrV)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
CDictObject* pOwner = GetObjOwnValue("V");
if (!pOwner)
pOwner = this;
pOwner->Add("V", pArray);
for (int i = 0; i < arrV.size(); ++i)
pArray->Add(new PdfWriter::CStringObject(U_TO_UTF8(arrV[i]).c_str(), true));
}
void CChoiceWidget::SetOpt(const std::vector< std::pair<std::wstring, std::wstring> >& arrOpt)
{
m_arrOpt = arrOpt;
if (m_arrOpt.empty())
return;
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
CDictObject* pOwner = GetObjOwnValue("Opt");
if (!pOwner)
pOwner = this;
pOwner->Add("Opt", pArray);
for (const std::pair<std::wstring, std::wstring>& PV : arrOpt)
{
if (PV.first.empty())
{
std::string sValue = U_TO_UTF8(PV.second);
pArray->Add(new CStringObject(sValue.c_str(), true));
}
else
{
CArrayObject* pArray2 = new CArrayObject();
pArray->Add(pArray2);
std::string sValue = U_TO_UTF8(PV.first);
pArray2->Add(new CStringObject(sValue.c_str(), true));
sValue = U_TO_UTF8(PV.second);
pArray2->Add(new CStringObject(sValue.c_str(), true));
}
}
}
std::wstring CChoiceWidget::GetValue(const std::wstring& wsExportV)
{
for (int i = 0; i < m_arrOpt.size(); ++i)
{
if (( m_arrOpt[i].first.empty() && m_arrOpt[i].second == wsExportV) ||
(!m_arrOpt[i].first.empty() && m_arrOpt[i].first == wsExportV))
return m_arrOpt[i].second;
}
return wsExportV;
}
std::wstring CChoiceWidget::SetListBoxIndex(const std::vector<std::wstring>& arrV)
{
std::wstring sRes;
int i = 0;
if (m_nTI < 0)
{
// Ищем верхний элемент отрисовки
for (; i < m_arrOpt.size(); ++i)
{
if (( m_arrOpt[i].first.empty() && m_arrOpt[i].second == arrV.front()) ||
(!m_arrOpt[i].first.empty() && m_arrOpt[i].first == arrV.front()))
{
m_nTI = i;
break;
}
}
}
else
i = m_nTI;
if (m_nTI < 0)
return L"";
for (; i < m_arrOpt.size(); ++i)
sRes += (m_arrOpt[i].second + L"\n");
i = m_nTI;
for (const std::wstring& sV : arrV)
{
for (int j = i; j < m_arrOpt.size(); ++j)
{
if (( m_arrOpt[j].first.empty() && m_arrOpt[j].second == sV) ||
(!m_arrOpt[j].first.empty() && m_arrOpt[j].first == sV))
{
m_arrIndex.push_back(j - m_nTI);
i = j + 1;
break;
}
}
}
if (!sRes.empty())
{
sRes.pop_back();
return sRes;
}
return L"";
}
//----------------------------------------------------------------------------------------
// CSignatureWidget
//----------------------------------------------------------------------------------------
CSignatureWidget::CSignatureWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget)
{
}
//----------------------------------------------------------------------------------------
// CAction
//----------------------------------------------------------------------------------------
CAction::CAction(CXref* pXref)
{
pXref->Add(this);
Add("Type", "Action");
}
void CAction::SetType(const std::wstring& wsType)
{
m_sType = U_TO_UTF8(wsType);
}
void CAction::SetNext(CAction* pNext)
{
Add("Next", pNext);
}
//----------------------------------------------------------------------------------------
CActionResetForm::CActionResetForm(CXref* pXref) : CAction(pXref)
{
Add("S", "ResetForm");
Add("Flags", 1);
}
void CActionResetForm::SetFlags(int nFlag)
{
Add("Flags", nFlag);
}
void CActionResetForm::SetFields(const std::vector<std::wstring>& arrFileds)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("Fields", pArray);
for (const std::wstring& A : arrFileds)
{
std::string sValue = U_TO_UTF8(A);
pArray->Add(new CStringObject(sValue.c_str(), true));
}
}
//----------------------------------------------------------------------------------------
CActionJavaScript::CActionJavaScript(CXref* pXref) : CAction(pXref)
{
Add("S", "JavaScript");
}
void CActionJavaScript::SetJS(const std::wstring& wsJS)
{
std::string sValue = U_TO_UTF8(wsJS);
Add("JS", new CStringObject(sValue.c_str(), true));
}
//----------------------------------------------------------------------------------------
CActionGoTo::CActionGoTo(CXref* pXref) : CAction(pXref)
{
Add("S", "GoTo");
}
void CActionGoTo::SetDestination(CArrayObject* pDest)
{
Add("D", pDest);
}
//----------------------------------------------------------------------------------------
CActionURI::CActionURI(CXref* pXref) : CAction(pXref)
{
Add("S", "URI");
}
void CActionURI::SetURI(const std::wstring& wsURI)
{
std::string sValue = U_TO_UTF8(wsURI);
Add("URI", new CStringObject(sValue.c_str(), true));
}
//----------------------------------------------------------------------------------------
CActionHide::CActionHide(CXref* pXref) : CAction(pXref)
{
Add("S", "Hide");
}
void CActionHide::SetH(BYTE nH)
{
Add("H", !!nH);
}
void CActionHide::SetT(const std::vector<std::wstring>& arrT)
{
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
Add("T", pArray);
for (const std::wstring& A : arrT)
{
std::string sValue = U_TO_UTF8(A);
pArray->Add(new CStringObject(sValue.c_str(), true));
}
}
//----------------------------------------------------------------------------------------
CActionNamed::CActionNamed(CXref* pXref) : CAction(pXref)
{
Add("S", "Named");
}
void CActionNamed::SetN(const std::wstring& wsN)
{
std::string sValue = U_TO_UTF8(wsN);
Add("N", sValue.c_str());
}
}