diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h index 9442163c61..ee297d100e 100644 --- a/DesktopEditor/doctrenderer/drawingfile.h +++ b/DesktopEditor/doctrenderer/drawingfile.h @@ -505,7 +505,13 @@ public: } if (m_nType == 0) + { + std::vector arrLinks = ((CPdfFile*)m_pFile)->GetPdfLinks(nPageIndex); + // TODO Usage + for (int i = 0; i < arrLinks.size(); ++i) + RELEASEOBJECT(arrLinks[i]); ((CPdfFile*)m_pFile)->SetPageFonts(nPageIndex); + } BYTE* res = oRes.GetBuffer(); oRes.ClearWithoutAttack(); diff --git a/DesktopEditor/graphics/pro/officedrawingfile.cpp b/DesktopEditor/graphics/pro/officedrawingfile.cpp index cd066c7a77..d5dbb4b0b7 100644 --- a/DesktopEditor/graphics/pro/officedrawingfile.cpp +++ b/DesktopEditor/graphics/pro/officedrawingfile.cpp @@ -141,3 +141,8 @@ void IOfficeDrawingFile::ConvertToRaster(int nPageIndex, const std::wstring& pat pFrame->SaveFile(path, nImageType); RELEASEOBJECT(pFrame); } + +std::vector IOfficeDrawingFile::GetPdfLinks(int nPageIndex) +{ + return std::vector(); +} diff --git a/DesktopEditor/graphics/pro/officedrawingfile.h b/DesktopEditor/graphics/pro/officedrawingfile.h index 836d038bc3..796925e8d9 100644 --- a/DesktopEditor/graphics/pro/officedrawingfile.h +++ b/DesktopEditor/graphics/pro/officedrawingfile.h @@ -56,6 +56,20 @@ struct COfficeDrawingPageParams } }; +struct CPdfLink +{ + ~CPdfLink() { RELEASEOBJECT(pNext); } + + double pRect[4]; + BYTE nType; + BYTE nKind; + unsigned int unPage; + unsigned int unKindFlag; + double pData[4]; + std::string sData; + CPdfLink* pNext = NULL; +}; + class GRAPHICS_DECL IOfficeDrawingFile { public: @@ -103,6 +117,8 @@ public: virtual std::wstring GetInfo() = 0; virtual unsigned char* GetStructure() = 0; virtual unsigned char* GetLinks(int nPageIndex) = 0; + + virtual std::vector GetPdfLinks(int nPageIndex); }; #endif // _OFFICE_DRAWING_FILE_H diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 257eecd0ff..7d4d7873c4 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -605,6 +605,12 @@ BYTE* CPdfFile::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, in return NULL; return m_pInternal->pReader->GetAPAnnots(nRasterW, nRasterH, nBackgroundColor, nPageIndex, nAnnot, sView); } +std::vector CPdfFile::GetPdfLinks(int nPageIndex) +{ + if (!m_pInternal->pReader) + return std::vector(); + return m_pInternal->pReader->GetPdfLinks(nPageIndex); +} // ------------------------------------------------------------------------ diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 384c2983b2..e8b76e166a 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -136,6 +136,7 @@ public: virtual std::wstring GetInfo(); virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); + std::vector GetPdfLinks(int nPageIndex) override; bool ValidMetaData(); // Захватывает полученную память malloc data diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index dfae5f1603..afd46bd627 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1124,7 +1124,6 @@ BYTE* CPdfReader::GetStructure() } BYTE* CPdfReader::GetLinks(int _nPageIndex) { - // TODO Links должны стать частью Annots PDFDoc* pDoc = NULL; int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) @@ -1257,6 +1256,64 @@ BYTE* CPdfReader::GetLinks(int _nPageIndex) return oLinks.Serialize(); } +std::vector CPdfReader::GetPdfLinks(int _nPageIndex) +{ + std::vector oRes; + if (m_vPDFContext.empty()) + return oRes; + + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) + return oRes; + + Page* pPage = pDoc->getCatalog()->getPage(nPageIndex); + if (!pPage) + return oRes; + + Object oAnnots; + if (!pPage->getAnnots(&oAnnots)->isArray()) + { + oAnnots.free(); + return oRes; + } + + for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) + { + Object oAnnot; + if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) + { + oAnnot.free(); + continue; + } + + Object oSubtype; + std::string sType; + if (oAnnot.dictLookup("Subtype", &oSubtype)->isName()) + sType = oSubtype.getName(); + oSubtype.free(); oAnnot.free(); + + Object oAnnotRef; + PdfReader::CAnnotLink* pAnnot = NULL; + oAnnots.arrayGetNF(i, &oAnnotRef); + + if (sType == "Link") + pAnnot = new PdfReader::CAnnotLink(pDoc, &oAnnotRef, nPageIndex, nStartRefID); + + CPdfLink* pLink = NULL; + if (pAnnot) + pLink = pAnnot->GetPdfLink(); + + if (pLink) + oRes.push_back(pLink); + RELEASEOBJECT(pAnnot); + } + + oAnnots.free(); + return oRes; +} BYTE* CPdfReader::GetWidgets() { NSWasm::CData oRes; diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index bf2f4a8273..af7c17c08c 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -126,6 +126,7 @@ public: BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); BYTE* StreamToCData(BYTE* pSteam, int nLength); const std::map& GetFonts() { return m_mFonts; } + std::vector GetPdfLinks(int nPageIndex); private: void Clear(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 1f910dc96e..4460d4bad4 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -533,6 +533,75 @@ CAnnot::CBorderType* getBorder(Object* oBorder, bool bBSorBorder) return pBorderType; } +//------------------------------------------------------------------------ +// Action +//------------------------------------------------------------------------ + +void CActionGoTo::GetPdfLink(CPdfLink* pLink) +{ + pLink->nType = 1; + pLink->unPage = unPage; + pLink->nKind = nKind; + switch (nKind) + { + case destXYZ: + case destFitH: + case destFitBH: + case destFitV: + case destFitBV: + { + pLink->unKindFlag = unKindFlag; + if (unKindFlag & (1 << 0)) + pLink->pData[0] = pRect[0]; + if (unKindFlag & (1 << 1)) + pLink->pData[1] = pRect[1]; + if (unKindFlag & (1 << 2)) + pLink->pData[2] = pRect[2]; + break; + } + case destFitR: + { + pLink->pData[0] = pRect[0]; + pLink->pData[1] = pRect[1]; + pLink->pData[2] = pRect[2]; + pLink->pData[3] = pRect[3]; + break; + } + case destFit: + case destFitB: + default: + break; + } + + if (pNext) + { + pLink->pNext = new CPdfLink(); + GetPdfLink(pLink->pNext); + } +} +void CActionURI::GetPdfLink(CPdfLink* pLink) +{ + pLink->nType = 6; + pLink->sData = sURI; + + if (pNext) + { + pLink->pNext = new CPdfLink(); + GetPdfLink(pLink->pNext); + } +} +void CActionNamed::GetPdfLink(CPdfLink* pLink) +{ + pLink->nType = 10; + pLink->sData = sNamed; + + if (pNext) + { + pLink->pNext = new CPdfLink(); + GetPdfLink(pLink->pNext); + } +} + //------------------------------------------------------------------------ // Widget //------------------------------------------------------------------------ @@ -1265,6 +1334,17 @@ CAnnotLink::~CAnnotLink() RELEASEOBJECT(m_pAction); RELEASEOBJECT(m_pPA); } +CPdfLink* CAnnotLink::GetPdfLink() +{ + CPdfLink* pRes = new CPdfLink(); + pRes->pRect[0] = m_pRect[0]; + pRes->pRect[1] = m_pRect[1]; + pRes->pRect[2] = m_pRect[2]; + pRes->pRect[3] = m_pRect[3]; + if (m_pAction) + m_pAction->GetPdfLink(pRes); + return pRes; +} //------------------------------------------------------------------------ // Screen diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 3357104b17..94585e573a 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -41,6 +41,7 @@ #include "../../DesktopEditor/graphics/pro/Fonts.h" #include "../../DesktopEditor/graphics/pro/Graphics.h" #include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" +#include "../../DesktopEditor/graphics/pro/officedrawingfile.h" #include "RendererOutputDev.h" @@ -57,6 +58,7 @@ public: virtual ~CAction() { RELEASEOBJECT(pNext); } virtual void ToWASM(NSWasm::CData& oRes); + virtual void GetPdfLink(CPdfLink* pLink); std::string sType; CAction* pNext; @@ -70,18 +72,21 @@ struct CActionGoTo final : public CAction double pRect[4]; BYTE nKind; + virtual void GetPdfLink(CPdfLink* pLink) override; void ToWASM(NSWasm::CData& oRes) override; }; struct CActionURI final : public CAction { std::string sURI; + virtual void GetPdfLink(CPdfLink* pLink) override; void ToWASM(NSWasm::CData& oRes) override; }; struct CActionNamed final : public CAction { std::string sNamed; + virtual void GetPdfLink(CPdfLink* pLink) override; void ToWASM(NSWasm::CData& oRes) override; }; struct CActionJavaScript final : public CAction @@ -347,6 +352,8 @@ public: CAnnotLink(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); virtual ~CAnnotLink(); + CPdfLink* GetPdfLink(); + void ToWASM(NSWasm::CData& oRes) override; private: