From 2f8e492fc6d1d3fd6a8382e83cfb9c7bac0831fc Mon Sep 17 00:00:00 2001 From: Kulikova Svetlana Date: Tue, 20 Jul 2021 16:38:02 +0300 Subject: [PATCH] xps structure --- .../graphics/pro/js/wasm/js/xps_base.js | 51 ++++++++++++++++-- .../graphics/pro/js/wasm/src/wasmgraphics.cpp | 53 +++++++++++++++---- .../graphics/pro/js/wasm/src/wasmgraphics.h | 8 +++ DesktopEditor/graphics/pro/js/xps_make.py | 2 + DjVuFile/wasm/all_files_test/code.js | 3 ++ XpsFile/XpsFile.cpp | 23 ++++---- XpsFile/XpsFile.h | 4 ++ XpsFile/XpsLib/Document.cpp | 10 ++-- XpsFile/XpsLib/Document.h | 4 +- XpsFile/XpsLib/Page.cpp | 9 ++-- XpsFile/XpsLib/Page.h | 2 +- 11 files changed, 129 insertions(+), 40 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js b/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js index a7dcd0b4d3..61b478a2bf 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js @@ -126,14 +126,18 @@ { var res = Module["_XPS_GetPixmap"](this.nativeFile, pageIndex, width, height); - var lenArray = new Int32Array(Module["HEAP8"].buffer, res + 4 * width * height, 4); + var glyphs = Module["_XPS_GetGlyphs"](this.nativeFile, pageIndex); + + var lenArray = new Int32Array(Module["HEAP8"].buffer, glyphs, 4); + if (lenArray == null) + return res; var len = lenArray[0]; len -= 4; if (len <= 0) return res; this.pages[pageIndex].Lines = []; - var buffer = new Uint8Array(Module["HEAP8"].buffer, res + 4 * width * height + 4, len); + var buffer = new Uint8Array(Module["HEAP8"].buffer, glyphs + 4, len); var index = 0; var Line = -1; var prevY = -1; @@ -174,8 +178,47 @@ UChar : String.fromCharCode(lenRec) }); } - if (len > 0) - this.pages[pageIndex].Lines.sort((prev, next) => prev.Glyphs[0].Y - next.Glyphs[0].Y); + this.pages[pageIndex].Lines.sort((prev, next) => prev.Glyphs[0].Y - next.Glyphs[0].Y); + Module["_XPS_Delete"](glyphs); + return res; + }; + CFile.prototype.structure = function() + { + var res = []; + var str = Module["_XPS_GetStructure"](this.nativeFile); + var lenArray = new Int32Array(Module["HEAP8"].buffer, str, 4); + if (lenArray == null) + return res; + var len = lenArray[0]; + len -= 4; + if (len <= 0) + return res; + + var buffer = new Uint8Array(Module["HEAP8"].buffer, str + 4, len); + var index = 0; + var Line = -1; + var prevY = -1; + while (index < len) + { + var lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Page = lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Level = lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Y = parseFloat("".fromUtf8(buffer, index, lenRec)); + index += lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Description = "".fromUtf8(buffer, index, lenRec); + index += lenRec; + + res.push({ page : _Page, level : _Level, Y : _Y, description : _Description}); + } + + Module["_XPS_Delete"](str); return res; }; CFile.prototype.close = function() diff --git a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp index fcaf0298c4..ed8e5acdfd 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp @@ -53,6 +53,14 @@ WASM_EXPORT BYTE* XPS_GetPixmap(CGraphicsFileDrawing* pGraphics, int nPageIndex, { return pGraphics->GetPage(nPageIndex, nRasterW, nRasterH); } +WASM_EXPORT BYTE* XPS_GetGlyphs(CGraphicsFileDrawing* pGraphics, int nPageIndex) +{ + return pGraphics->GetXPSGlyphs(nPageIndex); +} +WASM_EXPORT BYTE* XPS_GetStructure(CGraphicsFileDrawing* pGraphics) +{ + return pGraphics->GetXPSStructure(); +} WASM_EXPORT void XPS_Delete(BYTE* pData) { RELEASEARRAYOBJECTS(pData); @@ -754,34 +762,59 @@ int main() resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG); resFrame->ClearNoAttack(); - DWORD nLength = GetLength(res + width * height * 4); + BYTE* pGlyphs = XPS_GetGlyphs(test, 0); + DWORD nLength = GetLength(pGlyphs); DWORD i = 4; nLength -= 4; while (i < nLength) { - DWORD nPathLength = GetLength(res + width * height * 4 + i); + DWORD nPathLength = GetLength(pGlyphs + i); i += 4; - std::cout << std::string((char*)(res + width * height * 4 + i), nPathLength) << " "; + std::cout << std::string((char*)(pGlyphs + i), nPathLength) << " "; i += nPathLength; - nPathLength = GetLength(res + width * height * 4 + i); + nPathLength = GetLength(pGlyphs + i); i += 4; - std::cout << std::string((char*)(res + width * height * 4 + i), nPathLength) << " "; + std::cout << std::string((char*)(pGlyphs + i), nPathLength) << " "; i += nPathLength; - nPathLength = GetLength(res + width * height * 4 + i); + nPathLength = GetLength(pGlyphs + i); i += 4; - std::cout << std::string((char*)(res + width * height * 4 + i), nPathLength) << " "; + std::cout << std::string((char*)(pGlyphs + i), nPathLength) << " "; i += nPathLength; - nPathLength = GetLength(res + width * height * 4 + i); + nPathLength = GetLength(pGlyphs + i); i += 4; - std::cout << std::string((char*)(res + width * height * 4 + i), nPathLength) << " "; + std::cout << std::string((char*)(pGlyphs + i), nPathLength) << " "; i += nPathLength; - nPathLength = GetLength(res + width * height * 4 + i); + nPathLength = GetLength(pGlyphs + i); i += 4; std::cout << nPathLength << std::endl; } + BYTE* pStructure = XPS_GetStructure(test); + nLength = GetLength(pStructure); + i = 4; + nLength -= 4; + while (i < nLength) + { + DWORD nPathLength = GetLength(pStructure + i); + i += 4; + std::cout << "Page " << nPathLength << ", "; + nPathLength = GetLength(pStructure + i); + i += 4; + std::cout << "Level " << nPathLength << ", "; + nPathLength = GetLength(pStructure + i); + i += 4; + std::cout << "Y "<< std::string((char*)(pStructure + i), nPathLength) << ", "; + i += nPathLength; + nPathLength = GetLength(pStructure + i); + i += 4; + std::cout << "Description "<< std::string((char*)(pStructure + i), nPathLength) << std::endl; + i += nPathLength; + } + XPS_Close(test); RELEASEARRAYOBJECTS(res); + RELEASEARRAYOBJECTS(pGlyphs); + RELEASEARRAYOBJECTS(pStructure); RELEASEOBJECT(resFrame); return 0; } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.h b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.h index c393bb5dfa..3f96059a45 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.h @@ -66,6 +66,14 @@ public: } return flipped; } + BYTE* GetXPSGlyphs(int nPageIndex) + { + return ((CXpsFile*)pReader)->GetGlyphs(nPageIndex); + } + BYTE* GetXPSStructure() + { + return ((CXpsFile*)pReader)->GetStructure(); + } }; #endif // _WASM_GRAPHICS_ diff --git a/DesktopEditor/graphics/pro/js/xps_make.py b/DesktopEditor/graphics/pro/js/xps_make.py index 04a962ea5a..907d6cce2b 100644 --- a/DesktopEditor/graphics/pro/js/xps_make.py +++ b/DesktopEditor/graphics/pro/js/xps_make.py @@ -44,6 +44,8 @@ exported_functions = ["_malloc", "_XPS_Close", "_XPS_GetInfo", "_XPS_GetPixmap", + "_XPS_GetGlyphs", + "_XPS_GetStructure", "_XPS_Delete"] libGraphics_src_path = "../../" diff --git a/DjVuFile/wasm/all_files_test/code.js b/DjVuFile/wasm/all_files_test/code.js index b31a153023..48c12ca769 100644 --- a/DjVuFile/wasm/all_files_test/code.js +++ b/DjVuFile/wasm/all_files_test/code.js @@ -327,6 +327,9 @@ window.onload = function() { if (!this.file.isValid()) return; + + if (!down && !this.Selection.IsSelection) + return; let lCurrentPage = -1; for (let i = 0; i < this.drawingPages.length; i++) diff --git a/XpsFile/XpsFile.cpp b/XpsFile/XpsFile.cpp index 7d85faf3e8..fba55cf5bd 100644 --- a/XpsFile/XpsFile.cpp +++ b/XpsFile/XpsFile.cpp @@ -208,19 +208,6 @@ BYTE* CXpsFile::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH) RELEASEOBJECT(pRenderer); oFrame.ClearNoAttack(); - #ifdef BUILDING_WASM_MODULE - BYTE* pGlyphs = NULL; - DWORD dGlyphs = 0; - m_pInternal->m_pDocument->GetPageGlyphs(nPageIndex, pGlyphs, dGlyphs); - if (pGlyphs && dGlyphs) - { - BYTE* pRes = new BYTE[nWidth * nHeight * 4 + dGlyphs]; - memcpy(pRes, pBgraData, nWidth * nHeight * 4); - memcpy(pRes + nWidth * nHeight * 4, pGlyphs, dGlyphs); - RELEASEARRAYOBJECTS(pBgraData); - return pRes; - } - #endif return pBgraData; } void CXpsFile::ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int nRasterW, const int nRasterH) @@ -295,3 +282,13 @@ void CXpsFile::ConvertToPdf(const std::wstring& wsPath) oPdf.SaveToFile(wsPath); } +#ifdef BUILDING_WASM_MODULE +BYTE* CXpsFile::GetGlyphs(int nPageIndex) +{ + return m_pInternal->m_pDocument->GetPageGlyphs(nPageIndex); +} +BYTE* CXpsFile::GetStructure() +{ + return m_pInternal->m_pDocument->GetStructure(); +} +#endif diff --git a/XpsFile/XpsFile.h b/XpsFile/XpsFile.h index 52e0ae7716..c07316c7bf 100644 --- a/XpsFile/XpsFile.h +++ b/XpsFile/XpsFile.h @@ -66,6 +66,10 @@ public: virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1); void ConvertToPdf(const std::wstring& wsDstPath); + #ifdef BUILDING_WASM_MODULE + BYTE* GetGlyphs(int nPageIndex); + BYTE* GetStructure(); + #endif private: CXpsFile_Private* m_pInternal; diff --git a/XpsFile/XpsLib/Document.cpp b/XpsFile/XpsLib/Document.cpp index 658fdfc8ac..5faecb289a 100644 --- a/XpsFile/XpsLib/Document.cpp +++ b/XpsFile/XpsLib/Document.cpp @@ -190,7 +190,7 @@ namespace XPS if (wsAttrName == L"OutlineLevel") oStructure.nLevel = GetInteger(wsAttrText); else if (wsAttrName == L"Description") - oStructure.wsDescription = wsAttrText; + oStructure.sDescription = U_TO_UTF8(wsAttrText); else if (wsAttrName == L"OutlineTarget") { size_t nSharp = wsAttrText.find(L'#'); @@ -292,19 +292,19 @@ namespace XPS oRes.AddInt(str.nPage); oRes.AddInt(str.nLevel); oRes.WriteString((BYTE*)sY.c_str(), sY.length()); - oRes.WriteString((BYTE*)str.wsDescription.c_str(), str.wsDescription.length()); - oRes.WriteString((BYTE*)str.wsTarget.c_str(), str.wsTarget.length()); + oRes.WriteString((BYTE*)str.sDescription.c_str(), str.sDescription.length()); } oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); oRes.ClearWithoutAttack(); return bRes; } - void CDocument::GetPageGlyphs(int nPageIndex, BYTE*& pGlyphs, DWORD& length) + BYTE* CDocument::GetPageGlyphs(int nPageIndex) { std::map::const_iterator oIter = m_mPages.find(nPageIndex); if (oIter != m_mPages.end()) - oIter->second->GetGlyphs(pGlyphs, length); + return oIter->second->GetGlyphs(); + return NULL; } #endif void CDocument::DrawPage(int nPageIndex, IRenderer* pRenderer, bool* pbBreak) diff --git a/XpsFile/XpsLib/Document.h b/XpsFile/XpsLib/Document.h index 710daa419f..606a303a2a 100644 --- a/XpsFile/XpsLib/Document.h +++ b/XpsFile/XpsLib/Document.h @@ -64,11 +64,11 @@ namespace XPS int nLevel; int nPage; double dY; - std::wstring wsDescription; + std::string sDescription; std::wstring wsTarget; }; BYTE* GetStructure(); - void GetPageGlyphs(int nPageIndex, BYTE*& pGlyphs, DWORD& length); + BYTE* GetPageGlyphs(int nPageIndex); std::vector m_vStructure; #endif private: diff --git a/XpsFile/XpsLib/Page.cpp b/XpsFile/XpsLib/Page.cpp index bc7f65fb58..0ac4724690 100644 --- a/XpsFile/XpsLib/Page.cpp +++ b/XpsFile/XpsLib/Page.cpp @@ -176,13 +176,11 @@ namespace XPS } } #ifdef BUILDING_WASM_MODULE - void Page::GetGlyphs(BYTE*& pGlyphs, DWORD& length) + BYTE* Page::GetGlyphs() { if (m_pGlyphs) - { - pGlyphs = m_pGlyphs->GetBuffer(); - length = m_pGlyphs->GetSize(); - } + return m_pGlyphs->GetBuffer(); + return NULL; } #endif void Page::Draw(IRenderer* pRenderer, bool* pbBreak) @@ -977,6 +975,7 @@ namespace XPS size_t nFindY = wsPath.find(L','); if (nFindY != std::wstring::npos) { + nFindY++; size_t nFindEndY = wsPath.find(L' ', nFindY); if (nFindEndY != std::wstring::npos) find->dY = GetDouble(wsPath.substr(nFindY, nFindEndY - nFindY)); diff --git a/XpsFile/XpsLib/Page.h b/XpsFile/XpsLib/Page.h index a51b49b616..70eab1a3b0 100644 --- a/XpsFile/XpsLib/Page.h +++ b/XpsFile/XpsLib/Page.h @@ -54,7 +54,7 @@ namespace XPS void GetSize(int& nW, int& nH) const; #ifdef BUILDING_WASM_MODULE - void GetGlyphs(BYTE*& pGlyphs, DWORD& length); + BYTE* GetGlyphs(); class CData { protected: