Get Stamp stream AP

This commit is contained in:
Svetlana Kulikova
2024-10-22 13:25:02 +03:00
parent a8e3dd2ef5
commit 894f78d143
5 changed files with 57 additions and 162 deletions

View File

@ -1112,43 +1112,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID)
else if (oType.isName("Caret"))
pAnnot = new PdfWriter::CCaretAnnotation(pXref);
else if (oType.isName("Stamp"))
{
pAnnot = new PdfWriter::CStampAnnotation(pXref);
Object oAP, oAPN;
if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oAPN)->isStream())
{
Object oObj;
Dict* pAPN = oAPN.streamGetDict();
if (pAPN->lookup("BBox", &oObj)->isArray() && oObj.arrayGetLength() == 4)
{
double d[4];
for (int i = 0; i < 4; ++i)
{
Object oObj2;
oObj.arrayGet(i, &oObj2);
d[i] = oObj2.getNum();
oObj2.free();
}
((PdfWriter::CStampAnnotation*)pAnnot)->SetBBox({ d[0], d[1], d[2], d[3] });
}
oObj.free();
if (pAPN->lookup("Matrix", &oObj)->isArray() && oObj.arrayGetLength() == 6)
{
double d[6];
for (int i = 0; i < 6; ++i)
{
Object oObj2;
oObj.arrayGet(i, &oObj2);
d[i] = oObj2.getNum();
oObj2.free();
}
((PdfWriter::CStampAnnotation*)pAnnot)->SetMatrix({ d[0], d[1], d[2], d[3], d[4], d[5] });
}
oObj.free();
}
oAP.free(); oAPN.free();
}
else if (oType.isName("Popup"))
pAnnot = new PdfWriter::CPopupAnnotation(pXref);
else if (oType.isName("Widget"))
@ -1223,11 +1187,10 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID)
}
oFT.free();
}
oType.free();
if (!pAnnot)
{
oAnnotRef.free(); oAnnot.free();
oAnnotRef.free(); oAnnot.free(); oType.free();
RELEASEOBJECT(pXref);
return false;
}
@ -1286,7 +1249,44 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID)
DictToCDictObject(&oTemp, pAnnot, false, chKey);
oTemp.free();
}
oAnnotRef.free(); oAnnot.free();
if (oType.isName("Stamp"))
{
Object oAP, oAPN;
if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oAPN)->isStream())
{
Object oAPNRef;
oAP.dictLookupNF("N", &oAPNRef);
PdfWriter::CXref* pXRef = new PdfWriter::CXref(pDoc, oAPNRef.getRefNum());
pDoc->EditXref(pXRef);
PdfWriter::CDictObject* pAPN = new PdfWriter::CDictObject();
pXRef->Add(pAPN, oAPNRef.getRefGen());
((PdfWriter::CStampAnnotation*)pAnnot)->SetAPStream(pAPN);
oAPNRef.free();
Object oTemp;
Dict* pODict = oAPN.streamGetDict();
for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex)
{
char* chKey = pODict->getKey(nIndex);
pODict->getValNF(nIndex, &oTemp);
DictToCDictObject(&oTemp, pAPN, false, chKey);
oTemp.free();
}
int nLength = 0;
if (pODict->lookup("Length", &oTemp)->isInt())
nLength = oTemp.getInt();
PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(nLength);
pAPN->SetStream(pStream);
Stream* pOStream = oAPN.getStream()->getUndecodedStream();
pOStream->reset();
for (int nI = 0; nI < nLength; ++nI)
pStream->WriteChar(pOStream->getChar());
}
oAP.free(); oAPN.free();
}
oAnnotRef.free(); oAnnot.free(); oType.free();
if (pDoc->EditAnnot(pXref, pAnnot, nID))
return true;

View File

@ -2102,8 +2102,6 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
pStampAnnot->SetName(pPr->GetName());
pStampAnnot->SetRotate(pPr->GetRotate());
pStampAnnot->SetAP();
}
}
else if (oInfo.IsPopup())

View File

@ -1343,134 +1343,38 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
// CStampAnnotation
//----------------------------------------------------------------------------------------
CStampAnnotation::CStampAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotStamp), m_oBeforeRect(0, 0, 0, 0), m_nDiffRotate(0)
CStampAnnotation::CStampAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotStamp), m_pAPStream(NULL)
{
}
void CStampAnnotation::SetRect(const TRect& oRect)
{
CObjectBase* pObj = Get("Rect");
if (pObj->GetType() != object_type_ARRAY)
return;
CArrayObject* pRect = (CArrayObject*)pObj;
pObj = pRect->Get(0);
m_oBeforeRect.fLeft = pObj->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pObj)->Get() : ((PdfWriter::CRealObject*)pObj)->Get();
pObj = pRect->Get(1);
m_oBeforeRect.fBottom = pObj->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pObj)->Get() : ((PdfWriter::CRealObject*)pObj)->Get();
pObj = pRect->Get(2);
m_oBeforeRect.fRight = pObj->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pObj)->Get() : ((PdfWriter::CRealObject*)pObj)->Get();
pObj = pRect->Get(3);
m_oBeforeRect.fTop = pObj->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pObj)->Get() : ((PdfWriter::CRealObject*)pObj)->Get();
CAnnotation::SetRect(oRect);
}
void CStampAnnotation::SetRotate(int nRotate)
{
CObjectBase* pObj = Get("Rotate");
if (pObj->GetType() == object_type_NUMBER)
m_nDiffRotate = nRotate - ((CNumberObject*)pObj)->Get();
//m_nDiffRotate = nRotate;
Add("Rotate", nRotate);
}
void CStampAnnotation::SetName(const std::wstring& wsName)
{
std::string sValue = U_TO_UTF8(wsName);
Add("Name", sValue.c_str());
}
void CStampAnnotation::SetBBox(const TRect& oRect)
{
m_oBBox = oRect;
}
void CStampAnnotation::SetMatrix(const CMatrix& oMatrix)
{
m_oMatrix = oMatrix;
}
void CStampAnnotation::SetAP()
{
CObjectBase* pAPN = ((CDictObject*)Get("AP"))->Get("N");
CObjectBase* pN = new CObjectBase();
pN->SetRef(pAPN->GetObjId(), pAPN->GetGenNo());
pN->SetIndirect();
CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this);
Add("AP", pAppearance);
CAnnotAppearanceObject* pNormal = pAppearance->GetNormal();
CStream* pStream = pNormal->GetStream();
CResourcesDict* pResources = (CResourcesDict*)pNormal->Get("Resources");
const char* sXObjectName = pResources->GetXObjectName(pN);
if (!sXObjectName)
if (!m_pAPStream)
return;
CArrayObject* pArray = new CArrayObject();
if (!pArray)
return;
pNormal->Add("BBox", pArray);
double x, y, formXMin, formYMin, formXMax, formYMax;
x = m_oBBox.fLeft;
y = m_oBBox.fBottom;
m_oMatrix.Apply(x, y);
formXMin = formXMax = x;
formYMin = formYMax = y;
x = m_oBBox.fLeft;
y = m_oBBox.fTop;
m_oMatrix.Apply(x, y);
if (x < formXMin)
formXMin = x;
else if (x > formXMax)
formXMax = x;
if (y < formYMin)
formYMin = y;
else if (y > formYMax)
formYMax = y;
x = m_oBBox.fRight;
y = m_oBBox.fBottom;
m_oMatrix.Apply(x, y);
if (x < formXMin)
formXMin = x;
else if (x > formXMax)
formXMax = x;
if (y < formYMin)
formYMin = y;
else if (y > formYMax)
formYMax = y;
x = m_oBBox.fRight;
y = m_oBBox.fTop;
m_oMatrix.Apply(x, y);
if (x < formXMin)
formXMin = x;
else if (x > formXMax)
formXMax = x;
if (y < formYMin)
formYMin = y;
else if (y > formYMax)
formYMax = y;
pArray->Add(formXMin);
pArray->Add(formYMin);
pArray->Add(formXMax);
pArray->Add(formYMax);
pArray = new CArrayObject();
if (!pArray)
return;
double ca = cos(m_nDiffRotate / 180.0 * M_PI);
double sa = sin(m_nDiffRotate / 180.0 * M_PI);
pNormal->Add("Matrix", pArray);
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);
pStream->WriteEscapeName(sXObjectName);
pStream->WriteStr(" Do\012");
}
void CStampAnnotation::SetName(const std::wstring& wsName)
{
std::string sValue = U_TO_UTF8(wsName);
Add("Name", sValue.c_str());
}
void CStampAnnotation::SetAPStream(CDictObject* pStream)
{
m_pAPStream = pStream;
}
//----------------------------------------------------------------------------------------
// CWidgetAnnotation

View File

@ -172,7 +172,7 @@ namespace PdfWriter
return false;
}
virtual void SetRect(const TRect& oRect);
void SetRect(const TRect& oRect);
void SetBorder(BYTE nType, double dWidth, const std::vector<double>& arrDash);
void SetAnnotFlag(const int& nAnnotFlag);
void SetPage(CPage* pPage, double dW = 0, double dH = 0, double dX = 0);
@ -387,10 +387,7 @@ namespace PdfWriter
class CStampAnnotation : public CMarkupAnnotation
{
private:
TRect m_oBeforeRect;
TRect m_oBBox;
CMatrix m_oMatrix;
double m_nDiffRotate;
CDictObject* m_pAPStream;
public:
CStampAnnotation(CXref* pXref);
EAnnotType GetAnnotationType() const override
@ -398,13 +395,9 @@ namespace PdfWriter
return AnnotStamp;
}
virtual void SetRect(const TRect& oRect) override;
void SetRotate(int nRotate);
void SetName(const std::wstring& wsName);
void SetBBox(const TRect& oRect);
void SetMatrix(const CMatrix& oMatrix);
void SetAP();
void SetAPStream(CDictObject* pStream);
};
class CWidgetAnnotation : public CAnnotation
{

View File

@ -209,6 +209,7 @@ namespace PdfWriter
void AddShapeXML(const std::string& sXML);
void EndShapeXML();
void ClearPage();
bool EditXref(CXref* pXref);
private:
char* GetTTFontTag();
@ -224,7 +225,6 @@ namespace PdfWriter
bool CheckAcroForm();
CRadioGroupField* FindRadioGroupField(const std::wstring& wsGroupName);
void Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef = false);
bool EditXref(CXref* pXref);
private: