diff --git a/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js b/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js index 477cdb46d2..ebf0ed352c 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/xps_base.js @@ -74,6 +74,8 @@ } } + //string_utf8 + //module /** @@ -122,7 +124,39 @@ }; CFile.prototype.getPagePixmap = function(pageIndex, width, height) { - return Module["_XPS_GetPixmap"](this.nativeFile, pageIndex, width, height); + var res = Module["_XPS_GetPixmap"](this.nativeFile, pageIndex, width, height); + + var lenArray = new Int32Array(Module["HEAP8"].buffer, res + 4 * width * height, 4); + var len = lenArray[0]; + len -= 4; + if (len) + this.pages[pageIndex].Glyphs = []; + + var buffer = new Uint8Array(Module["HEAP8"].buffer, res + 4 * width * height + 4, len); + var index = 0; + while (index < len) + { + var lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _fontName = "".fromUtf8(buffer, index, lenRec); + index += lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _fontSize = "".fromUtf8(buffer, index, lenRec); + index += lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _X = "".fromUtf8(buffer, index, lenRec); + index += lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Y = "".fromUtf8(buffer, index, lenRec); + index += lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + this.pages[pageIndex].Glyphs.push({ fontName : _fontName, fontSize : _fontSize, X : _X, Y : _Y, UChar : lenRec}); + } + 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 55f6776d85..dd0ffc7f13 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp @@ -53,9 +53,9 @@ WASM_EXPORT BYTE* XPS_GetPixmap(CGraphicsFileDrawing* pGraphics, int nPageIndex, { return pGraphics->GetPage(nPageIndex, nRasterW, nRasterH); } -WASM_EXPORT void XPS_Delete(unsigned char* pData) +WASM_EXPORT void XPS_Delete(BYTE* pData) { - delete[] pData; + RELEASEARRAYOBJECTS(pData); } /* @@ -691,6 +691,11 @@ WASM_EXPORT void Graphics_drawHorLine(void* graphics, BYTE align, double y, dou #endif #ifdef TEST_AS_EXECUTABLE +static DWORD GetLength(BYTE* x) +{ + return x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24; +} + int main() { //void* test = Graphics_Create(412, 151, 109.008, 39.9521); @@ -747,6 +752,32 @@ int main() resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG); resFrame->ClearNoAttack(); + DWORD nLength = GetLength(res + info[1] * info[2] * 4); + DWORD i = 4; + nLength -= 4; + while (i < nLength) + { + DWORD nPathLength = GetLength(res + info[1] * info[2] * 4 + i); + i += 4; + std::cout << std::string((char*)(res + info[1] * info[2] * 4 + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(res + info[1] * info[2] * 4 + i); + i += 4; + std::cout << std::string((char*)(res + info[1] * info[2] * 4 + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(res + info[1] * info[2] * 4 + i); + i += 4; + std::cout << std::string((char*)(res + info[1] * info[2] * 4 + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(res + info[1] * info[2] * 4 + i); + i += 4; + std::cout << std::string((char*)(res + info[1] * info[2] * 4 + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(res + info[1] * info[2] * 4 + i); + i += 4; + std::cout << nPathLength << std::endl; + } + XPS_Close(test); RELEASEARRAYOBJECTS(res); RELEASEOBJECT(resFrame); diff --git a/DesktopEditor/graphics/pro/js/xps_make.py b/DesktopEditor/graphics/pro/js/xps_make.py index 5b1913b045..04a962ea5a 100644 --- a/DesktopEditor/graphics/pro/js/xps_make.py +++ b/DesktopEditor/graphics/pro/js/xps_make.py @@ -197,7 +197,9 @@ base.run_as_bat(windows_bat) base.replaceInFile("./xps.js", "function getBinaryPromise(){", "function getBinaryPromise2(){") graphics_js_content = base.readFile("./xps.js") engine_base_js_content = base.readFile("./wasm/js/xps_base.js") +string_utf8_content = base.readFile("./../../../../Common/js/string_utf8.js") engine_js_content = engine_base_js_content.replace("//module", graphics_js_content) +engine_js_content = engine_js_content.replace("//string_utf8", string_utf8_content) base.replaceInFile("./xps.js", "__ATPOSTRUN__=[];", "__ATPOSTRUN__=[function(){self.onEngineGraphicsInit();}];") graphics_js_content = base.readFile("./xps.js") diff --git a/XpsFile/XpsFile.cpp b/XpsFile/XpsFile.cpp index 5b72e0d334..7d85faf3e8 100644 --- a/XpsFile/XpsFile.cpp +++ b/XpsFile/XpsFile.cpp @@ -207,6 +207,20 @@ BYTE* CXpsFile::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH) RELEASEINTERFACE(pFontManager); 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) diff --git a/XpsFile/XpsLib/Document.cpp b/XpsFile/XpsLib/Document.cpp index e6aab68583..5c1ff83a5b 100644 --- a/XpsFile/XpsLib/Document.cpp +++ b/XpsFile/XpsLib/Document.cpp @@ -178,6 +178,14 @@ namespace XPS if (oIter != m_mPages.end()) oIter->second->GetSize(nW, nH); } + #ifdef BUILDING_WASM_MODULE + void CDocument::GetPageGlyphs(int nPageIndex, BYTE*& pGlyphs, DWORD& length) + { + std::map::const_iterator oIter = m_mPages.find(nPageIndex); + if (oIter != m_mPages.end()) + oIter->second->GetGlyphs(pGlyphs, length); + } + #endif void CDocument::DrawPage(int nPageIndex, IRenderer* pRenderer, bool* pbBreak) { std::map::const_iterator oIter = m_mPages.find(nPageIndex); diff --git a/XpsFile/XpsLib/Document.h b/XpsFile/XpsLib/Document.h index 32b3c9006c..cd59a02c68 100644 --- a/XpsFile/XpsLib/Document.h +++ b/XpsFile/XpsLib/Document.h @@ -54,6 +54,9 @@ namespace XPS bool Read(IFolder* pFolder); int GetPageCount() const; void GetPageSize(int nPageIndex, int& nW, int& nH); + #ifdef BUILDING_WASM_MODULE + void GetPageGlyphs(int nPageIndex, BYTE*& pGlyphs, DWORD& length); + #endif void DrawPage(int nPageIndex, IRenderer* pRenderer, bool* pbBreak); void Close(); CStaticResource* GetStaticResource(const wchar_t* wsPath); diff --git a/XpsFile/XpsLib/Page.cpp b/XpsFile/XpsLib/Page.cpp index 1e3f88d2e3..63609a9efe 100644 --- a/XpsFile/XpsLib/Page.cpp +++ b/XpsFile/XpsLib/Page.cpp @@ -87,9 +87,15 @@ namespace XPS m_pFontList = pFontList; m_pFontManager = pFontManager; m_pDocument = pDocument; + #ifdef BUILDING_WASM_MODULE + m_pGlyphs = NULL; + #endif } Page::~Page() { + #ifdef BUILDING_WASM_MODULE + RELEASEOBJECT(m_pGlyphs); + #endif } void Page::GetSize(int& nW, int& nH) const { @@ -169,6 +175,16 @@ namespace XPS nH = wsAttrName.tointeger(); } } + #ifdef BUILDING_WASM_MODULE + void Page::GetGlyphs(BYTE*& pGlyphs, DWORD& length) + { + if (m_pGlyphs) + { + pGlyphs = m_pGlyphs->GetBuffer(); + length = m_pGlyphs->GetSize(); + } + } + #endif void Page::Draw(IRenderer* pRenderer, bool* pbBreak) { XmlUtils::CXmlLiteReader oReader; @@ -693,6 +709,26 @@ namespace XPS pState->PushTransform(pTransform); } + #ifdef BUILDING_WASM_MODULE + if (!m_pGlyphs) + { + m_pGlyphs = new CData(); + m_pGlyphs->SkipLen(); + } + std::wstring wsFontName; + pRenderer->get_FontName(&wsFontName); + std::string sFontName = U_TO_UTF8(wsFontName); + m_pGlyphs->WriteString((BYTE*)sFontName.c_str(), sFontName.length()); + std::string sFontSize = std::to_string(dFontSize * 0.75); + m_pGlyphs->WriteString((BYTE*)sFontSize.c_str(), sFontSize.length()); + std::string sX = std::to_string(xpsUnitToMM(dXorigin)); + m_pGlyphs->WriteString((BYTE*)sX.c_str(), sX.length()); + std::string sY = std::to_string(xpsUnitToMM(dYorigin)); + m_pGlyphs->WriteString((BYTE*)sY.c_str(), sY.length()); + m_pGlyphs->AddInt(oEntry.nUnicode); + m_pGlyphs->WriteLen(); + #endif + if (oEntry.bGid) pRenderer->CommandDrawTextExCHAR(oEntry.nUnicode, oEntry.nGid, xpsUnitToMM(dXorigin), xpsUnitToMM(dYorigin), 0, 0); else diff --git a/XpsFile/XpsLib/Page.h b/XpsFile/XpsLib/Page.h index 0c4d6f5703..25baf8004c 100644 --- a/XpsFile/XpsLib/Page.h +++ b/XpsFile/XpsLib/Page.h @@ -53,6 +53,9 @@ namespace XPS ~Page(); void GetSize(int& nW, int& nH) const; + #ifdef BUILDING_WASM_MODULE + void GetGlyphs(BYTE*& pGlyphs, DWORD& length); + #endif void Draw(IRenderer* pRenderer, bool* pbBreak); private: @@ -74,6 +77,140 @@ namespace XPS CFontList* m_pFontList; NSFonts::IFontManager* m_pFontManager; CDocument* m_pDocument; + + #ifdef BUILDING_WASM_MODULE + class CData + { + protected: + unsigned char* m_pData; + size_t m_lSize; + + unsigned char* m_pDataCur; + size_t m_lSizeCur; + + public: + CData() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = m_lSize; + } + CData(size_t nLen) + { + m_lSize = nLen; + m_pData = (unsigned char*)malloc(m_lSize * sizeof(unsigned char)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + } + CData(unsigned char* value, unsigned int len) + { + m_lSize = len; + m_pData = value; + + m_lSizeCur = m_lSize; + m_pDataCur = m_pData + m_lSizeCur; + } + virtual ~CData() + { + Clear(); + } + + inline void AddSize(size_t nSize) + { + if (NULL == m_pData) + { + m_lSize = 1000; + if (nSize > m_lSize) + m_lSize = nSize; + + m_pData = (unsigned char*)malloc(m_lSize * sizeof(unsigned char)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + return; + } + + if ((m_lSizeCur + nSize) > m_lSize) + { + while ((m_lSizeCur + nSize) > m_lSize) + m_lSize *= 2; + + unsigned char* pRealloc = (unsigned char*)realloc(m_pData, m_lSize * sizeof(unsigned char)); + if (NULL != pRealloc) + { + m_pData = pRealloc; + m_pDataCur = m_pData + m_lSizeCur; + } + else + { + unsigned char* pMalloc = (unsigned char*)malloc(m_lSize * sizeof(unsigned char)); + memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(unsigned char)); + + free(m_pData); + m_pData = pMalloc; + m_pDataCur = m_pData + m_lSizeCur; + } + } + } + + public: + void AddInt(unsigned int value) + { + AddSize(4); + memcpy(m_pDataCur, &value, sizeof(unsigned int)); + m_pDataCur += 4; + m_lSizeCur += 4; + } + void WriteString(unsigned char* value, unsigned int len) + { + AddSize(len + 4); + memcpy(m_pDataCur, &len, sizeof(unsigned int)); + m_pDataCur += 4; + m_lSizeCur += 4; + memcpy(m_pDataCur, value, len); + m_pDataCur += len; + m_lSizeCur += len; + } + unsigned char* GetBuffer() + { + return m_pData; + } + + void Clear() + { + if (m_pData) free(m_pData); + + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void ClearNoAttack() + { + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + unsigned int GetSize() + { + return (unsigned int)m_lSizeCur; + } + + void SkipLen() + { + AddInt(0); + } + void WriteLen() + { + unsigned int len = (unsigned int)m_lSizeCur; + memcpy(m_pData, &len, sizeof(unsigned int)); + } + }; + CData* m_pGlyphs; + #endif }; }