xps external and internal links

This commit is contained in:
Kulikova Svetlana
2021-08-05 14:30:22 +03:00
parent 7b0bc5a059
commit d4de820fa3
8 changed files with 228 additions and 8 deletions

View File

@ -36,12 +36,12 @@ WASM_EXPORT CGraphicsFileDrawing* DJVU_Load(BYTE* data, LONG size)
pGraphics->LoadFromMemory(data, size);
return pGraphics;
}
WASM_EXPORT void XPS_Close (CGraphicsFileDrawing* pGraphics)
WASM_EXPORT void XPS_Close (CGraphicsFileDrawing* pGraphics)
{
delete pGraphics;
RELEASEOBJECT(CApplicationFontStreams::m_pMemoryStorage);
}
WASM_EXPORT int* XPS_GetInfo (CGraphicsFileDrawing* pGraphics)
WASM_EXPORT int* XPS_GetInfo (CGraphicsFileDrawing* pGraphics)
{
int pages_count = pGraphics->GetPagesCount();
int* buffer = new int[pages_count * 3 + 1];
@ -59,11 +59,11 @@ WASM_EXPORT int* XPS_GetInfo (CGraphicsFileDrawing* pGraphics)
}
return buffer;
}
WASM_EXPORT BYTE* XPS_GetPixmap(CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH)
WASM_EXPORT BYTE* XPS_GetPixmap (CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH)
{
return pGraphics->GetPage(nPageIndex, nRasterW, nRasterH);
}
WASM_EXPORT BYTE* XPS_GetGlyphs(CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH)
WASM_EXPORT BYTE* XPS_GetGlyphs (CGraphicsFileDrawing* pGraphics, int nPageIndex, int nRasterW, int nRasterH)
{
return pGraphics->GetXPSGlyphs(nPageIndex, nRasterW, nRasterH);
}
@ -71,6 +71,14 @@ WASM_EXPORT BYTE* DJVU_GetGlyphs(CGraphicsFileDrawing* pGraphics, int nPageIndex
{
return pGraphics->GetDJVUGlyphs(nPageIndex, nRasterW, nRasterH);
}
WASM_EXPORT BYTE* XPS_GetExternalLinks(CGraphicsFileDrawing* pGraphics, int nPageIndex)
{
return pGraphics->GetXPSExternalLinks(nPageIndex);
}
WASM_EXPORT BYTE* XPS_GetInternalLinks(CGraphicsFileDrawing* pGraphics, int nPageIndex)
{
return pGraphics->GetXPSInternalLinks(nPageIndex);
}
WASM_EXPORT BYTE* XPS_GetStructure(CGraphicsFileDrawing* pGraphics)
{
return pGraphics->GetXPSStructure();
@ -116,7 +124,7 @@ int main()
int width = info[1] * 96 / info[3];
int height = info[2] * 96 / info[3];
BYTE* pGlyphs = XPS_GetGlyphs(test, 0, width, height);
BYTE* pGlyphs = XPS_GetGlyphs(test, 22, width, height);
DWORD nLength = GetLength(pGlyphs);
DWORD i = 4;
nLength -= 4;
@ -152,10 +160,11 @@ int main()
BYTE* res = NULL;
if (pages_count > 0)
res = XPS_GetPixmap(test, 0, width, height);
res = XPS_GetPixmap(test, 22, width, height);
for (int i = 0; i < 100; i++)
std::cout << (int)res[i] << " ";
std::cout << std::endl;
CBgraFrame* resFrame = new CBgraFrame();
resFrame->put_Data(res);
@ -166,6 +175,61 @@ int main()
resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG);
resFrame->ClearNoAttack();
BYTE* pInternal = XPS_GetInternalLinks(test, 22);
nLength = GetLength(pInternal);
i = 4;
nLength -= 4;
while (i < nLength)
{
DWORD nPathLength = GetLength(pInternal + i);
i += 4;
std::cout << "Page "<< nPathLength;
nPathLength = GetLength(pInternal + i);
i += 4;
std::cout << " X "<< std::string((char*)(pInternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pInternal + i);
i += 4;
std::cout << " Y "<< std::string((char*)(pInternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pInternal + i);
i += 4;
std::cout << " W "<< std::string((char*)(pInternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pInternal + i);
i += 4;
std::cout << " H "<< std::string((char*)(pInternal + i), nPathLength) << std::endl;
i += nPathLength;
}
BYTE* pExternal = XPS_GetExternalLinks(test, 22);
nLength = GetLength(pExternal);
i = 4;
nLength -= 4;
while (i < nLength)
{
DWORD nPathLength = GetLength(pExternal + i);
i += 4;
std::cout << "X "<< std::string((char*)(pExternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pExternal + i);
i += 4;
std::cout << " Y "<< std::string((char*)(pExternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pExternal + i);
i += 4;
std::cout << " W "<< std::string((char*)(pExternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pExternal + i);
i += 4;
std::cout << " H "<< std::string((char*)(pExternal + i), nPathLength);
i += nPathLength;
nPathLength = GetLength(pExternal + i);
i += 4;
std::cout << " Link "<< std::string((char*)(pExternal + i), nPathLength) << std::endl;
i += nPathLength;
}
BYTE* pStructure = XPS_GetStructure(test);
nLength = GetLength(pStructure);
i = 4;

View File

@ -82,6 +82,14 @@ public:
{
return ((CDjVuFile*)pReader)->GetPageGlyphs(nPageIndex, nRasterW, nRasterH);
}
BYTE* GetXPSExternalLinks(int nPageIndex)
{
return ((CXpsFile*)pReader)->GetExternalLinks(nPageIndex);
}
BYTE* GetXPSInternalLinks(int nPageIndex)
{
return ((CXpsFile*)pReader)->GetInternalLinks(nPageIndex);
}
BYTE* GetXPSStructure()
{
return ((CXpsFile*)pReader)->GetStructure();

View File

@ -293,4 +293,12 @@ BYTE* CXpsFile::GetStructure()
{
return m_pInternal->m_pDocument->GetStructure();
}
BYTE* CXpsFile::GetExternalLinks(int nPageIndex)
{
return m_pInternal->m_pDocument->GetExternalLinks(nPageIndex);
}
BYTE* CXpsFile::GetInternalLinks(int nPageIndex)
{
return m_pInternal->m_pDocument->GetInternalLinks(nPageIndex);
}
#endif

View File

@ -69,6 +69,8 @@ public:
#ifdef BUILDING_WASM_MODULE
BYTE* GetGlyphs(int nPageIndex, int nRasterW, int nRasterH);
BYTE* GetStructure();
BYTE* GetExternalLinks(int nPageIndex);
BYTE* GetInternalLinks(int nPageIndex);
#endif
private:

View File

@ -257,6 +257,8 @@ namespace XPS
std::vector<CDocumentStructure>::iterator find = std::find_if(m_vStructure.begin(), m_vStructure.end(), [wsNameTarget](const CDocumentStructure& str){ return str.wsTarget == wsNameTarget; });
if (find != m_vStructure.end())
find->nPage = nIndex;
else
m_mInternalLinks.insert(std::pair<std::wstring, int>(wsNameTarget, nIndex));
}
}
}
@ -306,6 +308,20 @@ namespace XPS
return oIter->second->GetGlyphs();
return NULL;
}
BYTE* CDocument::GetExternalLinks(int nPageIndex)
{
std::map<int, XPS::Page*>::const_iterator oIter = m_mPages.find(nPageIndex);
if (oIter != m_mPages.end())
return oIter->second->GetExternalLinks();
return NULL;
}
BYTE* CDocument::GetInternalLinks(int nPageIndex)
{
std::map<int, XPS::Page*>::const_iterator oIter = m_mPages.find(nPageIndex);
if (oIter != m_mPages.end())
return oIter->second->GetInternalLinks();
return NULL;
}
#endif
void CDocument::DrawPage(int nPageIndex, IRenderer* pRenderer, bool* pbBreak)
{

View File

@ -69,7 +69,10 @@ namespace XPS
};
BYTE* GetStructure();
BYTE* GetPageGlyphs(int nPageIndex);
BYTE* GetExternalLinks(int nPageIndex);
BYTE* GetInternalLinks(int nPageIndex);
std::vector<CDocumentStructure> m_vStructure;
std::map<std::wstring, int> m_mInternalLinks;
#endif
private:

View File

@ -187,6 +187,51 @@ namespace XPS
}
return NULL;
}
BYTE* Page::GetExternalLinks()
{
CData oRes;
oRes.SkipLen();
for (const CPageLink& link : m_vExternalLinks)
{
std::string s = std::to_string(link.dX);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = std::to_string(link.dY);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = std::to_string(link.dW);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = std::to_string(link.dH);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = U_TO_UTF8(link.sLink);
oRes.WriteString((BYTE*)s.c_str(), s.length());
}
oRes.WriteLen();
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return res;
}
BYTE* Page::GetInternalLinks()
{
CData oRes;
oRes.SkipLen();
for (const CPageLink& link : m_vInternalLinks)
{
oRes.AddInt(link.nPage);
std::string s = std::to_string(link.dX);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = std::to_string(link.dY);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = std::to_string(link.dW);
oRes.WriteString((BYTE*)s.c_str(), s.length());
s = std::to_string(link.dH);
oRes.WriteString((BYTE*)s.c_str(), s.length());
}
oRes.WriteLen();
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return res;
}
#endif
void Page::Draw(IRenderer* pRenderer, bool* pbBreak)
{
@ -972,12 +1017,81 @@ namespace XPS
}
else if (L"FixedPage.NavigateUri" == wsAttrName)
{
CPageLink oLink = {0,0,0,0,L"",-1};
std::wstring wsPath = wsPathData.c_stdstr();
size_t nFindX = wsPath.find(L"M ");
if (nFindX != std::wstring::npos)
{
nFindX += 2;
size_t nFindEndX = wsPath.find(L',', nFindX);
if (nFindEndX != std::wstring::npos)
{
oLink.dX = GetDouble(wsPath.substr(nFindX, nFindEndX - nFindX));
size_t nFindY = nFindEndX + 1;
size_t nFindEndY = wsPath.find(L' ', nFindY);
if (nFindEndY != std::wstring::npos)
oLink.dY = GetDouble(wsPath.substr(nFindY, nFindEndY - nFindY));
}
}
double MaybeH = 0;
double MaybeW = 0;
nFindX = wsPath.find(L"L ");
if (nFindX != std::wstring::npos)
{
nFindX += 2;
size_t nFindEndX = wsPath.find(L',', nFindX);
if (nFindEndX != std::wstring::npos)
{
MaybeW = GetDouble(wsPath.substr(nFindX, nFindEndX - nFindX));
size_t nFindY = nFindEndX + 1;
size_t nFindEndY = wsPath.find(L' ', nFindY);
if (nFindEndY != std::wstring::npos)
MaybeH = GetDouble(wsPath.substr(nFindY, nFindEndY - nFindY));
if (MaybeW == oLink.dX)
oLink.dH = MaybeH - oLink.dY;
if (MaybeH == oLink.dY)
oLink.dW = MaybeW - oLink.dX;
}
}
nFindX = wsPath.find(L"L ", nFindX);
if (nFindX != std::wstring::npos)
{
nFindX += 2;
size_t nFindEndX = wsPath.find(L',', nFindX);
if (nFindEndX != std::wstring::npos)
{
double MaybeInH = 0;
double MaybeInW = GetDouble(wsPath.substr(nFindX, nFindEndX - nFindX));
size_t nFindY = nFindEndX + 1;
size_t nFindEndY = wsPath.find(L' ', nFindY);
if (nFindEndY != std::wstring::npos)
MaybeInH = GetDouble(wsPath.substr(nFindY, nFindEndY - nFindY));
if (MaybeInW == MaybeW)
oLink.dH = MaybeInH - oLink.dY;
if (MaybeInH == MaybeH)
oLink.dW = MaybeInW - oLink.dX;
}
}
std::wstring wsNameTarget = oReader.GetText();
if (wsNameTarget.find(L"http") == 0)
{
m_vExternalLinks.push_back({});
oLink.sLink = wsNameTarget;
m_vExternalLinks.push_back(oLink);
}
else
{
size_t nSharp = wsNameTarget.find(L'#');
if (nSharp != std::wstring::npos)
{
oLink.sLink = wsNameTarget.substr(nSharp + 1);
std::map<std::wstring, int>::iterator find = m_pDocument->m_mInternalLinks.find(oLink.sLink);
if (find != m_pDocument->m_mInternalLinks.end())
{
oLink.nPage = find->second;
m_vInternalLinks.push_back(oLink);
}
}
}
}
#endif

View File

@ -55,6 +55,8 @@ namespace XPS
void GetSize(int& nW, int& nH) const;
#ifdef BUILDING_WASM_MODULE
BYTE* GetGlyphs();
BYTE* GetExternalLinks();
BYTE* GetInternalLinks();
class CData
{
protected:
@ -178,14 +180,17 @@ namespace XPS
}
};
CData* m_pGlyphs;
class CPageLink
struct CPageLink
{
double dX;
double dY;
double dW;
double dH;
std::wstring sLink;
int nPage;
};
std::vector<CPageLink> m_vExternalLinks;
std::vector<CPageLink> m_vInternalLinks;
#endif
void Draw(IRenderer* pRenderer, bool* pbBreak);