Add caption to pushbutton AP

This commit is contained in:
Svetlana Kulikova
2024-01-11 14:30:09 +03:00
parent 2ba62286d0
commit 57497bc14b
8 changed files with 145 additions and 130 deletions

View File

@ -2394,13 +2394,13 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi
} }
std::vector<std::wstring> arrBI = pFieldInfo->GetButtonImg(); std::vector<std::wstring> arrBI = pFieldInfo->GetButtonImg();
std::vector<PdfWriter::CImageDict*> arrImg; std::vector<PdfWriter::CXObject*> arrForm;
for (int i = 0; i < arrBI.size(); ++i) for (int i = 0; i < arrBI.size(); ++i)
{ {
std::wstring wsPath = arrBI[i]; std::wstring wsPath = arrBI[i];
if (wsPath.empty()) if (wsPath.empty())
{ {
arrImg.push_back(NULL); arrForm.push_back(NULL);
continue; continue;
} }
std::wstring sTempImagePath = GetDownloadFile(wsPath, wsTempDirectory); std::wstring sTempImagePath = GetDownloadFile(wsPath, wsTempDirectory);
@ -2430,10 +2430,10 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi
PdfWriter::CImageDict* pImage = LoadImage(pCImage, 255); PdfWriter::CImageDict* pImage = LoadImage(pCImage, 255);
RELEASEOBJECT(pCImage); RELEASEOBJECT(pCImage);
arrImg.push_back(pImage); arrForm.push_back(m_pDocument->CreateForm(pImage, std::to_string(i)));
} }
if (arrImg.empty()) if (arrForm.empty())
return S_OK; return S_OK;
std::map<int, PdfWriter::CAnnotation*> mAnnots = m_pDocument->GetAnnots(); std::map<int, PdfWriter::CAnnotation*> mAnnots = m_pDocument->GetAnnots();
@ -2444,24 +2444,10 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi
continue; continue;
PdfWriter::CPushButtonWidget* pPBWidget = (PdfWriter::CPushButtonWidget*)pAnnot; PdfWriter::CPushButtonWidget* pPBWidget = (PdfWriter::CPushButtonWidget*)pAnnot;
if (pPBWidget->m_nI >= 0) DrawButtonWidget(pAppFonts, pPBWidget,
{ pPBWidget->m_nI >= 0 ? arrForm[pPBWidget->m_nI] : NULL,
std::string sFrmName = "FRM" + std::to_string(it->first) + "I"; pPBWidget->m_nRI >= 0 ? arrForm[pPBWidget->m_nRI] : NULL,
std::string sImgName = "Img" + std::to_string(pPBWidget->m_nI); pPBWidget->m_nIX >= 0 ? arrForm[pPBWidget->m_nIX] : NULL);
DrawButtonWidget(pAppFonts, pPBWidget, arrImg[pPBWidget->m_nI], "I", sImgName, sFrmName);
}
if (pPBWidget->m_nRI >= 0)
{
std::string sFrmName = "FRM" + std::to_string(it->first) + "RI";
std::string sImgName = "Img" + std::to_string(pPBWidget->m_nRI);
DrawButtonWidget(pAppFonts, pPBWidget, arrImg[pPBWidget->m_nRI], "RI", sImgName, sFrmName);
}
if (pPBWidget->m_nIX >= 0)
{
std::string sFrmName = "FRM" + std::to_string(it->first) + "IX";
std::string sImgName = "Img" + std::to_string(pPBWidget->m_nIX);
DrawButtonWidget(pAppFonts, pPBWidget, arrImg[pPBWidget->m_nIX], "IX", sImgName, sFrmName);
}
} }
return S_OK; return S_OK;
@ -3533,15 +3519,18 @@ void CPdfWriter::DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
RELEASEARRAYOBJECTS(ppFonts); RELEASEARRAYOBJECTS(ppFonts);
} }
} }
void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, PdfWriter::CImageDict* pImage, const std::string& sAP, const std::string& sImgName, const std::string& sFrmName) void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, PdfWriter::CXObject* pFormI, PdfWriter::CXObject* pFormRI, PdfWriter::CXObject* pFormIX)
{ {
if (!pAppFonts || !pButtonWidget) if (!pAppFonts || !pButtonWidget || (!pFormI && !pFormRI && !pFormIX))
return; return;
pButtonWidget->SetAP(pImage, sAP, sImgName, sFrmName); double dShiftX = 0;
double dShiftY = 0;
unsigned int unLen = 0;
unsigned int* pUnicodes = NULL;
unsigned short* pCodes = NULL;
PdfWriter::CFontCidTrueType** ppFonts = NULL;
std::wstring wsValue = pButtonWidget->GetCA(); std::wstring wsValue = pButtonWidget->GetCA();
// Caption
if (!wsValue.empty()) if (!wsValue.empty())
{ {
PdfWriter::CFontCidTrueType* pFont = pButtonWidget->GetFont(); PdfWriter::CFontCidTrueType* pFont = pButtonWidget->GetFont();
@ -3560,10 +3549,6 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
if (nType == 1 || nType == 3) if (nType == 1 || nType == 3)
dShiftBorder *= 2; dShiftBorder *= 2;
unsigned int unLen = 0;
unsigned int* pUnicodes = NULL;
unsigned short* pCodes = NULL;
PdfWriter::CFontCidTrueType** ppFonts = NULL;
bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts);
if (!bFont) if (!bFont)
{ {
@ -3573,12 +3558,12 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
return; return;
} }
double dShiftX = dShiftBorder * 2; dShiftX = dShiftBorder * 2;
if (dShiftX == 0) if (dShiftX == 0)
dShiftX = 2; dShiftX = 2;
double dBaseLine = (dHeight - dFontSize) / 2.0 - dShiftBorder; dShiftY = (dHeight - dFontSize) / 2.0 - dShiftBorder;
if (pFontTT) if (pFontTT)
dBaseLine = (dHeight - pFontTT->m_dHeight * dFontSize / pFontTT->m_dUnitsPerEm) / 2.0 + std::abs(pFontTT->m_dDescent * dFontSize / pFontTT->m_dUnitsPerEm); dShiftY = (dHeight - pFontTT->m_dHeight * dFontSize / pFontTT->m_dUnitsPerEm) / 2.0 + std::abs(pFontTT->m_dDescent * dFontSize / pFontTT->m_dUnitsPerEm);
double dSumWidth = 0; double dSumWidth = 0;
for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex)
@ -3587,19 +3572,23 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize; double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize;
dSumWidth += dLetterWidth; dSumWidth += dLetterWidth;
} }
switch (pButtonWidget->GetTP())
{
case 0:
{
}
}
pButtonWidget->SetCaptionAP(pCodes, unLen, dShiftX, dBaseLine, ppFonts);
RELEASEARRAYOBJECTS(pUnicodes);
RELEASEARRAYOBJECTS(pCodes);
RELEASEARRAYOBJECTS(ppFonts);
} }
switch (pButtonWidget->GetTP())
{
case 0:
{
}
}
if (pFormI)
pButtonWidget->SetAP(pFormI, "I", pCodes, unLen, dShiftX, dShiftY, ppFonts);
if (pFormRI)
pButtonWidget->SetAP(pFormRI, "RI", pCodes, unLen, dShiftX, dShiftY, ppFonts);
if (pFormIX)
pButtonWidget->SetAP(pFormIX, "IX", pCodes, unLen, dShiftX, dShiftY, ppFonts);
RELEASEARRAYOBJECTS(pUnicodes);
RELEASEARRAYOBJECTS(pCodes);
RELEASEARRAYOBJECTS(ppFonts);
} }

View File

@ -245,7 +245,7 @@ private:
std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory); std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory);
void DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); void DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue);
void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector<std::wstring>& arrValue); void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector<std::wstring>& arrValue);
void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, PdfWriter::CImageDict* pImage, const std::string& sAP, const std::string& sImgName, const std::string& sFrmName); void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, PdfWriter::CXObject* pFormI, PdfWriter::CXObject* pFormRI, PdfWriter::CXObject* pFormIX);
private: private:
NSFonts::IFontManager* m_pFontManager; NSFonts::IFontManager* m_pFontManager;

View File

@ -1226,27 +1226,32 @@ namespace PdfWriter
std::string sValue = U_TO_UTF8(wsAC); std::string sValue = U_TO_UTF8(wsAC);
m_pMK->Add("AC", new CStringObject(sValue.c_str(), true)); m_pMK->Add("AC", new CStringObject(sValue.c_str(), true));
} }
void CPushButtonWidget::SetAP(CImageDict* pImage, const std::string& sAP, const std::string& sImgName, const std::string& sFrmName) void CPushButtonWidget::SetAP(CXObject* pForm, const std::string& sAP, unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts)
{ {
m_pAppearance = new CAnnotAppearance(m_pXref, this); m_pAppearance = new CAnnotAppearance(m_pXref, this);
if (!m_pAppearance) if (!m_pAppearance)
return; return;
CAnnotAppearanceObject* pAppearance = NULL;
if (sAP == "I")
pAppearance = m_pAppearance->GetNormal();
else if (sAP == "RI")
pAppearance = m_pAppearance->GetRollover();
else if (sAP == "IX")
pAppearance = m_pAppearance->GetDown();
if (!pAppearance)
return;
Add("AP", m_pAppearance); Add("AP", m_pAppearance);
CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); if (pForm)
CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources();
CXObject* pForm = NULL;
if (pImage)
{ {
TRect oRect = GetRect(); TRect oRect = GetRect();
double dH = fabs(oRect.fTop - oRect.fBottom); double dH = fabs(oRect.fTop - oRect.fBottom);
double dW = fabs(oRect.fRight - oRect.fLeft); double dW = fabs(oRect.fRight - oRect.fLeft);
double dOriginW = pImage->GetWidth(); double dOriginW = pForm->GetWidth();
double dOriginH = pImage->GetHeight(); double dOriginH = pForm->GetHeight();
bool bNeedScale = (0 == m_nScaleType bool bNeedScale = (0 == m_nScaleType
|| (2 == m_nScaleType && (dOriginH > dH || dOriginW > dW)) || (2 == m_nScaleType && (dOriginH > dH || dOriginW > dW))
@ -1284,61 +1289,18 @@ namespace PdfWriter
dDstX += (dW - dDstW) * m_dShiftX; dDstX += (dW - dDstW) * m_dShiftX;
dDstY += (dH - dDstH) * m_dShiftY; dDstY += (dH - dDstH) * m_dShiftY;
pForm = new CXObject(); pAppearance->DrawPicture(pForm->GetName().c_str(), dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders);
CStream* pStream = new CMemoryStream();
pForm->SetStream(m_pXref, pStream);
#ifndef FILTER_FLATE_DECODE_DISABLED
if (m_pDocument->GetCompressionMode() & COMP_TEXT)
pForm->SetFilter(STREAM_FILTER_FLATE_DECODE);
#endif
CArrayObject* pBBox = new CArrayObject();
pForm->Add("BBox", pBBox);
pBBox->Add(0);
pBBox->Add(0);
pBBox->Add(dOriginW);
pBBox->Add(dOriginH);
pForm->Add("FormType", 1);
CArrayObject* pFormMatrix = new CArrayObject();
pForm->Add("Matrix", pFormMatrix);
pFormMatrix->Add(1);
pFormMatrix->Add(0);
pFormMatrix->Add(0);
pFormMatrix->Add(1);
pFormMatrix->Add(0);
pFormMatrix->Add(0);
pForm->Add("Name", sFrmName.c_str());
CDictObject* pFormRes = new CDictObject();
CArrayObject* pFormResProcset = new CArrayObject();
pFormRes->Add("ProcSet", pFormResProcset);
pFormResProcset->Add(new CNameObject("PDF"));
pFormResProcset->Add(new CNameObject("ImageC"));
CDictObject* pFormResXObject = new CDictObject();
pFormRes->Add("XObject", pFormResXObject);
pFormResXObject->Add(sImgName, pImage);
pForm->Add("Resources", pFormRes);
pForm->Add("Subtype", "Form");
pForm->Add("Type", "XObject");
pStream->WriteStr("q\012");
pStream->WriteReal(dOriginW);
pStream->WriteStr(" 0 0 ");
pStream->WriteReal(dOriginH);
pStream->WriteStr(" 0 0 cm\012/");
pStream->WriteStr(sImgName.c_str());
pStream->WriteStr(" Do\012Q");
pFieldsResources->AddXObjectWithName(sFrmName.c_str(), pForm);
pNormal->DrawPicture(sFrmName.c_str(), dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders);
} }
else else
pNormal->DrawPicture(); pAppearance->DrawPicture();
if (!m_sCaptionForAP.empty()) if (pCodes)
pNormal->GetStream()->WriteStr(m_sCaptionForAP.c_str()); {
CStream* pStream = pAppearance->GetStream();
pStream->WriteStr("\012q\012BT\012");
pAppearance->DrawTextLine(dX, dY, pCodes, unCount, ppFonts, NULL);
pStream->WriteStr("ET\012Q\012");
}
if (pForm) if (pForm)
{ {
@ -1346,25 +1308,6 @@ namespace PdfWriter
m_pMK->Add(sAP, pForm); m_pMK->Add(sAP, pForm);
} }
} }
void CPushButtonWidget::SetCaptionAP(unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts)
{
m_sCaptionForAP.append("\012q\012BT\012");
CAnnotAppearanceObject* pNormal = new CAnnotAppearanceObject(NULL, this);
pNormal->m_bStart = true;
pNormal->DrawTextLine(dX, dY, pCodes, unCount, ppFonts, NULL);
CStream* pStream = pNormal->GetStream();
pStream->Seek(0, SeekSet);
unsigned int nBufferSize = pStream->Size();
BYTE* pBuffer = new BYTE[nBufferSize];
pStream->Read(pBuffer, NULL);
m_sCaptionForAP.append((char*)pBuffer, nBufferSize);
RELEASEARRAYOBJECTS(pBuffer);
RELEASEOBJECT(pNormal);
m_sCaptionForAP.append("ET\012Q\012");
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CCheckBoxWidget // CCheckBoxWidget
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------

View File

@ -439,8 +439,7 @@ namespace PdfWriter
void SetRC(const std::wstring& wsRC); void SetRC(const std::wstring& wsRC);
void SetAC(const std::wstring& wsAC); void SetAC(const std::wstring& wsAC);
void SetAP(CImageDict* pImage, const std::string& sAP, const std::string& sImgName, const std::string& sFrmName); void SetAP(CXObject* pForm, const std::string& sAP, unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts);
void SetCaptionAP(unsigned short* pCodes, unsigned int unCount, double dX, double dY, CFontCidTrueType** ppFonts);
const std::wstring& GetCA() { return m_wsCA; } const std::wstring& GetCA() { return m_wsCA; }
BYTE GetTP() { return m_nTP; } BYTE GetTP() { return m_nTP; }

View File

@ -698,6 +698,71 @@ namespace PdfWriter
{ {
return new CImageDict(m_pXref, this); return new CImageDict(m_pXref, this);
} }
CXObject* CDocument::CreateForm(CImageDict* pImage, const std::string& sName)
{
if (!pImage)
return NULL;
std::string sFrmName = "FRM" + sName;
std::string sImgName = "Img" + sName;
CXObject* pForm = new CXObject();
CStream* pStream = new CMemoryStream();
pForm->SetStream(m_pXref, pStream);
#ifndef FILTER_FLATE_DECODE_DISABLED
if (m_unCompressMode & COMP_TEXT)
pForm->SetFilter(STREAM_FILTER_FLATE_DECODE);
#endif
double dOriginW = pImage->GetWidth();
double dOriginH = pImage->GetHeight();
pForm->SetWidth(dOriginW);
pForm->SetHeight(dOriginH);
CArrayObject* pBBox = new CArrayObject();
pForm->Add("BBox", pBBox);
pBBox->Add(0);
pBBox->Add(0);
pBBox->Add(dOriginW);
pBBox->Add(dOriginH);
pForm->Add("FormType", 1);
CArrayObject* pFormMatrix = new CArrayObject();
pForm->Add("Matrix", pFormMatrix);
pFormMatrix->Add(1);
pFormMatrix->Add(0);
pFormMatrix->Add(0);
pFormMatrix->Add(1);
pFormMatrix->Add(0);
pFormMatrix->Add(0);
pForm->Add("Name", sFrmName.c_str());
pForm->SetName(sFrmName);
CDictObject* pFormRes = new CDictObject();
CArrayObject* pFormResProcset = new CArrayObject();
pFormRes->Add("ProcSet", pFormResProcset);
pFormResProcset->Add(new CNameObject("PDF"));
pFormResProcset->Add(new CNameObject("ImageC"));
CDictObject* pFormResXObject = new CDictObject();
pFormRes->Add("XObject", pFormResXObject);
pFormResXObject->Add(sImgName, pImage);
pForm->Add("Resources", pFormRes);
pForm->Add("Subtype", "Form");
pForm->Add("Type", "XObject");
pStream->WriteStr("q\012");
pStream->WriteReal(dOriginW);
pStream->WriteStr(" 0 0 ");
pStream->WriteReal(dOriginH);
pStream->WriteStr(" 0 0 cm\012/");
pStream->WriteStr(sImgName.c_str());
pStream->WriteStr(" Do\012Q");
GetFieldsResources()->AddXObjectWithName(sFrmName.c_str(), pForm);
return pForm;
}
CFont14* CDocument::CreateFont14(EStandard14Fonts eType) CFont14* CDocument::CreateFont14(EStandard14Fonts eType)
{ {
return new CFont14(m_pXref, this, eType); return new CFont14(m_pXref, this, eType);

View File

@ -91,6 +91,7 @@ namespace PdfWriter
class CDateTimeField; class CDateTimeField;
class CFieldBase; class CFieldBase;
class CStreamData; class CStreamData;
class CXObject;
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CDocument // CDocument
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
@ -155,6 +156,7 @@ namespace PdfWriter
CAction* CreateAction(BYTE nType); CAction* CreateAction(BYTE nType);
CImageDict* CreateImage(); CImageDict* CreateImage();
CXObject* CreateForm(CImageDict* pImage, const std::string& sName);
CFont14* CreateFont14(EStandard14Fonts eType); CFont14* CreateFont14(EStandard14Fonts eType);
CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex);
CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex);

View File

@ -89,6 +89,11 @@ namespace NSImageReSaver
namespace PdfWriter namespace PdfWriter
{ {
CXObject::CXObject()
{
m_dOriginW = 0;
m_dOriginH = 0;
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CImageDict // CImageDict
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------

View File

@ -41,11 +41,23 @@ namespace PdfWriter
class CMemoryStream; class CMemoryStream;
class CXObject : public CDictObject class CXObject : public CDictObject
{ {
private:
double m_dOriginW;
double m_dOriginH;
std::string m_sName;
public: public:
CXObject();
EDictType GetDictType() const EDictType GetDictType() const
{ {
return dict_type_XOBJECT; return dict_type_XOBJECT;
} }
void SetWidth (double dW) { m_dOriginW = dW; }
void SetHeight(double dH) { m_dOriginH = dH; }
void SetName(const std::string& sName) { m_sName = sName; }
double GetWidth() { return m_dOriginW; }
double GetHeight() { return m_dOriginH; }
const std::string& GetName() { return m_sName; }
}; };
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CImageDict // CImageDict