From 583f7b0d0ca6a2c200422aab2b989de5668d07dd Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 4 Mar 2024 17:08:42 +0300 Subject: [PATCH] Create CFile.prototype["getShapes"] --- .../graphics/pro/js/drawingfile.json | 1 + .../pro/js/wasm/js/drawingfile_base.js | 41 +++++++++++++++++++ .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 +- .../graphics/pro/js/wasm/src/drawingfile.h | 4 +- .../pro/js/wasm/src/drawingfile_test.cpp | 29 +++++++++++++ .../graphics/pro/js/wasm/src/metafile.cpp | 1 + PdfFile/PdfFile.cpp | 2 +- PdfFile/PdfFile.h | 2 +- PdfFile/PdfReader.cpp | 39 ++++++++++++++++-- PdfFile/SrcWriter/Document.cpp | 2 +- PdfFile/lib/xpdf/Gfx.cc | 17 +++----- 11 files changed, 121 insertions(+), 21 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index efdba26d0b..3644f0c46d 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -36,6 +36,7 @@ "_GetButtonIcons", "_GetAnnotationsInfo", "_GetAnnotationsAP", + "_GetShapes", "_InitializeFontsBin", "_InitializeFontsBase64", "_InitializeFontsRanges", diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 838e3c515e..bfa98b4eb7 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1498,6 +1498,47 @@ Module["_free"](ext); return res; }; + CFile.prototype["getShapes"] = function(pageIndex) + { + let res = []; + let ext = Module["_GetShapes"](this.nativeFile, pageIndex); + if (ext == 0) + return res; + + let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); + if (lenArray == null) + { + Module["_free"](ext); + return res; + } + + let len = lenArray[0]; + len -= 4; + if (len <= 0) + { + Module["_free"](ext); + return res; + } + + let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); + let reader = new CBinaryReader(buffer, 0, len); + + if (!reader.isValid()) + { + Module["_free"](ext); + return res; + } + + while (reader.isValid()) + { + let n = reader.readInt(); + for (let i = 0; i < n; ++i) + res.push(reader.readString()); + } + + Module["_free"](ext); + return res; + }; CFile.prototype["getStructure"] = function() { let res = []; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index bb3e56f82a..a7229e6ba5 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -243,9 +243,9 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) oRes.ClearWithoutAttack(); return bRes; } -WASM_EXPORT BYTE* GetShapesXML(CGraphicsFileDrawing* pGraphics, int nPageIndex) +WASM_EXPORT BYTE* GetShapes(CGraphicsFileDrawing* pGraphics, int nPageIndex) { - return pGraphics->GetShapesXML(nPageIndex); + return pGraphics->GetShapes(nPageIndex); } WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index ca969e8beb..531f44ba05 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -148,10 +148,10 @@ public: return ((CPdfFile*)pReader)->GetAnnots(nPageIndex); return NULL; } - BYTE* GetShapesXML(int nPageIndex) + BYTE* GetShapes(int nPageIndex) { if (nType == 0) - return ((CPdfFile*)pReader)->GetShapesXML(nPageIndex); + return ((CPdfFile*)pReader)->GetShapes(nPageIndex); return NULL; } BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 1a80dd548c..fcf3b8d42b 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1717,6 +1717,35 @@ int main(int argc, char* argv[]) free(pAnnotAP); } + // SHAPES + if (true) + { + BYTE* pShapes = GetShapes(pGrFile, 0); + nLength = READ_INT(pShapes); + int i = 4; + nLength -= 4; + + std::cout << std::endl; + + while (i < nLength) + { + int nShapesLength = READ_INT(pShapes + i); + i += 4; + std::cout << "Shapes" << std::endl; + + for (int j = 0; j < nShapesLength; ++j) + { + int nPathLength = READ_INT(pShapes + i); + i += 4; + std::cout << std::string((char*)(pShapes + i), nPathLength) << std::endl; + i += nPathLength; + } + } + + if (pShapes) + free(pShapes); + } + Close(pGrFile); RELEASEARRAYOBJECTS(pCMapData); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index 2379a2b3e7..cf6435762c 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -39,6 +39,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : IMetaFile(pAppFonts) {} virtual ~CMetaFile() {} + virtual void SetImageSize(int nWidth, int nHeight) {} virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; } virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; } virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 0739d2b63a..91568833c8 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1586,7 +1586,7 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) return NULL; return m_pInternal->pReader->GetAnnots(nPageIndex); } -BYTE* CPdfFile::GetShapesXML(int nPageIndex) +BYTE* CPdfFile::GetShapes(int nPageIndex) { if (!m_pInternal->pReader) return NULL; diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 0fa93e7fda..b060246605 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -135,7 +135,7 @@ public: BYTE* GetWidgetEmbeddedFonts(); BYTE* GetWidgetStandardFonts(); BYTE* GetAnnots (int nPageIndex = -1); - BYTE* GetShapesXML (int nPageIndex); + BYTE* GetShapes (int nPageIndex); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index c300625ee9..782313e86a 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1565,16 +1565,49 @@ BYTE* CPdfReader::GetShapes(int nPageIndex) if (!pPageRef) return NULL; - Object oPageObj; + Object oPageObj, oMetaOForm, oID; XRef* xref = m_pPDFDocument->getXRef(); - if (!xref->fetch(pPageRef->num, pPageRef->gen, &oPageObj)->isDict()) + if (!xref->fetch(pPageRef->num, pPageRef->gen, &oPageObj)->isDict() || !oPageObj.dictLookup("MetaOForm", &oMetaOForm)->isDict("MetaOForm") || !oMetaOForm.dictLookup("ID", &oID)->isString()) { - oPageObj.free(); + oPageObj.free(); oMetaOForm.free(); oID.free(); return NULL; } + oPageObj.free(); + + Object oTID, oID2; + Object* pTrailerDict = xref->getTrailerDict(); + if (!pTrailerDict || !pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString() || oID2.getString()->cmp(oID.getString()) != 0) + { + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); + return NULL; + } + oTID.free(); oID.free(); oID2.free(); + + Object oMetadata; + if (!oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray()) + { + oMetaOForm.free(); oMetadata.free(); + return NULL; + } + oMetaOForm.free(); NSWasm::CData oRes; oRes.SkipLen(); + int nMetadataLength = oMetadata.arrayGetLength(); + oRes.AddInt(nMetadataLength); + + for (int i = 0; i < nMetadataLength; ++i) + { + Object oMetaStr; + std::string sStr; + if (oMetadata.arrayGet(i, &oMetaStr)->isString()) + { + TextString* s = new TextString(oMetaStr.getString()); + sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oRes.WriteString(sStr); + } oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index d8f6aa57be..d62d3e1614 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1775,7 +1775,7 @@ namespace PdfWriter } pArrayMeta->Add(new CStringObject(sXML.c_str())); - m_pCurPage->BeginShape(); + m_pCurPage->BeginMarkedContent("MetaOForm"); } void CDocument::EndMarkedContent() { diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 655eb42de1..29f241de63 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,19 +5053,14 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); - } else if (args[0].isName("MetaOForm") && numArgs == 2 && args[1].isDict()) { - if (args[1].dictLookup("Revision", &obj)->isInt()) { - // TODO и совпадает с текущим в adaptor - Object obj2; - getContentObj(&obj2); - while (!obj2.isEOF() && !obj2.isCmd("EMC")) { - obj2.free(); - getContentObj(&obj2); - } - obj2.free(); obj.free(); - return; + } else if (args[0].isName("MetaOForm")) { + getContentObj(&obj); + while (!obj.isEOF() && !obj.isCmd("EMC")) { + obj.free(); + getContentObj(&obj); } obj.free(); + return; } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc);