diff --git a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp index e08ccd51a8..bd6797ecfc 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/wasmgraphics.cpp @@ -284,6 +284,22 @@ int main() int width = info[1] * 96 / info[3]; int height = info[2] * 96 / info[3]; + BYTE* res = NULL; + if (pages_count > 0) + res = XPS_GetPixmap(test, 0, width, height); + + for (int i = 0; i < 100; i++) + std::cout << (int)res[i] << " "; + + CBgraFrame* resFrame = new CBgraFrame(); + resFrame->put_Data(res); + resFrame->put_Width(width); + resFrame->put_Height(height); + resFrame->put_Stride(-4 * width); + resFrame->put_IsRGBA(true); + resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG); + resFrame->ClearNoAttack(); + BYTE* pGlyphs = DJVU_GetGlyphs(test, 0, width, height); DWORD nLength = GetLength(pGlyphs); DWORD i = 4; @@ -321,26 +337,26 @@ int main() { DWORD nPathLength = GetLength(pLinks + i); i += 4; - std::cout << "Link "<< std::string((char*)(pLinks + i), nPathLength) << std::endl; + std::cout << "Link "<< std::string((char*)(pLinks + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(pLinks + i); + i += 4; + std::cout << "X " << std::string((char*)(pLinks + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(pLinks + i); + i += 4; + std::cout << "Y " << std::string((char*)(pLinks + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(pLinks + i); + i += 4; + std::cout << "W " << std::string((char*)(pLinks + i), nPathLength) << " "; + i += nPathLength; + nPathLength = GetLength(pLinks + i); + i += 4; + std::cout << "H " << std::string((char*)(pLinks + i), nPathLength) << std::endl; i += nPathLength; } - BYTE* res = NULL; - if (pages_count > 0) - res = XPS_GetPixmap(test, 0, width, height); - - for (int i = 0; i < 100; i++) - std::cout << (int)res[i] << " "; - - CBgraFrame* resFrame = new CBgraFrame(); - resFrame->put_Data(res); - resFrame->put_Width(width); - resFrame->put_Height(height); - resFrame->put_Stride(-4 * width); - resFrame->put_IsRGBA(true); - resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG); - resFrame->ClearNoAttack(); - BYTE* pStructure = DJVU_GetStructure(test); nLength = GetLength(pStructure); i = 4; diff --git a/DesktopEditor/graphics/pro/js/xps_djvu_make.py b/DesktopEditor/graphics/pro/js/xps_djvu_make.py index b94df1a9b7..10cc83249e 100644 --- a/DesktopEditor/graphics/pro/js/xps_djvu_make.py +++ b/DesktopEditor/graphics/pro/js/xps_djvu_make.py @@ -51,6 +51,7 @@ exported_functions = ["_malloc", "_DJVU_GetGlyphs", "_XPS_GetExternalLinks", "_XPS_GetInternalLinks", + "_DJVU_GetLinks", "_XPS_GetStructure", "_DJVU_GetStructure", "_XPS_Delete"] diff --git a/DjVuFile/DjVuFileImplementation.cpp b/DjVuFile/DjVuFileImplementation.cpp index 0799430bd9..25afac1a57 100644 --- a/DjVuFile/DjVuFileImplementation.cpp +++ b/DjVuFile/DjVuFileImplementation.cpp @@ -570,16 +570,32 @@ BYTE* CDjVuFileImplementation::GetPageGlyphs(int nPageIndex, const } BYTE* CDjVuFileImplementation::GetPageLinks (int nPageIndex, const int& nRasterW, const int& nRasterH) { + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + GP pPage = m_pDoc->get_page(nPageIndex); GP pAnno = pPage->get_decoded_anno(); GPList map_areas = pAnno->ant->map_areas; CData oRes; oRes.SkipLen(); + double dKoefX = (double)nRasterW * dPageDpiX / 25.4 / dWidth; + double dKoefY = (double)nRasterH * dPageDpiY / 25.4 / dHeight; for(GPosition pos(map_areas); pos; ++pos) { - GUTF8String sURL = map_areas[pos]->url; - oRes.WriteString((BYTE*)sURL.getbuf(), sURL.length()); + GUTF8String str = map_areas[pos]->url; + oRes.WriteString((BYTE*)str.getbuf(), str.length()); + double x = map_areas[pos]->get_xmin() * dKoefX; + std::string s = std::to_string(x); + oRes.WriteString((BYTE*)s.c_str(), s.length()); + double y = map_areas[pos]->get_ymin() * dKoefY; + s = std::to_string(y); + oRes.WriteString((BYTE*)s.c_str(), s.length()); + s = std::to_string(map_areas[pos]->get_xmax() * dKoefX - x); + oRes.WriteString((BYTE*)s.c_str(), s.length()); + s = std::to_string(map_areas[pos]->get_ymax() * dKoefY - y); + oRes.WriteString((BYTE*)s.c_str(), s.length()); } oRes.WriteLen(); diff --git a/DjVuFile/wasm/all_files_test/code.js b/DjVuFile/wasm/all_files_test/code.js index 822738bef5..e2e86e8c16 100644 --- a/DjVuFile/wasm/all_files_test/code.js +++ b/DjVuFile/wasm/all_files_test/code.js @@ -382,18 +382,14 @@ window.onload = function() this.file.getGlyphs(pageIndex, width, height); }; - this.getExternalLinks = function(pageIndex, width, height) + this.getLinks = function(pageIndex, width, height) { - var res = this.file.getExtLinks(pageIndex, width, height); - return res; - }; - - this.getInternalLinks = function(pageIndex, width, height) - { - var res = this.file.getIntLinks(pageIndex, width, height); + var res = this.file.getLinks(pageIndex, width, height); return res; }; + this.links = null; + this._paint = function() { if (!this.isRepaint) @@ -474,6 +470,8 @@ window.onload = function() { page.Image = this.file.getPage(i, w, h); this.getGlyphs(i, w, h); + this.links = this.getLinks(i, w, h); + this.links.Page = i; } let x = ((xCenter * this.retinaPixelRatio) >> 0) - (w >> 1); @@ -482,6 +480,16 @@ window.onload = function() ctx.drawImage(page.Image, 0, 0, w, h, x, y, w, h); if (this.Selection.page == i && this.Selection.IsSelection) ctx.drawImage(this.Selection.Image, 0, 0, w, h, x, y, w, h); + + if (this.links && this.links.Page == i) + { + ctx.fillStyle = "#FF0000"; + for (let j = 0; j < this.links.length; j++) + { + let Link = this.links[j]; + ctx.fillRect(x + Link.X, y + Link.Y, Link.W, Link.H); + } + } ctx.strokeRect(x + lineW / 2, y + lineW / 2, w - lineW, h - lineW); } diff --git a/DjVuFile/wasm/djvu_base.js b/DjVuFile/wasm/djvu_base.js index 3a2f10d062..550180bf3e 100644 --- a/DjVuFile/wasm/djvu_base.js +++ b/DjVuFile/wasm/djvu_base.js @@ -178,6 +178,44 @@ } Module["_XPS_Delete"](glyphs); }; + CFile.prototype.getLinks = function(pageIndex, width, height) + { + var res = []; + var ext = Module["_DJVU_GetLinks"](this.nativeFile, pageIndex, width, height); + var lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); + if (lenArray == null) + return res; + var len = lenArray[0]; + len -= 4; + if (len <= 0) + return res; + + var index = 0; + var buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); + while (index < len) + { + var lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Link = "".fromUtf8(buffer, index, lenRec); + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _X = lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _Y = lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _W = lenRec; + lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; + index += 4; + var _H = lenRec; + + res.push({ X : _X, Y : _Y, W : _W, H : _H, Link : _Link}); + } + + Module["_XPS_Delete"](ext); + return res; + }; CFile.prototype.structure = function() { var res = [];