mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Draw Stamp
This commit is contained in:
@ -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; }
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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"))
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -132,7 +132,7 @@ namespace PdfWriter
|
||||
|
||||
return sKey;
|
||||
}
|
||||
const char* CResourcesDict::GetXObjectName(CXObject* pObject)
|
||||
const char* CResourcesDict::GetXObjectName(CObjectBase* pObject)
|
||||
{
|
||||
if (!m_pXObjects)
|
||||
{
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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));
|
||||
|
||||
Reference in New Issue
Block a user