diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 342b4c97e5..cbea5d2de7 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1035,7 +1035,7 @@ { rec["Open"] = (flags >> 15) & 1; // иконка - Name - // 0 - Check, 1 - Circle, 2 - Comment, 3 - Cross, 4 - Help, 5 - Insert, 6 - Key, 7 - NewParagraph, 8 - Note, 9 - Paragraph, 10 - RightArrow, 11 - RightPointer, 12 - Star, 13 - UpArrow, 14 - UpLeftArrow + // 0 - Check, 1 - Checkmark, 2 - Circle, 3 - Comment, 4 - Cross, 5 - CrossHairs, 6 - Help, 7 - Insert, 8 - Key, 9 - NewParagraph, 10 - Note, 11 - Paragraph, 12 - RightArrow, 13 - RightPointer, 14 - Star, 15 - UpArrow, 16 - UpLeftArrow if (flags & (1 << 16)) rec["Icon"] = reader.readByte(); // Модель состояния - StateModel diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 102e0244f8..4a55aa8bc5 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -1274,7 +1274,7 @@ int main(int argc, char* argv[]) { nPathLength = READ_BYTE(pAnnots + i); i += 1; - std::string arrIcon[] = {"Check", "Circle", "Comment", "Cross", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; + std::string arrIcon[] = {"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; std::cout << "Icon " << arrIcon[nPathLength] << ", "; } if (nFlags & (1 << 17)) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 753626e33e..2a82331315 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -52,6 +52,7 @@ #include "SrcWriter/Catalog.h" #include "SrcWriter/EncryptDictionary.h" #include "SrcWriter/Info.h" +#include "SrcWriter/Annotation.h" #define AddToObject(oVal)\ {\ @@ -68,7 +69,8 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, { case objBool: { - AddToObject(obj->getBool()) + bool b = obj->getBool(); + AddToObject(b) break; } case objInt: @@ -589,6 +591,14 @@ bool CPdfFile::EditPage(int nPageIndex) if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) return false; + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (pEditPage) + { + pDoc->SetCurPage(pEditPage); + m_pInternal->pWriter->EditPage(pEditPage); + return true; + } + XRef* xref = pPDFDocument->getXRef(); Catalog* pCatalog = pPDFDocument->getCatalog(); if (!xref || !pCatalog) @@ -627,23 +637,7 @@ bool CPdfFile::EditPage(int nPageIndex) Object oTemp; char* chKey = pageObj.dictGetKey(nIndex); if (strcmp("Resources", chKey) == 0 || strcmp("AcroForm", chKey) == 0 || strcmp("Annots", chKey) == 0) - { pageObj.dictGetVal(nIndex, &oTemp); - if (strcmp("Annots", chKey) == 0 && oTemp.isArray()) - { - std::map mAnnots; - for (int i = 0; i < oTemp.arrayGetLength(); ++i) - { - Object oAnnot, oPopupRef, oAnnotRef; - if (oTemp.arrayGet(i, &oAnnot)->isDict() && oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef() && oTemp.arrayGetNF(i, &oAnnotRef)->isRef()) - { - mAnnots[oAnnotRef.getRefNum()] = oPopupRef.getRefNum(); - } - oAnnot.free(); oPopupRef.free(); oAnnotRef.free(); - } - pPage->SetAnnots(mAnnots); - } - } else pageObj.dictGetValNF(nIndex, &oTemp); DictToCDictObject(&oTemp, pPage, true, chKey); @@ -655,7 +649,7 @@ bool CPdfFile::EditPage(int nPageIndex) // Применение редактирования страницы для writer m_pInternal->bEditPage = true; - if (m_pInternal->pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage)) + if (m_pInternal->pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) return true; RELEASEOBJECT(pXref); @@ -691,6 +685,165 @@ bool CPdfFile::AddPage(int nPageIndex) } return bRes; } +bool CPdfFile::EditAnnot(int nPageIndex, int nID) +{ + // Проверка режима редактирования + if (!m_pInternal->pWriter || !m_pInternal->bEdit) + return false; + + PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; + if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) + return false; + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (!pEditPage) + { + pEditPage = pDoc->GetCurPage(); + EditPage(nPageIndex); + pDoc->SetCurPage(pEditPage); + m_pInternal->pWriter->EditPage(pEditPage); + } + + XRef* xref = pPDFDocument->getXRef(); + std::pair pPageRef = pDoc->GetPageRef(nPageIndex); + if (!xref || pPageRef.first == 0) + return false; + + // Получение объекта аннотации + Object pageRefObj, pageObj, oAnnots; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) + { + pageRefObj.free(); pageObj.free(); oAnnots.free(); + return false; + } + pageRefObj.free(); pageObj.free(); + + Object oAnnotRef, oAnnot, oType; + for (int i = 0; i < oAnnots.arrayGetLength(); ++i) + { + if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + break; + oAnnotRef.free(); + } + oAnnots.free(); + if (!oAnnotRef.isRef() || !oAnnotRef.fetch(xref, &oAnnot)->isDict() || !oAnnot.dictLookup("Subtype", &oType)->isName()) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + return false; + } + + // Воспроизведение словаря аннотации из reader для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); + if (!pXref) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + return false; + } + + PdfWriter::CAnnotation* pAnnot = NULL; + if (oType.isName("Text")) + pAnnot = new PdfWriter::CTextAnnotation(pXref); + else if (oType.isName("Ink")) + pAnnot = new PdfWriter::CInkAnnotation(pXref); + else if (oType.isName("Line")) + pAnnot = new PdfWriter::CLineAnnotation(pXref); + else if (oType.isName("Highlight") || oType.isName("Underline") || oType.isName("Squiggly") || oType.isName("StrikeOut")) + pAnnot = new PdfWriter::CTextMarkupAnnotation(pXref); + else if (oType.isName("Square") || oType.isName("Circle")) + pAnnot = new PdfWriter::CSquareCircleAnnotation(pXref); + else if (oType.isName("Polygon") || oType.isName("PolyLine")) + pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); + else if (oType.isName("FreeText")) + pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); + else if (oType.isName("Caret")) + pAnnot = new PdfWriter::CCaretAnnotation(pXref); + else if (oType.isName("Popup")) + pAnnot = new PdfWriter::CPopupAnnotation(pXref); + else if (oType.isName("Widget")) + { + char* sName = NULL; + Object oFT; + if (oAnnot.dictLookup("FT", &oFT)->isName()) + sName = oFT.getName(); + + if (!sName) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("FT", &oFT)->isName()) + { + sName = oFT.getName(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + if (sName) + { + if (strcmp("Btn", sName) == 0) + pAnnot = new PdfWriter::CButtonWidget(pXref); + else if (strcmp("Tx", sName) == 0) + pAnnot = new PdfWriter::CTextWidget(pXref); + else if (strcmp("Ch", sName) == 0) + pAnnot = new PdfWriter::CChoiceWidget(pXref); + else if (strcmp("Sig", sName) == 0) + pAnnot = new PdfWriter::CSignatureWidget(pXref); + else + pAnnot = new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); + } + oFT.free(); + } + oType.free(); + + if (!pAnnot) + { + oAnnotRef.free(); oAnnot.free(); + RELEASEOBJECT(pXref); + return false; + } + + for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) + { + char* chKey = oAnnot.dictGetKey(nIndex); + if (strcmp("AP", chKey) == 0) + continue; + if (strcmp("Popup", chKey) == 0) + { + Object oPopupRef; + if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) + { + PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum()); + if (pPopup) + { + pAnnot->Add("Popup", pPopup); + pPopup->Add("Parent", pAnnot); + } + } + continue; + } + Object oTemp; + oAnnot.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pAnnot, false, chKey); + oTemp.free(); + } + pAnnot->SetRef(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); + oAnnotRef.free(); oAnnot.free(); + + if (pDoc->EditAnnot(pXref, pAnnot, nID)) + return true; + + RELEASEOBJECT(pXref); + return false; +} bool CPdfFile::DeleteAnnot(int nPageIndex, int nID) { // Проверка режима редактирования @@ -1623,7 +1776,12 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) } case IAdvancedCommand::AdvancedCommandType::Annotaion: { - return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, (CAnnotFieldInfo*)command); + CAnnotFieldInfo* cCommand = (CAnnotFieldInfo*)command; +#ifndef BUILDING_WASM_MODULE + if (m_pInternal->bEdit && m_pInternal->bEditPage) + EditAnnot(cCommand->GetPage(), cCommand->GetID()); +#endif + return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, cCommand); } default: break; diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index f52b09c920..c850b6408b 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -94,9 +94,10 @@ public: // Переходит в режим редактирования. Pdf уже должен быть открыт на чтение - LoadFromFile/LoadFromMemory bool EditPdf(const std::wstring& wsDstFile = L""); // Манипуляции со страницами возможны в режиме редактирования - bool EditPage (int nPageIndex); - bool DeletePage(int nPageIndex); - bool AddPage (int nPageIndex); + bool EditPage (int nPageIndex); + bool DeletePage (int nPageIndex); + bool AddPage (int nPageIndex); + bool EditAnnot (int nPageIndex, int nID); bool DeleteAnnot(int nPageIndex, int nID); #endif diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index c4b198f44c..d42ea4cccc 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -746,8 +746,6 @@ HRESULT CPdfWriter::EndCommand(const DWORD& dwType, const LONG& lClipMode) nCount--; } } - - m_pDocument->MatchAnnotation(); } return S_OK; @@ -1677,112 +1675,90 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF return S_OK; CAnnotFieldInfo& oInfo = *pFieldInfo; - - // if (m_bNeedUpdateTextFont) - // UpdateFont(); - // if (!m_pFont) - // return S_OK; - PdfWriter::CAnnotation* pAnnot = NULL; - if (oInfo.IsText()) - { - pAnnot = m_pDocument->CreateTextAnnot(); - } - else if (oInfo.IsInk()) - { - pAnnot = m_pDocument->CreateInkAnnot(); - } - else if (oInfo.IsLine()) - { - pAnnot = m_pDocument->CreateLineAnnot(); - } - else if (oInfo.IsTextMarkup()) - { - pAnnot = m_pDocument->CreateTextMarkupAnnot(); - } - else if (oInfo.IsSquareCircle()) - { - pAnnot = m_pDocument->CreateSquareCircleAnnot(); - } - else if (oInfo.IsPolygonLine()) - { - pAnnot = m_pDocument->CreatePolygonLineAnnot(); - } - else if (oInfo.IsPopup()) - { - pAnnot = m_pDocument->CreatePopupAnnot(); - } - else if (oInfo.IsFreeText()) - { - pAnnot = m_pDocument->CreateFreeTextAnnot(); - } - else if (oInfo.IsCaret()) - { - pAnnot = m_pDocument->CreateCaretAnnot(); - } - + int nID = oInfo.GetID(); + pAnnot = m_pDocument->GetAnnot(nID); BYTE nWidgetType = 0; - if (oInfo.IsWidget()) + if (!pAnnot) { - CAnnotFieldInfo::CWidgetAnnotPr* pPr = oInfo.GetWidgetAnnotPr(); - nWidgetType = pPr->GetType(); + if (oInfo.IsText()) + pAnnot = m_pDocument->CreateTextAnnot(); + else if (oInfo.IsInk()) + pAnnot = m_pDocument->CreateInkAnnot(); + else if (oInfo.IsLine()) + pAnnot = m_pDocument->CreateLineAnnot(); + else if (oInfo.IsTextMarkup()) + pAnnot = m_pDocument->CreateTextMarkupAnnot(); + else if (oInfo.IsSquareCircle()) + pAnnot = m_pDocument->CreateSquareCircleAnnot(); + else if (oInfo.IsPolygonLine()) + pAnnot = m_pDocument->CreatePolygonLineAnnot(); + else if (oInfo.IsPopup()) + pAnnot = m_pDocument->CreatePopupAnnot(); + else if (oInfo.IsFreeText()) + pAnnot = m_pDocument->CreateFreeTextAnnot(); + else if (oInfo.IsCaret()) + pAnnot = m_pDocument->CreateCaretAnnot(); - switch (nWidgetType) + if (oInfo.IsWidget()) { - case 26: - { - pAnnot = m_pDocument->CreateWidgetAnnot(); - break; - } - case 27: - case 28: - case 29: - { - pAnnot = m_pDocument->CreateButtonWidget(); - break; - } - case 30: - { - pAnnot = m_pDocument->CreateTextWidget(); - break; - } - case 31: - case 32: - { - pAnnot = m_pDocument->CreateChoiceWidget(); - break; - } - case 33: - { - pAnnot = m_pDocument->CreateSignatureWidget(); - break; - } + CAnnotFieldInfo::CWidgetAnnotPr* pPr = oInfo.GetWidgetAnnotPr(); + nWidgetType = pPr->GetType(); + + switch (nWidgetType) + { + case 26: + { + pAnnot = m_pDocument->CreateWidgetAnnot(); + break; + } + case 27: + case 28: + case 29: + { + pAnnot = m_pDocument->CreateButtonWidget(); + break; + } + case 30: + { + pAnnot = m_pDocument->CreateTextWidget(); + break; + } + case 31: + case 32: + { + pAnnot = m_pDocument->CreateChoiceWidget(); + break; + } + case 33: + { + pAnnot = m_pDocument->CreateSignatureWidget(); + break; + } + } } + + if (pAnnot) + m_pDocument->AddAnnotation(nID, pAnnot); } if (!pAnnot) return S_FALSE; - int nID = oInfo.GetID(); pAnnot->SetID(nID); - int nOriginalPage = oInfo.GetPage(); - PdfWriter::CPage* pOrigPage = m_pPage;// TODO m_pDocument->GetPage(nOriginalPage); - if (pOrigPage) - pOrigPage->DeleteAnnotation(nID); - - //int nPopupID = pOrigPage->GetAnnot(nID); - //if (nPopupID) - // pOrigPage->DeleteAnnotation(nPopupID); - + PdfWriter::CPage* pOrigPage = m_pDocument->GetPage(oInfo.GetPage()); PdfWriter::CPage* pPage = m_pPage; - pPage->AddAnnotation(pAnnot); + if (pOrigPage && pPage != pOrigPage) + { + pOrigPage->DeleteAnnotation(nID); + pPage->AddAnnotation(pAnnot); + } - m_pDocument->AddAnnotation(nID, pAnnot); - - pAnnot->SetAnnotFlag(oInfo.GetAnnotFlag()); pAnnot->SetPage(pPage); + pAnnot->SetHeight(pPage->GetHeight()); + pAnnot->SetAnnotFlag(oInfo.GetAnnotFlag()); double dX1, dY1, dX2, dY2; oInfo.GetBounds(dX1, dY1, dX2, dY2); @@ -1823,10 +1799,18 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (nFlags & (1 << 0)) { int nPopupID = pPr->GetPopupID(); - if (pOrigPage) + if (nPopupID && pOrigPage && pPage != pOrigPage) + { pOrigPage->DeleteAnnotation(nPopupID); - PdfWriter::CPopupAnnotation* pPopupAnnot = pMarkupAnnot->SetPopupID(nPopupID); - pPage->AddAnnotation(pPopupAnnot); + PdfWriter::CAnnotation* pPopupAnnot = m_pDocument->GetAnnot(nPopupID); + if (pPopupAnnot) + { + pPage->AddAnnotation(pPopupAnnot); + pPopupAnnot->SetPage(pPage); + } + } + // PdfWriter::CPopupAnnotation* pPopupAnnot = pMarkupAnnot->SetPopupID(nPopupID); + // pPage->AddAnnotation(pPopupAnnot); } if (nFlags & (1 << 1)) pMarkupAnnot->SetT(pPr->GetT()); @@ -2149,8 +2133,6 @@ bool CPdfWriter::EditPage(PdfWriter::CPage* pNewPage) return false; m_oCommandManager.Flush(); - m_pDocument->MatchAnnotation(); - m_pPage = pNewPage; if (m_pPage) { @@ -2183,8 +2165,6 @@ bool CPdfWriter::EditClose() return false; m_oCommandManager.Flush(); - m_pDocument->MatchAnnotation(); - unsigned int nPagesCount = m_pDocument->GetPagesCount(); for (int nIndex = 0, nCount = m_vDestinations.size(); nIndex < nCount; ++nIndex) { @@ -2220,10 +2200,12 @@ void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, cons bool CPdfWriter::DeleteAnnot(int nPageIndex, int nID) { PdfWriter::CPage* pPage = m_pDocument->GetPage(nPageIndex); - if (!pPage) - pPage = m_pPage; - pPage->DeleteAnnotation(nID); - return true; + if (pPage) + { + pPage->DeleteAnnotation(nID); + return true; + } + return false; } //---------------------------------------------------------------------------------------- // Внутренние функции diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 50eed29633..a9b453eab1 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -885,35 +885,11 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar { m_unFlags |= (1 << 16); std::string sName(oObj.getName()); - m_nName = 2; // Default: Comment - if (sName == "Check") - m_nName = 0; - else if (sName == "Circle") - m_nName = 1; - else if (sName == "Cross") - m_nName = 3; - else if (sName == "Help") - m_nName = 4; - else if (sName == "Insert") - m_nName = 5; - else if (sName == "Key") - m_nName = 6; - else if (sName == "NewParagraph") - m_nName = 7; - else if (sName == "Note") - m_nName = 8; - else if (sName == "Paragraph") - m_nName = 9; - else if (sName == "RightArrow") - m_nName = 10; - else if (sName == "RightPointer") - m_nName = 11; - else if (sName == "Star") - m_nName = 12; - else if (sName == "UpArrow") - m_nName = 13; - else if (sName == "UpLeftArrow") - m_nName = 14; + std::vector arrName = {"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; + m_nName = 10; // Default: Note + std::vector::iterator p = std::find(arrName.begin(), arrName.end(), sName); + if (p != arrName.end()) + m_nName = p - arrName.begin(); } oObj.free(); diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index c0832a2620..ec81d7dac7 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -66,13 +66,7 @@ namespace PdfWriter }; const static char* c_sAnnotIconNames[] = { - "Comment", - "Key", - "Note", - "Help", - "NewParagraph", - "Paragraph", - "Insert" + "Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow" }; //---------------------------------------------------------------------------------------- @@ -90,8 +84,10 @@ namespace PdfWriter // Для PDFA нужно, чтобы 0, 1, 4 биты были выключены, а второй включен Add("F", 4); - - //Add("M", new CStringObject(DateNow().c_str())); + } + void CAnnotation::SetHeight(double dHeight) + { + m_dPageHeight = dHeight; } void CAnnotation::SetRect(const TRect& oRect) { @@ -217,9 +213,7 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- CMarkupAnnotation::CMarkupAnnotation(CXref* pXref, EAnnotType eType) : CAnnotation(pXref, eType) { - m_nIRTID = 0; - - // Add("CreationDate", new CStringObject(DateNow().c_str())); + m_nIRTID = 0; } void CMarkupAnnotation::SetRT(const BYTE& nRT) { @@ -385,7 +379,6 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- CInkAnnotation::CInkAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotInk) { - } void CInkAnnotation::SetInkList(const std::vector< std::vector >& arrInkList) { @@ -400,8 +393,8 @@ namespace PdfWriter CArrayObject* pArrayI = new CArrayObject(); pArray->Add(pArrayI); - for (const double& dInk : arrInk) - pArrayI->Add(dInk); + for (int i = 0; i < arrInk.size(); ++i) + pArrayI->Add(i % 2 == 0 ? arrInk[i] : (m_dPageHeight - arrInk[i])); } } //---------------------------------------------------------------------------------------- @@ -502,9 +495,9 @@ namespace PdfWriter Add("L", pArray); pArray->Add(dL1); - pArray->Add(dL2); + pArray->Add(m_dPageHeight - dL2); pArray->Add(dL3); - pArray->Add(dL4); + pArray->Add(m_dPageHeight - dL4); } void CLineAnnotation::SetCO(const double& dCO1, const double& dCO2) { @@ -590,7 +583,14 @@ namespace PdfWriter } void CFreeTextAnnotation::SetCL(const std::vector& arrCL) { - AddToVectorD(this, "CL", arrCL); + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + Add("CL", pArray); + + for (int i = 0; i < arrCL.size(); ++i) + pArray->Add(i % 2 == 0 ? arrCL[i] : (m_dPageHeight - arrCL[i])); } //---------------------------------------------------------------------------------------- // CTextMarkupAnnotation @@ -617,7 +617,14 @@ namespace PdfWriter } void CTextMarkupAnnotation::SetQuadPoints(const std::vector& arrQuadPoints) { - AddToVectorD(this, "QuadPoints", arrQuadPoints); + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + Add("QuadPoints", pArray); + + for (int i = 0; i < arrQuadPoints.size(); ++i) + pArray->Add(i % 2 == 0 ? arrQuadPoints[i] : (m_dPageHeight - arrQuadPoints[i])); } //---------------------------------------------------------------------------------------- // CSquareCircleAnnotation @@ -706,7 +713,14 @@ namespace PdfWriter } void CPolygonLineAnnotation::SetVertices(const std::vector& arrVertices) { - AddToVectorD(this, "Vertices", arrVertices); + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + Add("Vertices", pArray); + + for (int i = 0; i < arrVertices.size(); ++i) + pArray->Add(i % 2 == 0 ? arrVertices[i] : (m_dPageHeight - arrVertices[i])); } //---------------------------------------------------------------------------------------- // CCaretAnnotation diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 895a5531fc..9e38f4b31b 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -100,7 +100,8 @@ namespace PdfWriter CAnnotation(CXref* pXref, EAnnotType eType); CXref* m_pXref; - TRect m_oRect; + TRect m_oRect; + double m_dPageHeight = 0; public: int m_nID; // Идентификатор сопоставления @@ -118,6 +119,7 @@ namespace PdfWriter { return false; } + void SetHeight(double dHeight); void SetRect(const TRect& oRect); void SetBorder(BYTE nType, double dWidth, double dDashesAlternating = 0.0, double dGaps = 0.0); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index b9bd716086..f4d603c096 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -311,11 +311,23 @@ namespace PdfWriter } CPage* CDocument::GetPage(const unsigned int &unPage) { + CPage* pRes = GetEditPage(unPage); + if (pRes) + return pRes; + if (unPage >= m_pPageTree->GetCount()) return NULL; return m_pPageTree->GetPage(unPage); } + CPage* CDocument::GetEditPage(const unsigned int& unPage) + { + CPage* pRes = NULL; + std::map::iterator p = m_mEditPages.find(unPage); + if (p != m_mEditPages.end()) + pRes = p->second; + return pRes; + } unsigned int CDocument::GetPagesCount() const { return m_pPageTree->GetCount(); @@ -613,49 +625,6 @@ namespace PdfWriter { m_mAnnotations[nID] = pAnnot; } - void CDocument::MatchAnnotation() - { - if (!m_pCurPage) - return; - - CArrayObject* pArray = (CArrayObject*)(m_pCurPage->Get("Annots")); - if (!pArray) - return; - - for (int i = 0, count = pArray->GetCount(); i < count; ++i) - { - CAnnotation* pAnnot = dynamic_cast(pArray->Get(i)); - if (!pAnnot) - continue; - - if (pAnnot->isMarkup()) - { - CMarkupAnnotation* pMarkupAnnot = (CMarkupAnnotation*)pAnnot; - - // int nID = pMarkupAnnot->GetPopupID(); - // std::map::iterator it = m_mAnnotations.find(nID); - // if (it != m_mAnnotations.end()) - // pMarkupAnnot->SetPopupID(it->second); - - int nID = pMarkupAnnot->GetIRTID(); - std::map::iterator it = m_mAnnotations.find(nID); - if (it != m_mAnnotations.end()) - pMarkupAnnot->SetIRTID(it->second); - } - - if (pAnnot->GetAnnotationType() == EAnnotType::AnnotPopup) - { - CPopupAnnotation* pPopupAnnot = (CPopupAnnotation*)pAnnot; - - int nID = pPopupAnnot->GetParentID(); - std::map::iterator it = m_mAnnotations.find(nID); - if (it != m_mAnnotations.end()) - pPopupAnnot->SetParentID(it->second); - } - } - - m_mAnnotations.clear(); - } CImageDict* CDocument::CreateImage() { return new CImageDict(m_pXref, this); @@ -1271,7 +1240,7 @@ namespace PdfWriter return pRes; } - bool CDocument::EditPage(CXref* pXref, CPage* pPage) + bool CDocument::EditPage(CXref* pXref, CPage* pPage, int nPageIndex) { if (!pXref || !pPage) return false; @@ -1285,9 +1254,28 @@ namespace PdfWriter pXref->SetPrev(m_pLastXref); m_pLastXref = pXref; m_pCurPage = pPage; + m_mEditPages[nPageIndex] = pPage; return true; } + bool CDocument::EditAnnot(CXref* pXref, CAnnotation* pAnnot, int nID) + { + if (!pXref || !pAnnot) + return false; + + pXref->SetPrev(m_pLastXref); + m_pLastXref = pXref; + m_mAnnotations[nID] = pAnnot; + + return true; + } + CAnnotation* CDocument::GetAnnot(int nID) + { + std::map::iterator p = m_mAnnotations.find(nID); + if (p != m_mAnnotations.end()) + return p->second; + return NULL; + } CPage* CDocument::AddPage(int nPageIndex) { if (!m_pPageTree) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 5c5c850be2..de90ace602 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -117,7 +117,8 @@ namespace PdfWriter bool IsPDFA() const; CPage* AddPage(); - CPage* GetPage(const unsigned int& unPage); + CPage* GetPage (const unsigned int& unPage); + CPage* GetEditPage(const unsigned int& unPage); unsigned int GetPagesCount() const; void AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); void AddPageLabel(unsigned int unPageIndex, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); @@ -146,7 +147,6 @@ namespace PdfWriter CAnnotation* CreateChoiceWidget(); CAnnotation* CreateSignatureWidget(); void AddAnnotation(const int& nID, CAnnotation* pAnnot); - void MatchAnnotation(); CImageDict* CreateImage(); CFont14* CreateFont14(EStandard14Fonts eType); @@ -174,12 +174,16 @@ namespace PdfWriter bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); std::pair GetPageRef(int nPageIndex); - bool EditPage(CXref* pXref, CPage* pPage); + bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); CPage* AddPage(int nPageIndex); bool DeletePage(int nPageIndex); bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); std::wstring GetEditPdfPath() { return m_wsFilePath; } + bool EditAnnot(CXref* pXref, CAnnotation* pAnnot, int nID); + CAnnotation* GetAnnot(int nID); + CPage* GetCurPage() { return m_pCurPage; } + void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } private: char* GetTTFontTag(); @@ -262,6 +266,7 @@ namespace PdfWriter std::vector m_vRadioGroups; std::map m_mFields; std::map m_mAnnotations; + std::map m_mEditPages; friend class CFontCidTrueType; friend class CFontTrueType; diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 162121fdfc..b63f33c1b2 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1584,13 +1584,6 @@ namespace PdfWriter CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); return pRotate ? pRotate->Get() : 0; } - int CPage::GetAnnot(int nAnnot) - { - std::map::iterator it = m_mAnnots.find(nAnnot); - if (it != m_mAnnots.end()) - return it->second; - return 0; - } //---------------------------------------------------------------------------------------- // CTextWord //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index add63b3a4d..edeffed1f2 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -162,8 +162,6 @@ namespace PdfWriter void AddContents(CXref* pXref); void SetRotate(int nRotate); int GetRotate(); - void SetAnnots(const std::map& mAnnots) { m_mAnnots = mAnnots; } - int GetAnnot(int nAnnot); private: @@ -210,8 +208,6 @@ namespace PdfWriter unsigned int m_unShadingsCount; CDictObject* m_pPatterns; unsigned int m_unPatternsCount; - - std::map m_mAnnots; }; //---------------------------------------------------------------------------------------- // CTextWord