Refactoring

This commit is contained in:
Oleg Korshul
2022-01-13 20:11:38 +03:00
parent c0c11cf928
commit 28ac386e08
28 changed files with 308 additions and 2095 deletions

View File

@ -120,6 +120,7 @@ const long c_nDocxWriter = 0x0008;
const long c_nVifFormat = 0x0009;
const long c_nGrRenderer = 0x0010;
const long c_nHtmlRendrerer3 = 0x0011;
const long c_nHtmlRendrererText = 0x0012;
// типы команд
const long c_nCommandLongTypeOnlyText = 0x1000;

View File

@ -461,11 +461,13 @@ SOURCES += \
$$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/sel2.cpp \
$$LIB_GRAPHICS_PRI_PATH/raster/JBig2/source/LeptonLib/skew.cpp
HEADERS += \
./../../fontengine/ApplicationFontsWorker.h
# Application fonts worker
HEADERS += ./../../fontengine/ApplicationFontsWorker.h
SOURCES += ./../../fontengine/ApplicationFontsWorker.cpp
SOURCES += \
./../../fontengine/ApplicationFontsWorker.cpp
# drawing file
HEADERS += ./officedrawingfile.h
SOURCES += ./officedrawingfile.cpp
# deprecated!!! remove after 6.5 ------------------
HEADERS += ./../../fontengine/FontsAssistant.h

View File

@ -1,9 +1,10 @@
#ifndef _WASM_SERIALIZE_H
#define _WASM_SERIALIZE_H
#include "../../../../../common/Types.h"
#include <string>
#include <string.h>
#include "../../../../../graphics/IRenderer.h"
#include "../../../../../common/StringExt.h"
#include "../../../../../common/StringUTF32.h"
#include "../../../../../graphics/pro/Fonts.h"
namespace NSWasm
{
@ -381,4 +382,45 @@ namespace NSWasm
};
}
namespace NSWasm
{
struct CPageLinkItem
{
std::string Link;
double Dest;
double X;
double Y;
double W;
double H;
};
class CPageLink
{
public:
std::vector<CPageLinkItem> m_arLinks;
public:
BYTE* Serialize()
{
NSWasm::CData oRes;
oRes.SkipLen();
for (const CPageLinkItem& link : m_arLinks)
{
oRes.WriteString((BYTE*)link.Link.c_str(), link.Link.length());
oRes.AddDouble(link.Dest);
oRes.AddDouble(link.X);
oRes.AddDouble(link.Y);
oRes.AddDouble(link.W);
oRes.AddDouble(link.H);
}
oRes.WriteLen();
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return res;
}
};
}
#endif // _WASM_SERIALIZE_H

View File

@ -0,0 +1,103 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "./officedrawingfile.h"
#include "./Graphics.h"
CBgraFrame* GetFrame(IOfficeDrawingFile* pFile, int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip, bool bIsSwapRGB)
{
NSFonts::IApplicationFonts* pApplicationFonts = pFile->GetFonts();
if (!pApplicationFonts)
return NULL;
NSFonts::IFontManager *pFontManager = pApplicationFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(pApplicationFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dPageDpiX, dPageDpiY;
double dWidth, dHeight;
pFile->GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 96 / dPageDpiX);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 96 / dPageDpiY);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return NULL;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame* pFrame = new CBgraFrame();
pFrame->put_Data(pBgraData);
pFrame->put_Width(nWidth);
pFrame->put_Height(nHeight);
pFrame->put_Stride((bIsFlip ? 4 : -4) * nWidth);
pRenderer->CreateFromBgraFrame(pFrame);
pRenderer->SetSwapRGB(bIsSwapRGB);
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
pFile->DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
return pFrame;
}
unsigned char* IOfficeDrawingFile::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip)
{
CBgraFrame* pFrame = GetFrame(this, nPageIndex, nRasterW, nRasterH, bIsFlip, true);
if (!pFrame)
return NULL;
unsigned char* pData = pFrame->get_Data();
pFrame->ClearNoAttack();
RELEASEOBJECT(pFrame);
return pData;
}
void IOfficeDrawingFile::ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW, const int nRasterH, bool bIsFlip)
{
CBgraFrame* pFrame = GetFrame(this, nPageIndex, nRasterW, nRasterH, bIsFlip, false);
if (!pFrame)
return;
pFrame->SaveFile(path, nImageType);
RELEASEOBJECT(pFrame);
}

View File

@ -32,7 +32,7 @@
#ifndef _OFFICE_DRAWING_FILE_H
#define _OFFICE_DRAWING_FILE_H
#include <string>
#include "./Fonts.h"
class IRenderer;
enum OfficeDrawingFileType
@ -43,32 +43,43 @@ enum OfficeDrawingFileType
odftUndefined = 255
};
class IOfficeDrawingFile
class GRAPHICS_DECL IOfficeDrawingFile
{
public:
virtual ~IOfficeDrawingFile() {}
// Open
virtual bool LoadFromFile(const std::wstring& file, const std::wstring& options = L"",
const std::wstring& owner_password = L"", const std::wstring& user_password = L"") = 0;
virtual bool LoadFromMemory(unsigned char* data, unsigned long length, const std::wstring& options = L"",
const std::wstring& owner_password = L"", const std::wstring& user_password = L"") = 0;
// Close
virtual void Close() = 0;
// Get IApplicationFonts for wrappers
virtual NSFonts::IApplicationFonts* GetFonts() = 0;
// Type
virtual OfficeDrawingFileType GetType() = 0;
// Temp directory
virtual std::wstring GetTempDirectory() = 0;
virtual void SetTempDirectory(const std::wstring& directory) = 0;
// Pages info/draw
virtual int GetPagesCount() = 0;
virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) = 0;
virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) = 0;
virtual unsigned char* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip = false) = 0;
virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1) = 0;
// Common methods/wrappers on GetPageInfo + DrawPageOnRenderer
virtual unsigned char* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip = false);
virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1, bool bIsFlip = false);
// Common methods for viewer
#ifdef BUILDING_WASM_MODULE
virtual unsigned char* GetStructure() = 0;
virtual unsigned char* GetGlyphs(int nPageIndex) = 0;
virtual unsigned char* GetLinks (int nPageIndex) = 0;
virtual unsigned char* GetLinks(int nPageIndex) = 0;
#endif
};

View File

@ -67,6 +67,10 @@ OfficeDrawingFileType CDjVuFile::GetType()
{
return odftDJVU;
}
NSFonts::IApplicationFonts* CDjVuFile::GetFonts()
{
return m_pImplementation->GetFonts();
}
std::wstring CDjVuFile::GetTempDirectory()
{
@ -94,17 +98,6 @@ void CDjVuFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* p
if (m_pImplementation)
m_pImplementation->DrawPageOnRenderer(pRenderer, nPageIndex, pBreak);
}
BYTE* CDjVuFile::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip)
{
if (m_pImplementation)
return m_pImplementation->ConvertToPixels(nPageIndex, nRasterW, nRasterH, bIsFlip);
return NULL;
}
void CDjVuFile::ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int nRasterW, const int nRasterH)
{
if (m_pImplementation)
m_pImplementation->ConvertToRaster(nPageIndex, wsDstPath, nImageType, nRasterW, nRasterH);
}
void CDjVuFile::ConvertToPdf(const std::wstring& wsDstPath)
{
if (m_pImplementation)

View File

@ -38,7 +38,7 @@
#define DJVU_DECL_EXPORT Q_DECL_EXPORT
#endif
#include "../DesktopEditor/common/officedrawingfile.h"
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../DesktopEditor/graphics/pro/Fonts.h"
// работаем через класс CDjVuFileImplementation, чтобы когда цеплялся данный h-файл, ничего лишнего не инклюдилось
@ -60,6 +60,7 @@ public:
const std::wstring& owner_password = L"", const std::wstring& user_password = L"");
virtual void Close();
virtual NSFonts::IApplicationFonts* GetFonts() = 0;
virtual OfficeDrawingFileType GetType();
@ -69,10 +70,9 @@ public:
virtual int GetPagesCount();
virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY);
virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak);
virtual BYTE* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip = false);
virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1);
void ConvertToPdf(const std::wstring& path);
#ifdef BUILDING_WASM_MODULE
virtual BYTE* GetStructure();
virtual BYTE* GetGlyphs(int nPageIndex);

View File

@ -100,7 +100,7 @@ SOURCES += DjVu.cpp \
libdjvu/XMLTags.cpp \
libdjvu/ZPCodec.cpp
HEADERS += DjVu.h \
HEADERS += DjVu.h \
DjVuFileImplementation.h \
libdjvu/Arrays.h \
libdjvu/atomic.h \
@ -152,3 +152,5 @@ HEADERS += DjVu.h \
libdjvu/XMLParser.h \
libdjvu/XMLTags.h \
libdjvu/ZPCodec.h
#DEFINES += BUILDING_WASM_MODULE

View File

@ -46,7 +46,9 @@
#define HOR_DPI 96
#include <vector>
#ifdef BUILDING_WASM_MODULE
#define DISABLE_TEMP_DIRECTORY
#include "../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
#endif
@ -63,7 +65,7 @@ namespace NSDjvu
std::string sString(strText.getbuf());
return sString;
}
static int GetInteger(const std::wstring& wsString)
static int GetInteger(const std::wstring& wsString)
{
if (wsString.size() < 1)
return 0;
@ -90,21 +92,22 @@ namespace NSDjvu
CDjVuFileImplementation::CDjVuFileImplementation(NSFonts::IApplicationFonts* pFonts)
{
m_pDoc = NULL;
#ifndef BUILDING_WASM_MODULE
std::wstring wsTempPath = NSFile::CFileBinary::GetTempPath();
wsTempPath += L"DJVU\\";
m_wsTempDirectory = wsTempPath;
NSDirectory::CreateDirectory(m_wsTempDirectory);
#endif
m_wsTempDirectory = L"";
SetTempDirectory(L"");
m_pApplicationFonts = pFonts;
}
CDjVuFileImplementation::~CDjVuFileImplementation()
{
#ifndef BUILDING_WASM_MODULE
#ifndef DISABLE_TEMP_DIRECTORY
NSDirectory::DeleteDirectory(m_wsTempDirectory);
#endif
}
bool CDjVuFileImplementation::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXMLOptions)
NSFonts::IApplicationFonts* CDjVuFileImplementation::GetFonts()
{
return m_pApplicationFonts;
}
bool CDjVuFileImplementation::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXMLOptions)
{
m_pDoc = NULL;
try
@ -121,7 +124,7 @@ bool CDjVuFileImplementation::LoadFromFile(const std::wstring& wsS
return true;
}
bool CDjVuFileImplementation::LoadFromMemory(BYTE* data, DWORD length, const std::wstring& wsXmlOptions)
bool CDjVuFileImplementation::LoadFromMemory(BYTE* data, DWORD length, const std::wstring& wsXmlOptions)
{
m_pDoc = NULL;
try
@ -137,29 +140,36 @@ bool CDjVuFileImplementation::LoadFromMemory(BYTE* data, DWORD len
return true;
}
void CDjVuFileImplementation::Close()
void CDjVuFileImplementation::Close()
{
}
std::wstring CDjVuFileImplementation::GetTempDirectory() const
std::wstring CDjVuFileImplementation::GetTempDirectory() const
{
return m_wsTempDirectory;
}
void CDjVuFileImplementation::SetTempDirectory(const std::wstring& wsDirectory)
void CDjVuFileImplementation::SetTempDirectory(const std::wstring& wsDirectory)
{
NSDirectory::DeleteDirectory(m_wsTempDirectory);
#ifndef DISABLE_TEMP_DIRECTORY
if (!m_wsTempDirectory.empty())
NSDirectory::DeleteDirectory(m_wsTempDirectory);
m_wsTempDirectory = wsDirectory;
m_wsTempDirectory += L"\\DJVU\\";
m_wsTempDirectory = wsDirectory;
if (m_wsTempDirectory.empty())
m_wsTempDirectory = NSFile::CFileBinary::GetTempPath();
m_wsTempDirectory += L"/DJVU/";
NSDirectory::CreateDirectory(m_wsTempDirectory);
#endif
}
int CDjVuFileImplementation::GetPagesCount() const
int CDjVuFileImplementation::GetPagesCount() const
{
if (!m_pDoc)
return 0;
return m_pDoc->get_pages_num();
}
void CDjVuFileImplementation::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const
void CDjVuFileImplementation::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const
{
if (!m_pDoc)
{
@ -191,7 +201,7 @@ void CDjVuFileImplementation::GetPageInfo(int nPageIndex, double*
*pdDpiX = nDpi;
*pdDpiY = nDpi;
}
void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak)
void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak)
{
if (!m_pDoc)
return;
@ -204,19 +214,16 @@ void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRende
long lRendererType = c_nUnknownRenderer;
pRenderer->get_Type(&lRendererType);
if (false)//c_nGrRenderer == lRendererType)
{
CreateGrFrame(pRenderer, pPage, pBreak);
}
#ifndef BUILDING_WASM_MODULE
else if (c_nPDFWriter == lRendererType)
#ifndef BUILDING_WASM_MODULE
if (c_nPDFWriter == lRendererType)
{
XmlUtils::CXmlNode oText = ParseText(pPage);
CreatePdfFrame(pRenderer, pPage, nPageIndex, oText);
}
#endif
else
{
else
#endif
{
XmlUtils::CXmlNode oText = ParseText(pPage);
CreateFrame(pRenderer, pPage, nPageIndex, oText);
}
@ -226,95 +233,7 @@ void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRende
// белая страница
}
}
BYTE* CDjVuFileImplementation::ConvertToPixels(int nPageIndex, const int& nRasterW, const int& nRasterH, bool bIsFlip)
{
if (!m_pApplicationFonts)
return NULL;
NSFonts::IFontManager *pFontManager = m_pApplicationFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pApplicationFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dPageDpiX;
double dWidth, dHeight;
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiX);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 96 / dPageDpiX);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 96 / dPageDpiX);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return NULL;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride((bIsFlip ? 4 : -4) * nWidth);
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetSwapRGB(true);
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
oFrame.ClearNoAttack();
return pBgraData;
}
void CDjVuFileImplementation::ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int& nRasterW, const int& nRasterH)
{
if (!m_pApplicationFonts)
return;
NSFonts::IFontManager *pFontManager = m_pApplicationFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pApplicationFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dPageDpiX, dPageDpiY;
double dWidth, dHeight;
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiX);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 96 / dPageDpiX);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 96 / dPageDpiX);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(-4 * nWidth);
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetSwapRGB(false);
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
oFrame.SaveFile(wsDstPath, nImageType);
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
}
void CDjVuFileImplementation::ConvertToPdf(const std::wstring& wsDstPath)
void CDjVuFileImplementation::ConvertToPdf(const std::wstring& wsDstPath)
{
CPdfRenderer oPdf(m_pApplicationFonts);
@ -332,13 +251,14 @@ void CDjVuFileImplementation::ConvertToPdf(const std::wstring& wsD
oPdf.put_Height(dHeight);
DrawPageOnRenderer(&oPdf, nPageIndex, &bBreak);
//#ifdef _DEBUG
#ifdef _DEBUG
printf("%d of %d pages\n", nPageIndex + 1, nPagesCount);
//#endif
#endif
}
oPdf.SaveToFile(wsDstPath);
}
#ifdef BUILDING_WASM_MODULE
void getBookmars(const GP<DjVmNav>& nav, int& pos, int count, NSWasm::CData& out, int level)
{
@ -363,7 +283,7 @@ void getBookmars(const GP<DjVmNav>& nav, int& pos, int count, NSWasm::CData& out
count--;
}
}
BYTE* CDjVuFileImplementation::GetStructure()
BYTE* CDjVuFileImplementation::GetStructure()
{
GP<DjVmNav> nav = m_pDoc->get_djvm_nav();
if (!nav)
@ -382,7 +302,7 @@ BYTE* CDjVuFileImplementation::GetStructure()
oRes.ClearWithoutAttack();
return bRes;
}
BYTE* CDjVuFileImplementation::GetPageGlyphs(int nPageIndex)
BYTE* CDjVuFileImplementation::GetPageGlyphs(int nPageIndex)
{
return NULL;
try
@ -445,7 +365,7 @@ BYTE* CDjVuFileImplementation::GetPageGlyphs(int nPageIndex)
catch (...) {}
return NULL;
}
BYTE* CDjVuFileImplementation::GetPageLinks (int nPageIndex)
BYTE* CDjVuFileImplementation::GetPageLinks(int nPageIndex)
{
double dPageDpiX, dPageDpiY;
double dWidth, dHeight;
@ -485,7 +405,8 @@ BYTE* CDjVuFileImplementation::GetPageLinks (int nPageIndex)
return NULL;
}
#endif
void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
{
int nWidth = pPage->get_real_width();
int nHeight = pPage->get_real_height();
@ -688,7 +609,7 @@ void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP
pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dRendWidth, dRendHeight);
pRenderer->EndCommand(c_nPageType);
}
void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPageIndex, XmlUtils::CXmlNode& oText)
void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPageIndex, XmlUtils::CXmlNode& oText)
{
double dPageDpiX, dPageDpiY;
double dWidth, dHeight;
@ -940,166 +861,7 @@ void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer,
pRenderer->EndCommand(c_nPageType);
}
void CDjVuFileImplementation::CreateGrFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, bool* pBreak)
{
int nWidth = pPage->get_real_width();
int nHeight = pPage->get_real_height();
BYTE* pBufferDst = NULL;
LONG lImageWidth = 0;
LONG lImageHeight = 0;
// TODO: Реализовать для графического рендерера
//VARIANT var;
//renderer->GetAdditionalParam(L"Pixels", &var);
//pBufferDst = (BYTE*)var.lVal;
//renderer->GetAdditionalParam(L"PixelsWidth", &var);
//lImageWidth = var.lVal;
//renderer->GetAdditionalParam(L"PixelsHeight", &var);
//lImageHeight = var.lVal;
volatile bool* pCancel = pBreak;
if ((NULL != pCancel) && (TRUE == *pCancel))
return;
if (pPage->is_legal_photo() || pPage->is_legal_compound())
{
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
BYTE* pBuffer = pBufferDst;
for (int j = 0; j < lImageHeight; ++j)
{
GPixel* pLine = pImage->operator [](j);
if ((NULL != pCancel) && (TRUE == *pCancel))
return;
for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine)
{
pBuffer[0] = pLine->b;
pBuffer[1] = pLine->g;
pBuffer[2] = pLine->r;
pBuffer[3] = 255;
}
}
}
else if (pPage->is_legal_bilevel())
{
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
int nPaletteEntries = pBitmap->get_grays();
unsigned int* palette = new unsigned int[nPaletteEntries];
// Create palette for the bitmap
int color = 0xff0000;
int decrement = color / (nPaletteEntries - 1);
for (int i = 0; i < nPaletteEntries; ++i)
{
BYTE level = (BYTE)(color >> 16);
palette[i] = (0xFF000000 | level << 16 | level << 8 | level);
color -= decrement;
}
unsigned int* pBuffer = (unsigned int*)pBufferDst;
for (int j = 0; j < lImageHeight; ++j)
{
BYTE* pLine = pBitmap->operator [](j);
if ((NULL != pCancel) && (TRUE == *pCancel))
return;
for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine)
{
if (*pLine < nPaletteEntries)
{
*pBuffer = palette[*pLine];
}
else
{
*pBuffer = palette[0];
}
}
}
RELEASEARRAYOBJECTS(palette);
}
else
{
// белый фрейм??
//memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight);
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
if (NULL != pImage)
{
BYTE* pBuffer = pBufferDst;
for (int j = 0; j < lImageHeight; ++j)
{
GPixel* pLine = pImage->operator [](j);
if ((NULL != pCancel) && (TRUE == *pCancel))
return;
for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine)
{
pBuffer[0] = pLine->b;
pBuffer[1] = pLine->g;
pBuffer[2] = pLine->r;
pBuffer[3] = 255;
}
}
return;
}
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
if (NULL != pBitmap)
{
int nPaletteEntries = pBitmap->get_grays();
unsigned int* palette = new unsigned int[nPaletteEntries];
// Create palette for the bitmap
int color = 0xff0000;
int decrement = color / (nPaletteEntries - 1);
for (int i = 0; i < nPaletteEntries; ++i)
{
BYTE level = (BYTE)(color >> 16);
palette[i] = (0xFF000000 | level << 16 | level << 8 | level);
color -= decrement;
}
unsigned int* pBuffer = (unsigned int*)pBufferDst;
for (int j = 0; j < lImageHeight; ++j)
{
BYTE* pLine = pBitmap->operator [](j);
if ((NULL != pCancel) && (TRUE == *pCancel))
return;
for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine)
{
if (*pLine < nPaletteEntries)
{
*pBuffer = palette[*pLine];
}
else
{
*pBuffer = palette[0];
}
}
}
RELEASEARRAYOBJECTS(palette);
}
}
}
XmlUtils::CXmlNode CDjVuFileImplementation::ParseText(GP<DjVuImage> pPage)
{
XmlUtils::CXmlNode paragraph;
@ -1119,7 +881,7 @@ XmlUtils::CXmlNode CDjVuFileImplementation::ParseText(GP<DjVuImage> pPage)
}
return paragraph;
}
void CDjVuFileImplementation::TextToRenderer(IRenderer* pRenderer, XmlUtils::CXmlNode oTextNode, double dKoef, bool isView)
void CDjVuFileImplementation::TextToRenderer(IRenderer* pRenderer, XmlUtils::CXmlNode oTextNode, double dKoef, bool isView)
{
// Выставим шрифт пустой (чтобы растягивать по всему ректу)
pRenderer->put_FontName(L"DjvuEmptyFont");
@ -1144,7 +906,7 @@ void CDjVuFileImplementation::TextToRenderer(IRenderer* pRenderer,
}
}
}
void CDjVuFileImplementation::DrawPageText(IRenderer* pRenderer, double* pdCoords, const std::wstring& wsText)
void CDjVuFileImplementation::DrawPageText(IRenderer* pRenderer, double* pdCoords, const std::wstring& wsText)
{
pRenderer->put_FontSize(pdCoords[1] - pdCoords[3]);
pRenderer->CommandDrawText(wsText,
@ -1153,7 +915,7 @@ void CDjVuFileImplementation::DrawPageText(IRenderer* pRenderer, d
(float)(pdCoords[2] - pdCoords[0]),
(float)(pdCoords[1] - pdCoords[3]));
}
void CDjVuFileImplementation::ParseCoords(const std::wstring& wsCoordsStr, double* pdCoords, double dKoef)
void CDjVuFileImplementation::ParseCoords(const std::wstring& wsCoordsStr, double* pdCoords, double dKoef)
{
std::vector<std::wstring> vCoords = NSStringExt::Split(wsCoordsStr, L',');
if (vCoords.size() >= 4)

View File

@ -47,22 +47,18 @@
#define ZIP_BEST_COMPRESSION 9
#define ZIP_DEFAULT_COMPRESSION (-1)
#define UNICODE
#define _UNICODE
#define _USE_LIBXML2_READER_
#define LIBXML_READER_ENABLED
#include "../DesktopEditor/xml/include/xmlutils.h"
#include "../DesktopEditor/graphics/IRenderer.h"
#include "../DesktopEditor/graphics/pro/Fonts.h"
#ifdef BUILDING_WASM_MODULE
#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
#include "../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
#endif
class CDjVuFileImplementation
{
private:
std::wstring m_wsTempDirectory;
std::wstring m_wsTempDirectory;
GP<DjVuDocument> m_pDoc;
NSFonts::IApplicationFonts* m_pApplicationFonts;
@ -70,6 +66,7 @@ public:
CDjVuFileImplementation(NSFonts::IApplicationFonts* pFonts);
~CDjVuFileImplementation();
NSFonts::IApplicationFonts* GetFonts();
bool LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXmlOptions = L"");
bool LoadFromMemory(BYTE* data, DWORD length, const std::wstring& wsXmlOptions = L"");
@ -79,9 +76,8 @@ public:
int GetPagesCount() const;
void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const;
void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak);
BYTE* ConvertToPixels(int nPageIndex, const int& nRasterW = -1, const int& nRasterH = -1, bool bIsFlip = false);
void ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int& nRasterW = -1, const int& nRasterH = -1);
void ConvertToPdf(const std::wstring& wsDstPath);
#ifdef BUILDING_WASM_MODULE
BYTE* GetStructure();
BYTE* GetPageGlyphs(int nPageIndex);
@ -91,8 +87,7 @@ public:
private:
void CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);
void CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);
void CreateGrFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, bool* pBreak);
void CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);
XmlUtils::CXmlNode ParseText(GP<DjVuImage> pPage);
void TextToRenderer(IRenderer* pRenderer, XmlUtils::CXmlNode text, double koef, bool isView = true);
void DrawPageText(IRenderer* pRenderer, double* pdCoords, const std::wstring& wsText);

View File

@ -25,10 +25,10 @@ LIBS += -lgdi32 \
-lshell32
}
SOURCES += \
SOURCES += \
src/HTMLRenderer3.cpp
HEADERS += \
HEADERS += \
src/CanvasWriter.h \
src/Common.h \
src/Document.h \
@ -42,4 +42,8 @@ HEADERS += \
src/VMLWriter.h \
src/Writer.h \
include/HTMLRenderer3.h \
src/Common2.h
src/Common2.h \
src/Meta.h
#HEADERS += $$PWD/include/HTMLRendererText.h
#SOURCES += $$PWD/src/HTMLRendererText.cpp

View File

@ -33,7 +33,7 @@
#define _ASC_HTMLRENDERER3_H_
#include "../../DesktopEditor/graphics/IRenderer.h"
#include "../../DesktopEditor/common/officedrawingfile.h"
#include "../../DesktopEditor/graphics/pro/officedrawingfile.h"
#ifndef HTMLRENDERER_USE_DYNAMIC_LIBRARY
#define HTMLRENDERER_DECL_EXPORT

View File

@ -249,12 +249,7 @@ namespace NSHtmlRenderer
LONG top;
LONG right;
LONG bottom;
};
inline bool IsEqualMain(const Aggplus::CMatrix* pMatrix, const Aggplus::CMatrix* pMatrix2)
{
return Aggplus::CMatrix::IsEqual(pMatrix, pMatrix2, 0.001, true);
}
};
const double c_ag_Inch_to_MM = 25.4;
const double c_ag_1pxWidth = 25.4 / 96;

View File

@ -33,6 +33,7 @@
#define _ASC_HTMLRENDERER_COMMON2_H_
#include "Common.h"
#include "Meta.h"
#include "../../DesktopEditor/raster/BgraFrame.h"
#include "../../DesktopEditor/xml/include/xmlutils.h"
@ -230,471 +231,4 @@ namespace NSHtmlRenderer
}
}
namespace NSHtmlRenderer
{
class CMetafile
{
public:
enum CommandType
{
// pen
ctPenXML = 0,
ctPenColor = 1,
ctPenAlpha = 2,
ctPenSize = 3,
ctPenDashStyle = 4,
ctPenLineStartCap = 5,
ctPenLineEndCap = 6,
ctPenLineJoin = 7,
ctPenDashPatern = 8,
ctPenDashPatternCount = 9,
ctPenDashOffset = 10,
ctPenAlign = 11,
ctPenMiterLimit = 12,
// brush
ctBrushXML = 20,
ctBrushType = 21,
ctBrushColor1 = 22,
ctBrushColor2 = 23,
ctBrushAlpha1 = 24,
ctBrushAlpha2 = 25,
ctBrushTexturePath = 26,
ctBrushTextureAlpha = 27,
ctBrushTextureMode = 28,
ctBrushRectable = 29,
ctBrushAngle = 30,
ctBrushSubColors = 31,
// font
ctFontXML = 40,
ctFontName = 41,
ctFontSize = 42,
ctFontStyle = 43,
ctFontPath = 44,
ctFontGID = 45,
ctFontCharSpace = 46,
// shadow
ctShadowXML = 50,
ctShadowVisible = 51,
ctShadowDistanceX = 52,
ctShadowDistanceY = 53,
ctShadowBlurSize = 54,
ctShadowColor = 55,
ctShadowAlpha = 56,
// edge
ctEdgeXML = 70,
ctEdgeVisible = 71,
ctEdgeDistance = 72,
ctEdgeColor = 73,
ctEdgeAlpha = 74,
// text
ctDrawText = 80,
ctDrawTextEx = 81,
// pathcommands
ctPathCommandMoveTo = 91,
ctPathCommandLineTo = 92,
ctPathCommandLinesTo = 93,
ctPathCommandCurveTo = 94,
ctPathCommandCurvesTo = 95,
ctPathCommandArcTo = 96,
ctPathCommandClose = 97,
ctPathCommandEnd = 98,
ctDrawPath = 99,
ctPathCommandStart = 100,
ctPathCommandGetCurrentPoint = 101,
ctPathCommandText = 102,
ctPathCommandTextEx = 103,
// image
ctDrawImage = 110,
ctDrawImageFromFile = 111,
ctSetParams = 120,
ctBeginCommand = 121,
ctEndCommand = 122,
ctSetTransform = 130,
ctResetTransform = 131,
ctClipMode = 140,
ctCommandLong1 = 150,
ctCommandDouble1 = 151,
ctCommandString1 = 152,
ctCommandLong2 = 153,
ctCommandDouble2 = 154,
ctCommandString2 = 155,
ctCommandTextLine = 160,
ctCommandTextTransform = 161,
ctCommandTextLineEnd = 162,
ctCommandTextClipRectReset = 163,
ctCommandTextClipRect = 164,
ctError = 255
};
private:
// сам метафайл
BYTE* m_pBuffer;
BYTE* m_pBufferMem;
size_t m_lPosition;
size_t m_lSize;
LONG m_lSizeofDouble;
LONG m_lSizeofFloat;
LONG m_lSizeofLONG;
LONG m_lSizeofBYTE;
public:
double m_fWidth;
double m_fHeight;
public:
CMetafile()
{
Clear();
m_lSizeofDouble = sizeof(double);
m_lSizeofFloat = sizeof(float);
m_lSizeofLONG = sizeof(int);
m_lSizeofBYTE = sizeof(BYTE);
}
~CMetafile()
{
RELEASEARRAYOBJECTS(m_pBuffer);
}
public:
inline LONG GetPosition()
{
return (LONG)m_lPosition;
}
inline BYTE* GetData()
{
return m_pBuffer;
}
inline void ClearNoAttack()
{
m_lPosition = 0;
m_pBufferMem = m_pBuffer;
}
inline void Clear()
{
m_lSize = 0;
m_lPosition = 0;
m_pBuffer = NULL;
m_pBufferMem = NULL;
}
inline void Seek(LONG lPos)
{
m_lPosition = (size_t)lPos;
m_pBufferMem = m_pBuffer + m_lPosition;
}
inline void CheckBufferSize(size_t lPlus)
{
if (NULL != m_pBuffer)
{
size_t nNewSize = m_lPosition + lPlus;
if (nNewSize >= m_lSize)
{
while (nNewSize >= m_lSize)
{
m_lSize *= 2;
}
BYTE* pNew = new BYTE[m_lSize];
memcpy(pNew, m_pBuffer, m_lPosition);
RELEASEARRAYOBJECTS(m_pBuffer);
m_pBuffer = pNew;
}
}
else
{
m_lSize = 1000;
m_pBuffer = new BYTE[m_lSize];
CheckBufferSize(lPlus);
}
}
inline void WriteCommandType(const CommandType& eType)
{
CheckBufferSize(m_lSizeofBYTE);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
}
//
inline void WriteBYTE_nocheck(const BYTE& lValue)
{
*(m_pBuffer + m_lPosition) = lValue;
m_lPosition += m_lSizeofBYTE;
}
inline void WriteLONG_nocheck(const int& lValue)
{
*((int*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += m_lSizeofLONG;
}
inline void WriteUSHORT_nocheck(const USHORT& lValue)
{
*((USHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(USHORT);
}
inline void WriteWCHAR_nocheck(const WCHAR& lValue)
{
*((WCHAR*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(WCHAR);
}
inline void WriteWCHAR_nocheck2(const int& lValue)
{
if (lValue < 0x10000)
{
*((USHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += 2;
}
else
{
int code = lValue - 0x10000;
*((USHORT*)(m_pBuffer + m_lPosition)) = 0xD800 | ((code >> 10) & 0x03FF);
*((USHORT*)(m_pBuffer + m_lPosition + 2)) = 0xDC00 | (code & 0x03FF);
m_lPosition += 4;
}
}
inline void WriteDouble_nocheck(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
LONG lValue = (LONG)(dValue * 10000);
WriteLONG_nocheck(lValue);
return;
CheckBufferSize(m_lSizeofDouble);
*((double*)(m_pBuffer + m_lPosition)) = dValue;
m_lPosition += m_lSizeofDouble;
}
inline void WriteDouble2_nocheck(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
SHORT lValue = (SHORT)(dValue * 100);
*((SHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(SHORT);
}
//
inline void WriteBYTE(const BYTE& lValue)
{
CheckBufferSize(m_lSizeofBYTE);
*(m_pBuffer + m_lPosition) = lValue;
m_lPosition += m_lSizeofBYTE;
}
inline void WriteLONG(const int& lValue)
{
CheckBufferSize(m_lSizeofLONG);
*((int*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += m_lSizeofLONG;
}
inline void WriteUSHORT(const USHORT& lValue)
{
CheckBufferSize(sizeof(USHORT));
*((USHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(USHORT);
}
inline void WriteWCHAR(const WCHAR& lValue)
{
CheckBufferSize(sizeof(WCHAR));
*((WCHAR*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(WCHAR);
}
inline void WriteDouble(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
int lValue = (int)(dValue * 10000);
WriteLONG(lValue);
return;
CheckBufferSize(m_lSizeofDouble);
*((double*)(m_pBuffer + m_lPosition)) = dValue;
m_lPosition += m_lSizeofDouble;
}
inline void WriteDouble2(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
SHORT lValue = (SHORT)(dValue * 100);
CheckBufferSize(sizeof(SHORT));
*((SHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(SHORT);
}
inline void WriteFloat(const float& fValue)
{
CheckBufferSize(m_lSizeofFloat);
*((float*)(m_pBuffer + m_lPosition)) = fValue;
m_lPosition += m_lSizeofFloat;
}
inline void WriteString(wchar_t* bstrValue)
{
int lSize = (int)wcslen(bstrValue) + 1;
int lSizeMem = lSize * sizeof(wchar_t);
CheckBufferSize(m_lSizeofLONG + lSizeMem);
*((int*)(m_pBuffer + m_lPosition)) = lSizeMem;
m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem);
m_lPosition += lSizeMem;
}
inline void WriteBYTE(const CommandType& eType, const BYTE& lValue)
{
CheckBufferSize(2 * m_lSizeofBYTE);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*(m_pBuffer + m_lPosition) = lValue;
m_lPosition += m_lSizeofBYTE;
}
inline void WriteLONG(const CommandType& eType, const int& lValue)
{
CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += m_lSizeofLONG;
}
inline void WriteDouble(const CommandType& eType, const double& dValue)
{
CheckBufferSize(m_lSizeofBYTE + m_lSizeofDouble);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((double*)(m_pBuffer + m_lPosition)) = dValue;
m_lPosition += m_lSizeofDouble;
}
inline void WriteFloat(const CommandType& eType, const float& fValue)
{
CheckBufferSize(m_lSizeofBYTE + m_lSizeofFloat);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((float*)(m_pBuffer + m_lPosition)) = fValue;
m_lPosition += m_lSizeofFloat;
}
inline void WriteString(const CommandType& eType, wchar_t* bstrValue)
{
int lSize = (int)wcslen(bstrValue) + 1;
int lSizeMem = lSize * sizeof(wchar_t);
CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG + lSizeMem);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lSizeMem;
m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem);
m_lPosition += lSizeMem;
}
inline void Write(const BYTE* pData, const LONG& lLen)
{
CheckBufferSize((size_t)lLen);
memcpy(m_pBuffer + m_lPosition, pData, lLen);
m_lPosition += lLen;
}
inline void Write(const CommandType& eCommand, const double& f1, const double& f2)
{
size_t lMem = m_lSizeofBYTE + 2 * m_lSizeofDouble;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((double*)(m_pBuffer + m_lPosition))= f1; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f2; m_lPosition += m_lSizeofDouble;
}
inline void Write(const CommandType& eCommand, const double& f1, const double& f2, const double& f3, const double& f4, const double& f5, const double& f6)
{
size_t lMem = m_lSizeofBYTE + 6 * m_lSizeofDouble;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((double*)(m_pBuffer + m_lPosition))= f1; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f2; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f3; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f4; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f5; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f6; m_lPosition += m_lSizeofDouble;
}
inline void Write(const CommandType& eCommand, const int& lCount, float* pData)
{
size_t lFloats = lCount * m_lSizeofFloat;
size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, pData, lFloats);
m_lPosition += lFloats;
}
inline void Write(const CommandType& eCommand, const int& lCount, double* pData)
{
size_t lFloats = lCount * m_lSizeofDouble;
size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, pData, lFloats);
m_lPosition += lFloats;
}
inline void Write(CMetafile& oMeta)
{
LONG lPos = oMeta.GetPosition();
CheckBufferSize(lPos);
memcpy(m_pBuffer + m_lPosition, oMeta.GetData(), lPos);
m_lPosition += lPos;
}
};
}
#endif // _ASC_HTMLRENDERER_COMMON2_H_

View File

@ -32,7 +32,14 @@
#ifndef _ASC_HTMLRENDERER_FMBASE_H_
#define _ASC_HTMLRENDERER_FMBASE_H_
#include "Common.h"
#include "../../DesktopEditor/common/Types.h"
#include "../../DesktopEditor/graphics/Matrix.h"
#include "../../DesktopEditor/graphics/structures.h"
#include "../../DesktopEditor/common/StringBuilder.h"
#include "../../DesktopEditor/graphics/IRenderer.h"
#include "../../DesktopEditor/graphics/pro/Fonts.h"
#include "../../DesktopEditor/xml/include/xmlutils.h"
#include <vector>
#include <map>
#include <list>

View File

@ -34,6 +34,7 @@
#include "FontManager.h"
#include "../../Common/OfficeFileFormats.h"
#include "Meta.h"
#ifdef min
#undef min
@ -338,7 +339,7 @@ namespace NSHtmlRenderer
public:
inline void LoadCurrentFont(bool bIsAttack, int lFaceIndex = 0)
{
if (L"" == m_pFont->Path)
if (m_pFont->Path.empty())
{
std::wstring sFind = m_pFont->Name + L"__ASC_FONT__" + std::to_wstring(m_pFont->GetStyle());
@ -466,7 +467,6 @@ namespace NSHtmlRenderer
NSStructures::CFont* m_pFont;
NSStructures::CBrush* m_pLastBrush;
NSStructures::CFont* m_pLastFont;
Aggplus::CMatrix* m_pTransform;
Aggplus::CMatrix* m_pLastTransform;
@ -505,7 +505,6 @@ namespace NSHtmlRenderer
m_pFont = writer->m_pFont;
m_pLastBrush = &writer->m_oLastBrush;
m_pLastFont = &writer->m_oLastFont;
m_pTransform = writer->m_pTransform;
m_pLastTransform = &writer->m_oLastTransform;

View File

@ -1222,7 +1222,6 @@ namespace NSHtmlRenderer
NSStructures::CPen m_oLastPen;
NSStructures::CBrush m_oLastBrush;
NSStructures::CFont m_oLastFont;
int m_lCurrentFont;
double m_dCurrentFontSize;
@ -1545,7 +1544,6 @@ namespace NSHtmlRenderer
m_oLastBrush.Color1 = -1;
m_oLastPen.Color = -1;
m_oLastFont.Name = L"";
m_lCurrentFont = -1;
m_dCurrentFontSize = 0.0;

View File

@ -97,8 +97,6 @@ namespace PdfReader
((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager);
#ifndef BUILDING_WASM_MODULE
globalParams->setupBaseFonts(NULL);
#else
m_pGlyphs = {-1, NULL};
#endif
m_eError = errNone;
@ -122,9 +120,6 @@ namespace PdfReader
RELEASEOBJECT((m_pInternal->m_pPDFDocument));
RELEASEOBJECT((globalParams));
RELEASEINTERFACE((m_pInternal->m_pFontManager));
#ifdef BUILDING_WASM_MODULE
RELEASEARRAYOBJECTS(m_pGlyphs.second);
#endif
}
bool CPdfReader::LoadFromFile(const std::wstring& wsSrcPath, const std::wstring& wsOptions,
const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword)
@ -220,6 +215,11 @@ namespace PdfReader
{
RELEASEOBJECT((m_pInternal->m_pPDFDocument));
}
NSFonts::IApplicationFonts* CPdfReader::GetFonts()
{
return m_pInternal->m_pAppFonts;
}
OfficeDrawingFileType CPdfReader::GetType()
{
return odftPDF;
@ -348,127 +348,11 @@ namespace PdfReader
if (m_pInternal->m_pPDFDocument && pRenderer)
{
RendererOutputDev oRendererOut(pRenderer, m_pInternal->m_pFontManager, m_pInternal->m_pFontList);
#ifdef BUILDING_WASM_MODULE
//oRendererOut.m_pPageMeta.SkipLen();
oRendererOut.m_pPageMeta.SkipLen();
m_pGlyphs.first = _nPageIndex;
RELEASEARRAYOBJECTS(m_pGlyphs.second);
#endif
oRendererOut.NewPDF(m_pInternal->m_pPDFDocument->getXRef());
oRendererOut.SetBreak(pbBreak);
m_pInternal->m_pPDFDocument->displayPage(&oRendererOut, nPageIndex, 72.0, 72.0, 0, false, true, false);
#ifdef BUILDING_WASM_MODULE
//oRendererOut.m_pPageMeta.WriteLen();
oRendererOut.m_pPageMeta.WriteLen();
m_pGlyphs.second = oRendererOut.m_pPageMeta.GetBuffer();
/* С конвертацией в Base64
char* pDst = NULL;
int nDst = 0;
NSFile::CBase64Converter::Encode(oRendererOut.m_pPageMeta.GetBuffer(), oRendererOut.m_pPageMeta.GetSize(), pDst, nDst, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sBase64Data;
if (0 < nDst)
sBase64Data = std::string(pDst);
sBase64Data = std::to_string(oRendererOut.m_pPageMeta.GetSize()) + ";" + sBase64Data;
std::ofstream fout("res.txt");
fout << sBase64Data;
fout.close();
RELEASEARRAYOBJECTS(pDst);
*/
oRendererOut.m_pPageMeta.ClearWithoutAttack();
#endif
}
}
BYTE* CPdfReader::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip)
{
NSFonts::IFontManager *pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dWidth, dHeight;
double dDpiX, dDpiY;
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dDpiX, &dDpiY);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 72 / 25.4);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 72 / 25.4);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return NULL;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride((bIsFlip ? 4 : -4) * nWidth);
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetSwapRGB(true);
dWidth *= 25.4 / dDpiX;
dHeight *= 25.4 / dDpiY;
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
oFrame.ClearNoAttack();
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
return pBgraData;
}
void CPdfReader::ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int nRasterW, const int nRasterH)
{
NSFonts::IFontManager *pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dWidth, dHeight;
double dDpiX, dDpiY;
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dDpiX, &dDpiY);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 72 / 25.4);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 72 / 25.4);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(-4 * nWidth);
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetSwapRGB(false);
dWidth *= 25.4 / dDpiX;
dHeight *= 25.4 / dDpiY;
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
oFrame.SaveFile(wsDstPath, nImageType);
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
}
int CPdfReader::GetImagesCount()
{
// ImageOutputDev *pOutputDev = new ImageOutputDev(NULL, true, true, false);
@ -618,37 +502,15 @@ return 0;
oRes.ClearWithoutAttack();
return bRes;
}
BYTE* CPdfReader::GetGlyphs(int nPageIndex)
{
if (nPageIndex != m_pGlyphs.first)
{
BYTE* res = ConvertToPixels(nPageIndex, 0, 0);
RELEASEARRAYOBJECTS(res);
}
// Будет освобожден в js
BYTE* res = m_pGlyphs.second;
m_pGlyphs.second = NULL;
return res;
}
BYTE* CPdfReader::GetLinks (int nPageIndex)
BYTE* CPdfReader::GetLinks(int nPageIndex)
{
if (!m_pInternal->m_pPDFDocument)
return NULL;
nPageIndex++;
NSWasm::CData oRes;
oRes.SkipLen();
double height = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex);
struct _link
{
std::string link;
double x;
double y;
double w;
double h;
};
std::vector<_link> arrLinks;
NSWasm::CPageLink oLinks;
double height = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex);
// Текст-ссылка
TextOutputControl textOutControl;
@ -676,21 +538,10 @@ return 0;
link.erase(0, find);
double x1, y1, x2, y2;
pWord->getBBox(&x1, &y1, &x2, &y2);
arrLinks.push_back({link, x1, y1, x2 - x1, y2 - y1});
oLinks.m_arLinks.push_back({link, 0, x1, y1, x2 - x1, y2 - y1});
}
}
for (_link& l : arrLinks)
{
oRes.WriteString((BYTE*)l.link.c_str(), l.link.length());
// Верхний левый угол
oRes.AddDouble(0.0);
oRes.AddDouble(l.x);
oRes.AddDouble(l.y);
oRes.AddDouble(l.w);
oRes.AddDouble(l.h);
}
RELEASEOBJECT(pTextOut);
arrLinks.clear();
// Гиперссылка
Links* pLinks = m_pInternal->m_pPDFDocument->getLinks(nPageIndex);
@ -737,24 +588,11 @@ return 0;
else if (kind == actionURI)
str = ((LinkURI*)pLinkAction)->getURI()->copy();
if (str)
oRes.WriteString((BYTE*)str->getCString(), str->getLength());
else
oRes.WriteString(NULL, 0);
// Верхний левый угол
oRes.AddDouble(dy);
oRes.AddDouble(x1);
oRes.AddDouble(y2);
oRes.AddDouble(x2 - x1);
oRes.AddDouble(y1 - y2);
oLinks.m_arLinks.push_back({str ? std::string(str->getCString(), str->getLength()) : "", dy, x1, y2, x2 - x1, y1 - y2});
RELEASEOBJECT(str);
}
oRes.WriteLen();
RELEASEOBJECT(pLinks);
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return res;
return oLinks.Serialize();
}
#endif
}

View File

@ -38,7 +38,7 @@
#include "../DesktopEditor/common/base_export.h"
#define PDFREADER_DECL_EXPORT Q_DECL_EXPORT
#endif
#include "../DesktopEditor/common/officedrawingfile.h"
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../DesktopEditor/graphics/pro/Fonts.h"
namespace PdfReader
@ -74,6 +74,8 @@ namespace PdfReader
virtual void Close();
virtual NSFonts::IApplicationFonts* GetFonts();
virtual OfficeDrawingFileType GetType();
virtual std::wstring GetTempDirectory();
@ -82,8 +84,6 @@ namespace PdfReader
virtual int GetPagesCount();
virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY);
virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak);
virtual BYTE* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip = false);
virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1);
int GetError();
double GetVersion();
@ -97,13 +97,10 @@ namespace PdfReader
NSFonts::IFontManager* GetFontManager();
std::wstring ToXml(const std::wstring& wsXmlPath);
#ifdef BUILDING_WASM_MODULE
virtual BYTE* GetStructure();
virtual BYTE* GetGlyphs(int nPageIndex);
virtual BYTE* GetLinks (int nPageIndex);
private:
std::pair<int, BYTE*> m_pGlyphs;
virtual BYTE* GetLinks(int nPageIndex);
#endif
private:

View File

@ -85,3 +85,12 @@ SOURCES += \
Resources/BaseFonts.cpp
core_windows:LIBS += -lOle32
#CONFIG += build_viewer_module
build_viewer_module {
DEFINES += BUILDING_WASM_MODULE
DEFINES += TEST_AS_EXECUTABLE
HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h
SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp
}

View File

@ -584,11 +584,6 @@ namespace PdfReader
}
void RendererOutputDev::endPage()
{
#ifdef BUILDING_WASM_MODULE
LONG nCount = m_oLine.GetCountChars();
if (0 != nCount)
DumpLine();
#endif
m_pRenderer->EndCommand(c_nPageType);
}
void RendererOutputDev::saveState(GfxState *pGState)
@ -3547,9 +3542,6 @@ namespace PdfReader
}
m_pRenderer->CommandDrawTextEx(wsUnicodeText, pGids, unGidsCount, PDFCoordsToMM(100), PDFCoordsToMM(100), 0, PDFCoordsToMM(0));
#ifdef BUILDING_WASM_MODULE
GetGlyphs(wsUnicodeText, pGids, PDFCoordsToMM(100), PDFCoordsToMM(100));
#endif
RELEASEARRAYOBJECTS(pGids);
}
void RendererOutputDev::drawChar(GfxState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen)
@ -3711,9 +3703,6 @@ namespace PdfReader
else
{
m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(0 + dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy));
#ifdef BUILDING_WASM_MODULE
GetGlyphs(wsUnicodeText, &unGid, PDFCoordsToMM(0 + dShiftX), PDFCoordsToMM(dShiftY));
#endif
}
}
@ -4505,444 +4494,4 @@ namespace PdfReader
}
return;
}
#ifdef BUILDING_WASM_MODULE
int GetCurrentFont(const std::wstring& sFont)
{
size_t nLast = sFont.rfind(L'_');
if (nLast == std::wstring::npos)
return -1;
return std::stoi(sFont.substr(nLast + 1)) - 1;
}
void RendererOutputDev::GetGlyphs(const std::wstring& bsUnicodeText, unsigned int* pGids, double x, double y)
{
// m_pInternal->GetUnicodes(bsUnicodeText);
int nLen = (int)bsUnicodeText.length();
int* pTempUnicodes = new int[nLen];
int nTempUnicodesLen = 0;
const wchar_t* pWchars = bsUnicodeText.c_str();
if (sizeof(wchar_t) == 2)
{
for (int i = 0; i < nLen; i++)
{
int code = (int)pWchars[i];
if (code >= 0xD800 && code <= 0xDFFF && (i + 1) < nLen)
{
i++;
code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[i]));
}
pTempUnicodes[nTempUnicodesLen++] = code;
}
}
else
for (int i = 0; i < nLen; i++)
pTempUnicodes[nTempUnicodesLen++] = (int)pWchars[i];
// m_pInternal->m_oWriter.WriteText(pTempUnicodes, (const int*)pGids, nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
/*
* CheckTectClipRect(); никогда не вызывает запись в m_oPage, т.к
* в текстовом режиме EndCommand(c_nClipType) не обрабатывается
* Аналогично: WriteDrawPath, Pattern, Image, Image2 и ImagePattrern
* WriteImageID_SVG(); не вызывается, т.к размер m_oSVGWriter.m_oDocument
* не изменяется в текстовом режиме
*/
bool bIsDumpFont = false;
std::wstring sCurrentFontName; double dFontSize;
m_pRenderer->get_FontPath(&sCurrentFontName);
m_pRenderer->get_FontSize(&dFontSize);
int nCurrentFont = GetCurrentFont(sCurrentFontName);
if ((nCurrentFont != m_lCurrentFont) || (dFontSize != m_dCurrentFontSize))
{
m_lCurrentFont = nCurrentFont;
m_dCurrentFontSize = dFontSize;
bIsDumpFont = true;
}
// m_oSmartText.CommandText(pTempUnicodes, (const int*)pGids, nTempUnicodesLen, x, y, w, h, bIsDumpFont, this);
// 1) сначала определяем точку отсчета и направление baseline
double _x1 = x;
double _y1 = y;
double _x2 = x + 1;
double _y2 = y;
double sx, shy, shx, sy, tx, ty, tmp;
m_pRenderer->GetTransform(&sx, &shy, &shx, &sy, &tx, &ty);
// m_pTransform->TransformPoint(_x1, _y1);
tmp = _x1;
_x1 = tmp * sx + _y1 * shx + tx;
_y1 = tmp * shy + _y1 * sy + ty;
// m_pTransform->TransformPoint(_x2, _y2);
tmp = _x2;
_x2 = tmp * sx + _y2 * shx + tx;
_y2 = tmp * shy + _y2 * sy + ty;
double _k = 0;
double _b = 0;
bool _isConstX = false;
if (fabs(_x1 - _x2) < 0.001)
{
_isConstX = true;
_b = _x1;
}
else
{
_k = (_y1 - _y2) / (_x1 - _x2);
_b = _y1 - _k * _x1;
}
double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2));
if (dAbsVec == 0)
dAbsVec = 1;
LONG nCountChars = m_oLine.GetCountChars();
bool bIsNewLine = true;
if (0 != nCountChars)
{
if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
}
if (bIsNewLine && (nCountChars != 0))
{
// не совпала baseline. поэтому просто скидываем линию в поток
DumpLine();
}
// теперь нужно определить сдвиг по baseline относительно destination точки
nCountChars = m_oLine.GetCountChars();
double dOffsetX = 0;
if (nCountChars == 0)
{
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
else
{
double _sx = _x1 - m_oLine.m_dEndX;
double _sy = _y1 - m_oLine.m_dEndY;
double len = sqrt(_sx * _sx + _sy * _sy);
if (_sx * m_oLine.m_ex >= 0 && _sy * m_oLine.m_ey >= 0)
{
// продолжаем линию
dOffsetX = len;
// теперь посмотрим, может быть нужно вставить пробел??
NSWasm::CHChar* pLastChar = m_oLine.GetTail();
if (dOffsetX > (pLastChar->width + 0.5))
{
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
pSpaceChar->x = pLastChar->width;
pSpaceChar->width = dOffsetX - pLastChar->width;
pSpaceChar->unicode = 0xFFFF;
pSpaceChar->gid = 0xFFFF;
dOffsetX -= pLastChar->width;
m_oMeta.WriteBYTE(0);
}
}
else
{
// буква сдвинута влево относительно предыдущей буквы
// на такую ситуацию реагируем просто - просто начинаем новую линию,
// предварительно сбросив старую
DumpLine();
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
}
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
// смотрим, совпадает ли главная часть матрицы.
bool bIsTransform = !(fabs(m_pLastTransform.sx() - sx) < 0.001 &&
fabs(m_pLastTransform.sy() - sy) < 0.001 &&
fabs(m_pLastTransform.shx() - shx) < 0.001 &&
fabs(m_pLastTransform.shy() - shy) < 0.001);
if (bIsTransform)
bIsDumpFont = true;
LONG nColor1, nAlpha1;
m_pRenderer->get_BrushColor1(&nColor1);
m_pRenderer->get_BrushAlpha1(&nAlpha1);
bool bIsColor = ((nColor1 != m_nLastBrushColor1) || (nAlpha1 != m_nLastBrushAlpha1));
BYTE nLenMetaCommands = 0;
if (bIsColor)
nLenMetaCommands += 5;
if (bIsTransform)
nLenMetaCommands += 17;
if (bIsDumpFont)
nLenMetaCommands += 13;
m_oMeta.WriteBYTE(nLenMetaCommands);
double _dumpSize = dFontSize;
double _dumpMtx[4];
_dumpMtx[0] = sx;
_dumpMtx[1] = shy;
_dumpMtx[2] = shx;
_dumpMtx[3] = sy;
double dTextScale = std::min(sqrt(_dumpMtx[2] * _dumpMtx[2] + _dumpMtx[3] * _dumpMtx[3]),
sqrt(_dumpMtx[0] * _dumpMtx[0] + _dumpMtx[1] * _dumpMtx[1]));
if ((_dumpSize < 0.1 && dTextScale > 10) || (_dumpSize > 10 && dTextScale < 0.1))
{
_dumpSize *= dTextScale;
_dumpMtx[0] /= dTextScale;
_dumpMtx[1] /= dTextScale;
_dumpMtx[2] /= dTextScale;
_dumpMtx[3] /= dTextScale;
}
if (bIsDumpFont)
{
LONG nFontStyle;
m_pRenderer->get_FontStyle(&nFontStyle);
m_oMeta.WriteBYTE(41); // CMetafile::ctFontName
m_oMeta.AddInt(nCurrentFont);
m_oMeta.AddInt(nFontStyle);
m_oMeta.WriteDouble(_dumpSize);
}
if (bIsTransform)
{
m_pLastTransform.SetElements(sx, shy, shx, sy);
m_oLine.m_bIsSetUpTransform = true;
m_oLine.m_sx = sx;
m_oLine.m_shx = shx;
m_oLine.m_shy = shy;
m_oLine.m_sy = sy;
m_oMeta.WriteBYTE(161); // CMetafile::ctCommandTextTransform
m_oMeta.WriteDouble(_dumpMtx[0]);
m_oMeta.WriteDouble(_dumpMtx[1]);
m_oMeta.WriteDouble(_dumpMtx[2]);
m_oMeta.WriteDouble(_dumpMtx[3]);
}
if (bIsColor)
{
m_nLastBrushColor1 = nColor1;
m_nLastBrushAlpha1 = nAlpha1;
m_oMeta.WriteBYTE(22); // CMetafile::ctBrushColor1
LONG lBGR = nColor1;
m_oMeta.WriteBYTE((BYTE)(lBGR & 0xFF));
m_oMeta.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF));
m_oMeta.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF));
m_oMeta.WriteBYTE((BYTE)nAlpha1);
}
// все, baseline установлен. теперь просто продолжаем линию
if (bIsDumpFont)
{
m_pFontManager->LoadFontFromFile(sCurrentFontName, 0, dFontSize, 72.0, 72.0);
m_pFontManager->AfterLoad();
}
double dKoef = dFontSize * 25.4 / (72 * abs(m_pFontManager->GetUnitsPerEm()));
double dAscender = abs(m_pFontManager->GetAscender()) * dKoef * dAbsVec;
double dDescender = abs(m_pFontManager->GetDescender()) * dKoef * dAbsVec;
if (m_oLine.m_dAscent < dAscender)
m_oLine.m_dAscent = dAscender;
if (m_oLine.m_dDescent < dDescender)
m_oLine.m_dDescent = dDescender;
double dPlusOffset = 0;
int* input = NULL;
if (pGids)
{
input = (int*)pGids;
m_pFontManager->SetStringGID(TRUE);
}
else
{
input = pTempUnicodes;
m_pFontManager->SetStringGID(FALSE);
}
for (int i = 0; i < nTempUnicodesLen; i++)
{
// double dW = m_oFontManager.MeasureString((const unsigned int*)(input + lIndex), 1, 0, 0, dBoxX, dBoxY, dBoxW, dBoxH);
m_pFontManager->LoadString1((unsigned int*)(input + i), 1, 0, 0);
TBBox _box = m_pFontManager->MeasureString2();
double dBoxW = abs(_box.fMaxX - _box.fMinX) * 25.4 / 72.0;
NSWasm::CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pTempUnicodes[i];
pChar->gid = pGids ? pGids[i] : 0xFFFF;
pChar->x = dOffsetX;
if (i != 0)
dPlusOffset += dOffsetX;
dOffsetX = dBoxW;
pChar->width = dBoxW * dAbsVec;
if (i != 0)
m_oMeta.WriteBYTE(0);
if (i == (nTempUnicodesLen - 1))
{
m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex;
m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey;
}
}
RELEASEARRAYOBJECTS(pTempUnicodes);
}
void RendererOutputDev::DumpLine()
{
if (m_oLine.m_bIsSetUpTransform)
{
// выставится трансформ!!!
// cравнивать нужно с ним!!!
m_pLastTransform.SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy);
}
// скидываем линию в поток pMeta
BYTE mask = 0;
if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001)
mask |= 0x01;
LONG lCountSpaces = 0;
LONG lCountSymbols = 0;
LONG lCountWords = 0;
bool bIsLastSymbol = false;
bool bIsGidExist = false;
LONG nCount = m_oLine.GetCountChars();
for (LONG i = 0; i < nCount; i++)
{
NSWasm::CHChar* pChar = &m_oLine.m_pChars[i];
if (pChar->gid != 0xFFFF)
{
mask |= 0x02;
bIsGidExist = true;
}
if (0xFFFF == pChar->unicode || L' ' == pChar->unicode || L'\t' == pChar->unicode)
{
lCountSpaces++;
if (bIsLastSymbol)
{
bIsLastSymbol = false;
lCountWords++;
}
}
else
{
bIsLastSymbol = true;
lCountSymbols++;
}
}
if (bIsLastSymbol)
lCountWords++;
if (0 == nCount)
{
m_oLine.Clear();
m_oMeta.ClearNoAttack();
return;
}
if (nCount > 1)
mask |= 0x04;
m_pPageMeta.WriteBYTE(160); // CMetafile::ctCommandTextLine
m_pPageMeta.WriteBYTE(mask);
m_pPageMeta.WriteDouble(m_oLine.m_dX);
m_pPageMeta.WriteDouble(m_oLine.m_dY);
if ((mask & 0x01) == 0)
{
m_pPageMeta.WriteDouble(m_oLine.m_ex);
m_pPageMeta.WriteDouble(m_oLine.m_ey);
}
m_pPageMeta.WriteDouble(m_oLine.m_dAscent);
m_pPageMeta.WriteDouble(m_oLine.m_dDescent);
LONG _position = 0;
if (nCount > 1)
{
_position = m_pPageMeta.GetSize();
m_pPageMeta.AddInt(0);
}
BYTE* pBufferMeta = m_oMeta.GetBuffer();
double dWidthLine = 0;
double dCurrentGlyphLineOffset = 0;
for (LONG lIndexChar = 0; lIndexChar < nCount; lIndexChar++)
{
NSWasm::CHChar* pChar = &m_oLine.m_pChars[lIndexChar];
// все настроки буквы (m_oMeta)
BYTE lLen = *pBufferMeta;
pBufferMeta++;
if (lLen > 0)
m_pPageMeta.Write(pBufferMeta, lLen);
pBufferMeta += lLen;
// смещение относительно предыдущей буквы (у всех, кроме первой)
// юникодное значение
// гид (если bIsGidExist == true)
// ширина буквы
m_pPageMeta.WriteBYTE(80); // CMetafile::ctDrawText
if (lIndexChar)
m_pPageMeta.WriteDouble2(pChar->x);
m_pPageMeta.WriteWCHAR(pChar->unicode);
if (bIsGidExist)
m_pPageMeta.WriteUSHORT(pChar->gid);
m_pPageMeta.WriteDouble2(pChar->width);
if (lIndexChar)
dCurrentGlyphLineOffset += pChar->x;
if (lIndexChar == (nCount - 1))
dWidthLine = dCurrentGlyphLineOffset + pChar->width;
}
if (nCount > 1)
{
int* pWidthBuf = (int*)(m_pPageMeta.GetBuffer() + _position);
*pWidthBuf = (int)(dWidthLine * 10000);
}
m_oLine.Clear();
m_oMeta.ClearNoAttack();
m_pPageMeta.WriteBYTE(162); // CMetafile::ctCommandTextLineEnd
}
#endif
}

View File

@ -289,21 +289,6 @@ namespace PdfReader
m_pbBreak = pbBreak;
}
#ifdef BUILDING_WASM_MODULE
void GetGlyphs(const std::wstring& bsUnicodeText, unsigned int* pGids, double x, double y);
void DumpLine();
NSWasm::CData m_pPageMeta;
private:
double m_dCurrentFontSize = 0.0;
NSWasm::CHLine m_oLine;
NSWasm::CData m_oMeta;
Aggplus::CMatrix m_pLastTransform;
LONG m_lCurrentFont = -1;
LONG m_nLastBrushColor1 = -1;
LONG m_nLastBrushAlpha1 = -1;
#endif
private:
void Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY);

View File

@ -145,6 +145,11 @@ void CXpsFile::Close()
m_pInternal->m_wsTempFolder = NULL;
}
}
NSFonts::IApplicationFonts* CXpsFile::GetFonts()
{
return m_pInternal->m_pAppFonts;
}
OfficeDrawingFileType CXpsFile::GetType()
{
return odftXPS;
@ -175,88 +180,6 @@ void CXpsFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pB
m_pInternal->m_pDocument->DrawPage(nPageIndex, pRenderer, pBreak);
}
BYTE* CXpsFile::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip)
{
NSFonts::IFontManager *pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dPageDpiX;
double dWidth, dHeight;
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiX);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 96 / dPageDpiX);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 96 / dPageDpiX);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return NULL;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride((bIsFlip ? 4 : -4) * nWidth);
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetSwapRGB(true);
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
oFrame.ClearNoAttack();
return pBgraData;
}
void CXpsFile::ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int nRasterW, const int nRasterH)
{
NSFonts::IFontManager *pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create();
pRenderer->SetFontManager(pFontManager);
double dPageDpiX, dPageDpiY;
double dWidth, dHeight;
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY);
int nWidth = (nRasterW > 0) ? nRasterW : ((int)dWidth * 96 / dPageDpiX);
int nHeight = (nRasterH > 0) ? nRasterH : ((int)dHeight * 96 / dPageDpiX);
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return;
memset(pBgraData, 0xff, nWidth * nHeight * 4);
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(-4 * nWidth);
pRenderer->CreateFromBgraFrame(&oFrame);
pRenderer->SetSwapRGB(false);
pRenderer->put_Width(dWidth);
pRenderer->put_Height(dHeight);
bool bBreak = false;
DrawPageOnRenderer(pRenderer, nPageIndex, &bBreak);
oFrame.SaveFile(wsDstPath, nImageType);
RELEASEINTERFACE(pFontManager);
RELEASEOBJECT(pRenderer);
}
#ifndef DISABLE_PDF_CONVERTATION
void CXpsFile::ConvertToPdf(const std::wstring& wsPath)
@ -298,10 +221,6 @@ BYTE* CXpsFile::GetStructure()
{
return m_pInternal->m_pDocument->GetStructure();
}
BYTE* CXpsFile::GetGlyphs(int nPageIndex)
{
return m_pInternal->m_pDocument->GetPageGlyphs(nPageIndex);
}
BYTE* CXpsFile::GetLinks (int nPageIndex)
{
return m_pInternal->m_pDocument->GetPageLinks(nPageIndex);

View File

@ -39,7 +39,7 @@
#define XPS_DECL_EXPORT Q_DECL_EXPORT
#endif
#include "../DesktopEditor/common/officedrawingfile.h"
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../DesktopEditor/graphics/pro/Fonts.h"
class CXpsFile_Private;
@ -55,6 +55,7 @@ public:
const std::wstring& owner_password = L"", const std::wstring& user_password = L"");
virtual void Close();
virtual NSFonts::IApplicationFonts* GetFonts();
virtual OfficeDrawingFileType GetType();
@ -64,17 +65,14 @@ public:
virtual int GetPagesCount();
virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY);
virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak);
virtual BYTE* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip = false);
virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1);
#ifndef DISABLE_PDF_CONVERTATION
void ConvertToPdf(const std::wstring& wsDstPath);
void ConvertToPdf(const std::wstring& wsDstPath);
#endif
#ifdef BUILDING_WASM_MODULE
virtual BYTE* GetStructure();
virtual BYTE* GetGlyphs(int nPageIndex);
virtual BYTE* GetLinks (int nPageIndex);
virtual BYTE* GetLinks(int nPageIndex);
#endif
private:

View File

@ -46,3 +46,10 @@ SOURCES += \
XpsLib/Utils.cpp \
XpsLib/WString.cpp
#CONFIG += build_viewer_module
build_viewer_module {
DEFINES += BUILDING_WASM_MODULE
HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h
SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp
}

View File

@ -303,18 +303,11 @@ namespace XPS
oRes.ClearWithoutAttack();
return bRes;
}
BYTE* CDocument::GetPageGlyphs(int nPageIndex)
{
std::map<int, XPS::Page*>::const_iterator oIter = m_mPages.find(nPageIndex);
if (oIter != m_mPages.end())
return oIter->second->GetGlyphs();
return NULL;
}
BYTE* CDocument::GetPageLinks (int nPageIndex)
{
std::map<int, XPS::Page*>::const_iterator oIter = m_mPages.find(nPageIndex);
if (oIter != m_mPages.end())
return oIter->second->GetLinks();
return oIter->second->m_oLinks.Serialize();
return NULL;
}
#endif

View File

@ -165,484 +165,8 @@ namespace XPS
nH = wsAttrName.tointeger();
}
}
#ifdef BUILDING_WASM_MODULE
BYTE* Page::GetGlyphs()
{
// Будет освобожден в js
BYTE* res = m_pPageMeta.GetBuffer();
/*
char* pDst = NULL;
int nDst = 0;
NSFile::CBase64Converter::Encode(m_pPageMeta.GetBuffer(), m_pPageMeta.GetSize(), pDst, nDst, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sBase64Data;
if (0 < nDst)
sBase64Data = std::string(pDst);
sBase64Data = std::to_string(m_pPageMeta.GetSize()) + ";" + sBase64Data;
std::ofstream fout("res.txt");
fout << sBase64Data;
fout.close();
*/
m_pPageMeta.ClearWithoutAttack();
return res;
}
BYTE* Page::GetLinks()
{
NSWasm::CData oRes;
oRes.SkipLen();
for (const CPageLink& link : m_vLinks)
{
oRes.WriteString((BYTE*)link.sLink.c_str(), link.sLink.length());
oRes.AddDouble(0.0);
oRes.AddDouble(link.dX);
oRes.AddDouble(link.dY);
oRes.AddDouble(link.dW);
oRes.AddDouble(link.dH);
}
oRes.WriteLen();
BYTE* res = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return res;
}
void Page::GetGlyphs(IRenderer* m_pRenderer, const std::wstring& bsUnicodeText, unsigned short* pGids, double x, double y, bool bChangeFont)
{
// m_pInternal->GetUnicodes(bsUnicodeText);
int nUnicodeLen = (int)bsUnicodeText.length();
unsigned int* pTempUnicodes = new unsigned int[nUnicodeLen];
int nTempUnicodesLen = 0;
const wchar_t* pWchars = bsUnicodeText.c_str();
if (sizeof(wchar_t) == 2)
{
for (int i = 0; i < nUnicodeLen; i++)
{
unsigned int code = (unsigned int)pWchars[i];
if (code >= 0xD800 && code <= 0xDFFF && (i + 1) < nUnicodeLen)
{
i++;
code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[i]));
}
pTempUnicodes[nTempUnicodesLen++] = code;
}
}
else
for (int i = 0; i < nUnicodeLen; i++)
pTempUnicodes[nTempUnicodesLen++] = (unsigned int)pWchars[i];
// m_pInternal->m_oWriter.WriteText(m_pTempUnicodes, (const int*)pGids, m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
bool bIsDumpFont = false;
std::wstring sCurrentFontName; double dFontSize;
m_pRenderer->get_FontPath(&sCurrentFontName);
m_pRenderer->get_FontSize(&dFontSize);
std::wstring wsFontName = sCurrentFontName;
NSStringExt::Replace(wsFontName, L"\\", L"/");
wsFontName = GetFileName(wsFontName);
NSStringExt::ToLower(wsFontName);
int nCurrentFont = m_pFontList->GetFontId(wsFontName);
if ((nCurrentFont != m_nCurrentFont) || (dFontSize != m_dCurrentFontSize))
{
m_nCurrentFont = nCurrentFont;
m_dCurrentFontSize = dFontSize;
bIsDumpFont = true;
}
// m_oSmartText.CommandText(m_pTempUnicodes, (const int*)pGids, m_nTempUnicodesLen, x, y, w, h, bIsDumpFont, this);
// 1) сначала определяем точку отсчета и направление baseline
double _x1 = x;
double _y1 = y;
double _x2 = x + 1;
double _y2 = y;
double sx, shy, shx, sy, tx, ty, tmp;
m_pRenderer->GetTransform(&sx, &shy, &shx, &sy, &tx, &ty);
// m_pTransform->TransformPoint(_x1, _y1);
tmp = _x1;
_x1 = tmp * sx + _y1 * shx + tx;
_y1 = tmp * shy + _y1 * sy + ty;
// m_pTransform->TransformPoint(_x2, _y2);
tmp = _x2;
_x2 = tmp * sx + _y2 * shx + tx;
_y2 = tmp * shy + _y2 * sy + ty;
double _k = 0;
double _b = 0;
bool _isConstX = false;
if (fabs(_x1 - _x2) < 0.001)
{
_isConstX = true;
_b = _x1;
}
else
{
_k = (_y1 - _y2) / (_x1 - _x2);
_b = _y1 - _k * _x1;
}
double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2));
if (dAbsVec == 0)
dAbsVec = 1;
LONG nCountChars = m_oLine.GetCountChars();
bool bIsNewLine = true;
if (nCountChars != 0)
{
if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
}
if (bIsNewLine && (nCountChars != 0))
{
// не совпала baseline. поэтому просто скидываем линию в поток
DumpLine();
}
// теперь нужно определить сдвиг по baseline относительно destination точки
nCountChars = m_oLine.GetCountChars();
double dOffsetX = 0;
if (nCountChars == 0)
{
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
else
{
double _sx = _x1 - m_oLine.m_dEndX;
double _sy = _y1 - m_oLine.m_dEndY;
double len = sqrt(_sx * _sx + _sy * _sy);
if (_sx * m_oLine.m_ex >= 0 && _sy * m_oLine.m_ey >= 0)
{
// продолжаем линию
dOffsetX = len;
// теперь посмотрим, может быть нужно вставить пробел??
NSWasm::CHChar* pLastChar = m_oLine.GetTail();
if (dOffsetX > (pLastChar->width + 0.5))
{
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
pSpaceChar->x = pLastChar->width;
pSpaceChar->width = dOffsetX - pLastChar->width;
pSpaceChar->unicode = 0xFFFF;
pSpaceChar->gid = 0xFFFF;
dOffsetX -= pLastChar->width;
m_oMeta.WriteBYTE(0);
}
}
else
{
// буква сдвинута влево относительно предыдущей буквы
// на такую ситуацию реагируем просто - просто начинаем новую линию,
// предварительно сбросив старую
DumpLine();
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
}
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
// смотрим, совпадает ли главная часть матрицы.
bool bIsTransform = !(fabs(m_pLastTransform.sx() - sx) < 0.001 &&
fabs(m_pLastTransform.sy() - sy) < 0.001 &&
fabs(m_pLastTransform.shx() - shx) < 0.001 &&
fabs(m_pLastTransform.shy() - shy) < 0.001);
if (bIsTransform)
bIsDumpFont = true;
LONG nColor1, nAlpha1;
m_pRenderer->get_BrushColor1(&nColor1);
m_pRenderer->get_BrushAlpha1(&nAlpha1);
bool bIsColor = ((nColor1 != m_nLastBrushColor1) || (nAlpha1 != m_nLastBrushAlpha1));
BYTE nLenMetaCommands = 0;
if (bIsColor)
nLenMetaCommands += 5;
if (bIsTransform)
nLenMetaCommands += 17;
if (bIsDumpFont)
nLenMetaCommands += 13;
m_oMeta.WriteBYTE(nLenMetaCommands);
double _dumpSize = m_dCurrentFontSize;
double _dumpMtx[4];
_dumpMtx[0] = sx;
_dumpMtx[1] = shy;
_dumpMtx[2] = shx;
_dumpMtx[3] = sy;
double dTextScale = std::min(sqrt(_dumpMtx[2] * _dumpMtx[2] + _dumpMtx[3] * _dumpMtx[3]),
sqrt(_dumpMtx[0] * _dumpMtx[0] + _dumpMtx[1] * _dumpMtx[1]));
if ((_dumpSize < 0.1 && dTextScale > 10) || (_dumpSize > 10 && dTextScale < 0.1))
{
_dumpSize *= dTextScale;
_dumpMtx[0] /= dTextScale;
_dumpMtx[1] /= dTextScale;
_dumpMtx[2] /= dTextScale;
_dumpMtx[3] /= dTextScale;
}
if (bIsDumpFont)
{
LONG nFontStyle;
m_pRenderer->get_FontStyle(&nFontStyle);
m_oMeta.WriteBYTE(41); // CMetafile::ctFontName
m_oMeta.AddInt(m_nCurrentFont);
m_oMeta.AddInt(nFontStyle);
m_oMeta.WriteDouble(_dumpSize);
}
if (bIsTransform)
{
m_pLastTransform.SetElements(sx, shy, shx, sy);
m_oLine.m_bIsSetUpTransform = true;
m_oLine.m_sx = sx;
m_oLine.m_shx = shx;
m_oLine.m_shy = shy;
m_oLine.m_sy = sy;
m_oMeta.WriteBYTE(161); // CMetafile::ctCommandTextTransform
m_oMeta.WriteDouble(_dumpMtx[0]);
m_oMeta.WriteDouble(_dumpMtx[1]);
m_oMeta.WriteDouble(_dumpMtx[2]);
m_oMeta.WriteDouble(_dumpMtx[3]);
}
if (bIsColor)
{
m_nLastBrushColor1 = nColor1;
m_nLastBrushAlpha1 = nAlpha1;
m_oMeta.WriteBYTE(22); // CMetafile::ctBrushColor1
LONG lBGR = m_nLastBrushColor1;
m_oMeta.WriteBYTE((BYTE)(lBGR & 0xFF));
m_oMeta.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF));
m_oMeta.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF));
m_oMeta.WriteBYTE((BYTE)m_nLastBrushAlpha1);
}
// все, baseline установлен. теперь просто продолжаем линию
if (bIsDumpFont || bChangeFont)
{
m_pFontManager->LoadFontFromFile(sCurrentFontName, 0, m_dCurrentFontSize, 72.0, 72.0);
m_pFontManager->AfterLoad();
}
double dKoef = m_dCurrentFontSize * 25.4 / (72 * abs(m_pFontManager->GetUnitsPerEm()));
double dAscender = abs(m_pFontManager->GetAscender()) * dKoef * dAbsVec;
double dDescender = abs(m_pFontManager->GetDescender()) * dKoef * dAbsVec;
if (m_oLine.m_dAscent < dAscender)
m_oLine.m_dAscent = dAscender;
if (m_oLine.m_dDescent < dDescender)
m_oLine.m_dDescent = dDescender;
double dPlusOffset = 0;
unsigned int* input = NULL;
if (pGids)
{
input = (unsigned int*)pGids;
m_pFontManager->SetStringGID(TRUE);
}
else
{
input = pTempUnicodes;
m_pFontManager->SetStringGID(FALSE);
}
for (int i = 0; i < nTempUnicodesLen; i++)
{
// double dW = m_oFontManager.MeasureString((const unsigned int*)(input + lIndex), 1, 0, 0, dBoxX, dBoxY, dBoxW, dBoxH);
m_pFontManager->LoadString1(input + i, 1, 0, 0);
TBBox _box = m_pFontManager->MeasureString2();
double dBoxW = abs(_box.fMaxX - _box.fMinX) * 25.4 / 72.0;
NSWasm::CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pTempUnicodes[i];
pChar->gid = pGids ? pGids[i] : 0xFFFF;
pChar->x = dOffsetX;
if (i != 0)
dPlusOffset += dOffsetX;
dOffsetX = dBoxW;
pChar->width = dBoxW * dAbsVec;
if (i != 0)
m_oMeta.WriteBYTE(0);
if (i == (nTempUnicodesLen - 1))
{
m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex;
m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey;
}
}
RELEASEARRAYOBJECTS(pTempUnicodes);
}
void Page::DumpLine()
{
if (m_oLine.m_bIsSetUpTransform)
{
// выставится трансформ!!!
// cравнивать нужно с ним!!!
m_pLastTransform.SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy);
}
// скидываем линию в поток pMeta
BYTE mask = 0;
if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001)
mask |= 0x01;
LONG lCountSpaces = 0;
LONG lCountSymbols = 0;
LONG lCountWords = 0;
bool bIsLastSymbol = false;
bool bIsGidExist = false;
LONG nCount = m_oLine.GetCountChars();
for (LONG i = 0; i < nCount; i++)
{
NSWasm::CHChar* pChar = &m_oLine.m_pChars[i];
if (pChar->gid != 0xFFFF)
{
mask |= 0x02;
bIsGidExist = true;
}
if (0xFFFF == pChar->unicode || L' ' == pChar->unicode || L'\t' == pChar->unicode)
{
lCountSpaces++;
if (bIsLastSymbol)
{
bIsLastSymbol = false;
lCountWords++;
}
}
else
{
bIsLastSymbol = true;
lCountSymbols++;
}
}
if (bIsLastSymbol)
lCountWords++;
if (nCount == 0)
{
m_oLine.Clear();
m_oMeta.ClearNoAttack();
return;
}
if (nCount > 1)
mask |= 0x04;
m_pPageMeta.WriteBYTE(160); // CMetafile::ctCommandTextLine
m_pPageMeta.WriteBYTE(mask);
m_pPageMeta.WriteDouble(m_oLine.m_dX);
m_pPageMeta.WriteDouble(m_oLine.m_dY);
if ((mask & 0x01) == 0)
{
m_pPageMeta.WriteDouble(m_oLine.m_ex);
m_pPageMeta.WriteDouble(m_oLine.m_ey);
}
m_pPageMeta.WriteDouble(m_oLine.m_dAscent);
m_pPageMeta.WriteDouble(m_oLine.m_dDescent);
LONG _position = 0;
if (nCount > 1)
{
_position = m_pPageMeta.GetSize();
m_pPageMeta.AddInt(0);
}
BYTE* pBufferMeta = m_oMeta.GetBuffer();
double dWidthLine = 0;
double dCurrentGlyphLineOffset = 0;
for (LONG lIndexChar = 0; lIndexChar < nCount; lIndexChar++)
{
NSWasm::CHChar* pChar = &m_oLine.m_pChars[lIndexChar];
// все настроки буквы (m_oMeta)
BYTE lLen = *pBufferMeta;
pBufferMeta++;
if (lLen > 0)
m_pPageMeta.Write(pBufferMeta, lLen);
pBufferMeta += lLen;
// смещение относительно предыдущей буквы (у всех, кроме первой)
// юникодное значение
// гид (если bIsGidExist == true)
// ширина буквы
m_pPageMeta.WriteBYTE(80); // CMetafile::ctDrawText
if (lIndexChar)
m_pPageMeta.WriteDouble2(pChar->x);
m_pPageMeta.WriteWCHAR(pChar->unicode);
if (bIsGidExist)
m_pPageMeta.WriteUSHORT(pChar->gid);
m_pPageMeta.WriteDouble2(pChar->width);
if (lIndexChar)
dCurrentGlyphLineOffset += pChar->x;
if (lIndexChar == (nCount - 1))
dWidthLine = dCurrentGlyphLineOffset + pChar->width;
}
if (nCount > 1)
{
int* pWidthBuf = (int*)(m_pPageMeta.GetBuffer() + _position);
*pWidthBuf = (int)(dWidthLine * 10000);
}
m_oLine.Clear();
m_oMeta.ClearNoAttack();
m_pPageMeta.WriteBYTE(162); // CMetafile::ctCommandTextLineEnd
}
#endif
void Page::Draw(IRenderer* pRenderer, bool* pbBreak)
{
#ifdef BUILDING_WASM_MODULE
m_pPageMeta.Clear();
//m_pPageMeta.SkipLen();
m_pPageMeta.SkipLen();
m_vLinks.clear();
#endif
XmlUtils::CXmlLiteReader oReader;
if (!oReader.FromStringA(m_wsRootPath->readXml(m_wsPagePath)))
@ -707,13 +231,6 @@ namespace XPS
{
DrawCanvas(oReader, pRenderer, &oState, pbBreak);
}
#ifdef BUILDING_WASM_MODULE
LONG nCount = m_oLine.GetCountChars();
if (nCount)
DumpLine();
//m_pPageMeta.WriteLen();
m_pPageMeta.WriteLen();
#endif
}
void Page::DrawCanvas(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState, bool* pbBreak)
{
@ -1183,12 +700,6 @@ namespace XPS
if (oEntry.bGid)
{
pRenderer->CommandDrawTextExCHAR(oEntry.nUnicode, oEntry.nGid, xpsUnitToMM(dXorigin), xpsUnitToMM(dYorigin), 0, 0);
#ifdef BUILDING_WASM_MODULE
std::wstring sUnicode;
sUnicode += wchar_t(oEntry.nUnicode);
GetGlyphs(pRenderer, sUnicode, &oEntry.nGid, xpsUnitToMM(dXorigin), xpsUnitToMM(dYorigin), bChangeFont);
bChangeFont = false;
#endif
}
else
{
@ -1198,12 +709,6 @@ namespace XPS
pRenderer->put_FontStringGID(FALSE);
pRenderer->CommandDrawTextCHAR(oEntry.nUnicode, xpsUnitToMM(dXorigin), xpsUnitToMM(dYorigin), 0, 0);
#ifdef BUILDING_WASM_MODULE
std::wstring sUnicode;
sUnicode += wchar_t(oEntry.nUnicode);
GetGlyphs(pRenderer, sUnicode, NULL, xpsUnitToMM(dXorigin), xpsUnitToMM(dYorigin), bChangeFont);
bChangeFont = false;
#endif
}
if (bNeedBold)
@ -1257,22 +762,10 @@ namespace XPS
if (oEntry.bGid)
{
pRenderer->CommandDrawTextExCHAR(oEntry.nUnicode, oEntry.nGid, 0, 0, 0, 0);
#ifdef BUILDING_WASM_MODULE
std::wstring sUnicode;
sUnicode += wchar_t(oEntry.nUnicode);
GetGlyphs(pRenderer, sUnicode, &oEntry.nGid, 0, 0, bChangeFont);
bChangeFont = false;
#endif
}
else
{
pRenderer->CommandDrawTextCHAR(oEntry.nUnicode, 0, 0, 0, 0);
#ifdef BUILDING_WASM_MODULE
std::wstring sUnicode;
sUnicode += wchar_t(oEntry.nUnicode);
GetGlyphs(pRenderer, sUnicode, NULL, 0, 0, bChangeFont);
bChangeFont = false;
#endif
}
if (bNeedBold)
@ -1441,7 +934,7 @@ namespace XPS
Aggplus::CMatrix oTransform(pdA, pdB, pdC, pdD, pdE, pdF);
double x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0;
CPageLink oLink = {0, 0, 0, 0, ""};
NSWasm::CPageLinkItem oLink = {"", 0, 0, 0, 0, 0};
std::wstring wsPath = wsPathData.c_stdstr();
size_t nFindX = wsPath.find(L"M ");
if (nFindX != std::wstring::npos)
@ -1489,16 +982,16 @@ namespace XPS
}
}
// Верхний левый угол
oLink.dX = x1 == x2 ? fmin(x1, x3) : fmin(x1, x2);
oLink.dY = y1 == y2 ? fmin(y1, y3) : fmin(y1, y2);
oLink.dH = x1 == x2 ? abs(y1 - y2) : abs(y1 - y3);
oLink.dW = y1 == y2 ? abs(x1 - x2) : abs(x1 - x3);
oLink.X = x1 == x2 ? fmin(x1, x3) : fmin(x1, x2);
oLink.Y = y1 == y2 ? fmin(y1, y3) : fmin(y1, y2);
oLink.H = x1 == x2 ? abs(y1 - y2) : abs(y1 - y3);
oLink.W = y1 == y2 ? abs(x1 - x2) : abs(x1 - x3);
std::wstring wsNameTarget = oReader.GetText();
if (wsNameTarget.find(L"http") == 0)
{
oLink.sLink = U_TO_UTF8(wsNameTarget);
m_vLinks.push_back(oLink);
oLink.Link = U_TO_UTF8(wsNameTarget);
m_oLinks.m_arLinks.push_back(oLink);
}
else
{
@ -1509,8 +1002,8 @@ namespace XPS
std::map<std::wstring, int>::iterator find = m_pDocument->m_mInternalLinks.find(wsNameTarget.substr(nSharp + 1));
if (find != m_pDocument->m_mInternalLinks.end())
{
oLink.sLink = '#' + std::to_string(find->second);
m_vLinks.push_back(oLink);
oLink.Link = '#' + std::to_string(find->second);
m_oLinks.m_arLinks.push_back(oLink);
}
}
}

View File

@ -58,30 +58,7 @@ namespace XPS
void Draw(IRenderer* pRenderer, bool* pbBreak);
#ifdef BUILDING_WASM_MODULE
BYTE* GetGlyphs();
BYTE* GetLinks();
void GetGlyphs(IRenderer* pRenderer, const std::wstring& bsUnicodeText, unsigned short* pGids, double x, double y, bool bChangeFont);
void DumpLine();
private:
struct CPageLink
{
double dX;
double dY;
double dW;
double dH;
std::string sLink;
};
std::vector<CPageLink> m_vLinks;
double m_dCurrentFontSize = 0.0;
NSWasm::CHLine m_oLine;
NSWasm::CData m_oMeta;
NSWasm::CData m_pPageMeta;
Aggplus::CMatrix m_pLastTransform;
LONG m_nCurrentFont = -1;
LONG m_nLastBrushColor1 = -1;
LONG m_nLastBrushAlpha1 = -1;
NSWasm::CPageLink m_oLinks;
#endif
private: