Draw Stamp

This commit is contained in:
Svetlana Kulikova
2024-10-21 18:32:36 +03:00
parent f2aa34b5ce
commit 20a2aa1ef1
10 changed files with 208 additions and 8 deletions

View File

@ -645,10 +645,12 @@ void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader*
m_nSy = pReader->ReadByte();
}
int CAnnotFieldInfo::CStampAnnotPr::GetRotate() { return m_nRotate; }
const std::wstring& CAnnotFieldInfo::CStampAnnotPr::GetName() { return m_wsName; }
void CAnnotFieldInfo::CStampAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags)
{
m_wsName = pReader->ReadString();
m_nRotate = pReader->ReadInt();
}
bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; }

View File

@ -402,11 +402,13 @@ public:
class GRAPHICS_DECL CStampAnnotPr
{
public:
int GetRotate();
const std::wstring& GetName();
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags);
private:
int m_nRotate;
std::wstring m_wsName;
};

View File

@ -1111,6 +1111,44 @@ 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"))

View File

@ -1902,10 +1902,10 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
if (nFlags & (1 << 7))
pMarkupAnnot->SetSubj(pPr->GetSubj());
pMarkupAnnot->RemoveAP();
if (oInfo.IsText())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CTextAnnotPr* pPr = oInfo.GetTextAnnotPr();
PdfWriter::CTextAnnotation* pTextAnnot = (PdfWriter::CTextAnnotation*)pAnnot;
@ -1921,6 +1921,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsInk())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CInkAnnotPr* pPr = oInfo.GetInkAnnotPr();
PdfWriter::CInkAnnotation* pInkAnnot = (PdfWriter::CInkAnnotation*)pAnnot;
@ -1934,6 +1936,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsLine())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CLineAnnotPr* pPr = oInfo.GetLineAnnotPr();
PdfWriter::CLineAnnotation* pLineAnnot = (PdfWriter::CLineAnnotation*)pAnnot;
@ -1977,6 +1981,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsTextMarkup())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CTextMarkupAnnotPr* pPr = oInfo.GetTextMarkupAnnotPr();
PdfWriter::CTextMarkupAnnotation* pTextMarkupAnnot = (PdfWriter::CTextMarkupAnnotation*)pAnnot;
@ -1985,6 +1991,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsSquareCircle())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CSquareCircleAnnotPr* pPr = oInfo.GetSquareCircleAnnotPr();
PdfWriter::CSquareCircleAnnotation* pSquareCircleAnnot = (PdfWriter::CSquareCircleAnnotation*)pAnnot;
@ -2006,6 +2014,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsPolygonLine())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CPolygonLineAnnotPr* pPr = oInfo.GetPolygonLineAnnotPr();
PdfWriter::CPolygonLineAnnotation* pPolygonLineAnnot = (PdfWriter::CPolygonLineAnnotation*)pAnnot;
@ -2030,6 +2040,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsFreeText())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CFreeTextAnnotPr* pFTPr = oInfo.GetFreeTextAnnotPr();
PdfWriter::CFreeTextAnnotation* pFreeTextAnnot = (PdfWriter::CFreeTextAnnotation*)pAnnot;
@ -2069,6 +2081,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
}
else if (oInfo.IsCaret())
{
pMarkupAnnot->RemoveAP();
CAnnotFieldInfo::CCaretAnnotPr* pPr = oInfo.GetCaretAnnotPr();
PdfWriter::CCaretAnnotation* pCaretAnnot = (PdfWriter::CCaretAnnotation*)pAnnot;
@ -2087,6 +2101,9 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
PdfWriter::CStampAnnotation* pStampAnnot = (PdfWriter::CStampAnnotation*)pAnnot;
pStampAnnot->SetName(pPr->GetName());
pStampAnnot->SetRotate(pPr->GetRotate());
pStampAnnot->SetAP();
}
}
else if (oInfo.IsPopup())

View File

@ -1343,14 +1343,135 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
// CStampAnnotation
//----------------------------------------------------------------------------------------
CStampAnnotation::CStampAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotStamp)
CStampAnnotation::CStampAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotStamp), m_oBeforeRect(0, 0, 0, 0), m_nDiffRotate(0)
{
}
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)
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);
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");
}
//----------------------------------------------------------------------------------------
// CWidgetAnnotation
//----------------------------------------------------------------------------------------

View File

@ -172,7 +172,7 @@ namespace PdfWriter
return false;
}
void SetRect(const TRect& oRect);
virtual 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);
@ -386,6 +386,11 @@ namespace PdfWriter
};
class CStampAnnotation : public CMarkupAnnotation
{
private:
TRect m_oBeforeRect;
TRect m_oBBox;
CMatrix m_oMatrix;
double m_nDiffRotate;
public:
CStampAnnotation(CXref* pXref);
EAnnotType GetAnnotationType() const override
@ -393,7 +398,13 @@ 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();
};
class CWidgetAnnotation : public CAnnotation
{

View File

@ -132,7 +132,7 @@ namespace PdfWriter
return sKey;
}
const char* CResourcesDict::GetXObjectName(CXObject* pObject)
const char* CResourcesDict::GetXObjectName(CObjectBase* pObject)
{
if (!m_pXObjects)
{

View File

@ -48,7 +48,7 @@ namespace PdfWriter
const char* GetFontName(CFontDict* pFont);
const char* GetExtGrStateName(CExtGrState* pState);
const char* GetXObjectName(CXObject* pXObject);
const char* GetXObjectName(CObjectBase* pXObject);
void AddXObjectWithName(const char* sXObjectName, CXObject* pXObject);
void Fix();

View File

@ -89,6 +89,15 @@ namespace PdfWriter
x = 0;
y = 0;
}
CMatrix(double d1, double d2, double d3, double d4, double d5, double d6)
{
m11 = d1;
m12 = d2;
m21 = d3;
m22 = d4;
x = d5;
y = d6;
}
void Reset()
{

View File

@ -321,7 +321,7 @@ TEST_F(CPdfFileTest, SetMetaData)
TEST_F(CPdfFileTest, ConvertToRaster)
{
//GTEST_SKIP();
GTEST_SKIP();
LoadFromFile();
@ -372,7 +372,7 @@ TEST_F(CPdfFileTest, EditPdf)
TEST_F(CPdfFileTest, EditPdfFromBase64)
{
GTEST_SKIP();
//GTEST_SKIP();
LoadFromFile();
ASSERT_TRUE(pdfFile->EditPdf(wsDstFile));