From 2cceef7386d944d8ef4b83377ee4a3ad5176d27e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 9 Apr 2026 15:37:47 +0300 Subject: [PATCH] Write RedactAnnot without changes --- DesktopEditor/graphics/IRenderer.h | 2 +- DesktopEditor/graphics/MetafileToRenderer.cpp | 2 +- DesktopEditor/graphics/MetafileToRenderer.h | 1 - .../graphics/MetafileToRendererReader.cpp | 1 - .../graphics/commands/AnnotField.cpp | 2 +- PdfFile/OnlineOfficeBinToPdf.cpp | 16 +- PdfFile/PdfEditor.cpp | 446 +++++++++++------- PdfFile/PdfEditor.h | 2 + PdfFile/PdfFile.cpp | 4 +- PdfFile/SrcWriter/Document.cpp | 2 + PdfFile/SrcWriter/Pages.cpp | 24 +- PdfFile/SrcWriter/Pages.h | 1 + 12 files changed, 303 insertions(+), 200 deletions(-) diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 8d270d582e..c268c82bba 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -149,7 +149,7 @@ public: Link = 1, DocInfo = 2, FormField = 3, // Обратная совместимость для docxf - Annotaion = 4, + Annotation = 4, DeleteAnnot = 5, WidgetsInfo = 6, ShapeStart = 7, diff --git a/DesktopEditor/graphics/MetafileToRenderer.cpp b/DesktopEditor/graphics/MetafileToRenderer.cpp index 0b6f8d2ef3..a99eb094f6 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToRenderer.cpp @@ -1064,7 +1064,7 @@ namespace NSOnlineOfficeBinToPdf switch (eCommand) { case ctFormField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::FormField; break; - case ctAnnotField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Annotaion; break; + case ctAnnotField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Annotation; break; case ctAnnotFieldDelete: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::DeleteAnnot; break; case ctWidgetsInfo: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::WidgetsInfo; break; case ctShapeStart: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; break; diff --git a/DesktopEditor/graphics/MetafileToRenderer.h b/DesktopEditor/graphics/MetafileToRenderer.h index a6ae4cbc21..6314e43490 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.h +++ b/DesktopEditor/graphics/MetafileToRenderer.h @@ -189,7 +189,6 @@ namespace NSOnlineOfficeBinToPdf ctShapeEnd = 168, ctHeadings = 169, ctRedact = 170, - ctRedactAnnot = 171, ctPageWidth = 200, ctPageHeight = 201, diff --git a/DesktopEditor/graphics/MetafileToRendererReader.cpp b/DesktopEditor/graphics/MetafileToRendererReader.cpp index cdcc3b56fe..83527c66ff 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.cpp +++ b/DesktopEditor/graphics/MetafileToRendererReader.cpp @@ -72,7 +72,6 @@ namespace NSOnlineOfficeBinToPdf case ctPageRotate: return Read_Command (this, pCorrector); case ctHeadings: return Read_Command (this, pCorrector); case ctRedact: return Read_Command (this, pCorrector); - case ctRedactAnnot: return Read_Command (this, pCorrector); default: break; } diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index fd42ccc1ec..ba0c37c41e 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -132,7 +132,7 @@ CAnnotFieldInfo::CActionFieldPr* ReadAction(NSOnlineOfficeBinToPdf::CBufferReade return pRes; } -CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotaion) +CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotation) { m_nType = EAnnotType::Unknown; diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index e6ee2b90ee..38edcb72ef 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -33,6 +33,7 @@ #include "../../DesktopEditor/common/Directory.h" #include "../../DesktopEditor/graphics/MetafileToRenderer.h" +#include "../../DesktopEditor/graphics/commands/AnnotField.h" namespace NSOnlineOfficeBinToPdf { @@ -269,8 +270,11 @@ namespace NSOnlineOfficeBinToPdf BYTE* cur = oReader.GetCurrentBuffer(); int nLen2 = oReader.ReadInt(); - // ctAnnotField - arrForms.push_back(oReader.Read(eCommand, &oCorrector, nLen)); + CAnnotFieldInfo* command = new CAnnotFieldInfo(); + if (command->Read(&oReader, &oCorrector)) + arrForms.push_back(command); + else + RELEASEOBJECT(command); oReader.SetCurrentBuffer(cur + nLen2); } @@ -281,7 +285,13 @@ namespace NSOnlineOfficeBinToPdf } } else - arrForms.push_back(oReader.Read(NSOnlineOfficeBinToPdf::CommandType::ctRedactAnnot, &oCorrector, nLen)); + { + CRedactAnnot* command = new CRedactAnnot(); + if (command->Read(&oReader, &oCorrector)) + arrForms.push_back(command); + else + RELEASEOBJECT(command); + } } } pPdf->RedactInfo(nPageNum, arrForms); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 0fe09630e7..f744ced7ec 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -172,6 +172,7 @@ bool SplitSkipDict(Object* obj, CObjectsManager* pManager, int nStartRefID) } else if (oTemp.isName("Annot") && obj->dictLookupNF("P", &oTemp2)->isRef()) { + // Skip annotations that don't have page created PdfWriter::CObjectBase* pObj = pManager->GetObj(oTemp2.getRefNum() + nStartRefID); if (!pObj) { @@ -476,6 +477,10 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD return pObj; } + std::vector::iterator it = std::find(pManager->m_arrRedactFormFieldsID.begin(), pManager->m_arrRedactFormFieldsID.end(), nObjNum); + if (it != pManager->m_arrRedactFormFieldsID.end()) + return NULL; + obj->fetch(xref, &oTemp); pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID, nObjNum, bUndecodedStream); oTemp.free(); @@ -934,6 +939,167 @@ void GetCTM(XRef* pXref, Object* oPage, double* dCTM) oContents.free(); } +void GetInvertCTM(double* dCTM, double* dInvCTM) +{ + double det = dCTM[0] * dCTM[3] - dCTM[1] * dCTM[2]; + if (fabs(det) > 1e-10) + { + double invDet = 1.0 / det; + dInvCTM[0] = dCTM[3] * invDet; + dInvCTM[1] = -dCTM[1] * invDet; + dInvCTM[2] = -dCTM[2] * invDet; + dInvCTM[3] = dCTM[0] * invDet; + dInvCTM[4] = (dCTM[2] * dCTM[5] - dCTM[3] * dCTM[4]) * invDet; + dInvCTM[5] = (dCTM[1] * dCTM[4] - dCTM[0] * dCTM[5]) * invDet; + } +} +void DrawAnnot(Object* oAnnot, PdfWriter::CPage* pPage, PdfWriter::CDocument* pDoc, XRef* xref, CObjectsManager* pManager, int nStartRefID) +{ + Object oAP, oAPN, oObj; + if (!oAnnot->dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oAPN)->isStream()) + { + oAP.free(); + Object oTemp; + if (!oAPN.isDict() || !oAnnot->dictLookup("AS", &oObj)->isName() || !oAPN.dictLookup(oObj.getName(), &oTemp)->isStream()) + { + oTemp.free(); oAPN.free(); oObj.free(); + return; + } + oAPN.free(); + oAPN = oTemp; + } + oAP.free(); + + PdfWriter::CXObject* pForm = pDoc->CreateForm(); + pPage->GrSave(); + pPage->ExecuteXObject(pForm); + pPage->GrRestore(); + + Object oTemp; + double m[6] = { 1, 0, 0, 1, 0, 0 }, bbox[4] = { 0, 0, 0, 0 }, rect[4] = { 0, 0, 0, 0 }; + if (oAnnot->dictLookup("Rect", &oTemp)->isArray() && oTemp.arrayGetLength() == 4) + { + for (int j = 0; j < 4; ++j) + { + oTemp.arrayGet(j, &oObj); + rect[j] = oObj.isNum() ? oObj.getNum() : 0; + oObj.free(); + } + + if (rect[0] > rect[2]) + std::swap(rect[0], rect[2]); + if (rect[1] > rect[3]) + std::swap(rect[1], rect[3]); + } + oTemp.free(); + + Dict* pODict = oAPN.streamGetDict(); + for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex) + { + char* chKey = pODict->getKey(nIndex); + if (strcmp("Length", chKey) == 0 || strcmp("Filter", chKey) == 0) + { + oTemp.free(); + continue; + } + else if (strcmp("BBox", chKey) == 0 && pODict->getVal(nIndex, &oTemp)->isArray() && oTemp.arrayGetLength() == 4) + { + for (int j = 0; j < 4; ++j) + { + oTemp.arrayGet(j, &oObj); + bbox[j] = oObj.isNum() ? oObj.getNum() : 0; + oObj.free(); + } + + if (bbox[0] > bbox[2]) + std::swap(bbox[0], bbox[2]); + if (bbox[1] > bbox[3]) + std::swap(bbox[1], bbox[3]); + } + else if (strcmp("Matrix", chKey) == 0 && pODict->getVal(nIndex, &oTemp)->isArray() && oTemp.arrayGetLength() == 6) + { + for (int j = 0; j < 6; ++j) + { + oTemp.arrayGet(j, &oObj); + m[j] = oObj.getNum(); + oObj.free(); + } + } + oTemp.free(); + pODict->getValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); + pForm->Add(chKey, pBase); + oTemp.free(); + } + + double formXMin, formYMin, formXMax, formYMax, x, y, sx, sy; + x = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; + y = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; + formXMin = formXMax = x; + formYMin = formYMax = y; + x = bbox[0] * m[0] + bbox[3] * m[2] + m[4]; + y = bbox[0] * m[1] + bbox[3] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + x = bbox[2] * m[0] + bbox[1] * m[2] + m[4]; + y = bbox[2] * m[1] + bbox[1] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + x = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; + y = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; + if (x < formXMin) + formXMin = x; + else if (x > formXMax) + formXMax = x; + if (y < formYMin) + formYMin = y; + else if (y > formYMax) + formYMax = y; + + if (formXMin == formXMax) + sx = 1; + else + sx = (rect[2] - rect[0]) / (formXMax - formXMin); + if (formYMin == formYMax) + sy = 1; + else + sy = (rect[3] - rect[1]) / (formYMax - formYMin); + double tx = -formXMin * sx + rect[0]; + double ty = -formYMin * sy + rect[1]; + + m[0] *= sx; + m[1] *= sy; + m[2] *= sx; + m[3] *= sy; + m[4] = m[4] * sx + tx; + m[5] = m[5] * sy + ty; + + pForm->Add("Matrix", PdfWriter::CArrayObject::CreateMatrix(m)); + + PdfWriter::CStream* pStream = pForm->GetStream(); + Stream* pOStream = oAPN.getStream(); + pOStream->reset(); + int nChar = pOStream->getChar(); + while (nChar != EOF) + { + pStream->WriteChar(nChar); + nChar = pOStream->getChar(); + } + + oAPN.free(); +} void CObjectsManager::AddObj(int nID, PdfWriter::CObjectBase* pObj) { @@ -1110,6 +1276,24 @@ void CPdfEditor::RedactInfo(int nFlag, const std::vector& arr // 8 - Deleted or cropped content // 9 - Links, actions and JavaScripts // 10 - Overlapping Objects + + m_mObjManager.m_arrRedactFormFields = arrForms; + for (int i = 0; i < arrForms.size(); ++i) + { + IAdvancedCommand::AdvancedCommandType nType = arrForms[i]->GetCommandType(); + if (nType == IAdvancedCommand::AdvancedCommandType::Annotation) + { + // Annotation - annotation that has changed or been created and needs to be drawn in Contents of page + CAnnotFieldInfo* command = dynamic_cast(arrForms[i]); + m_mObjManager.m_arrRedactFormFieldsID.push_back(command->GetID()); + } + else if (nType == IAdvancedCommand::AdvancedCommandType::RedactAnnot) + { + // RedactAnnot - annotation that needs to be drawn in Contents of page without changes + CRedactAnnot* command = dynamic_cast(arrForms[i]); + m_mObjManager.m_arrRedactFormFieldsID.push_back(command->GetID()); + } + } } bool CPdfEditor::IncrementalUpdates() { @@ -1623,6 +1807,64 @@ void CPdfEditor::Close() if (m_nMode == Mode::WriteNew) { PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + + for (int i = 0; i < m_mObjManager.m_arrRedactFormFields.size(); ++i) + { + IAdvancedCommand::AdvancedCommandType nType = m_mObjManager.m_arrRedactFormFields[i]->GetCommandType(); + if (nType == IAdvancedCommand::AdvancedCommandType::Annotation) + { + // Annotation - annotation that has changed or been created and needs to be drawn in Contents of page + CAnnotFieldInfo* command = dynamic_cast(m_mObjManager.m_arrRedactFormFields[i]); + } + else if (nType == IAdvancedCommand::AdvancedCommandType::RedactAnnot) + { + // RedactAnnot - annotation that needs to be drawn in Contents of page without changes + CRedactAnnot* command = dynamic_cast(m_mObjManager.m_arrRedactFormFields[i]); + + PDFDoc* pPDFDocument = NULL; + int nStartRefID = 0; + int nRefID = m_pReader->FindRefNum(command->GetID(), &pPDFDocument, &nStartRefID); + if (nRefID < 0) + continue; + + XRef* xref = pPDFDocument->getXRef(); + XRefEntry* pEntry = xref->getEntry(nRefID); + Object oAnnotRef, oAnnot; + oAnnotRef.initRef(nRefID, pEntry->type == xrefEntryCompressed ? 0 : pEntry->gen); + if (oAnnotRef.fetch(xref, &oAnnot)->isNull()) + { + oAnnotRef.free(); + continue; + } + oAnnotRef.free(); + + if (!oAnnot.isDict()) + { + oAnnot.free(); + continue; + } + + Object oP; + if (!oAnnot.dictLookupNF("P", &oP)->isRef()) + { + oAnnot.free(); oP.free(); + continue; + } + + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oP.getRefNum() + nStartRefID); + PdfWriter::CPage* pPage = dynamic_cast(pObj); + if (!pObj || !pPage) + { + oAnnot.free(); oP.free(); + continue; + } + + // Have page where we need to draw annotation + DrawAnnot(&oAnnot, pPage, pDoc, xref, &m_mObjManager, nStartRefID); + oAnnot.free(); + } + } + PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree(); int nPages = pPageTree->GetCount(); for (int i = 0; i < nPages; ++i) @@ -2108,9 +2350,6 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet, bool bActualPos) } pPage->Fix(); pDoc->FixEditPage(pPage); - double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; - GetCTM(xref, &pageObj, dCTM); - pageObj.free(); if (bSet) { @@ -2133,7 +2372,13 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet, bool bActualPos) } } - pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); + double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; + double dInvCTM[6] = { 1, 0, 0, 1, 0, 0 }; + GetCTM(xref, &pageObj, dCTM); + GetInvertCTM(dCTM, dInvCTM); + pageObj.free(); + + pPage->Transform(dInvCTM[0], dInvCTM[1], dInvCTM[2], dInvCTM[3], dInvCTM[4], dInvCTM[5]); pPage->SetStrokeColor(0, 0, 0); pPage->SetFillColor(0, 0, 0); pPage->SetExtGrState(pDoc->GetExtGState(255, 255)); @@ -2317,9 +2562,6 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet, bool bActualPos) } } pPage->Fix(); - double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; - GetCTM(xref, &pageObj, dCTM); - pageObj.free(); // Применение редактирования страницы для writer if (pDoc->EditPage(pXref, pPage, _nPageIndex)) @@ -2343,7 +2585,13 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet, bool bActualPos) pStream->WriteStr(" cm\012"); } } - pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); + double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; + double dInvCTM[6] = { 1, 0, 0, 1, 0, 0 }; + GetCTM(xref, &pageObj, dCTM); + GetInvertCTM(dCTM, dInvCTM); + pageObj.free(); + + pPage->Transform(dInvCTM[0], dInvCTM[1], dInvCTM[2], dInvCTM[3], dInvCTM[4], dInvCTM[5]); pPage->SetStrokeColor(0, 0, 0); pPage->SetFillColor(0, 0, 0); pPage->SetExtGrState(pDoc->GetExtGState(255, 255)); @@ -2355,6 +2603,7 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet, bool bActualPos) return true; } + pageObj.free(); RELEASEOBJECT(pXref); return false; } @@ -2550,8 +2799,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD pDoc->FixEditPage(pPage); double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; + double dInvCTM[6] = { 1, 0, 0, 1, 0, 0 }; GetCTM(xref, &pageObj, dCTM); - pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); + GetInvertCTM(dCTM, dInvCTM); + + pPage->Transform(dInvCTM[0], dInvCTM[1], dInvCTM[2], dInvCTM[3], dInvCTM[4], dInvCTM[5]); pPage->SetStrokeColor(0, 0, 0); pPage->SetFillColor(0, 0, 0); pPage->SetExtGrState(pDoc->GetExtGState(255, 255)); @@ -3196,35 +3448,11 @@ bool CPdfEditor::PrintPages(const std::vector& arrPages, int nFlag) pDoc->FixEditPage(pPage); double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; - double dInvMatrix[6] = { 1, 0, 0, 1, 0, 0 }; + double dInvCTM[6] = { 1, 0, 0, 1, 0, 0 }; GetCTM(xref, &pageObj, dCTM); + GetInvertCTM(dCTM, dInvCTM); - double det = dCTM[0] * dCTM[3] - dCTM[1] * dCTM[2]; - if (fabs(det) > 1e-10) - { - double invDet = 1.0 / det; - dInvMatrix[0] = dCTM[3] * invDet; - dInvMatrix[1] = -dCTM[1] * invDet; - dInvMatrix[2] = -dCTM[2] * invDet; - dInvMatrix[3] = dCTM[0] * invDet; - dInvMatrix[4] = (dCTM[2] * dCTM[5] - dCTM[3] * dCTM[4]) * invDet; - dInvMatrix[5] = (dCTM[1] * dCTM[4] - dCTM[0] * dCTM[5]) * invDet; - } - - PdfWriter::CStream* pStream = pPage->GetStream(); - pStream->WriteReal(dInvMatrix[0]); - pStream->WriteChar(' '); - pStream->WriteReal(dInvMatrix[1]); - pStream->WriteChar(' '); - pStream->WriteReal(dInvMatrix[2]); - pStream->WriteChar(' '); - pStream->WriteReal(dInvMatrix[3]); - pStream->WriteChar(' '); - pStream->WriteReal(dInvMatrix[4]); - pStream->WriteChar(' '); - pStream->WriteReal(dInvMatrix[5]); - pStream->WriteStr(" cm\012"); - + pPage->Transform(dInvCTM[0], dInvCTM[1], dInvCTM[2], dInvCTM[3], dInvCTM[4], dInvCTM[5]); pPage->SetStrokeColor(0, 0, 0); pPage->SetFillColor(0, 0, 0); pPage->SetExtGrState(pDoc->GetExtGState(255, 255)); @@ -3267,150 +3495,8 @@ bool CPdfEditor::PrintPages(const std::vector& arrPages, int nFlag) oType.free(); // TODO Нужно ли генерировать внешний вид тем у кого его нет - Object oAP, oAPN; - if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oAPN)->isStream()) - { - oAP.free(); - Object oTemp; - if (!oAPN.isDict() || !oAnnot.dictLookup("AS", &oObj)->isName() || !oAPN.dictLookup(oObj.getName(), &oTemp)->isStream()) - { - oAnnot.free(); oTemp.free(); oAPN.free(); oObj.free(); - continue; - } - oAPN.free(); - oAPN = oTemp; - } - oAP.free(); - - PdfWriter::CXObject* pForm = pDoc->CreateForm(); - pPage->GrSave(); - pPage->ExecuteXObject(pForm); - pPage->GrRestore(); - - Object oTemp; - double m[6] = { 1, 0, 0, 1, 0, 0 }, bbox[4] = { 0, 0, 0, 0 }, rect[4] = { 0, 0, 0, 0 }; - if (oAnnot.dictLookup("Rect", &oTemp)->isArray() && oTemp.arrayGetLength() == 4) - { - for (int j = 0; j < 4; ++j) - { - oTemp.arrayGet(j, &oObj); - rect[j] = oObj.isNum() ? oObj.getNum() : 0; - oObj.free(); - } - - if (rect[0] > rect[2]) - std::swap(rect[0], rect[2]); - if (rect[1] > rect[3]) - std::swap(rect[1], rect[3]); - } - oTemp.free(); - - Dict* pODict = oAPN.streamGetDict(); - for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex) - { - char* chKey = pODict->getKey(nIndex); - if (strcmp("Length", chKey) == 0 || strcmp("Filter", chKey) == 0) - { - oTemp.free(); - continue; - } - else if (strcmp("BBox", chKey) == 0 && pODict->getVal(nIndex, &oTemp)->isArray() && oTemp.arrayGetLength() == 4) - { - for (int j = 0; j < 4; ++j) - { - oTemp.arrayGet(j, &oObj); - bbox[j] = oObj.isNum() ? oObj.getNum() : 0; - oObj.free(); - } - - if (bbox[0] > bbox[2]) - std::swap(bbox[0], bbox[2]); - if (bbox[1] > bbox[3]) - std::swap(bbox[1], bbox[3]); - } - else if (strcmp("Matrix", chKey) == 0 && pODict->getVal(nIndex, &oTemp)->isArray() && oTemp.arrayGetLength() == 6) - { - for (int j = 0; j < 6; ++j) - { - oTemp.arrayGet(j, &oObj); - m[j] = oObj.getNum(); - oObj.free(); - } - } - oTemp.free(); - pODict->getValNF(nIndex, &oTemp); - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID); - pForm->Add(chKey, pBase); - oTemp.free(); - } - - double formXMin, formYMin, formXMax, formYMax, x, y, sx, sy; - x = bbox[0] * m[0] + bbox[1] * m[2] + m[4]; - y = bbox[0] * m[1] + bbox[1] * m[3] + m[5]; - formXMin = formXMax = x; - formYMin = formYMax = y; - x = bbox[0] * m[0] + bbox[3] * m[2] + m[4]; - y = bbox[0] * m[1] + bbox[3] * m[3] + m[5]; - if (x < formXMin) - formXMin = x; - else if (x > formXMax) - formXMax = x; - if (y < formYMin) - formYMin = y; - else if (y > formYMax) - formYMax = y; - x = bbox[2] * m[0] + bbox[1] * m[2] + m[4]; - y = bbox[2] * m[1] + bbox[1] * m[3] + m[5]; - if (x < formXMin) - formXMin = x; - else if (x > formXMax) - formXMax = x; - if (y < formYMin) - formYMin = y; - else if (y > formYMax) - formYMax = y; - x = bbox[2] * m[0] + bbox[3] * m[2] + m[4]; - y = bbox[2] * m[1] + bbox[3] * m[3] + m[5]; - if (x < formXMin) - formXMin = x; - else if (x > formXMax) - formXMax = x; - if (y < formYMin) - formYMin = y; - else if (y > formYMax) - formYMax = y; - - if (formXMin == formXMax) - sx = 1; - else - sx = (rect[2] - rect[0]) / (formXMax - formXMin); - if (formYMin == formYMax) - sy = 1; - else - sy = (rect[3] - rect[1]) / (formYMax - formYMin); - double tx = -formXMin * sx + rect[0]; - double ty = -formYMin * sy + rect[1]; - - m[0] *= sx; - m[1] *= sy; - m[2] *= sx; - m[3] *= sy; - m[4] = m[4] * sx + tx; - m[5] = m[5] * sy + ty; - - pForm->Add("Matrix", PdfWriter::CArrayObject::CreateMatrix(m)); - - PdfWriter::CStream* pStream = pForm->GetStream(); - Stream* pOStream = oAPN.getStream(); - pOStream->reset(); - int nChar = pOStream->getChar(); - while (nChar != EOF) - { - pStream->WriteChar(nChar); - nChar = pOStream->getChar(); - } - - oAPN.free(); oAnnot.free(); + DrawAnnot(&oAnnot, pPage, pDoc, xref, &m_mObjManager, nStartRefID); + oAnnot.free(); } oAnnots.free(); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 45bbac06f4..0269a46af5 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -61,6 +61,8 @@ public: void SetDoc(PdfWriter::CDocument* pDoc); std::vector m_arrSplitAddPages; + std::vector m_arrRedactFormFieldsID; + std::vector m_arrRedactFormFields; private: PdfWriter::CDocument* m_pDoc; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 3e9da2018d..4135031700 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1390,7 +1390,7 @@ HRESULT CPdfFile::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedComma case IAdvancedCommand::AdvancedCommandType::Link: case IAdvancedCommand::AdvancedCommandType::DocInfo: case IAdvancedCommand::AdvancedCommandType::FormField: - case IAdvancedCommand::AdvancedCommandType::Annotaion: + case IAdvancedCommand::AdvancedCommandType::Annotation: case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: case IAdvancedCommand::AdvancedCommandType::ShapeStart: @@ -1438,7 +1438,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) { return m_pInternal->pWriter->AddFormField(m_pInternal->pAppFonts, (CFormFieldInfo*)command, m_pInternal->wsTempFolder); } - case IAdvancedCommand::AdvancedCommandType::Annotaion: + case IAdvancedCommand::AdvancedCommandType::Annotation: { CAnnotFieldInfo* pCommand = (CAnnotFieldInfo*)command; if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 5a37450235..9f212fef07 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -224,6 +224,8 @@ namespace PdfWriter FT_Done_FreeType(m_pFreeTypeLibrary); m_pFreeTypeLibrary = NULL; } + + SetCompressionMode(COMP_ALL); } bool CDocument::SaveToFile(const std::wstring& wsPath) { diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 29a734704c..a29ad6552f 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1115,6 +1115,20 @@ namespace PdfWriter // Operator : cm // Description: меняем матрицу преобразований (CTM - Current Transformation Matrix) + Transform(dM11, dM12, dM21, dM22, dX, dY); + + CMatrix oCTM = m_pGrState->m_oMatrix; + + // Multiply matrices oCTM(new) = oCTM(transformation(given by parameters)) x oCTM(old) + m_pGrState->m_oMatrix.m11 = dM11 * oCTM.m11 + dM12 * oCTM.m21; + m_pGrState->m_oMatrix.m12 = dM11 * oCTM.m12 + dM12 * oCTM.m22; + m_pGrState->m_oMatrix.m21 = dM21 * oCTM.m11 + dM22 * oCTM.m21; + m_pGrState->m_oMatrix.m22 = dM21 * oCTM.m12 + dM22 * oCTM.m22; + m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x; + m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y; + } + void CPage::Transform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) + { m_pStream->WriteReal(dM11); m_pStream->WriteChar(' '); m_pStream->WriteReal(dM12); @@ -1127,16 +1141,6 @@ namespace PdfWriter m_pStream->WriteChar(' '); m_pStream->WriteReal(dY); m_pStream->WriteStr(" cm\012"); - - CMatrix oCTM = m_pGrState->m_oMatrix; - - // перемножаем матрицы oCTM(новая)= oCTM(преобразования(которая параметрами задана)) x oCTM(старая) - m_pGrState->m_oMatrix.m11 = dM11 * oCTM.m11 + dM12 * oCTM.m21; - m_pGrState->m_oMatrix.m12 = dM11 * oCTM.m12 + dM12 * oCTM.m22; - m_pGrState->m_oMatrix.m21 = dM21 * oCTM.m11 + dM22 * oCTM.m21; - m_pGrState->m_oMatrix.m22 = dM21 * oCTM.m12 + dM22 * oCTM.m22; - m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x; - m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y; } void CPage::StartTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) { diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 8cf9f1bceb..197f016a7d 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -150,6 +150,7 @@ namespace PdfWriter void SetFillRGB(double dR, double dG, double dB); void SetFillCMYK(double dC, double dM, double dY, double dK); void Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY); + void Transform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void StartTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void SetExtGrState(CExtGrState* pExtGrState);