Commit 1c98740b authored by Oleg.Korshul's avatar Oleg.Korshul Committed by Alexander Trofimov
parent dad0cae9
......@@ -51,8 +51,6 @@ INCLUDEPATH += \
../../DesktopEditor/freetype-2.5.2/include
SOURCES += \
src/HTMLRenderer.cpp \
src/HTMLRenderer2.cpp \
src/HTMLRenderer3.cpp
HEADERS += \
......@@ -68,11 +66,6 @@ HEADERS += \
src/VectorGraphicsWriter2.h \
src/VMLWriter.h \
src/Writer.h \
src/Writer2.h \
src/Writer3.h \
src/Writer4.h \
include/HTMLRenderer.h \
include/HTMLRenderer2.h \
include/HTMLRenderer3.h
unix {
......
......@@ -6,6 +6,9 @@
class CASCHTMLRenderer_Private;
class CASCHTMLRenderer : public IRenderer
{
public:
CASCHTMLRenderer();
~CASCHTMLRenderer();
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType);
......
......@@ -221,6 +221,16 @@ namespace NSHtmlRenderer
LONG bottom;
};
inline bool IsEqualMain(const Aggplus::CMatrix* pMatrix, const Aggplus::CMatrix* pMatrix2)
{
if (fabs(pMatrix->m_agg_mtx.sx - pMatrix2->m_agg_mtx.sx) < 0.001 &&
fabs(pMatrix->m_agg_mtx.sy - pMatrix2->m_agg_mtx.sy) < 0.001 &&
fabs(pMatrix->m_agg_mtx.shx - pMatrix2->m_agg_mtx.shx) < 0.001 &&
fabs(pMatrix->m_agg_mtx.shy - pMatrix2->m_agg_mtx.shy) < 0.001)
return true;
return false;
}
static RECT GetImageBounds(CBgraFrame* pFrame)
{
BYTE* pBuffer = pFrame->get_Data();
......@@ -687,6 +697,21 @@ namespace NSHtmlRenderer
*((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)
{
// здесь никаких даблов. Сплошные округления
......
......@@ -42,6 +42,7 @@ namespace NSHtmlRenderer
m_bInitH = oSrc.m_bInitH;
m_pUpdater = oSrc.m_pUpdater;
return *this;
}
inline double GetWidth()
......
......@@ -12,6 +12,710 @@
class CASCHTMLRenderer_Private
{
public:
NSHtmlRenderer::CDocument m_oDocument; // вся информация о документе (только страницы и их размеры)
NSHtmlRenderer::CThumbnails m_oThumbnail; // генератор табнейлов (создает, отрисовывает, сохраняет)
//NSHtmlRenderer::CWriter m_oWriter; // сам вьюер. основной класс
std::wstring m_strDstFile;
LONG m_lLastSavedPage;
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter; // конвертер сложных гафических путей в простые
CApplicationFonts m_oApplicationFonts;
CFontManager* m_pFontManager; // менеджер шрифтов
Aggplus::CMatrix m_oBaseTransform; // матрица перерасчета координатных осей (здесь: миллиметры -> пикселы)
Aggplus::CMatrix m_oTransform; // текущая матрица преобразований рендерера
Aggplus::CMatrix m_oFullTransform; // полная матрица преобразований (m_oBaseTransform * m_oTransform)
double m_dTransformAngle;
LONG m_lCurrentCommandType; // текущая команда
LONG m_lCurrentPage; // текущая страница
bool m_bIsMetafileDrawing;
bool m_bIsTextGraphicType;
double m_dDpiX;
double m_dDpiY;
LONG m_lClipMode;
NSStructures::CPen m_oPen; // настройки всей графики (скопирован ашник из AVSGraphics)
NSStructures::CBrush m_oBrush;
NSStructures::CFont m_oFont;
NSStructures::CShadow m_oShadow;
NSStructures::CEdgeText m_oEdge;
NSStructures::CFont m_oInstalledFont;
bool m_bPageClosed;
bool m_bPageOpened;
bool m_bIsThumbnailsCreate;
bool m_bIsWEB;
bool m_bIsMenu;
public:
};
CASCHTMLRenderer::CASCHTMLRenderer()
{
m_pInternal->m_lLastSavedPage = 0;
m_pInternal->m_oDocument.SetUpdater(this);
m_pInternal->m_dDpiX = 96.0;
m_pInternal->m_dDpiY = 96.0;
m_pInternal->m_lClipMode = c_nClipRegionTypeWinding;
m_pInternal->m_oWriter.m_dDpiX = m_dDpiX;
m_pInternal->m_oWriter.m_dDpiY = m_dDpiY;
m_pInternal->m_oWriter.m_pPen = &m_oPen;
m_pInternal->m_oWriter.m_pBrush = &m_oBrush;
m_pInternal->m_oWriter.m_pFont = &m_oFont;
m_pInternal->m_pSimpleGraphicsConverter = new Aggplus::CGraphicsPathSimpleConverter();
m_pInternal->m_pSimpleGraphicsConverter->SetRenderer(this);
m_pInternal->m_bPageClosed = TRUE;
m_pInternal->m_dTransformAngle = 0.0;
m_pInternal->m_pFontManager = NULL;
//m_oWriter.SetSimpleConverter(m_pSimpleGraphicsConverter, &m_oFullTransform);
//m_oWriter.m_oPage.SetSettings(&m_oPen, &m_oBrush, &m_oFont, m_oWriter.GetStyles(), &m_oTransform);
m_pInternal->m_bIsThumbnailsCreate = false;
m_pInternal->m_bIsWEB = false;
m_pInternal->m_bIsMenu = false;
m_bIsMetafileDrawing = false;
m_bIsTextGraphicType = false;
}
CASCHTMLRenderer::~CASCHTMLRenderer()
{
RELEASEOBJECT((m_pInternal->m_pSimpleGraphicsConverter));
}
HRESULT CASCHTMLRenderer::get_Type(LONG* lType)
{
*lType = c_nHtmlRendrerer;
return S_OK;
}
//-------- Функции для работы со страницей --------------------------------------------------
HRESULT CASCHTMLRenderer::NewPage()
{
if (m_pInternal->m_bPageOpened)
{
m_pInternal->EndPage();
}
m_pInternal->m_oDocument.NewPage();
m_pInternal->m_bPageClosed = false;
m_pInternal->m_bPageOpened = true;
m_pInternal->m_bIsMetafileDrawing = false;
m_pInternal->m_bIsTextGraphicType = false;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_Height(double* dHeight)
{
size_t nCount = m_pInternal->m_oDocument.m_arrPages.size();
if (nCount > 0)
*dHeight = m_pInternal->m_oDocument.m_arrPages[nCount - 1].GetHeight();
return S_OK;
}
HRESULT CASCHTMLRenderer::put_Height(const double& dHeight)
{
size_t lCount = m_pInternal->m_oDocument.m_arrPages.size();
if (0 != lCount)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_Height(dHeight);
}
m_pInternal->m_oDocument.m_arrPages[lCount - 1].SetHeight(dHeight);
}
}
HRESULT CASCHTMLRenderer::get_Width(double* dWidth)
{
size_t nCount = m_pInternal->m_oDocument.m_arrPages.size();
if (nCount > 0)
*dWidth = m_pInternal->m_oDocument.m_arrPages[nCount - 1].GetWidth();
return S_OK;
}
HRESULT CASCHTMLRenderer::put_Width(const double& dWidth)
{
size_t lCount = m_pInternal->m_oDocument.m_arrPages.size();
if (0 != lCount)
{
if (m_bIsThumbnailsCreate)
{
m_oThumbnail.put_Width(dWidth);
}
m_oDocument.m_arrPages[lCount - 1].SetWidth(dWidth);
}
return S_OK;
}
HRESULT CASCHTMLRenderer::get_DpiX(double* dDpiX)
{
*dDpiX = m_pInternal->m_dDpiX;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_DpiY(double* dDpiY)
{
*dDpiY = m_pInternal->m_dDpiY;
}
// pen --------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer::get_PenColor(LONG* lColor)
{
*lColor = m_pInternal->m_oPen.Color;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenColor(const LONG& lColor)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenColor(lColor);
}
m_pInternal->m_oPen.Color = lColor;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenAlpha(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oPen.Alpha;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenAlpha(const LONG& lAlpha)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenAlpha(lAlpha);
}
m_pInternal->m_oPen.Alpha = lAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenSize(double* dSize)
{
*dSize = m_pInternal->m_oPen.Size;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenSize(const double& dSize)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenSize(dSize);
}
m_pInternal->m_oPen.Size = dSize;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenDashStyle(BYTE* val)
{
*val = m_pInternal->m_oPen.DashStyle;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenDashStyle(const BYTE& val)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenDashStyle(val);
}
m_pInternal->m_oPen.DashStyle = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenLineStartCap(BYTE* val)
{
*val = m_pInternal->m_oPen.LineStartCap;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenLineStartCap(const BYTE& val)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenLineStartCap(val);
}
m_pInternal->m_oPen.LineStartCap = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenLineEndCap(BYTE* val)
{
*val = m_pInternal->m_oPen.LineEndCap;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenLineEndCap(const BYTE& val)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenLineEndCap(val);
}
m_pInternal->m_oPen.LineEndCap = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenLineJoin(BYTE* val)
{
*val = m_pInternal->m_oPen.LineJoin;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenLineJoin(const BYTE& val)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenLineJoin(val);
}
m_pInternal->m_oPen.LineJoin = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenDashOffset(double* dOffset)
{
*val = m_pInternal->m_oPen.DashOffset;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenDashOffset(const double& dOffset)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenDashOffset(val);
}
m_pInternal->m_oPen.DashOffset = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenAlign(LONG* lAlign)
{
*val = m_pInternal->m_oPen.Align;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenAlign(const LONG& lAlign)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenAlign(val);
}
m_pInternal->m_oPen.Align = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_PenMiterLimit(double* dOffset)
{
*val = m_pInternal->m_oPen.MiterLimit;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_PenMiterLimit(const double& dOffset)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_PenMiterLimit(val);
}
m_pInternal->m_oPen.MiterLimit = val;
return S_OK;
}
HRESULT CASCHTMLRenderer::PenDashPattern(double* pPattern, LONG lCount)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.PenDashPattern(pPattern);
}
if (NULL != pPattern)
{
m_pInternal->m_oPen.SetDashPattern(pPattern, lCount);
}
return S_OK;
}
// brush ------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer::get_BrushType(LONG* lType)
{
*lType = m_pInternal->m_oBrush.Type;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushType(const LONG& lType)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushType(lType);
}
m_pInternal->m_oBrush.Type = lType;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushColor1(LONG* lColor)
{
*lColor = m_pInternal->m_oBrush.Color1;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushColor1(const LONG& lColor)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushColor1(lColor);
}
m_pInternal->m_oBrush.Color1 = lColor;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushAlpha1(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oBrush.Alpha1;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushAlpha1(const LONG& lAlpha)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushAlpha1(lAlpha);
}
m_pInternal->m_oBrush.Alpha1 = lAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushColor2(LONG* lColor)
{
*lColor = m_pInternal->m_oBrush.Color2;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushColor2(const LONG& lColor)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushColor2(lColor);
}
m_pInternal->m_oBrush.Color2 = lColor;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushAlpha2(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oBrush.Alpha2;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushAlpha2(const LONG& lAlpha)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushAlpha2(lAlpha);
}
m_pInternal->m_oBrush.Alpha2 = lAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushTexturePath(std::wstring* bsPath)
{
*bsPath = m_pInternal->m_oBrush.TexturePath;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushTexturePath(const std::wstring& bsPath)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushTexturePath(bsPath);
}
m_pInternal->m_oBrush.TexturePath = bsPath;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushTextureMode(LONG* lMode)
{
*lMode = m_pInternal->m_oBrush.TextureMode;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushTextureMode(const LONG& lMode)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushTextureMode(lMode);
}
m_pInternal->m_oBrush.TextureMode = lMode;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushTextureAlpha(LONG* lTxAlpha)
{
*lTxAlpha = m_pInternal->m_oBrush.TextureAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushTextureAlpha(const LONG& lTxAlpha)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushTextureAlpha(lTxAlpha);
}
m_pInternal->m_oBrush.TextureAlpha = lTxAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_BrushLinearAngle(double* dAngle)
{
*dAngle = m_pInternal->m_oBrush.LinearAngle;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushLinearAngle(const double& dAngle)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushLinearAngle(dAngle);
}
m_pInternal->m_oBrush.LinearAngle = dAngle;
return S_OK;
}
HRESULT CASCHTMLRenderer::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.BrushRect(val, left, top, width, height);
}
m_pInternal->m_oBrush.Rectable = val;
m_pInternal->m_oBrush.Rect.X = (float)left;
m_pInternal->m_oBrush.Rect.Y = (float)top;
m_pInternal->m_oBrush.Rect.Width = (float)width;
m_pInternal->m_oBrush.Rect.Height = (float)height;
return S_OK;
}
HRESULT CASCHTMLRenderer::BrushBounds(const double& left, const double& top, const double& width, const double& height)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.BrushBounds(left, top, width, height);
}
m_pInternal->m_oBrush.Bounds.left = left;
m_pInternal->m_oBrush.Bounds.top = top;
m_pInternal->m_oBrush.Bounds.right = left + width;
m_pInternal->m_oBrush.Bounds.bottom = top + height;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_BrushGradientColors(lColors, pPositions, nCount);
}
m_pInternal->m_oBrush.m_arrSubColors.RemoveAll();
for (LONG i = 0; i < nCount; ++i)
{
NSStructures::CBrush::TSubColor color;
color.color = lColors[i];
color.position = (long)(pPositions[i] * 65536);
m_pInternal->m_oBrush.m_arrSubColors.Add(color);
}
return S_OK;
}
// font -------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer::get_FontName(std::wstring* bsName)
{
*bsName = m_pInternal->m_oFont.Name;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontName(const std::wstring& bsName)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_FontName(bsName);
}
m_pInternal->m_oFont.Name = bsName;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_FontPath(std::wstring* bsName)
{
*bsName = m_pInternal->m_oFont.Path;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontPath(const std::wstring& bsName)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_FontPath(bsName);
}
m_pInternal->m_oFont.Path = bsName;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_FontSize(double* dSize)
{
*dSize = m_pInternal->m_oFont.Size;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontSize(const double& dSize)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_FontSize(dSize);
}
m_pInternal->m_oFont.Size = dSize;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_FontStyle(LONG* lStyle)
{
*lStyle = m_pInternal->m_oFont.GetStyle();
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontStyle(const LONG& lStyle)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_FontStyle(lStyle);
}
m_pInternal->m_oFont.SetStyle(lStyle);
return S_OK;
}
HRESULT CASCHTMLRenderer::get_FontStringGID(INT* bGID)
{
*bGID = m_pInternal->m_oFont.StringGID;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontStringGID(const INT& bGID)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_FontStringGID(bGID);
}
m_pInternal->m_oFont.StringGID = bGID;
m_pInternal->m_pFontManager->SetStringGID(bGID);
return S_OK;
}
HRESULT CASCHTMLRenderer::get_FontCharSpace(double* dSpace)
{
*dSpace = m_pInternal->m_oFont.CharSpace;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontCharSpace(const double& dSpace)
{
if (m_pInternal->m_bIsThumbnailsCreate)
{
m_pInternal->m_oThumbnail.put_FontCharSpace(dSpace);
}
m_pInternal->m_oFont.CharSpace = dSpace;
return S_OK;
}
HRESULT CASCHTMLRenderer::get_FontFaceIndex(int* lFaceIndex)
{
*lFaceIndex = m_pInternal->m_oFont.FaceIndex;
return S_OK;
}
HRESULT CASCHTMLRenderer::put_FontFaceIndex(const int& lFaceIndex)
{
if (m_bIsThumbnailsCreate)
{
m_oThumbnail.put_FontCharSpace(dSpace);
}
m_oFont.CharSpace = dSpace;
return S_OK;
}
//-------- Функции для вывода текста --------------------------------------------------------
HRESULT CASCHTMLRenderer::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h);
//-------- Маркеры для команд ---------------------------------------------------------------
HRESULT CASCHTMLRenderer::BeginCommand(const DWORD& lType);
HRESULT CASCHTMLRenderer::EndCommand(const DWORD& lType);
//-------- Функции для работы с Graphics Path -----------------------------------------------
HRESULT CASCHTMLRenderer::PathCommandMoveTo(const double& x, const double& y);
HRESULT CASCHTMLRenderer::PathCommandLineTo(const double& x, const double& y);
HRESULT CASCHTMLRenderer::PathCommandLinesTo(double* points, const int& count);
HRESULT CASCHTMLRenderer::PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3);
HRESULT CASCHTMLRenderer::PathCommandCurvesTo(double* points, const int& count);
HRESULT CASCHTMLRenderer::PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle);
HRESULT CASCHTMLRenderer::PathCommandClose();
HRESULT CASCHTMLRenderer::PathCommandEnd();
HRESULT CASCHTMLRenderer::DrawPath(const LONG& nType);
HRESULT CASCHTMLRenderer::PathCommandStart();
HRESULT CASCHTMLRenderer::PathCommandGetCurrentPoint(double* x, double* y);
HRESULT CASCHTMLRenderer::PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::PathCommandTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h);
//-------- Функции для вывода изображений ---------------------------------------------------
HRESULT CASCHTMLRenderer::DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h);
HRESULT CASCHTMLRenderer::DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255);
// transform --------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer::SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6);
HRESULT CASCHTMLRenderer::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF);
HRESULT CASCHTMLRenderer::ResetTransform();
// -----------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer::get_ClipMode(LONG* plMode);
HRESULT CASCHTMLRenderer::put_ClipMode(const LONG& lMode);
// additiaonal params ----------------------------------------------------------------------
HRESULT CASCHTMLRenderer::CommandLong(const LONG& lType, const LONG& lCommand);
HRESULT CASCHTMLRenderer::CommandDouble(const LONG& lType, const double& dCommand);
HRESULT CASCHTMLRenderer::CommandString(const LONG& lType, const std::wstring& sCommand);
// owner params ----------------------------------------------------------------------
HRESULT CASCHTMLRenderer::get_Mode(LONG *plMode);
HRESULT CASCHTMLRenderer::put_Mode(LONG lMode);
HRESULT CASCHTMLRenderer::CreateOfficeFile(std::wstring bsFileName);
HRESULT CASCHTMLRenderer::CloseFile();
HRESULT CASCHTMLRenderer::SetAdditionalParam(std::string sParamName, int nValue);
#include "../include/HTMLRenderer3.h"
#include "./Common.h"
#include "./Document.h"
#include "./Writer.h"
class CASCHTMLRenderer3_Private : public NSHtmlRenderer::IBaseMatrixUpdater
{
public:
NSHtmlRenderer::CDocument m_oDocument; // вся информация о документе (только страницы и их размеры)
NSHtmlRenderer::CWriter m_oWriter; // сам вьюер. основной класс
NSHtmlRenderer::CGraphicsDumper m_oDumper;
bool m_bIsGraphicsDumperMode;
std::wstring m_strDstFile;
int m_lLastSavedPage;
Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; // конвертер сложных гафических путей в простые
CApplicationFonts m_oApplicationFonts;
CFontManager* m_pFontManager; // менеджер шрифтов
Aggplus::CMatrix m_oTransform; // текущая матрица преобразований рендерера
double m_dTransformAngle;
int m_lCurrentCommandType; // текущая команда
int m_lCurrentPage; // текущая страница
bool m_bIsMetafileDrawing;
bool m_bIsTextGraphicType;
int m_lClipMode;
NSStructures::CPen m_oPen; // настройки всей графики (скопирован ашник из AVSGraphics)
NSStructures::CBrush m_oBrush;
NSStructures::CFont m_oFont;
NSStructures::CFont m_oInstalledFont;
bool m_bPageClosed;
bool m_bPageOpened;
bool m_bIsChangedFontParamBetweenDrawText;
public:
int* m_pTempUnicodes;
int m_nTempUnicodesAlloc;
int m_nTempUnicodesLen;
public:
CASCHTMLRenderer3_Private()
{
m_oApplicationFonts.Initialize();
m_lLastSavedPage = 0;
m_oDocument.SetUpdater(this);
m_oWriter.m_pPen = &m_oPen;
m_oWriter.m_pBrush = &m_oBrush;
m_oWriter.m_pFont = &m_oFont;
m_bPageClosed = true;
m_dTransformAngle = 0.0;
m_pFontManager = NULL;
m_oWriter.SetSimpleConverter(&m_oSimpleGraphicsConverter, &m_oTransform);
m_bIsMetafileDrawing = false;
m_bIsTextGraphicType = false;
m_bIsChangedFontParamBetweenDrawText = true;
m_bIsGraphicsDumperMode = false;
m_nTempUnicodesAlloc = 100;
m_pTempUnicodes = new int[m_nTempUnicodesAlloc];
m_nTempUnicodesLen = 0;
}
~CASCHTMLRenderer3_Private()
{
RELEASEARRAYOBJECTS(m_pTempUnicodes);
}
public:
void GetUnicodes(const std::wstring& sText)
{
int nLen = (int)sText.length();
if (nLen > m_nTempUnicodesAlloc)
{
RELEASEARRAYOBJECTS(m_pTempUnicodes);
m_nTempUnicodesAlloc = nLen;
m_pTempUnicodes = new int[m_nTempUnicodesAlloc];
}
m_nTempUnicodesLen = 0;
const wchar_t* pWchars = sText.c_str();
if (sizeof(wchar_t) == 2)
{
for (int nIndex = 0, nGlyphIndex = 0; nIndex < nLen; ++nIndex, ++nGlyphIndex)
{
int code = (int)pWchars[nIndex];
if (code >= 0xD800 && code <= 0xDFFF && (nIndex + 1) < nLen)
{
++nIndex;
code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[nIndex]));
}
m_pTempUnicodes[m_nTempUnicodesLen++] = code;
}
}
else
{
for ( int nIndex = 0; nIndex < nLen; ++nIndex )
{
m_pTempUnicodes[m_nTempUnicodesLen++] = (int)pWchars[nIndex];
}
}
}
public:
virtual void OnBaseMatrixUpdate(const double& dWidth, const double& dHeight)
{
if (m_bPageClosed)
{
// значит размеры пришли не в первый раз для текущей страницы
return;
}
m_bPageClosed = true;
StartPage(dWidth, dHeight);
}
void CalculateFullTransform()
{
m_dTransformAngle = m_oTransform.z_Rotation();
}
inline void MoveTo(const double& dX, const double& dY)
{
m_oWriter.WritePathMoveTo(dX, dY);
}
inline void LineTo(const double& dX, const double& dY)
{
m_oWriter.WritePathLineTo(dX, dY);
}
inline void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3)
{
m_oWriter.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
}
void Start()
{
m_oWriter.WriteBeginPath();
}
void End()
{
m_oWriter.WriteEndPath();
}
void Close()
{
m_oWriter.WritePathClose();
}
void StartPage(const double& dWidth, const double& dHeight)
{
++m_lCurrentPage;
m_oWriter.NewPage(dWidth, dHeight);
}
void EndPage()
{
m_oWriter.EndPage();
m_bPageOpened = FALSE;
}
void _SetFont()
{
if (NULL == m_pFontManager)
{
m_pFontManager = m_oApplicationFonts.GenerateFontManager();
}
double dPix = m_oFont.CharSpace * 96 / 25.4;
if (m_oInstalledFont.IsEqual(&m_oFont))
{
if (1 < m_oWriter.m_dWidth)
{
m_pFontManager->SetCharSpacing(dPix);
}
return;
}
m_pFontManager->SetStringGID(m_oFont.StringGID);
if (1 < m_oWriter.m_dWidth)
{
m_pFontManager->SetCharSpacing(dPix);
}
if (m_oFont.Path.empty())
{
m_pFontManager->LoadFontByName(m_oFont.Name, m_oFont.Size, m_oFont.GetStyle(), 96, 96);
}
else
{
m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, m_oFont.Size, 96, 96);
}
m_oInstalledFont = m_oFont;
}
};
HRESULT CASCHTMLRenderer3::get_Type(LONG* lType)
{
*lType = c_nHtmlRendrerer2;
return S_OK;
}
//-------- Функции для работы со страницей --------------------------------------------------
HRESULT CASCHTMLRenderer3::NewPage()
{
if (m_pInternal->m_bPageOpened)
{
m_pInternal->EndPage();
}
m_pInternal->m_oPen.SetDefaultParams();
m_pInternal->m_oBrush.SetDefaultParams();
m_pInternal->m_oFont.SetDefaultParams();
m_pInternal->m_oDocument.NewPage();
m_pInternal->m_bPageClosed = false;
m_pInternal->m_bPageOpened = true;
m_pInternal->m_bIsMetafileDrawing = false;
m_pInternal->m_bIsTextGraphicType = false;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_Height(double* dHeight)
{
size_t nCount = m_pInternal->m_oDocument.m_arrPages.size();
if ((nCount > 0) && (NULL != dHeight))
*dHeight = m_pInternal->m_oDocument.m_arrPages[nCount - 1].GetHeight();
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_Height(const double& dHeight)
{
size_t nCount = m_pInternal->m_oDocument.m_arrPages.size();
if (nCount > 0)
m_pInternal->m_oDocument.m_arrPages[nCount - 1].SetHeight(dHeight);
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_Width(double* dWidth)
{
size_t nCount = m_pInternal->m_oDocument.m_arrPages.size();
if ((nCount > 0) && (NULL != dWidth))
*dWidth = m_pInternal->m_oDocument.m_arrPages[nCount - 1].GetWidth();
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_Width(const double& dWidth)
{
size_t nCount = m_pInternal->m_oDocument.m_arrPages.size();
if (nCount > 0)
m_pInternal->m_oDocument.m_arrPages[nCount - 1].SetWidth(dWidth);
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_DpiX(double* dDpiX)
{
*dDpiX = 96;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_DpiY(double* dDpiY)
{
*dDpiY = 96;
return S_OK;
}
// pen --------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::get_PenColor(LONG* lColor)
{
*lColor = m_pInternal->m_oPen.Color;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenColor(const LONG& lColor)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenColor(lColor);
m_pInternal->m_oPen.Color = lColor;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenAlpha(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oPen.Alpha;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenAlpha(const LONG& lAlpha)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenAlpha(lAlpha);
m_pInternal->m_oPen.Alpha = lAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenSize(double* dSize)
{
*dSize = m_pInternal->m_oPen.Size;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenSize(const double& dSize)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenSize(dSize);
m_pInternal->m_oPen.Size = dSize;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenDashStyle(BYTE* val)
{
*val = m_pInternal->m_oPen.DashStyle;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenDashStyle(const BYTE& val)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenDashStyle(val);
m_pInternal->m_oPen.DashStyle = val;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenLineStartCap(BYTE* val)
{
*val = m_pInternal->m_oPen.LineStartCap;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenLineStartCap(const BYTE& val)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenLineStartCap(val);
m_pInternal->m_oPen.LineStartCap = val;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenLineEndCap(BYTE* val)
{
*val = m_pInternal->m_oPen.LineEndCap;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenLineEndCap(const BYTE& val)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenLineEndCap(val);
m_pInternal->m_oPen.LineEndCap = val;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenLineJoin(BYTE* val)
{
*val = m_pInternal->m_oPen.LineJoin;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenLineJoin(const BYTE& val)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenLineJoin(val);
m_pInternal->m_oPen.LineJoin = val;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenDashOffset(double* dOffset)
{
*dOffset = m_pInternal->m_oPen.DashOffset;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenDashOffset(const double& dOffset)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenDashOffset(dOffset);
m_pInternal->m_oPen.DashOffset = dOffset;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenAlign(LONG* lAlign)
{
*lAlign = m_pInternal->m_oPen.Align;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenAlign(const LONG& lAlign)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenAlign(lAlign);
m_pInternal->m_oPen.Align = lAlign;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_PenMiterLimit(double* dOffset)
{
*dOffset = m_pInternal->m_oPen.MiterLimit;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_PenMiterLimit(const double& dOffset)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_PenMiterLimit(dOffset);
m_pInternal->m_oPen.MiterLimit = dOffset;
return S_OK;
}
HRESULT CASCHTMLRenderer3::PenDashPattern(double* pPattern, LONG lCount)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PenDashPattern(pPattern, lCount);
m_pInternal->m_oPen.SetDashPattern(pPattern, lCount);
return S_OK;
}
// brush ------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::get_BrushType(LONG* lType)
{
*lType = m_pInternal->m_oBrush.Type;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushType(const LONG& lType)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushType(lType);
m_pInternal->m_oBrush.Type = lType;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushColor1(LONG* lColor)
{
*lColor = m_pInternal->m_oBrush.Color1;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushColor1(const LONG& lColor)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushColor1(lColor);
m_pInternal->m_oBrush.Color1 = lColor;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushAlpha1(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oBrush.Alpha1;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushAlpha1(const LONG& lAlpha)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushAlpha1(lAlpha);
m_pInternal->m_oBrush.Alpha1 = lAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushColor2(LONG* lColor)
{
*lColor = m_pInternal->m_oBrush.Color2;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushColor2(const LONG& lColor)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushColor2(lColor);
m_pInternal->m_oBrush.Color2 = lColor;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushAlpha2(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oBrush.Alpha2;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushAlpha2(const LONG& lAlpha)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushAlpha2(lAlpha);
m_pInternal->m_oBrush.Alpha2 = lAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushTexturePath(std::wstring* bsPath)
{
*bsPath = m_pInternal->m_oBrush.TexturePath;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushTexturePath(const std::wstring& bsPath)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushTexturePath(bsPath);
m_pInternal->m_oBrush.TexturePath = bsPath;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushTextureMode(LONG* lMode)
{
*lMode = m_pInternal->m_oBrush.TextureMode;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushTextureMode(const LONG& lMode)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushTextureMode(lMode);
m_pInternal->m_oBrush.TextureMode = lMode;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushTextureAlpha(LONG* lTxAlpha)
{
*lTxAlpha = m_pInternal->m_oBrush.TextureAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushTextureAlpha(const LONG& lTxAlpha)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushTextureAlpha(lTxAlpha);
m_pInternal->m_oBrush.TextureAlpha = lTxAlpha;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_BrushLinearAngle(double* dAngle)
{
*dAngle = m_pInternal->m_oBrush.LinearAngle;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushLinearAngle(const double& dAngle)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushLinearAngle(dAngle);
m_pInternal->m_oBrush.LinearAngle = dAngle;
return S_OK;
}
HRESULT CASCHTMLRenderer3::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.BrushRect(val, left, top, width, height);
m_pInternal->m_oBrush.Rectable = val;
m_pInternal->m_oBrush.Rect.X = (float)left;
m_pInternal->m_oBrush.Rect.Y = (float)top;
m_pInternal->m_oBrush.Rect.Width = (float)width;
m_pInternal->m_oBrush.Rect.Height = (float)height;
return S_OK;
}
HRESULT CASCHTMLRenderer3::BrushBounds(const double& left, const double& top, const double& width, const double& height)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.BrushBounds(left, top, width, height);
m_pInternal->m_oBrush.Bounds.left = left;
m_pInternal->m_oBrush.Bounds.top = top;
m_pInternal->m_oBrush.Bounds.right = left + width;
m_pInternal->m_oBrush.Bounds.bottom = top + height;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_BrushGradientColors(lColors, pPositions, nCount);
m_pInternal->m_oBrush.m_arrSubColors.RemoveAll();
for (LONG i = 0; i < nCount; ++i)
{
NSStructures::CBrush::TSubColor color;
color.color = lColors[i];
color.position = (long)(pPositions[i] * 65536);
m_pInternal->m_oBrush.m_arrSubColors.Add(color);
}
return S_OK;
}
// font -------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::get_FontName(std::wstring* bsName)
{
*bsName = m_pInternal->m_oFont.Name;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontName(const std::wstring& bsName)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontName(bsName);
m_pInternal->m_oFont.Name = bsName;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_FontPath(std::wstring* bsName)
{
*bsName = m_pInternal->m_oFont.Path;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontPath(const std::wstring& bsName)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontPath(bsName);
m_pInternal->m_oFont.Path = bsName;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_FontSize(double* dSize)
{
*dSize = m_pInternal->m_oFont.Size;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontSize(const double& dSize)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontSize(dSize);
if (m_pInternal->m_oFont.Size != dSize)
{
m_pInternal->m_oFont.Size = dSize;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_FontStyle(LONG* lStyle)
{
*lStyle = m_pInternal->m_oFont.GetStyle();
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontStyle(const LONG& lStyle)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontStyle(lStyle);
LONG lOld = m_pInternal->m_oFont.GetStyle();
if (lOld != lStyle)
{
m_pInternal->m_oFont.SetStyle(lStyle);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_FontStringGID(INT* bGID)
{
*bGID = m_pInternal->m_oFont.StringGID;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontStringGID(const INT& bGID)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontStringGID(bGID);
m_pInternal->m_oFont.StringGID = bGID;
m_pInternal->m_pFontManager->SetStringGID(bGID);
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_FontCharSpace(double* dSpace)
{
*dSpace = m_pInternal->m_oFont.CharSpace;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontCharSpace(const double& dSpace)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontCharSpace(dSpace);
m_pInternal->m_oFont.CharSpace = dSpace;
return S_OK;
}
HRESULT CASCHTMLRenderer3::get_FontFaceIndex(int* lFaceIndex)
{
*lFaceIndex = m_pInternal->m_oFont.FaceIndex;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_FontFaceIndex(const int& lFaceIndex)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_FontFaceIndex(lFaceIndex);
m_pInternal->m_oFont.FaceIndex = lFaceIndex;
return S_OK;
}
//-------- Функции для вывода текста --------------------------------------------------------
HRESULT CASCHTMLRenderer3::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.CommandDrawTextCHAR(c, x, y, w, h);
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
int _c = (int)c;
m_pInternal->m_oWriter.WriteText(&_c, NULL, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
return S_OK;
}
HRESULT CASCHTMLRenderer3::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.CommandDrawText(bsText, x, y, w, h);
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
m_pInternal->GetUnicodes(bsText);
m_pInternal->m_oWriter.WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen,
x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
return S_OK;
}
HRESULT CASCHTMLRenderer3::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.CommandDrawTextExCHAR(c, gid, x, y, w, h);
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
int _c = (int)c;
int _g = (int)gid;
m_pInternal->m_oWriter.WriteText(&_c, &_g, 1,
x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
return S_OK;
}
HRESULT CASCHTMLRenderer3::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.CommandDrawText(bsUnicodeText, x, y, w, h);
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
m_pInternal->GetUnicodes(bsUnicodeText);
m_pInternal->m_oWriter.WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen,
x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
return S_OK;
}
//-------- Маркеры для команд ---------------------------------------------------------------
HRESULT CASCHTMLRenderer3::BeginCommand(const DWORD& lType)
{
if (m_pInternal->m_bIsGraphicsDumperMode && lType != c_nPDFTilingFill)
return m_pInternal->m_oDumper.BeginCommand(lType);
if (c_nClipType == lType)
{
m_pInternal->m_oWriter.WritePathClip();
}
else if (c_nPathType == lType)
{
m_pInternal->m_oWriter.WriteBeginPath();
m_pInternal->m_oSimpleGraphicsConverter.PathCommandEnd();
}
else if (c_nImageType == lType)
{
m_pInternal->m_bIsMetafileDrawing = true;
}
else if (c_nTextGraphicType == lType)
{
m_pInternal->m_bIsTextGraphicType = true;
}
else if (c_nPDFTilingFill == lType)
{
m_pInternal->m_oWriter.m_lTilingCounter++;
}
m_pInternal->m_lCurrentCommandType = lType;
return S_OK;
}
HRESULT CASCHTMLRenderer3::EndCommand(const DWORD& lType)
{
if (m_pInternal->m_bIsGraphicsDumperMode && lType != c_nPDFTilingFill)
return m_pInternal->m_oDumper.EndCommand(lType);
if (c_nPageType == lType)
{
m_pInternal->EndPage();
}
else if (c_nClipType == lType)
{
m_pInternal->m_oWriter.WritePathClipEnd();
}
else if (c_nResetClipType == lType)
{
m_pInternal->m_oWriter.WritePathResetClip();
}
//else if (c_nPathType == lType)
//{
// PathCommandEnd();
//}
else if (c_nImageType == lType)
{
m_pInternal->m_bIsMetafileDrawing = false;
}
else if (c_nTextGraphicType == lType)
{
m_pInternal->m_bIsTextGraphicType = false;
}
else if (c_nPDFTilingFill == lType)
{
m_pInternal->m_oWriter.m_lTilingCounter--;
if (0 == m_pInternal->m_oWriter.m_lTilingCounter)
{
m_pInternal->m_bIsGraphicsDumperMode = false;
// dump Graphics
CBgraFrame* pFrame = m_pInternal->m_oDumper.ConvertVectorGraphics();
m_pInternal->m_oWriter.WritePattern(pFrame, m_pInternal->m_oDumper.m_oTile);
RELEASEOBJECT(pFrame);
}
}
//else if (c_nParagraphType == lType)
//{
// m_oWriter.m_oPage.m_oText.EndParagraph();
//}
m_pInternal->m_lCurrentCommandType = -1;
return S_OK;
}
//-------- Функции для работы с Graphics Path -----------------------------------------------
HRESULT CASCHTMLRenderer3::PathCommandMoveTo(const double& x, const double& y)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandMoveTo(x, y);
if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType)
{
m_pInternal->MoveTo(x, y);
}
else
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandMoveTo(x, y);
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandLineTo(const double& x, const double& y)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandLineTo(x, y);
if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType)
{
m_pInternal->LineTo(x, y);
}
else
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandLineTo(x, y);
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandLinesTo(double* points, const int& count)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandLinesTo(points, count);
m_pInternal->m_oSimpleGraphicsConverter.PathCommandLinesTo(points, count);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandCurveTo(x1, y1, x2, y2, x3, y3);
if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType)
{
m_pInternal->CurveTo(x1, y1, x2, y2, x3, y3);
}
else
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandCurveTo(x1, y1, x2, y2, x3, y3);
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandCurvesTo(double* points, const int& count)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandCurvesTo(points, count);
m_pInternal->m_oSimpleGraphicsConverter.PathCommandCurvesTo(points, count);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandArcTo(x, y, w, h, startAngle, sweepAngle);
m_pInternal->m_oSimpleGraphicsConverter.PathCommandArcTo(x, y, w, h, startAngle, sweepAngle);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandClose()
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandClose();
if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType)
{
m_pInternal->Close();
}
else
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandClose();
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandEnd()
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandEnd();
if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType)
{
m_pInternal->End();
}
else
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandEnd();
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::DrawPath(const LONG& nType)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.DrawPath(nType);
m_pInternal->m_oWriter.WriteDrawPath(nType);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandStart()
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandStart();
if (c_nSimpleGraphicType == m_pInternal->m_lCurrentCommandType)
{
m_pInternal->Start();
}
else
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandEnd();
m_pInternal->m_oSimpleGraphicsConverter.PathCommandStart();
}
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandGetCurrentPoint(double* x, double* y)
{
m_pInternal->m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(x, y);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandTextCHAR(c, x, y, w, h);
int _c = (int)c;
m_pInternal->_SetFont();
m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(&_c, NULL, 1, m_pInternal->m_pFontManager, x, y, w, h);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandText(bsText, x, y, w, h);
m_pInternal->GetUnicodes(bsText);
m_pInternal->_SetFont();
m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen,
m_pInternal->m_pFontManager, x, y, w, h);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandTextExCHAR(c, gid, x, y, w, h);
int _c = (int)c;
int _g = (int)gid;
m_pInternal->_SetFont();
m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(&_c, &_g, 1,
m_pInternal->m_pFontManager, x, y, w, h);
return S_OK;
}
HRESULT CASCHTMLRenderer3::PathCommandTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.PathCommandTextEx(bsUnicodeText, pGids, nGidsCount, x, y, w, h);
m_pInternal->_SetFont();
m_pInternal->m_oSimpleGraphicsConverter.PathCommandText2(NULL, (const int*)pGids, nGidsCount,
m_pInternal->m_pFontManager, x, y, w, h);
return S_OK;
}
//-------- Функции для вывода изображений ---------------------------------------------------
HRESULT CASCHTMLRenderer3::DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.DrawImage(pImage, x, y, w, h);
if (NULL == pImage)
return S_OK;
m_pInternal->m_oWriter.WriteImage(pImage, x, y, w, h);
return S_OK;
}
HRESULT CASCHTMLRenderer3::DrawImageFromFile(const std::wstring& sPath, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.DrawImageFromFile(sPath, x, y, w, h, lAlpha);
m_pInternal->m_oWriter.WriteImage(sPath, x, y, w, h);
return S_OK;
}
// transform --------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.SetTransform(m1, m2, m3, m4, m5, m6);
agg::trans_affine* paff = &m_pInternal->m_oTransform.m_agg_mtx;
paff->sx = m1;
paff->shy = m2;
paff->shx = m3;
paff->sy = m4;
paff->tx = m5;
paff->ty = m6;
return S_OK;
}
HRESULT CASCHTMLRenderer3::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
{
agg::trans_affine* paff = &m_pInternal->m_oTransform.m_agg_mtx;
*pdA = paff->sx;
*pdB = paff->shy;
*pdC = paff->shx;
*pdD = paff->sy;
*pdE = paff->tx;
*pdF = paff->ty;
return S_OK;
}
HRESULT CASCHTMLRenderer3::ResetTransform()
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.ResetTransform();
m_pInternal->m_oTransform.Reset();
return S_OK;
}
// -----------------------------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::get_ClipMode(LONG* plMode)
{
*plMode = m_pInternal->m_lClipMode;
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_ClipMode(const LONG& lMode)
{
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.put_ClipMode(lMode);
m_pInternal->m_lClipMode = lMode;
m_pInternal->m_oWriter.m_oSVGWriter.m_lClipMode = lMode;
return S_OK;
}
// additiaonal params ----------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::CommandLong(const LONG& lType, const LONG& lCommand)
{
return S_OK;
}
HRESULT CASCHTMLRenderer3::CommandDouble(const LONG& lType, const double& dCommand)
{
return S_OK;
}
HRESULT CASCHTMLRenderer3::CommandString(const LONG& lType, const std::wstring& sCommand)
{
return S_OK;
}
// owner params ----------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::get_Mode(LONG *plMode)
{
return S_OK;
}
HRESULT CASCHTMLRenderer3::put_Mode(LONG lMode)
{
return S_OK;
}
HRESULT CASCHTMLRenderer3::CreateOfficeFile(std::wstring bsFileName)
{
m_pInternal->m_strDstFile = bsFileName;
size_t pos1 = m_pInternal->m_strDstFile.find_last_of(wchar_t('/'));
size_t pos2 = m_pInternal->m_strDstFile.find_last_of(wchar_t('\\'));
size_t pos = std::wstring::npos;
if (pos1 != std::wstring::npos)
pos = pos1;
if (pos2 != std::wstring::npos)
{
if (pos == std::wstring::npos)
pos = pos2;
else if (pos2 > pos)
pos = pos2;
}
if (pos == std::wstring::npos)
return S_FALSE;
std::wstring strDir = m_pInternal->m_strDstFile.substr(0, pos);
size_t nIndexExt = m_pInternal->m_strDstFile.find_last_of(wchar_t('.'));
if (nIndexExt == std::wstring::npos || nIndexExt <= pos)
nIndexExt = pos;
std::wstring strName = m_pInternal->m_strDstFile.substr(pos + 1, nIndexExt - pos - 1);
m_pInternal->m_oWriter.m_pTransform = &m_pInternal->m_oTransform;
m_pInternal->m_oWriter.CreateFile(strDir, strName);
m_pInternal->m_oWriter.WriteStartDocument();
m_pInternal->m_oWriter.m_oSmartText.m_oFontManager.Init(&m_pInternal->m_oApplicationFonts);
m_pInternal->m_lCurrentPage = -1;
m_pInternal->m_bPageOpened = false;
m_pInternal->m_pFontManager = m_pInternal->m_oApplicationFonts.GenerateFontManager();
m_pInternal->m_oFont.SetDefaultParams();
m_pInternal->m_oInstalledFont.SetDefaultParams();
m_pInternal->m_oSimpleGraphicsConverter.SetRenderer(this);
return S_OK;
}
HRESULT CASCHTMLRenderer3::CloseFile()
{
if (m_pInternal->m_bPageOpened)
{
m_pInternal->EndPage();
}
m_pInternal->m_oWriter.WriteEndDocument(m_pInternal->m_oDocument);
return S_OK;
}
HRESULT CASCHTMLRenderer3::SetAdditionalParam(std::string sParamName, int nValue)
{
return S_OK;
}
HRESULT CASCHTMLRenderer3::SetAdditionalParam(std::string sParamName, const std::wstring& sParam)
{
return S_OK;
}
......@@ -2,1036 +2,922 @@
#define _ASC_HTMLRENDERER_TEXT_H_
#include "FontManager.h"
#include "../../../Common/OfficeFileFormats.h"
namespace NSHtmlRenderer
{
class CStyles
{
private:
std::map<std::wstring, LONG> m_mapStyles;
LONG m_lNexrID;
public:
NSStringUtils::CStringBuilder m_oWriterCSS;
double m_dDpiY;
public:
CStyles() : m_mapStyles(), m_lNexrID(0)
{
}
~CStyles()
{
m_mapStyles.clear();
}
public:
void NewDocument()
{
m_mapStyles.clear();
m_lNexrID = 0;
m_oWriterCSS.Clear();
std::wstring strCSS =
L".blockpage { position: relative; background: #FFFFFF; padding: 0; float: none; margin: 0px auto; overflow: hidden; box-shadow: 0 0 10px rgba(0,0,0,0.5); -moz-box-shadow: 0 0 10px rgba(0,0,0,0.5); -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.5); }\n\
.blockpagebetween { width: 100%; height: 20px; background: #FEFEFE; padding: 0px; float: none; text-align: center; }\n\
.bt { position: absolute; margin-top: 0px; padding: 0px; float: none; }\n\
.bs { margin-top: 0px; padding: 0px; float: none; }\n\
.rt { position: absolute; font-size: 0; padding: 0px; margin-left: 0px; margin-top: 0px; border-style: solid; }\n\
._svg { -moz-user-select: none;-khtml-user-select: none;user-select: none; width:100%; height:100%;}\n\
v\\:vmlframe { behavior:url(#default#VML); display: block; width: 100%; height: 100%; position: absolute; padding: 0px; margin-left:0px;margin-top:0px; }\n\
v\\:*{behavior:url(#default#VML)}\n";
m_oWriterCSS.WriteString(strCSS);
}
void CloseDocument()
{
m_mapStyles.clear();
m_lNexrID = 0;
m_oWriterCSS.Clear();
}
void WriteStylesForDiffBrowsers(const std::wstring& strDir)
{
std::wstring strIE = L".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; text-align: justify; text-align-last: justify; }";
std::wstring strOp = L".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; display:inline-table; text-align: justify; text-align-last: justify; }\
.bp:after { content:\"\"; display:inline-block; width:100%; font-size: 0px; height:0; overflow:hidden; }";
std::wstring strOt = L".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; display:inline-table; white-space:pre-line; text-align: justify; text-align-last: justify; }\
.bp:after { content:\"\"; display:inline-block; width:100%; font-size: 0px; height:0; overflow:hidden; }";
NSFile::CFileBinary::SaveToFile(strDir + L"\\css_ie.css", strIE);
NSFile::CFileBinary::SaveToFile(strDir + L"\\css_opera.css", strOp);
NSFile::CFileBinary::SaveToFile(strDir + L"\\css_other.css", strOt);
}
LONG GetClassID(NSStructures::CFont* pFont, NSStructures::CBrush* pBrush)
{
int nSize = round(m_dDpiY * pFont->Size / 72);
if (nSize >= 10)
--nSize;
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteString(L"font-family: ");
oBuilder.WriteString(pFont->Name);
oBuilder.WriteString(L"; font-size: ");
oBuilder.AddInt(nSize);
oBuilder.WriteString(L"px; color:");
oBuilder.WriteHexColor3(pBrush->Color1);
if (pFont->Italic && pFont->Bold)
{
oBuilder.WriteString(L"; font-style:italic; font-weight:bold;", 38);
}
else if (pFont->Italic)
{
oBuilder.WriteString(L"; font-style:italic; font-weight:normal;", 40);
}
else if (pFont->Bold)
{
oBuilder.WriteString(L"; font-weight:bold; font-style:normal;", 38);
}
else
{
oBuilder.WriteString(L"; font-style:normal; font-weight:normal;", 40);
}
std::wstring sFormat = oBuilder.GetData();
std::map<std::wstring, LONG>::iterator iFind = m_mapStyles.find(sFormat);
if (iFind == m_mapStyles.end())
{
// новый стиль
++m_lNexrID;
m_mapStyles.insert(std::pair<std::wstring, LONG>(sFormat, m_lNexrID));
m_oWriterCSS.WriteString(L".s", 2);
m_oWriterCSS.AddInt(m_lNexrID);
m_oWriterCSS.WriteString(L" {", 2);
m_oWriterCSS.WriteString(sFormat);
m_oWriterCSS.WriteString(L"}\n", 2);
return m_lNexrID;
}
return iFind->second;
}
};
class CWord
{
public:
NSStructures::CFont m_oFont;
NSStructures::CBrush m_oBrush;
NSStringUtils::CStringBuilder m_oText;
double m_dX;
double m_dY;
double m_dWidth;
double m_dHeight;
double m_dBaseLinePos;
double m_dWidthWithoutSpaces;
public:
CWord() : m_oFont(), m_oBrush(), m_oText()
{
m_dX = 0;
m_dY = 0;
m_dWidth = 0;
m_dHeight = 0;
m_dBaseLinePos = 0;
m_dWidthWithoutSpaces = 0;
}
CWord(CFontManager* pFontManager, NSStructures::CBrush* pBrush, NSStringUtils::CStringBuilder& oText,
double& x, double& y, double& width, double& height, double& baseoffset) : m_oFont(pFontManager->m_oFont.m_oFont), m_oBrush(*pBrush), m_oText(oText),
m_dX(x), m_dY(y), m_dWidth(width), m_dHeight(height), m_dBaseLinePos(baseoffset), m_dWidthWithoutSpaces(width)
{
if (GetCountSpaceLast() == m_oText.GetCurSize())
m_dWidthWithoutSpaces = 0;
if (L"" != pFontManager->m_strCurrentPickFont)
{
m_oFont.Name = pFontManager->m_strCurrentPickFont;
m_oFont.SetStyle(pFontManager->m_lCurrentPictFontStyle);
}
}
CWord(const CWord& oSrc)
{
*this = oSrc;
}
CWord& operator=(const CWord& oSrc)
{
m_oFont = oSrc.m_oFont;
m_oBrush = oSrc.m_oBrush;
m_oText = oSrc.m_oText;
m_dX = oSrc.m_dX;
m_dY = oSrc.m_dY;
m_dWidth = oSrc.m_dWidth;
m_dHeight = oSrc.m_dHeight;
m_dBaseLinePos = oSrc.m_dBaseLinePos;
m_dWidthWithoutSpaces = oSrc.m_dWidthWithoutSpaces;
return *this;
}
long GetCountSpaceLast()
{
LONG lCount = (LONG)m_oText.GetCurSize();
wchar_t* pData = m_oText.GetBuffer();
LONG lCur = 0;
while (lCount > 0)
{
if (((WCHAR)' ') == pData[lCount - 1])
++lCur;
else
break;
--lCount;
}
return lCur;
}
long GetCountLastPoints()
{
LONG lCount = (LONG)m_oText.GetCurSize();
wchar_t* pData = m_oText.GetBuffer() + lCount - 1;
LONG lCur = 0;
while (lCount > 0)
{
if (((WCHAR)'.') == *pData)
++lCur;
else
break;
--lCount;
}
return lCur;
}
inline void WriteToStringWriter(NSStringUtils::CStringBuilder& oWriter)
{
oWriter.WriteEncodeXmlString(m_oText.GetBuffer(), (int)m_oText.GetCurSize());
class CHChar
{
public:
int unicode; // юникодное значение
int gid; // индекс глифа в файле
double x; // сдвиг по baseline
double width; // ширина символа (сдвиг до след буквы)
double* matrix; // матрица преобразования (!!! без сдвига)
public:
CHChar()
{
unicode = 0;
gid = 0;
width = 0;
matrix = NULL;
}
CHChar(const CHChar& oSrc)
{
*this = oSrc;
}
};
class CTextLine
{
public:
NSStringUtils::CStringBuilder* m_pTextMeasurer;
std::list<CWord*> m_arWords;
LONG m_lNextID;
double m_dMinTop;
LONG m_lIndexZ;
public:
CTextLine() : m_arWords(), m_lIndexZ(0)
{
}
CTextLine(const CTextLine& oSrc)
{
*this = oSrc;
}
CTextLine& operator=(const CTextLine& oSrc)
{
Clear();
for (std::list<CWord*>::const_iterator iter = oSrc.m_arWords.begin(); iter != oSrc.m_arWords.end(); iter++)
CHChar& operator=(const CHChar& oSrc)
{
unicode = oSrc.unicode;
gid = oSrc.gid;
width = oSrc.width;
matrix = NULL;
if (NULL != oSrc.matrix)
{
CWord* pWord = new CWord(**iter);
m_arWords.push_back(pWord);
matrix = new double[4];
memcpy(matrix, oSrc.matrix, 4 * sizeof(double));
}
return *this;
}
~CHChar()
{
RELEASEARRAYOBJECTS(matrix);
}
inline void Clear()
{
unicode = 0;
gid = 0;
width = 0;
RELEASEARRAYOBJECTS(matrix);
}
};
class CHLine
{
public:
double m_dAscent;
double m_dDescent;
double m_dX;
double m_dY;
double m_dEndX;
double m_dEndY;
// baseline ruler: y = k*x + b
double m_dK;
double m_dB;
double m_ex;
double m_ey;
bool m_bIsConstX;
// symbols
// не менять на списки. постоянное создание объектов и их удаление -
// плохо влияет на скорость
CHChar* m_pChars;
LONG m_lSizeChars;
LONG m_lCharsTail;
bool m_bIsSetUpTransform;
double m_sx;
double m_sy;
double m_shx;
double m_shy;
public:
CHLine()
{
m_dAscent = 0;
m_dDescent = 0;
m_dX = 0;
m_dY = 0;
m_dK = 0;
m_dB = 0;
m_bIsConstX = false;
m_ex = 0;
m_ey = 0;
m_lSizeChars = 1000;
m_lCharsTail = 0;
m_pChars = new CHChar[m_lSizeChars];
m_bIsSetUpTransform = false;
m_sx = 1;
m_sy = 1;
m_shx = 0;
m_shy = 0;
}
CHLine& operator=(const CHLine& oLine)
{
m_dAscent = oLine.m_dAscent;
m_dDescent = oLine.m_dDescent;
m_dX = oLine.m_dX;
m_dY = oLine.m_dY;
m_dK = oLine.m_dK;
m_dB = oLine.m_dB;
m_lSizeChars = oLine.m_lSizeChars;
m_lCharsTail = oLine.m_lCharsTail;
RELEASEARRAYOBJECTS(m_pChars);
m_pChars = new CHChar[m_lSizeChars];
for (LONG i = 0; i < m_lSizeChars; ++i)
m_pChars[i] = oLine.m_pChars[i];
m_bIsSetUpTransform = oLine.m_bIsSetUpTransform;
m_sx = oLine.m_sx;
m_sy = oLine.m_sy;
m_shx = oLine.m_shx;
m_shy = oLine.m_shy;
return *this;
}
}
~CHLine()
{
RELEASEARRAYOBJECTS(m_pChars);
}
public:
void Clear()
inline void Clear()
{
for (std::list<CWord*>::iterator iter = m_arWords.begin(); iter != m_arWords.end(); iter++)
{
CWord* pWord = *iter;
RELEASEOBJECT(pWord);
}
m_arWords.clear();
m_dMinTop = 10000000;
}
void AddWord(CWord* pWord)
{
// смотрим, какое слово предыдущее.
// если оно - полностью пробел - то он прищел из пдф. а значит он любой длины может быть.
// зачем он нужен?? непонятно. Поэтому удаляем такое слово
if (m_arWords.size() > 0)
{
std::list<CWord*>::iterator iter = m_arWords.end();
iter--;
CWord* pTail = *iter;
if (pTail->GetCountSpaceLast() == pTail->m_oText.GetCurSize())
{
m_arWords.pop_back();
RELEASEOBJECT(pTail);
}
}
if (m_dMinTop > pWord->m_dY)
m_dMinTop = pWord->m_dY;
m_arWords.push_back(pWord);
}
CWord* GetLast()
{
if (0 == m_arWords.size())
return NULL;
m_dAscent = 0;
m_dDescent = 0;
m_dX = 0;
m_dY = 0;
m_dK = 0;
m_dB = 0;
m_bIsConstX = false;
m_ex = 0;
m_ey = 0;
std::list<CWord*>::iterator iter = m_arWords.end();
iter--;
return *iter;
}
CWord* GetHead()
{
if (0 == m_arWords.size())
m_lCharsTail = 0;
m_bIsSetUpTransform = false;
m_sx = 1;
m_sy = 1;
m_shx = 0;
m_shy = 0;
}
inline CHChar* AddTail()
{
if (m_lCharsTail >= m_lSizeChars)
{
CHChar* pNews = new CHChar[2 * m_lSizeChars];
for (LONG i = 0; i < m_lSizeChars; ++i)
{
pNews[i] = m_pChars[i];
}
RELEASEARRAYOBJECTS(m_pChars);
m_pChars = pNews;
m_lSizeChars *= 2;
}
CHChar* pChar = &m_pChars[m_lCharsTail];
++m_lCharsTail;
pChar->Clear();
return pChar;
}
inline CHChar* GetTail()
{
if (0 == m_lCharsTail)
return NULL;
return *m_arWords.begin();
}
size_t GetCount()
{
return m_arWords.size();
}
public:
inline void Write(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles, const LONG& lIndexZ)
{
return Write3(pWriter, dDpiX, dDpiY, pStyles, lIndexZ);
}
void Write1(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles)
{
// временно
//return Write2(pWriter, dDpiX, dDpiY);
size_t nCountWords = m_arWords.size();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = GetLast();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
pWriter->WriteString(L"<p class=\"bp\" style=\"font-family: ", 34);
pWriter->WriteString(pWord->m_oFont.Name);
pWriter->WriteString(L"; font-size: ");
pWriter->AddInt((int)(dDpiY * pWord->m_oFont.Size / 72));
pWriter->WriteString(L"px; color:", 10);
pWriter->WriteHexColor3(pWord->m_oBrush.Color1);
pWriter->WriteString(L";\">");
for (std::list<CWord*>::iterator pos = m_arWords.begin(); pos != m_arWords.end();)
{
pWord = *pos;
if (pWord->m_oFont.IsEqual(pFont0) && (pWord->m_oBrush.IsEqual(pBrush0)))
{
pWriter->WriteString(L"<span class=\"bt\" style=\"left:", 29);
pWriter->AddInt((int)pWord->m_dX);
pWriter->WriteString(L"; top:", 6);
pWriter->AddInt((int)pWord->m_dY);
pWriter->WriteString(L";\">", 3);
}
else
{
pWriter->WriteString(L"<span class=\"bs\" style=\"font-family: ", 37);
pWriter->WriteString(pWord->m_oFont.Name);
pWriter->WriteString(L"; font-size: ", 13);
pWriter->AddInt((int)(dDpiY * pWord->m_oFont.Size / 72));
pWriter->WriteString(L"px; color:", 10);
pWriter->WriteHexColor3(pWord->m_oBrush.Color1);
pWriter->WriteString(L";\">", 3);
}
pWord->WriteToStringWriter(*pWriter);
pos++;
if (pos != m_arWords.end())
{
pWriter->WriteString(L"&nbsp;", 6);
}
pWriter->WriteString(L"</span>", 7);
}
pWriter->WriteString(L"</p>\n", 5);
}
void Write2(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles)
{
size_t nCountWords = m_arWords.size();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = GetHead();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
pWriter->WriteString(L"<p class=\"bp\" style=\"left: ", 27);
pWriter->AddInt((int)pWord->m_dX);
pWriter->WriteString(L"px; top: ", 9);
pWriter->AddInt((int)pWord->m_dY);
pWriter->WriteString(L"px; font-family: ", 17);
pWriter->WriteString(pWord->m_oFont.Name);
pWriter->WriteString(L"; font-size: ", 13);
pWriter->AddInt((int)(dDpiY * pWord->m_oFont.Size / 72));
pWriter->WriteString(L"px; color:", 10);
pWriter->WriteHexColor3(pWord->m_oBrush.Color1);
pWriter->WriteString(L"; white-space: nowrap;\">", 24);
for (std::list<CWord*>::iterator pos = m_arWords.begin(); pos != m_arWords.end();)
return &m_pChars[m_lCharsTail - 1];
}
inline LONG GetCountChars()
{
return m_lCharsTail;
}
};
const BYTE g_lfHorizontal = 0x01;
const BYTE g_lfGids = 0x02;
const BYTE g_lfWidth = 0x04;
class CHFontInfo
{
public:
USHORT m_lAscent;
USHORT m_lDescent;
USHORT m_lLineHeight;
USHORT m_lUnitsPerEm;
public:
CHFontInfo()
{
m_lAscent = 0;
m_lDescent = 0;
m_lLineHeight = 0;
m_lUnitsPerEm = 0;
}
CHFontInfo(const CHFontInfo& oSrc)
{
m_lAscent = oSrc.m_lAscent;
m_lDescent = oSrc.m_lDescent;
m_lLineHeight = oSrc.m_lLineHeight;
m_lUnitsPerEm = oSrc.m_lUnitsPerEm;
}
CHFontInfo& operator=(const CHFontInfo& oSrc)
{
m_lAscent = oSrc.m_lAscent;
m_lDescent = oSrc.m_lDescent;
m_lLineHeight = oSrc.m_lLineHeight;
m_lUnitsPerEm = oSrc.m_lUnitsPerEm;
return *this;
}
};
class CFontMapInfo
{
public:
std::wstring Path;
int FaceIndex;
public:
CFontMapInfo()
{
Path = L"";
FaceIndex = 0;
}
CFontMapInfo(const CFontMapInfo& oSrc)
{
Path = oSrc.Path;
FaceIndex = oSrc.FaceIndex;
}
CFontMapInfo& operator=(const CFontMapInfo& oSrc)
{
Path = oSrc.Path;
FaceIndex = oSrc.FaceIndex;
return *this;
}
};
class CFontManagerWrapper
{
private:
::CFontManager* m_pManager;
public:
CHFontInfo m_oCurrentInfo;
NSStructures::CFont* m_pFont;
std::map<std::wstring, CHFontInfo> m_mapInfos;
public:
CFontManagerWrapper()
{
m_pManager = NULL;
}
void Init(CApplicationFonts* pApplicationFonts)
{
RELEASEOBJECT(m_pManager);
m_pManager = pApplicationFonts->GenerateFontManager();
}
virtual ~CFontManagerWrapper()
{
RELEASEOBJECT(m_pManager);
}
void SetStringGID(INT bGid)
{
m_pManager->SetStringGID(bGid);
}
public:
inline void LoadCurrentFont(bool bIsAttack, int lFaceIndex = 0)
{
if (L"" == m_pFont->Path)
{
std::wstring sFind = m_pFont->Name + L"__ASC_FONT__" + std::to_wstring(m_pFont->GetStyle());
std::map<std::wstring, CHFontInfo>::const_iterator pPair = m_mapInfos.find(sFind);
if (m_mapInfos.end() != pPair)
{
if (bIsAttack)
{
LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle());
}
else
{
m_oCurrentInfo = pPair->second;
}
}
else
{
LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle());
m_mapInfos.insert(std::pair<std::wstring, CHFontInfo>(sFind, m_oCurrentInfo));
}
}
else
{
std::map<std::wstring, CHFontInfo>::const_iterator pPair = m_mapInfos.find(m_pFont->Path);
if (m_mapInfos.end() != pPair)
{
if (bIsAttack)
{
LoadFontByFile(m_pFont->Path, m_pFont->Size, lFaceIndex);
}
else
{
m_oCurrentInfo = pPair->second;
}
}
else
{
LoadFontByFile(m_pFont->Path, m_pFont->Size, lFaceIndex);
m_mapInfos.insert(std::pair<std::wstring, CHFontInfo>(m_pFont->Path, m_oCurrentInfo));
}
}
}
inline void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle)
{
m_pManager->LoadFontByName(strName, dSize, lStyle, c_dDpi, c_dDpi);
LoadFontMetrics();
}
inline void LoadFontByFile(const std::wstring& strPath, const double& dSize, const int& lFaceIndex)
{
m_pManager->LoadFontFromFile(strPath, lFaceIndex, dSize, c_dDpi, c_dDpi);
LoadFontMetrics();
}
public:
double MeasureString(const unsigned int* symbols, const int& count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight)
{
dBoxX = 0;
dBoxY = 0;
dBoxWidth = 0;
dBoxHeight = 0;
if (NULL == m_pManager)
return 0;
m_pManager->LoadString1(symbols, count, (float)x, (float)y);
TBBox _box = m_pManager->MeasureString2();
dBoxX = (double)(_box.fMinX);
dBoxY = (double)(_box.fMinY);
dBoxWidth = (double)(_box.fMaxX - _box.fMinX);
dBoxHeight = (double)(_box.fMaxY - _box.fMinY);
if (dBoxWidth < 0)
dBoxWidth = -dBoxWidth;
if (dBoxHeight < 0)
dBoxHeight = -dBoxHeight;
// переводим в миллиметры
dBoxX *= c_dPixToMM;
dBoxY *= c_dPixToMM;
dBoxWidth *= c_dPixToMM;
dBoxHeight *= c_dPixToMM;
return dBoxWidth;
}
public:
void LoadFontMetrics()
{
m_oCurrentInfo.m_lAscent = (m_pManager->m_lAscender < 0) ? ((USHORT)(-m_pManager->m_lAscender)) : (USHORT)m_pManager->m_lAscender;
m_oCurrentInfo.m_lDescent = (m_pManager->m_lDescender < 0) ? ((USHORT)(-m_pManager->m_lDescender)) : (USHORT)m_pManager->m_lDescender;
m_oCurrentInfo.m_lLineHeight = (m_pManager->m_lLineHeight < 0) ? ((USHORT)(-m_pManager->m_lLineHeight)) : (USHORT)m_pManager->m_lLineHeight;
m_oCurrentInfo.m_lUnitsPerEm = (m_pManager->m_lUnits_Per_Em < 0) ? ((USHORT)(-m_pManager->m_lUnits_Per_Em)) : (USHORT)m_pManager->m_lUnits_Per_Em;
}
};
class CHText
{
public:
CFontManagerWrapper m_oFontManager;
CHLine m_oLine;
CMetafile* m_pMeta;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
NSStructures::CBrush* m_pLastBrush;
NSStructures::CFont* m_pLastFont;
Aggplus::CMatrix* m_pTransform;
Aggplus::CMatrix* m_pLastTransform;
CMetafile m_oMeta;
CMetafile* m_pPageMeta;
double m_dTextSpaceEps;
LONG m_lCountParagraphs;
LONG m_lCountWords;
LONG m_lCountSymbols;
LONG m_lCountSpaces;
public:
CHText() : m_oFontManager(), m_oLine()
{
m_dTextSpaceEps = 0.1;
m_lCountParagraphs = 0;
m_lCountWords = 0;
m_lCountSymbols = 0;
m_lCountSpaces = 0;
}
void Init(CApplicationFonts* pApplicationFonts)
{
m_oFontManager.Init(pApplicationFonts);
}
template<typename T>
void SetParams(T writer)
{
m_oFontManager.m_pFont = writer->m_pFont;
m_pBrush = writer->m_pBrush;
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;
m_pPageMeta = &writer->m_oPage;
switch (writer->m_lSrcFileType)
{
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF:
case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS:
break;
default:
m_dTextSpaceEps = 0.1;
break;
}
}
~CHText()
{
}
void NewPage()
{
m_oMeta.ClearNoAttack();
}
void ClosePage()
{
LONG nCount = m_oLine.GetCountChars();
if (0 != nCount)
DumpLine();
}
public:
template<typename T>
void CommandText(const int* pUnicodes, const int* pGids, const int& nCount,
const double& x, const double& y, const double& width, const double& height, bool bIsDumpFont, T writer)
{
// 1) сначала определяем точку отсчета и направление baseline
double _x1 = x;
double _y1 = y;
double _x2 = x + 1;
double _y2 = y;
m_pTransform->TransformPoint(_x1, _y1);
m_pTransform->TransformPoint(_x2, _y2);
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 && (0 != nCountChars))
{
// не совпала baseline. поэтому просто скидываем линию в поток
DumpLine();
}
// теперь нужно определить сдвиг по baseline относительно destination точки
nCountChars = m_oLine.GetCountChars();
double dOffsetX = 0;
if (0 == nCountChars)
{
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;
// теперь посмотрим, может быть нужно вставить пробел??
CHChar* pLastChar = m_oLine.GetTail();
if (dOffsetX > (pLastChar->width + 0.5))
{
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
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 = !IsEqualMain(m_pLastTransform, m_pTransform);
if (bIsTransform)
bIsDumpFont = true;
bool bIsColor = ((m_pBrush->Color1 != m_pLastBrush->Color1) || (m_pBrush->Alpha1 != m_pLastBrush->Alpha1));
BYTE nLenMetaCommands = 0;
if (bIsColor)
nLenMetaCommands += 5;
if (bIsTransform)
nLenMetaCommands += 17;
if (bIsDumpFont)
nLenMetaCommands += 13;
m_oMeta.WriteBYTE(nLenMetaCommands);
agg::trans_affine* _src = &m_pTransform->m_agg_mtx;
double _dumpSize = writer->m_dCurrentFontSize;
double _dumpMtx[4];
_dumpMtx[0] = _src->sx;
_dumpMtx[1] = _src->shy;
_dumpMtx[2] = _src->shx;
_dumpMtx[3] = _src->sy;
double dTextScale = 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)
{
m_oMeta.WriteCommandType(CMetafile::ctFontName);
m_oMeta.WriteLONG(writer->m_lCurrentFont);
m_oMeta.WriteLONG(writer->m_pFont->GetStyle());
m_oMeta.WriteDouble(_dumpSize/*writer->m_dCurrentFontSize*/);
}
if (bIsTransform)
{
agg::trans_affine* _dst = &m_pLastTransform->m_agg_mtx;
_dst->sx = _src->sx;
_dst->shx = _src->shx;
_dst->shy = _src->shy;
_dst->sy = _src->sy;
m_oLine.m_bIsSetUpTransform = true;
m_oLine.m_sx = _src->sx;
m_oLine.m_shx = _src->shx;
m_oLine.m_shy = _src->shy;
m_oLine.m_sy = _src->sy;
m_oMeta.WriteBYTE(CMetafile::ctCommandTextTransform);
//m_oMeta.WriteDouble(_dst->sx);
//m_oMeta.WriteDouble(_dst->shy);
//m_oMeta.WriteDouble(_dst->shx);
//m_oMeta.WriteDouble(_dst->sy);
m_oMeta.WriteDouble(_dumpMtx[0]);
m_oMeta.WriteDouble(_dumpMtx[1]);
m_oMeta.WriteDouble(_dumpMtx[2]);
m_oMeta.WriteDouble(_dumpMtx[3]);
}
if (bIsColor)
{
m_pLastBrush->Color1 = m_pBrush->Color1;
m_pLastBrush->Alpha1 = m_pBrush->Alpha1;
m_oMeta.WriteBYTE(CMetafile::ctBrushColor1);
LONG lBGR = m_pBrush->Color1;
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_pBrush->Alpha1);
}
// все, baseline установлен. теперь просто продолжаем линию
LONG lTextLen = nCount;
bool bIsLoadFontAttack = true;
// говенные значения приходят из пдф
/*
if (1 == lTextLen && 0 <= width)
bIsLoadFontAttack = false;
*/
if (bIsDumpFont)
m_oFontManager.LoadCurrentFont(bIsLoadFontAttack);
double dKoef = m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm);
double dKoefMetr = dAbsVec;
double dAscender = m_oFontManager.m_oCurrentInfo.m_lAscent * dKoef * dKoefMetr;
double dDescender = m_oFontManager.m_oCurrentInfo.m_lDescent * dKoef * dKoefMetr;
if (m_oLine.m_dAscent < dAscender)
m_oLine.m_dAscent = dAscender;
if (m_oLine.m_dDescent < dDescender)
m_oLine.m_dDescent = dDescender;
if (!bIsLoadFontAttack)
{
pWord = *pos;
pWriter->Write(pWord->m_oText);
CHChar* pChar = m_oLine.AddTail();
pos++;
if (pos != m_arWords.end())
pWriter->AddCharSafe(' ');
pChar->unicode = pUnicodes[0];
pChar->gid = (NULL == pGids) ? 0xFFFF : pGids[0];
pChar->width = width;
pChar->x = dOffsetX;
}
else
{
double dPlusOffset = 0;
const int* input = NULL;
if (NULL != pGids)
{
input = pGids;
m_oFontManager.SetStringGID(TRUE);
}
else
{
input = pUnicodes;
m_oFontManager.SetStringGID(FALSE);
}
double dBoxX = 0;
double dBoxY = 0;
double dBoxW = 0;
double dBoxH = 0;
double dPrevW = dOffsetX;
for (LONG lIndex = 0; lIndex < lTextLen; ++lIndex)
{
double dW = m_oFontManager.MeasureString((const unsigned int*)(input + lIndex), 1, 0, 0, dBoxX, dBoxY, dBoxW, dBoxH);
CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pUnicodes[lIndex];
pChar->gid = (NULL == pGids) ? 0xFFFF : pGids[lIndex];
pChar->x = dPrevW;
if (lIndex != 0)
dPlusOffset += dPrevW;
dPrevW = dW;
pChar->width = dW * dAbsVec;
if (0 != lIndex)
m_oMeta.WriteBYTE(0);
if (lIndex == (lTextLen - 1))
{
m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex;
m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey;
}
}
}
}
void DumpLine()
{
if (m_oLine.m_bIsSetUpTransform)
{
// выставится трансформ!!!
// cравнивать нужно с ним!!!
agg::trans_affine* _dst = &m_pLastTransform->m_agg_mtx;
_dst->sx = m_oLine.m_sx;
_dst->shx = m_oLine.m_shx;
_dst->shy = m_oLine.m_shy;
_dst->sy = m_oLine.m_sy;
_dst->tx = 0;
_dst->ty = 0;
}
// скидываем линию в поток pMeta
BYTE mask = 0;
if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001)
mask |= g_lfHorizontal;
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)
{
CHChar* pChar = &m_oLine.m_pChars[i];
if (pChar->gid != 0xFFFF)
{
mask |= g_lfGids;
bIsGidExist = true;
}
if (0xFFFF == pChar->unicode || ((WCHAR)' ') == pChar->unicode || ((WCHAR)'\t') == pChar->unicode)
{
lCountSpaces++;
if (bIsLastSymbol)
{
bIsLastSymbol = false;
lCountWords++;
}
}
else
{
lCountSymbols++;
bIsLastSymbol = true;
}
}
pWriter->WriteString(L"</p>\n", 5);
}
if (bIsLastSymbol)
lCountWords++;
void Write3(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles, const LONG& lIndexZ)
{
DeleteEmptyWords();
if (0 == nCount)
{
m_oLine.Clear();
m_oMeta.ClearNoAttack();
return;
}
size_t nCountWords = m_arWords.size();
if (0 == nCountWords)
return;
m_lCountParagraphs += 1;
m_lCountWords += lCountWords;
m_lCountSymbols += lCountSymbols;
m_lCountSpaces += lCountSpaces;
// генерим параграф, один на строку
CWord* pWord = GetHead();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
if (nCount > 1)
mask |= g_lfWidth;
pWord->m_dWidth = pWord->m_dWidthWithoutSpaces;
m_pPageMeta->CheckBufferSize(60);
int nLeft = (int)pWord->m_dX;
int nRight = (int)(pWord->m_dX + pWord->m_dWidthWithoutSpaces);
m_pPageMeta->WriteBYTE_nocheck(CMetafile::ctCommandTextLine);
m_pPageMeta->WriteBYTE_nocheck(mask);
double dRight = pWord->m_dX + pWord->m_dWidthWithoutSpaces;
m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dX);
m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dY);
std::list<CWord*>::iterator pos = m_arWords.begin();
pos++;
if ((mask & g_lfHorizontal) == 0)
{
m_pPageMeta->WriteDouble_nocheck(m_oLine.m_ex);
m_pPageMeta->WriteDouble_nocheck(m_oLine.m_ey);
}
while (pos != m_arWords.end())
m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dAscent);
m_pPageMeta->WriteDouble_nocheck(m_oLine.m_dDescent);
LONG _position = 0;
if (nCount > 1)
{
pWord->m_dWidth = pWord->m_dWidthWithoutSpaces;
nRight = (int)(pWord->m_dX + pWord->m_dWidth);
pos++;
_position = m_pPageMeta->GetPosition();
m_pPageMeta->WriteLONG_nocheck(0);
}
pos = m_arWords.begin();
pWord = *pos;
pStyles->m_dDpiY = dDpiY;
LONG lID = pStyles->GetClassID(&pWord->m_oFont, &pWord->m_oBrush);
LONG lDecoration = pWord->m_oFont.GetTextDecorationStyle();
pWriter->WriteString(L"<p class=\"bp s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"left: ", 15);
pWriter->AddInt((int)pWord->m_dX);
pWriter->WriteString(L"px; top: ", 9);
pWriter->AddInt((int)m_dMinTop);
pWriter->WriteString(L"px; width: ", 11);
pWriter->AddInt(nRight - nLeft);
pWriter->WriteString(L"px;\"><nobr>", 11);
if ((0 == lDecoration) || (3 < lDecoration))
{
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
}
else
{
switch (lDecoration)
{
case 1:
pWriter->WriteString(L"<span style=\"text-decoration:underline;\">", 41);
break;
case 2:
pWriter->WriteString(L"<span style=\"text-decoration:line-through;\">", 44);
break;
case 3:
pWriter->WriteString(L"<span style=\"text-decoration:underline line-through;\">", 54);
break;
default:
break;
}
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
pWriter->WriteString(L"</span>", 7);
}
pos++;
bool bSpanClose = false;
while (pos != m_arWords.end())
{
pWord = *pos;
if (1.0 < (pWord->m_dX - dRight))
{
pWriter->AddCharSafe(' ');
}
dRight = pWord->m_dX + pWord->m_dWidthWithoutSpaces;
if (bSpanClose)
pWriter->WriteString(L"</span>", 7);
bSpanClose = true;
lID = pStyles->GetClassID(&pWord->m_oFont, &pWord->m_oBrush);
lDecoration = pWord->m_oFont.GetTextDecorationStyle();
switch (lDecoration)
{
case 0:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\">", 2);
break;
case 1:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"text-decoration:underline;\">", 37);
break;
case 2:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"text-decoration:line-through;\">", 40);
break;
case 3:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"text-decoration:underline line-through;\">", 50);
break;
default:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\">", 2);
break;
}
pWord->WriteToStringWriter(*pWriter);
pos++;
}
if (bSpanClose)
pWriter->WriteString(L"</span>", 7);
pWriter->WriteString(L"</nobr></p>\n", 12);
//CString strLine = _T("");
//strLine.Format(g_string_lineFunc, m_lNextID++, nRight - nLeft);
//m_pTextMeasurer->WriteString(strLine);
}
void DeleteEmptyWords()
{
std::list<CWord*>::iterator pos = m_arWords.begin();
while (pos != m_arWords.end())
{
CWord* pWord = *pos;
if (pWord->GetCountSpaceLast() == pWord->m_oText.GetCurSize())
{
pos = m_arWords.erase(pos);
RELEASEOBJECT(pWord);
continue;
}
pos++;
}
if (0 != m_arWords.size())
{
// удалим последние пробелы линии.
CWord* pWord = GetLast();
pWord->m_oText.RemoveLastSpaces();
}
}
void Merge()
{
std::list<CWord*>::iterator pos = m_arWords.begin();
if (pos == m_arWords.end())
return;
std::list<CWord*>::iterator posCur = pos;
CWord* pWordPrev = *pos;
posCur++;
double dRightPos = pWordPrev->m_dX + pWordPrev->m_dWidth;
while (posCur != m_arWords.end())
{
std::list<CWord*>::iterator posCurOld = posCur;
CWord* pWord = *posCur;
posCur++;
bool bNextWord = true;
if (FABS(pWord->m_dX - dRightPos) < 0.1)
{
// одно и тоже слово
bNextWord = false;
}
dRightPos = pWord->m_dX + pWord->m_dWidth;
if ((pWord->m_oFont.IsEqual(&pWordPrev->m_oFont)) && (pWord->m_oBrush.IsEqual(&pWordPrev->m_oBrush)))
{
// продолжаем текущий спан
if (bNextWord)
{
pWordPrev->m_oText.AddCharSafe(' ');
}
pWordPrev->m_oText.Write(pWord->m_oText);
posCur = m_arWords.erase(posCurOld);
RELEASEOBJECT(pWord);
}
else
{
if (bNextWord)
pWordPrev->m_oText.AddCharSafe(' ');
pos = posCur;
pWordPrev = pWord;
}
}
}
};
class CText
{
public:
CFontManager m_oFontManager;
CTextLine m_oCurrentLine;
NSStringUtils::CStringBuilder* m_pWriter;
//NSStrings::CStringWriter m_oTextMeasurer;
CStyles* m_pStyles;
double m_dDpiX;
double m_dDpiY;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
Aggplus::CMatrix* m_pTransform;
LONG m_lIndexZ;
bool m_bIsNewLine;
bool m_bIsPDFTextStyle;
NSStringUtils::CStringBuilder m_oTextItem;
private:
double m_dEpsX;
double m_dEpsY;
public:
CText() : m_oFontManager(), m_oCurrentLine(), m_oTextItem()//, m_oTextMeasurer()
{
m_pWriter = NULL;
m_dEpsX = 0.5;
m_dEpsY = 0.5;
m_pPen = NULL;
m_pBrush = NULL;
m_pFont = NULL;
//m_oCurrentLine.m_pTextMeasurer = &m_oTextMeasurer;
m_pStyles = NULL;
m_pTransform = NULL;
m_lIndexZ = 0;
m_bIsNewLine = false;
m_bIsPDFTextStyle = false;
}
void SetParams(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CFont* pFont, CStyles* pStyles, Aggplus::CMatrix* pTransform)
{
m_pPen = pPen;
m_pBrush = pBrush;
m_pFont = pFont;
m_oFontManager.m_pFont = pFont;
m_oFontManager.m_pTransform = pTransform;
m_pStyles = pStyles;
m_pTransform = pTransform;
}
~CText()
{
}
void NewPage(double& dDpiX, double& dDpiY)
{
m_dDpiX = dDpiX;
m_dDpiY = dDpiY;
m_pPen->SetDefaultParams();
m_pBrush->SetDefaultParams();
m_pFont->SetDefaultParams();
}
void ClosePage()
{
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
}
void NewDocument()
{
m_oCurrentLine.m_lNextID = 1;
m_oCurrentLine.m_dMinTop = 1000000;
m_pPen->SetDefaultParams();
m_pBrush->SetDefaultParams();
m_pFont->SetDefaultParams();
}
protected:
inline bool GetIsNewLine()
{
if (m_bIsNewLine)
{
m_bIsNewLine = false;
return true;
}
return false;
}
void CommandText1(double& x, double& y, double& width, double& height, double& baselineoffset)
{
double dScaleFont = ((m_pTransform->m_agg_mtx.sx + m_pTransform->m_agg_mtx.sy) / 2);
bool bIsFontChanged = !CFontManagerBase::IsEqual2(&m_oFontManager.m_oFont.m_oFont, m_pFont, dScaleFont);
bool bIsTextDecorationChanged = ((m_oFontManager.m_oFont.m_oFont.Underline != m_pFont->Underline) ||
(m_oFontManager.m_oFont.m_oFont.Strikeout != m_pFont->Strikeout));
if (bIsFontChanged)
{
m_oFontManager.m_oFont.m_oFont = *m_pFont;
m_oFontManager.m_oFont.m_oFont.Size *= dScaleFont;
}
else if (bIsTextDecorationChanged)
{
m_oFontManager.m_oFont.m_oFont.Underline = m_pFont->Underline;
m_oFontManager.m_oFont.m_oFont.Strikeout = m_pFont->Strikeout;
}
// никакого подбора здесь нет. нужное имя должно быть выставлено у m_pFont
m_oFontManager.m_strCurrentPickFont = L"";
bool bIsNewLine = GetIsNewLine();
if (0 == width)
{
// откуда такое может быть?? формулы??
m_oFontManager.LoadCurrentFont();
double dOffset = m_oFontManager.m_oFont.m_dBaselineOffsetHTML;
dOffset *= (m_dDpiY / 72.0);
y -= dOffset;
baselineoffset = dOffset;
// текст не измерен. для начала нужно его измерить
double _x = 0;
double _y = 0;
double _w = 0;
double _h = 0;
LONG lGid = m_oFontManager.GetStringGid();
m_oFontManager.SetStringGid(0);
m_oFontManager.MeasureStringPix(m_oTextItem.GetData(), x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
m_oFontManager.SetStringGid(lGid);
width = _w;
height = _h;
}
double dYPos = y + baselineoffset;
LONG lCountWords = (LONG)m_oCurrentLine.GetCount();
if (0 == lCountWords)
{
// слов в линии нет, без всяких проверок создаем линию
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
CWord* pTail = m_oCurrentLine.GetLast();
double dYPosLine = pTail->m_dBaseLinePos;
if (FABS(dYPos - dYPosLine) > m_dEpsY)
{
// новая линия
// сначала запишем предыдущую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
double dRight = pTail->m_dX + pTail->m_dWidth;
if ((x + 0.5 < dRight) || (((x - dRight) * c_ag_Inch_to_MM / m_dDpiX) > g_lNewNoJustifySpace) || (bIsNewLine))
{
// здесь либо текст стал левее, либо расстояние слишком большое.
// создадим новую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
// текст уже измерен
if (!bIsFontChanged && pTail->m_oBrush.IsEqual(m_pBrush) && !bIsTextDecorationChanged)
{
if (1.0 < FABS(pTail->m_dX + pTail->m_dWidth - x))
{
// это не одно и то же слово!!!
pTail->m_oText.AddCharSafe(' ');
}
pTail->m_oText.Write(m_oTextItem);
pTail->m_dWidth = (x + width - pTail->m_dX);
pTail->m_dWidthWithoutSpaces = pTail->m_dWidth;
}
else
{
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
}
}
void CommandText2(const std::wstring& bsGid, double& x, double& y, double& width, double& height, double& baselineoffset)
{
bool bIsNewLine = GetIsNewLine();
double dScaleFont = ((m_pTransform->m_agg_mtx.sx + m_pTransform->m_agg_mtx.sy) / 2);
bool bIsFontChanged = !CFontManagerBase::IsEqual2(&m_oFontManager.m_oFont.m_oFont, m_pFont, dScaleFont);
if (bIsFontChanged)
{
m_oFontManager.m_oFont.m_oFont = *m_pFont;
m_oFontManager.m_oFont.m_oFont.Size *= dScaleFont;
m_oFontManager.LoadCurrentFont();
m_oFontManager.CalculateSpace();
m_pFont->SetStyle(m_oFontManager.m_oFont.m_oFont.GetStyle());
m_oFontManager.GenerateFontName(m_oTextItem, true);
}
else
{
m_oFontManager.GenerateFontName(m_oTextItem, false);
}
double dOffset = m_oFontManager.m_oFont.m_dBaselineOffsetHTML;
dOffset *= (m_dDpiY / 72.0);
y -= dOffset;
baselineoffset = dOffset;
// текст не измерен. для начала нужно его измерить
double _x = 0;
double _y = 0;
double _w = 0;
double _h = 0;
bool bIsMeasuring = false;
if (0 >= width)
{
if (bsGid.empty())
{
m_oFontManager.SetStringGid(0);
m_oFontManager.MeasureStringPix(m_oTextItem.GetData(), x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
}
else
{
m_oFontManager.SetStringGid(1);
m_oFontManager.MeasureStringPix(bsGid, x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
}
width = _w;
height = _h;
bIsMeasuring = true;
}
double dYPos = y + baselineoffset;
LONG lCountWords = (LONG)m_oCurrentLine.GetCount();
if (0 == lCountWords)
{
// слов в линии нет, без всяких проверок создаем линию
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
double dYPosLine = m_oCurrentLine.GetHead()->m_dBaseLinePos;
if (FABS(dYPos - dYPosLine) > m_dEpsY)
{
// новая линия
// сначала запишем предыдущую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
// теперь проверяем, продолжать ли слово
//double dSpace = MMToPX(m_oFontManager.m_dSpaceWidthMM, m_dDpiX) / 2.0;
double dSpace = 0.5 * m_dDpiX / c_dInchToMM;
if (bIsMeasuring)
{
dSpace = m_oFontManager.m_dSpaceWidthMM * m_dDpiX / 25.4;
}
CWord* pWordLast = m_oCurrentLine.GetLast();
double dRight = pWordLast->m_dX + pWordLast->m_dWidthWithoutSpaces;
if ((x + 10 < dRight) || (((x - dRight) * c_ag_Inch_to_MM / m_dDpiX) > g_lNewNoJustifySpace) || (bIsNewLine))
{
// создадим новую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
bool bIsBrushChanged = !pWordLast->m_oBrush.IsEqual(m_pBrush);
double dDelta = (x - (pWordLast->m_dX + pWordLast->m_dWidth));
if ((dDelta > dSpace) || bIsFontChanged || bIsBrushChanged)
{
if (m_oTextItem.IsSpace())
{
if (0 == pWordLast->GetCountSpaceLast())
{
pWordLast->m_oText.Write(m_oTextItem);
pWordLast->m_dWidth = x + width - pWordLast->m_dX;
}
return;
}
if (dDelta > dSpace)
pWordLast->m_oText.AddCharSafe(' ');
if (bIsFontChanged || bIsBrushChanged)
{
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
}
else
{
pWordLast->m_oText.Write(m_oTextItem);
pWordLast->m_dWidth = x + width - pWordLast->m_dX;
pWordLast->m_dWidthWithoutSpaces = pWordLast->m_dWidth;
}
}
else
{
// продолжаем слово
// сначала заглушку на строку, начинающуюся пробелами
if (pWordLast->GetCountSpaceLast() == pWordLast->m_oText.GetCurSize())
{
pWordLast->m_oText = m_oTextItem;
pWordLast->m_dX = x;
pWordLast->m_dWidth = width;
}
else
{
pWordLast->m_oText.Write(m_oTextItem);
pWordLast->m_dWidth = x + width - pWordLast->m_dX; // чтобы не накапливалась ошибка, не используем сумму длин
if (5 < pWordLast->GetCountLastPoints())
m_bIsNewLine = true;
}
if (!m_oTextItem.IsSpace())
pWordLast->m_dWidthWithoutSpaces = pWordLast->m_dWidth;
}
}
public:
inline void CommandText(const std::wstring& bsText, const std::wstring& bsGid, double& x, double& y, double& width, double& height, double& baselineoffset, LONG& lIndexZ)
{
if (bsText.empty())
return;
m_lIndexZ = lIndexZ;
m_oTextItem.SetText(bsText);
if (0 == m_oTextItem.GetCurSize())
return;
if (!bsGid.empty())
{
// TODO: m_oTextItem.CorrectUnicode(m_oFontManager.m_mapUnicode);
return CommandText2(bsGid, x, y, width, height, baselineoffset);
}
if (m_bIsPDFTextStyle)
{
return CommandText2(bsGid, x, y, width, height, baselineoffset);
}
return CommandText1(x, y, width, height, baselineoffset);
}
};
BYTE* pBufferMeta = m_oMeta.GetData();
double dWidthLine = 0;
double dCurrentGlyphLineOffset = 0;
for (LONG lIndexChar = 0; lIndexChar < nCount; ++lIndexChar)
{
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->CheckBufferSize(20);
m_pPageMeta->WriteBYTE_nocheck(CMetafile::ctDrawText);
if (0 != lIndexChar)
{
m_pPageMeta->WriteDouble2_nocheck(pChar->x);
}
m_pPageMeta->WriteWCHAR_nocheck2(pChar->unicode);
if (bIsGidExist)
m_pPageMeta->WriteUSHORT_nocheck(pChar->gid);
m_pPageMeta->WriteDouble2_nocheck(pChar->width);
if (lIndexChar != 0)
dCurrentGlyphLineOffset += pChar->x;
if (lIndexChar == (nCount - 1))
dWidthLine = dCurrentGlyphLineOffset + pChar->width;
}
if (nCount > 1)
{
LONG* pWidthBuf = (LONG*)(m_pPageMeta->GetData() + _position);
*pWidthBuf = (LONG)(dWidthLine * 10000);
}
m_oLine.Clear();
m_oMeta.ClearNoAttack();
m_pPageMeta->WriteBYTE(CMetafile::ctCommandTextLineEnd);
}
};
}
#endif // _ASC_HTMLRENDERER_TEXT_H_
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef _ASC_HTMLRENDERER_TEXT_H_
#define _ASC_HTMLRENDERER_TEXT_H_
#include "FontManager.h"
namespace NSHtmlRenderer
{
class CStyles
{
private:
std::map<std::wstring, LONG> m_mapStyles;
LONG m_lNexrID;
public:
NSStringUtils::CStringBuilder m_oWriterCSS;
double m_dDpiY;
public:
CStyles() : m_mapStyles(), m_lNexrID(0)
{
}
~CStyles()
{
m_mapStyles.clear();
}
public:
void NewDocument()
{
m_mapStyles.clear();
m_lNexrID = 0;
m_oWriterCSS.Clear();
std::wstring strCSS =
L".blockpage { position: relative; background: #FFFFFF; padding: 0; float: none; margin: 0px auto; overflow: hidden; box-shadow: 0 0 10px rgba(0,0,0,0.5); -moz-box-shadow: 0 0 10px rgba(0,0,0,0.5); -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.5); }\n\
.blockpagebetween { width: 100%; height: 20px; background: #FEFEFE; padding: 0px; float: none; text-align: center; }\n\
.bt { position: absolute; margin-top: 0px; padding: 0px; float: none; }\n\
.bs { margin-top: 0px; padding: 0px; float: none; }\n\
.rt { position: absolute; font-size: 0; padding: 0px; margin-left: 0px; margin-top: 0px; border-style: solid; }\n\
._svg { -moz-user-select: none;-khtml-user-select: none;user-select: none; width:100%; height:100%;}\n\
v\\:vmlframe { behavior:url(#default#VML); display: block; width: 100%; height: 100%; position: absolute; padding: 0px; margin-left:0px;margin-top:0px; }\n\
v\\:*{behavior:url(#default#VML)}\n";
m_oWriterCSS.WriteString(strCSS);
}
void CloseDocument()
{
m_mapStyles.clear();
m_lNexrID = 0;
m_oWriterCSS.Clear();
}
void WriteStylesForDiffBrowsers(const std::wstring& strDir)
{
std::wstring strIE = L".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; text-align: justify; text-align-last: justify; }";
std::wstring strOp = L".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; display:inline-table; text-align: justify; text-align-last: justify; }\
.bp:after { content:\"\"; display:inline-block; width:100%; font-size: 0px; height:0; overflow:hidden; }";
std::wstring strOt = L".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; display:inline-table; white-space:pre-line; text-align: justify; text-align-last: justify; }\
.bp:after { content:\"\"; display:inline-block; width:100%; font-size: 0px; height:0; overflow:hidden; }";
NSFile::CFileBinary::SaveToFile(strDir + L"\\css_ie.css", strIE);
NSFile::CFileBinary::SaveToFile(strDir + L"\\css_opera.css", strOp);
NSFile::CFileBinary::SaveToFile(strDir + L"\\css_other.css", strOt);
}
LONG GetClassID(NSStructures::CFont* pFont, NSStructures::CBrush* pBrush)
{
int nSize = round(m_dDpiY * pFont->Size / 72);
if (nSize >= 10)
--nSize;
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteString(L"font-family: ");
oBuilder.WriteString(pFont->Name);
oBuilder.WriteString(L"; font-size: ");
oBuilder.AddInt(nSize);
oBuilder.WriteString(L"px; color:");
oBuilder.WriteHexColor3(pBrush->Color1);
if (pFont->Italic && pFont->Bold)
{
oBuilder.WriteString(L"; font-style:italic; font-weight:bold;", 38);
}
else if (pFont->Italic)
{
oBuilder.WriteString(L"; font-style:italic; font-weight:normal;", 40);
}
else if (pFont->Bold)
{
oBuilder.WriteString(L"; font-weight:bold; font-style:normal;", 38);
}
else
{
oBuilder.WriteString(L"; font-style:normal; font-weight:normal;", 40);
}
std::wstring sFormat = oBuilder.GetData();
std::map<std::wstring, LONG>::iterator iFind = m_mapStyles.find(sFormat);
if (iFind == m_mapStyles.end())
{
// новый стиль
++m_lNexrID;
m_mapStyles.insert(std::pair<std::wstring, LONG>(sFormat, m_lNexrID));
m_oWriterCSS.WriteString(L".s", 2);
m_oWriterCSS.AddInt(m_lNexrID);
m_oWriterCSS.WriteString(L" {", 2);
m_oWriterCSS.WriteString(sFormat);
m_oWriterCSS.WriteString(L"}\n", 2);
return m_lNexrID;
}
return iFind->second;
}
};
class CWord
{
public:
NSStructures::CFont m_oFont;
NSStructures::CBrush m_oBrush;
NSStringUtils::CStringBuilder m_oText;
double m_dX;
double m_dY;
double m_dWidth;
double m_dHeight;
double m_dBaseLinePos;
double m_dWidthWithoutSpaces;
public:
CWord() : m_oFont(), m_oBrush(), m_oText()
{
m_dX = 0;
m_dY = 0;
m_dWidth = 0;
m_dHeight = 0;
m_dBaseLinePos = 0;
m_dWidthWithoutSpaces = 0;
}
CWord(CFontManager* pFontManager, NSStructures::CBrush* pBrush, NSStringUtils::CStringBuilder& oText,
double& x, double& y, double& width, double& height, double& baseoffset) : m_oFont(pFontManager->m_oFont.m_oFont), m_oBrush(*pBrush), m_oText(oText),
m_dX(x), m_dY(y), m_dWidth(width), m_dHeight(height), m_dBaseLinePos(baseoffset), m_dWidthWithoutSpaces(width)
{
if (GetCountSpaceLast() == m_oText.GetCurSize())
m_dWidthWithoutSpaces = 0;
if (L"" != pFontManager->m_strCurrentPickFont)
{
m_oFont.Name = pFontManager->m_strCurrentPickFont;
m_oFont.SetStyle(pFontManager->m_lCurrentPictFontStyle);
}
}
CWord(const CWord& oSrc)
{
*this = oSrc;
}
CWord& operator=(const CWord& oSrc)
{
m_oFont = oSrc.m_oFont;
m_oBrush = oSrc.m_oBrush;
m_oText = oSrc.m_oText;
m_dX = oSrc.m_dX;
m_dY = oSrc.m_dY;
m_dWidth = oSrc.m_dWidth;
m_dHeight = oSrc.m_dHeight;
m_dBaseLinePos = oSrc.m_dBaseLinePos;
m_dWidthWithoutSpaces = oSrc.m_dWidthWithoutSpaces;
return *this;
}
long GetCountSpaceLast()
{
LONG lCount = (LONG)m_oText.GetCurSize();
wchar_t* pData = m_oText.GetBuffer();
LONG lCur = 0;
while (lCount > 0)
{
if (((WCHAR)' ') == pData[lCount - 1])
++lCur;
else
break;
--lCount;
}
return lCur;
}
long GetCountLastPoints()
{
LONG lCount = (LONG)m_oText.GetCurSize();
wchar_t* pData = m_oText.GetBuffer() + lCount - 1;
LONG lCur = 0;
while (lCount > 0)
{
if (((WCHAR)'.') == *pData)
++lCur;
else
break;
--lCount;
}
return lCur;
}
inline void WriteToStringWriter(NSStringUtils::CStringBuilder& oWriter)
{
oWriter.WriteEncodeXmlString(m_oText.GetBuffer(), (int)m_oText.GetCurSize());
}
};
class CTextLine
{
public:
NSStringUtils::CStringBuilder* m_pTextMeasurer;
std::list<CWord*> m_arWords;
LONG m_lNextID;
double m_dMinTop;
LONG m_lIndexZ;
public:
CTextLine() : m_arWords(), m_lIndexZ(0)
{
}
CTextLine(const CTextLine& oSrc)
{
*this = oSrc;
}
CTextLine& operator=(const CTextLine& oSrc)
{
Clear();
for (std::list<CWord*>::const_iterator iter = oSrc.m_arWords.begin(); iter != oSrc.m_arWords.end(); iter++)
{
CWord* pWord = new CWord(**iter);
m_arWords.push_back(pWord);
}
return *this;
}
public:
void Clear()
{
for (std::list<CWord*>::iterator iter = m_arWords.begin(); iter != m_arWords.end(); iter++)
{
CWord* pWord = *iter;
RELEASEOBJECT(pWord);
}
m_arWords.clear();
m_dMinTop = 10000000;
}
void AddWord(CWord* pWord)
{
// смотрим, какое слово предыдущее.
// если оно - полностью пробел - то он прищел из пдф. а значит он любой длины может быть.
// зачем он нужен?? непонятно. Поэтому удаляем такое слово
if (m_arWords.size() > 0)
{
std::list<CWord*>::iterator iter = m_arWords.end();
iter--;
CWord* pTail = *iter;
if (pTail->GetCountSpaceLast() == pTail->m_oText.GetCurSize())
{
m_arWords.pop_back();
RELEASEOBJECT(pTail);
}
}
if (m_dMinTop > pWord->m_dY)
m_dMinTop = pWord->m_dY;
m_arWords.push_back(pWord);
}
CWord* GetLast()
{
if (0 == m_arWords.size())
return NULL;
std::list<CWord*>::iterator iter = m_arWords.end();
iter--;
return *iter;
}
CWord* GetHead()
{
if (0 == m_arWords.size())
return NULL;
return *m_arWords.begin();
}
size_t GetCount()
{
return m_arWords.size();
}
public:
inline void Write(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles, const LONG& lIndexZ)
{
return Write3(pWriter, dDpiX, dDpiY, pStyles, lIndexZ);
}
void Write1(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles)
{
// временно
//return Write2(pWriter, dDpiX, dDpiY);
size_t nCountWords = m_arWords.size();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = GetLast();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
pWriter->WriteString(L"<p class=\"bp\" style=\"font-family: ", 34);
pWriter->WriteString(pWord->m_oFont.Name);
pWriter->WriteString(L"; font-size: ");
pWriter->AddInt((int)(dDpiY * pWord->m_oFont.Size / 72));
pWriter->WriteString(L"px; color:", 10);
pWriter->WriteHexColor3(pWord->m_oBrush.Color1);
pWriter->WriteString(L";\">");
for (std::list<CWord*>::iterator pos = m_arWords.begin(); pos != m_arWords.end();)
{
pWord = *pos;
if (pWord->m_oFont.IsEqual(pFont0) && (pWord->m_oBrush.IsEqual(pBrush0)))
{
pWriter->WriteString(L"<span class=\"bt\" style=\"left:", 29);
pWriter->AddInt((int)pWord->m_dX);
pWriter->WriteString(L"; top:", 6);
pWriter->AddInt((int)pWord->m_dY);
pWriter->WriteString(L";\">", 3);
}
else
{
pWriter->WriteString(L"<span class=\"bs\" style=\"font-family: ", 37);
pWriter->WriteString(pWord->m_oFont.Name);
pWriter->WriteString(L"; font-size: ", 13);
pWriter->AddInt((int)(dDpiY * pWord->m_oFont.Size / 72));
pWriter->WriteString(L"px; color:", 10);
pWriter->WriteHexColor3(pWord->m_oBrush.Color1);
pWriter->WriteString(L";\">", 3);
}
pWord->WriteToStringWriter(*pWriter);
pos++;
if (pos != m_arWords.end())
{
pWriter->WriteString(L"&nbsp;", 6);
}
pWriter->WriteString(L"</span>", 7);
}
pWriter->WriteString(L"</p>\n", 5);
}
void Write2(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles)
{
size_t nCountWords = m_arWords.size();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = GetHead();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
pWriter->WriteString(L"<p class=\"bp\" style=\"left: ", 27);
pWriter->AddInt((int)pWord->m_dX);
pWriter->WriteString(L"px; top: ", 9);
pWriter->AddInt((int)pWord->m_dY);
pWriter->WriteString(L"px; font-family: ", 17);
pWriter->WriteString(pWord->m_oFont.Name);
pWriter->WriteString(L"; font-size: ", 13);
pWriter->AddInt((int)(dDpiY * pWord->m_oFont.Size / 72));
pWriter->WriteString(L"px; color:", 10);
pWriter->WriteHexColor3(pWord->m_oBrush.Color1);
pWriter->WriteString(L"; white-space: nowrap;\">", 24);
for (std::list<CWord*>::iterator pos = m_arWords.begin(); pos != m_arWords.end();)
{
pWord = *pos;
pWriter->Write(pWord->m_oText);
pos++;
if (pos != m_arWords.end())
pWriter->AddCharSafe(' ');
}
pWriter->WriteString(L"</p>\n", 5);
}
void Write3(NSStringUtils::CStringBuilder* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles, const LONG& lIndexZ)
{
DeleteEmptyWords();
size_t nCountWords = m_arWords.size();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = GetHead();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
pWord->m_dWidth = pWord->m_dWidthWithoutSpaces;
int nLeft = (int)pWord->m_dX;
int nRight = (int)(pWord->m_dX + pWord->m_dWidthWithoutSpaces);
double dRight = pWord->m_dX + pWord->m_dWidthWithoutSpaces;
std::list<CWord*>::iterator pos = m_arWords.begin();
pos++;
while (pos != m_arWords.end())
{
pWord->m_dWidth = pWord->m_dWidthWithoutSpaces;
nRight = (int)(pWord->m_dX + pWord->m_dWidth);
pos++;
}
pos = m_arWords.begin();
pWord = *pos;
pStyles->m_dDpiY = dDpiY;
LONG lID = pStyles->GetClassID(&pWord->m_oFont, &pWord->m_oBrush);
LONG lDecoration = pWord->m_oFont.GetTextDecorationStyle();
pWriter->WriteString(L"<p class=\"bp s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"left: ", 15);
pWriter->AddInt((int)pWord->m_dX);
pWriter->WriteString(L"px; top: ", 9);
pWriter->AddInt((int)m_dMinTop);
pWriter->WriteString(L"px; width: ", 11);
pWriter->AddInt(nRight - nLeft);
pWriter->WriteString(L"px;\"><nobr>", 11);
if ((0 == lDecoration) || (3 < lDecoration))
{
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
}
else
{
switch (lDecoration)
{
case 1:
pWriter->WriteString(L"<span style=\"text-decoration:underline;\">", 41);
break;
case 2:
pWriter->WriteString(L"<span style=\"text-decoration:line-through;\">", 44);
break;
case 3:
pWriter->WriteString(L"<span style=\"text-decoration:underline line-through;\">", 54);
break;
default:
break;
}
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
pWriter->WriteString(L"</span>", 7);
}
pos++;
bool bSpanClose = false;
while (pos != m_arWords.end())
{
pWord = *pos;
if (1.0 < (pWord->m_dX - dRight))
{
pWriter->AddCharSafe(' ');
}
dRight = pWord->m_dX + pWord->m_dWidthWithoutSpaces;
if (bSpanClose)
pWriter->WriteString(L"</span>", 7);
bSpanClose = true;
lID = pStyles->GetClassID(&pWord->m_oFont, &pWord->m_oBrush);
lDecoration = pWord->m_oFont.GetTextDecorationStyle();
switch (lDecoration)
{
case 0:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\">", 2);
break;
case 1:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"text-decoration:underline;\">", 37);
break;
case 2:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"text-decoration:line-through;\">", 40);
break;
case 3:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\" style=\"text-decoration:underline line-through;\">", 50);
break;
default:
pWriter->WriteString(L"<span class=\"s", 14);
pWriter->AddInt(lID);
pWriter->WriteString(L"\">", 2);
break;
}
pWord->WriteToStringWriter(*pWriter);
pos++;
}
if (bSpanClose)
pWriter->WriteString(L"</span>", 7);
pWriter->WriteString(L"</nobr></p>\n", 12);
//CString strLine = _T("");
//strLine.Format(g_string_lineFunc, m_lNextID++, nRight - nLeft);
//m_pTextMeasurer->WriteString(strLine);
}
void DeleteEmptyWords()
{
std::list<CWord*>::iterator pos = m_arWords.begin();
while (pos != m_arWords.end())
{
CWord* pWord = *pos;
if (pWord->GetCountSpaceLast() == pWord->m_oText.GetCurSize())
{
pos = m_arWords.erase(pos);
RELEASEOBJECT(pWord);
continue;
}
pos++;
}
if (0 != m_arWords.size())
{
// удалим последние пробелы линии.
CWord* pWord = GetLast();
pWord->m_oText.RemoveLastSpaces();
}
}
void Merge()
{
std::list<CWord*>::iterator pos = m_arWords.begin();
if (pos == m_arWords.end())
return;
std::list<CWord*>::iterator posCur = pos;
CWord* pWordPrev = *pos;
posCur++;
double dRightPos = pWordPrev->m_dX + pWordPrev->m_dWidth;
while (posCur != m_arWords.end())
{
std::list<CWord*>::iterator posCurOld = posCur;
CWord* pWord = *posCur;
posCur++;
bool bNextWord = true;
if (FABS(pWord->m_dX - dRightPos) < 0.1)
{
// одно и тоже слово
bNextWord = false;
}
dRightPos = pWord->m_dX + pWord->m_dWidth;
if ((pWord->m_oFont.IsEqual(&pWordPrev->m_oFont)) && (pWord->m_oBrush.IsEqual(&pWordPrev->m_oBrush)))
{
// продолжаем текущий спан
if (bNextWord)
{
pWordPrev->m_oText.AddCharSafe(' ');
}
pWordPrev->m_oText.Write(pWord->m_oText);
posCur = m_arWords.erase(posCurOld);
RELEASEOBJECT(pWord);
}
else
{
if (bNextWord)
pWordPrev->m_oText.AddCharSafe(' ');
pos = posCur;
pWordPrev = pWord;
}
}
}
};
class CText
{
public:
CFontManager m_oFontManager;
CTextLine m_oCurrentLine;
NSStringUtils::CStringBuilder* m_pWriter;
//NSStrings::CStringWriter m_oTextMeasurer;
CStyles* m_pStyles;
double m_dDpiX;
double m_dDpiY;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
Aggplus::CMatrix* m_pTransform;
LONG m_lIndexZ;
bool m_bIsNewLine;
bool m_bIsPDFTextStyle;
NSStringUtils::CStringBuilder m_oTextItem;
private:
double m_dEpsX;
double m_dEpsY;
public:
CText() : m_oFontManager(), m_oCurrentLine(), m_oTextItem()//, m_oTextMeasurer()
{
m_pWriter = NULL;
m_dEpsX = 0.5;
m_dEpsY = 0.5;
m_pPen = NULL;
m_pBrush = NULL;
m_pFont = NULL;
//m_oCurrentLine.m_pTextMeasurer = &m_oTextMeasurer;
m_pStyles = NULL;
m_pTransform = NULL;
m_lIndexZ = 0;
m_bIsNewLine = false;
m_bIsPDFTextStyle = false;
}
void SetParams(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CFont* pFont, CStyles* pStyles, Aggplus::CMatrix* pTransform)
{
m_pPen = pPen;
m_pBrush = pBrush;
m_pFont = pFont;
m_oFontManager.m_pFont = pFont;
m_oFontManager.m_pTransform = pTransform;
m_pStyles = pStyles;
m_pTransform = pTransform;
}
~CText()
{
}
void NewPage(double& dDpiX, double& dDpiY)
{
m_dDpiX = dDpiX;
m_dDpiY = dDpiY;
m_pPen->SetDefaultParams();
m_pBrush->SetDefaultParams();
m_pFont->SetDefaultParams();
}
void ClosePage()
{
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
}
void NewDocument()
{
m_oCurrentLine.m_lNextID = 1;
m_oCurrentLine.m_dMinTop = 1000000;
m_pPen->SetDefaultParams();
m_pBrush->SetDefaultParams();
m_pFont->SetDefaultParams();
}
protected:
inline bool GetIsNewLine()
{
if (m_bIsNewLine)
{
m_bIsNewLine = false;
return true;
}
return false;
}
void CommandText1(double& x, double& y, double& width, double& height, double& baselineoffset)
{
double dScaleFont = ((m_pTransform->m_agg_mtx.sx + m_pTransform->m_agg_mtx.sy) / 2);
bool bIsFontChanged = !CFontManagerBase::IsEqual2(&m_oFontManager.m_oFont.m_oFont, m_pFont, dScaleFont);
bool bIsTextDecorationChanged = ((m_oFontManager.m_oFont.m_oFont.Underline != m_pFont->Underline) ||
(m_oFontManager.m_oFont.m_oFont.Strikeout != m_pFont->Strikeout));
if (bIsFontChanged)
{
m_oFontManager.m_oFont.m_oFont = *m_pFont;
m_oFontManager.m_oFont.m_oFont.Size *= dScaleFont;
}
else if (bIsTextDecorationChanged)
{
m_oFontManager.m_oFont.m_oFont.Underline = m_pFont->Underline;
m_oFontManager.m_oFont.m_oFont.Strikeout = m_pFont->Strikeout;
}
// никакого подбора здесь нет. нужное имя должно быть выставлено у m_pFont
m_oFontManager.m_strCurrentPickFont = L"";
bool bIsNewLine = GetIsNewLine();
if (0 == width)
{
// откуда такое может быть?? формулы??
m_oFontManager.LoadCurrentFont();
double dOffset = m_oFontManager.m_oFont.m_dBaselineOffsetHTML;
dOffset *= (m_dDpiY / 72.0);
y -= dOffset;
baselineoffset = dOffset;
// текст не измерен. для начала нужно его измерить
double _x = 0;
double _y = 0;
double _w = 0;
double _h = 0;
LONG lGid = m_oFontManager.GetStringGid();
m_oFontManager.SetStringGid(0);
m_oFontManager.MeasureStringPix(m_oTextItem.GetData(), x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
m_oFontManager.SetStringGid(lGid);
width = _w;
height = _h;
}
double dYPos = y + baselineoffset;
LONG lCountWords = (LONG)m_oCurrentLine.GetCount();
if (0 == lCountWords)
{
// слов в линии нет, без всяких проверок создаем линию
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
CWord* pTail = m_oCurrentLine.GetLast();
double dYPosLine = pTail->m_dBaseLinePos;
if (FABS(dYPos - dYPosLine) > m_dEpsY)
{
// новая линия
// сначала запишем предыдущую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
double dRight = pTail->m_dX + pTail->m_dWidth;
if ((x + 0.5 < dRight) || (((x - dRight) * c_ag_Inch_to_MM / m_dDpiX) > g_lNewNoJustifySpace) || (bIsNewLine))
{
// здесь либо текст стал левее, либо расстояние слишком большое.
// создадим новую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
// текст уже измерен
if (!bIsFontChanged && pTail->m_oBrush.IsEqual(m_pBrush) && !bIsTextDecorationChanged)
{
if (1.0 < FABS(pTail->m_dX + pTail->m_dWidth - x))
{
// это не одно и то же слово!!!
pTail->m_oText.AddCharSafe(' ');
}
pTail->m_oText.Write(m_oTextItem);
pTail->m_dWidth = (x + width - pTail->m_dX);
pTail->m_dWidthWithoutSpaces = pTail->m_dWidth;
}
else
{
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
}
}
void CommandText2(const std::wstring& bsGid, double& x, double& y, double& width, double& height, double& baselineoffset)
{
bool bIsNewLine = GetIsNewLine();
double dScaleFont = ((m_pTransform->m_agg_mtx.sx + m_pTransform->m_agg_mtx.sy) / 2);
bool bIsFontChanged = !CFontManagerBase::IsEqual2(&m_oFontManager.m_oFont.m_oFont, m_pFont, dScaleFont);
if (bIsFontChanged)
{
m_oFontManager.m_oFont.m_oFont = *m_pFont;
m_oFontManager.m_oFont.m_oFont.Size *= dScaleFont;
m_oFontManager.LoadCurrentFont();
m_oFontManager.CalculateSpace();
m_pFont->SetStyle(m_oFontManager.m_oFont.m_oFont.GetStyle());
m_oFontManager.GenerateFontName(m_oTextItem, true);
}
else
{
m_oFontManager.GenerateFontName(m_oTextItem, false);
}
double dOffset = m_oFontManager.m_oFont.m_dBaselineOffsetHTML;
dOffset *= (m_dDpiY / 72.0);
y -= dOffset;
baselineoffset = dOffset;
// текст не измерен. для начала нужно его измерить
double _x = 0;
double _y = 0;
double _w = 0;
double _h = 0;
bool bIsMeasuring = false;
if (0 >= width)
{
if (bsGid.empty())
{
m_oFontManager.SetStringGid(0);
m_oFontManager.MeasureStringPix(m_oTextItem.GetData(), x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
}
else
{
m_oFontManager.SetStringGid(1);
m_oFontManager.MeasureStringPix(bsGid, x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
}
width = _w;
height = _h;
bIsMeasuring = true;
}
double dYPos = y + baselineoffset;
LONG lCountWords = (LONG)m_oCurrentLine.GetCount();
if (0 == lCountWords)
{
// слов в линии нет, без всяких проверок создаем линию
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
double dYPosLine = m_oCurrentLine.GetHead()->m_dBaseLinePos;
if (FABS(dYPos - dYPosLine) > m_dEpsY)
{
// новая линия
// сначала запишем предыдущую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
// теперь проверяем, продолжать ли слово
//double dSpace = MMToPX(m_oFontManager.m_dSpaceWidthMM, m_dDpiX) / 2.0;
double dSpace = 0.5 * m_dDpiX / c_dInchToMM;
if (bIsMeasuring)
{
dSpace = m_oFontManager.m_dSpaceWidthMM * m_dDpiX / 25.4;
}
CWord* pWordLast = m_oCurrentLine.GetLast();
double dRight = pWordLast->m_dX + pWordLast->m_dWidthWithoutSpaces;
if ((x + 10 < dRight) || (((x - dRight) * c_ag_Inch_to_MM / m_dDpiX) > g_lNewNoJustifySpace) || (bIsNewLine))
{
// создадим новую линию
m_oCurrentLine.Write(m_pWriter, m_dDpiX, m_dDpiY, m_pStyles, m_lIndexZ);
m_oCurrentLine.Clear();
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
return;
}
bool bIsBrushChanged = !pWordLast->m_oBrush.IsEqual(m_pBrush);
double dDelta = (x - (pWordLast->m_dX + pWordLast->m_dWidth));
if ((dDelta > dSpace) || bIsFontChanged || bIsBrushChanged)
{
if (m_oTextItem.IsSpace())
{
if (0 == pWordLast->GetCountSpaceLast())
{
pWordLast->m_oText.Write(m_oTextItem);
pWordLast->m_dWidth = x + width - pWordLast->m_dX;
}
return;
}
if (dDelta > dSpace)
pWordLast->m_oText.AddCharSafe(' ');
if (bIsFontChanged || bIsBrushChanged)
{
CWord* pWord = new CWord(&m_oFontManager, m_pBrush, m_oTextItem, x, y, width, height, dYPos);
m_oCurrentLine.AddWord(pWord);
}
else
{
pWordLast->m_oText.Write(m_oTextItem);
pWordLast->m_dWidth = x + width - pWordLast->m_dX;
pWordLast->m_dWidthWithoutSpaces = pWordLast->m_dWidth;
}
}
else
{
// продолжаем слово
// сначала заглушку на строку, начинающуюся пробелами
if (pWordLast->GetCountSpaceLast() == pWordLast->m_oText.GetCurSize())
{
pWordLast->m_oText = m_oTextItem;
pWordLast->m_dX = x;
pWordLast->m_dWidth = width;
}
else
{
pWordLast->m_oText.Write(m_oTextItem);
pWordLast->m_dWidth = x + width - pWordLast->m_dX; // чтобы не накапливалась ошибка, не используем сумму длин
if (5 < pWordLast->GetCountLastPoints())
m_bIsNewLine = true;
}
if (!m_oTextItem.IsSpace())
pWordLast->m_dWidthWithoutSpaces = pWordLast->m_dWidth;
}
}
public:
inline void CommandText(const std::wstring& bsText, const std::wstring& bsGid, double& x, double& y, double& width, double& height, double& baselineoffset, LONG& lIndexZ)
{
if (bsText.empty())
return;
m_lIndexZ = lIndexZ;
m_oTextItem.SetText(bsText);
if (0 == m_oTextItem.GetCurSize())
return;
if (!bsGid.empty())
{
// TODO: m_oTextItem.CorrectUnicode(m_oFontManager.m_mapUnicode);
return CommandText2(bsGid, x, y, width, height, baselineoffset);
}
if (m_bIsPDFTextStyle)
{
return CommandText2(bsGid, x, y, width, height, baselineoffset);
}
return CommandText1(x, y, width, height, baselineoffset);
}
};
}
#endif // _ASC_HTMLRENDERER_TEXT_H_
#pragma once
#include "Text.h"
#include "Document.h"
#include "CalculatorCRC32.h"
#include "..\Graphics\Matrix.h"
#include "VectorGraphicsWriter2.h"
namespace NSHtmlRenderer
{
class CPageWriter
{
public:
LONG m_lPageNumber;
CStringWriter m_oWriterPage;
CText m_oText;
LONG m_lPixWidth;
LONG m_lPixHeight;
double m_dDpiX;
double m_dDpiY;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
BOOL m_bIsClip;
BOOL m_bIsClipping;
Graphics::IASCGraphicSimpleComverter* m_pSimpleConverter;
CMatrix* m_pFullTransform;
LONG m_lCurTxBrush;
CVectorGraphicsWriter m_oVectorWriter;
CString m_strDstDirectory;
CString m_strDstMedia;
LONG m_lIndexZ;
public:
CPageWriter() : m_lPageNumber(0), m_oVectorWriter()
{
m_oText.m_pWriter = &m_oWriterPage;
m_lPixWidth = 0;
m_lPixHeight = 0;
m_dDpiX = 1;
m_dDpiY = 1;
m_pPen = NULL;
m_pBrush = NULL;
m_pFont = NULL;
m_bIsClip = FALSE;
m_bIsClipping = FALSE;
m_pSimpleConverter = NULL;
m_pFullTransform = NULL;
m_lCurTxBrush = 0;
}
~CPageWriter()
{
}
public:
AVSINLINE void NewPage(double dDpiX, double dDpiY, LONG lPixW, LONG lPixH)
{
m_lPixWidth = lPixW;
m_lPixHeight = lPixH;
m_dDpiX = dDpiX;
m_dDpiY = dDpiY;
m_oText.NewPage(dDpiX, dDpiY);
double w = (double)m_lPixWidth;
double h = (double)m_lPixHeight;
m_oVectorWriter.NewPage(w, h, m_lPageNumber);
m_lCurTxBrush = 0;
m_lIndexZ = 0;
}
AVSINLINE void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CFont* pFont, CStyles* pStyles, NSHtmlRenderer::CMatrix* pTransform)
{
m_pPen = pPen;
m_pBrush = pBrush;
m_pFont = pFont;
m_oText.SetParams(pPen, pBrush, pFont, pStyles, pTransform);
m_oVectorWriter.SetSettings(pPen, pBrush, m_pSimpleConverter);
}
AVSINLINE void ClosePage()
{
m_oVectorWriter.EndPage();
m_oWriterPage.ClearNoAttack();
m_oText.m_oCurrentLine.Clear();
m_lCurTxBrush = 0;
}
public:
void Write(CStringWriter* pWriterDoc, CStringWriter* pWriterScript, CStringWriter* pWriterThumbnails, CStringWriter* pTextMeasurer, double dHeightDoc, LONG lPageNumber, CDstInfo& oInfo)
{
CString strPage = _T("");
strPage.Format(g_string_viewer_page, lPageNumber + 1, (LONG)0/*dHeightDoc*/, m_lPixWidth, (LONG)m_lPixHeight);
pWriterDoc->WriteString(strPage);
m_oText.ClosePage();
if (m_oVectorWriter.IsGraphics())
{
m_oVectorWriter.WriteToDocument(pWriterDoc, oInfo);
// чтобы работал клик
CString strTransparentDiv = _T("<div style=\"position:absolute; top: 0px; width:100%; height:100%;\"></div>\n");
pWriterDoc->WriteString(strTransparentDiv);
}
pWriterDoc->Write(m_oWriterPage);
pWriterDoc->WriteString(g_bstr_viewer_end_div2);
}
public:
AVSINLINE void WriteImage(double& x, double& y, double& width, double& height, CImageInfo& oInfo, double dAngle)
{
m_oVectorWriter.WriteImage(x, y, width, height, oInfo, dAngle);
}
AVSINLINE void WriteBeginPath()
{
m_oVectorWriter.WritePathStart();
}
AVSINLINE void WriteEndPath()
{
m_oVectorWriter.WriteEndPath();
}
AVSINLINE void WritePathStart()
{
m_oVectorWriter.WritePathStart();
}
AVSINLINE void WritePathClose()
{
m_oVectorWriter.WritePathClose();
}
AVSINLINE void WritePathMoveTo(double& x, double& y)
{
m_oVectorWriter.WritePathMoveTo(x, y);
}
AVSINLINE void WritePathLineTo(double& x, double& y)
{
m_oVectorWriter.WritePathLineTo(x, y);
}
AVSINLINE void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
m_oVectorWriter.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
}
AVSINLINE void WriteDrawPath(LONG lType, CImageInfo& oInfo, const double& dAngle)
{
m_oVectorWriter.WriteDrawPath(lType, oInfo, dAngle);
m_oText.m_bIsNewLine = true;
}
AVSINLINE void WriteNewTableBox()
{
m_oText.m_bIsNewLine = true;
}
AVSINLINE void WritePathClip()
{
m_oVectorWriter.WritePathClip();
}
AVSINLINE void WritePathClipEnd()
{
m_oVectorWriter.WritePathClipEnd();
}
AVSINLINE void WritePathResetClip()
{
m_oVectorWriter.WritePathResetClip();
}
AVSINLINE void WriteText(BSTR bsText, BSTR bsGid, double x, double y, double width, double height, double baselineoffset)
{
//WriteGraphics();
m_oText.CommandText(bsText, bsGid, x, y, width, height, baselineoffset, m_lIndexZ);
}
AVSINLINE void WriteGraphics()
{
if (m_oVectorWriter.IsGraphics())
{
//m_oVectorWriter.WriteToDocument(&m_oWriterPage, m_strDstMedia);
++m_lIndexZ;
}
}
};
class CWriter
{
private:
CStringWriter m_oWriter;
CStringWriter m_oWriterThumbnails;
CStringWriter m_oWriterScript;
CStringWriter m_oWriterTextMeasurer;
CStyles m_oWriterCSS;
public:
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
double m_dDpiX;
double m_dDpiY;
BOOL m_bPathClosed;
CPageWriter m_oPage;
CAtlMap<CString, CImageInfo> m_mapImagesFile;
CAtlMap<DWORD, CImageInfo> m_mapImageData;
CCalculatorCRC32 m_oCRC;
LONG m_lWidthDocPix;
LONG m_lHeightDocPix;
LONG m_lHeightPagePix;
CDstInfo m_oDstInfo;
Graphics::IASCGraphicSimpleComverter* m_pSimpleConverter;
public:
double m_dWidthPix;
double m_dHeigthPix;
private:
LONG m_lNextIDShape;
LONG m_lNextIDImage;
LONG m_lCurrentPage;
LONG m_lPagesCount;
BOOL m_bIsClip;
BOOL m_bIsClipping;
double m_dHeightDoc;
LONG m_lMaxSizeImage;
public:
CString m_strDstDirectory;
CString m_strDstMedia;
CString m_strDstDirectoryFiles;
CString m_strFileName;
public:
bool m_bIsThumbnails;
bool m_bIsMenu;
private:
// здесь данные для накопления слов (а лучше и строки??)
public:
CWriter()
{
m_dDpiX = 96.0;
m_dDpiY = 96.0;
m_dWidthPix = 0;
m_dHeigthPix = 0;
m_lNextIDImage = 0;
m_lNextIDShape = 0;
m_lCurrentPage = -1;
m_bIsClip = FALSE;
m_bIsClipping = FALSE;
m_bPathClosed = TRUE;
m_dHeightDoc = 0;
m_pSimpleConverter = NULL;
m_lMaxSizeImage = 800;
m_lWidthDocPix = 0;
m_lHeightDocPix = 0;
m_lHeightPagePix = 0;
m_bIsThumbnails = false;
m_bIsMenu = false;
m_lPagesCount = 0;
}
AVSINLINE NSHtmlRenderer::CStyles* GetStyles()
{
return &m_oWriterCSS;
}
void CreateFile(CString& strDir, CString& strFileName)
{
m_lPagesCount = 0;
m_strDstDirectory = strDir;
m_strDstDirectoryFiles = m_strDstDirectory + _T("\\") + strFileName + _T("_files");
m_strFileName = strFileName;
CDirectory::CreateDirectory(m_strDstDirectoryFiles);
m_strDstMedia = m_strDstDirectoryFiles + _T("\\media");
CDirectory::CreateDirectory(m_strDstMedia);
if (m_bIsThumbnails)
CDirectory::CreateDirectory(m_strDstDirectoryFiles + _T("\\thumbnails"));
m_oPage.m_strDstDirectory = m_strDstDirectoryFiles;
m_oPage.m_strDstMedia = m_strDstMedia;
m_oDstInfo.m_strDstFilePath = m_strDstDirectoryFiles;
m_oDstInfo.m_strDstMedia = m_strDstMedia;
m_oDstInfo.m_strDstFilePath.Replace(_T("\\"), _T("/"));
m_oDstInfo.m_strAdditionalPath = _T("");
LONG lStart = m_oDstInfo.m_strDstFilePath.ReverseFind(TCHAR('/'));
if (-1 != lStart)
{
m_oDstInfo.m_strAdditionalPath = m_oDstInfo.m_strDstFilePath.Mid(0, lStart);
lStart = m_oDstInfo.m_strAdditionalPath.ReverseFind(TCHAR('/'));
if (-1 != lStart)
{
m_oDstInfo.m_strAdditionalPath = m_oDstInfo.m_strDstFilePath.Mid(lStart + 1);
}
}
m_oWriter.Clear();
m_oWriterScript.Clear();
m_oWriterThumbnails.Clear();
m_oWriterTextMeasurer.Clear();
}
void SetSimpleConverter(Graphics::IASCGraphicSimpleComverter* pSimpleConverter, CMatrix* pMatrix)
{
m_pSimpleConverter = pSimpleConverter;
m_oPage.m_pSimpleConverter = m_pSimpleConverter;
m_oPage.m_pFullTransform = pMatrix;
m_oPage.m_oVectorWriter.m_pSimpleConverter = m_pSimpleConverter;
m_oPage.m_oVectorWriter.m_pFullTransform = pMatrix;
}
AVSINLINE void WriteText(BSTR bsText, BSTR bsGid, double x, double y, double width, double height, double baselineoffset)
{
m_oPage.WriteText(bsText, bsGid, x, y, width, height, baselineoffset);
}
void WriteImage(IUnknown* punkImage, double x, double y, double width, double height, double dAngle)
{
//if (width < 0)
//{
// FlipX(punkImage);
// width = -width;
//}
if (height < 0)
{
FlipY(punkImage);
height = -height;
y -= height;
}
CImageInfo oID = GenerateImageID(punkImage);
m_oPage.WriteImage(x, y, width, height, oID, dAngle);
}
AVSINLINE void WriteImage(CString& strFile, double x, double y, double width, double height, double dAngle)
{
CImageInfo oID = GenerateImageID(strFile);
m_oPage.WriteImage(x, y, width, height, oID, dAngle);
}
AVSINLINE void WriteBeginPath()
{
m_oPage.WriteBeginPath();
}
AVSINLINE void WriteEndPath()
{
m_oPage.WriteEndPath();
}
AVSINLINE void WritePathStart()
{
m_oPage.WritePathStart();
}
AVSINLINE void WritePathClose()
{
m_oPage.WritePathClose();
}
AVSINLINE void WritePathMoveTo(double& x, double& y)
{
m_oPage.WritePathMoveTo(x, y);
}
AVSINLINE void WritePathLineTo(double& x, double& y)
{
m_oPage.WritePathLineTo(x, y);
}
AVSINLINE void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
m_oPage.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
}
AVSINLINE void WriteDrawPath(LONG lType, const double& dAngle)
{
CImageInfo oInfo;
if ((lType > 0xFF) && (c_BrushTypeTexture == m_pBrush->Type))
{
oInfo = GenerateImageID(m_pBrush->TexturePath);
}
m_oPage.WriteDrawPath(lType, oInfo, dAngle);
}
AVSINLINE void WritePathClip()
{
m_oPage.WritePathClip();
}
AVSINLINE void WritePathClipEnd()
{
m_oPage.WritePathClipEnd();
}
AVSINLINE void WritePathResetClip()
{
m_oPage.WritePathResetClip();
}
void NewPage(double& dWidthPix, double& dHeightPix)
{
if (0 != m_lPagesCount)
{
CString strNewPageWrite = _T("<div style=\"position:relative;margin:0;padding:0;top:0px;width:100%;height:20px\"></div>");
m_oWriter.WriteString(strNewPageWrite);
}
++m_lPagesCount;
m_dWidthPix = dWidthPix;
m_dHeigthPix = dHeightPix;
if (m_lWidthDocPix < (LONG)dWidthPix)
m_lWidthDocPix = (LONG)dWidthPix;
if (m_lHeightPagePix < (LONG)dHeightPix)
m_lHeightPagePix = (LONG)dHeightPix;
m_lHeightDocPix += (LONG)dHeightPix;
++m_lCurrentPage;
m_oPage.m_lPageNumber = m_lCurrentPage;
m_oPage.NewPage(m_dDpiX, m_dDpiY, (LONG)m_dWidthPix, (LONG)m_dHeigthPix);
}
void EndPage(bool bIsWEB)
{
if (m_bIsThumbnails)
{
// thumbnails
CString strPageThumbnail = _T("");
strPageThumbnail.Format(_T("<div class=\"blockpage\">\n\
<div class=\"blockthumbnail\" align=\"center\">\n\
<img align=\"center\" src=\"thumbnails/page%d.png\" onClick=\"OnChangePage(%d)\" width=\"%s\" height=\"%s\"/>\n\
page%d\n\
</div>\n\
</div>\n"), m_lCurrentPage + 1, m_lCurrentPage + 1, _T("100%"), _T("90%"), m_lCurrentPage + 1);
m_oWriterThumbnails.WriteString(strPageThumbnail);
}
// page
//m_oWriter.WriteString(g_bstr_viewer_end_div);
m_oPage.Write(&m_oWriter, &m_oWriterScript, &m_oWriterThumbnails, &m_oWriterTextMeasurer, /*m_dHeightDoc*/20 * m_lCurrentPage, m_lCurrentPage, m_oDstInfo);
m_oPage.ClosePage();
if (bIsWEB)
{
CString str = _T("");
str.Format(_T("<script type=\"text/javascript\">this.__pagesLoaded = %d;</script>"), m_lCurrentPage + 1);
m_oWriter.WriteString(str);
}
m_dHeightDoc += m_oPage.m_lPixHeight;
m_dHeightDoc += 20; // const
}
void WriteStartDocument()
{
//// 1) главный документ
//CString strHtml =
// _T("<html>\n\
// <head>\n\
// <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
// <title>document viewer</title>\n\
// </head>\n\
// <frameset rows=\"50,*\" framespacing=\"0\" frameborder=\"0\">\n\
// <frame src=\"menu.html\" name=\"menu\" noresize border=\"1\" bordercolor=\"#F0F0F0\" scrolling=\"no\"></frame>\n\
// <frameset cols=\"*,200\">\n\
// <frame id=\"id_viewer\" src=\"viewer.html\" name=\"viewer\" noresize></frame>\n\
// <frame id=\"id_thumbnails\" src=\"thumbnails.html\" name=\"thumbnail\"></frame>\n\
// </frameset>\n\
// </frameset>\n\
// </html>");
//
//CDirectory::SaveToFile(m_strDstDirectory + _T("\\document.html"), strHtml);
//// 2) menu
//CString strMenu =
// _T("<html>\n\
// <head>\n\
// <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
// <title>menu</title>\n\
// </head>\n\
// <body bgcolor=\"#5F5F5F\">\n\
// </body>\n\
// </html>");
//
//CDirectory::SaveToFile(m_strDstDirectory + _T("\\menu.html"), strMenu);
//// 3) viewer
//CString strViewer =
// _T("<!--[if IE]><!DOCTYPE html><![endif]-->\
// <html xmlns:v=\"urn:schemas-microsoft-com:vml\">\n\
// <head>\n\
// <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
// <title>viewer</title>\n\
// <link rel=\"stylesheet\" href=\"docstyles.css\" type=\"text/css\"/>\n\
// <script language=\"JavaScript\">\n\
// function OnChangePage(pageNum)\n\
// {\nvar _div_name = \"page\" + pageNum;\nvar _div = document.getElementById(_div_name);\nif (_div)\n{\nscroll(0, _div.offsetTop);\n}\n}\n\
// </script>\n\
// <script type=\"text/javascript\" src=\"script.js\"></script>\n\
// </head>\n\
// <body style=\"margin: 0px;\" bgcolor=\"#CBCFD4\">\n");
//m_oWriter.WriteString(strViewer);
//// 4) thumbnails
//CString strThumbnails = _T("<html>\
// <head>\n\
// <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
// <title>thumbnails</title>\n\
// <style type=\"text/css\">\n\
// .blockpage {\n\
// width: 80%;\n\
// height: 200px;\n\
// background: #FEFEFE;\n\
// padding: 10px;\n\
// float: none;\n\
// text-align: center;\n\
// }\n\
// .blockthumbnail {\n\
// width: 100%;\n\
// height: 100%;\n\
// background: #FEFEFE;\n\
// padding: 0px;\n\
// float: none;\n\
// }\n\
// </style>\n\
// <script language=\"JavaScript\">\n\
// function OnChangePage(pageNum)\n\
// {\n\
// top.frames['viewer'].OnChangePage(pageNum);\n\
// }\n\
// </script>\n\
// </head>\n\
// <body bgcolor=\"#FEFEFE\">");
//m_oWriterThumbnails.WriteString(strThumbnails);
m_dHeightDoc = 0;
m_oPage.m_oText.NewDocument();
//m_oWriterScript.WriteString(g_bstr_basicscript);
m_oWriterCSS.NewDocument();
//m_oWriterTextMeasurer.WriteString(g_bstr_lineMeasure);
}
void WriteEndDocument(CDocument& oDocument)
{
// скидывание canvas - у нас SVG
// CDirectory::SaveToFile(m_strDstDirectory + _T("\\script.js"), m_oWriterScript.GetData());
// docstyles
CDirectory::SaveToFile(m_strDstDirectoryFiles + _T("\\docstyles.css"), m_oWriterCSS.m_oWriterCSS.GetCString());
m_oWriterCSS.WriteStylesForDiffBrowsers(m_strDstDirectoryFiles);
// viewer.html
CFile oFileViewer;
oFileViewer.CreateFile(m_strDstDirectoryFiles + _T("\\viewer.html"));
CString strViewer = _T("<!--[if IE]><!DOCTYPE html><![endif]-->\n\
<html xmlns:v=\"urn:schemas-microsoft-com:vml\">\n\
<head>\n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
<title>viewer</title>\n\
<link rel=\"stylesheet\" href=\"docstyles.css\" type=\"text/css\"/>\n\
<script language=\"JavaScript\">\n");
CString strInfoDoc = _T("");
strInfoDoc.Format(_T("var dZoomKoef = 1.0;var lWidthDoc = %d; var lHeightPage = %d; var lHeightDoc = %d;var bIsFitToPage = 0;var nPagesCount = %d;\n"),
m_lWidthDocPix, m_lHeightPagePix, m_lHeightDocPix, m_lPagesCount);
strViewer += strInfoDoc;
CString str2 = _T("var bIsIE = /*@cc_on ! @*/ false;\
var bIsOpera = (window.opera != undefined);\
if (bIsIE)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_ie.css\\\"/>\");\
}\
else if (bIsOpera)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_opera.css\\\"/>\");\
}\
else\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_other.css\\\"/>\");\
}\n\
</script>\n");
strViewer += str2;
oFileViewer.WriteStringUTF8(strViewer);
CString strMainDiv = _T("");
strMainDiv.Format(_T("</head>\n\
<body style=\"padding: 0; margin: 0px;\" bgcolor=\"#eef0f2\">\n\
<div style=\"position:relative;margin:0px;padding:0px;height:16px;background-color:#eef0f2;\"></div>\n<div id=\"maindiv\" style=\"position: relative; width: %dpx; padding: 0; margin: 0 auto;\">\n"), m_lWidthDocPix);
oFileViewer.WriteStringUTF8(strMainDiv);
oFileViewer.WriteStringUTF8(m_oWriter.GetCString());
CString strEndBody = _T("<div style=\"position:relative;margin:0px;padding:0px;height:16px;\"></div></div></body></html>");
oFileViewer.WriteStringUTF8(strEndBody);
oFileViewer.CloseFile();
m_oPage.ClosePage();
m_mapImageData.RemoveAll();
m_mapImagesFile.RemoveAll();
m_oWriterCSS.CloseDocument();
// document.html
if (m_bIsThumbnails)
{
CString strHtml =
_T("<html>\n\
<head>\n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
<title>document viewer</title>\n\
</head>\n\
<frameset cols=\"*,200\" framespacing=\"0\" frameborder=\"0\">\n\
<frame id=\"id_viewer\" src=\"") + m_strFileName + _T("_files/viewer.html\" name=\"viewer\" noresize></frame>\n\
<frame id=\"id_thumbnails\" src=\"") + m_strFileName + _T("_files/thumbnails.html\" name=\"thumbnail\"></frame>\n\
</frameset>\n\
</frameset>\n\
</html>");
CDirectory::SaveToFile(m_strDstDirectory + _T("\\") + m_strFileName + _T(".html"), strHtml);
}
else
{
CString strHtml =
_T("<html>\n\
<head>\n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
<title>document viewer</title>\n\
</head>\n\
<frameset framespacing=\"0\" frameborder=\"0\">\n\
<frame id=\"id_viewer\" src=\"") + m_strFileName + _T("_files/viewer.html\" name=\"viewer\" noresize></frame>\n\
</frameset>\n\
</frameset>\n\
</html>");
CDirectory::SaveToFile(m_strDstDirectory + _T("\\") + m_strFileName + _T(".html"), strHtml);
}
}
void WriteEndDocument2(CDocument& oDocument)
{
// docstyles
CDirectory::SaveToFile(m_strDstDirectoryFiles + _T("\\docstyles.css"), m_oWriterCSS.m_oWriterCSS.GetCString());
m_oWriterCSS.WriteStylesForDiffBrowsers(m_strDstDirectoryFiles);
// viewer.html
CFile oFileViewer;
oFileViewer.CreateFile(m_strDstDirectoryFiles + _T("\\viewer.html"));
CString strViewer1 = _T("<!--[if IE]><!DOCTYPE html><![endif]-->\n\
<html xmlns:v=\"urn:schemas-microsoft-com:vml\">\n\
<head>\n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n\
<title>viewer</title>\n\
<meta http-equiv=\"X-UA-Compatible\" content=\"IE=8;IE=9;chrome=1;\"/>\n\
<link rel=\"stylesheet\" href=\"") + m_oDstInfo.m_strAdditionalPath + _T("/docstyles.css\" type=\"text/css\"/>\n\
<link rel=\"stylesheet\" href=\"styles/docviewer.css\" type=\"text/css\"/>\
<script type=\"text/javascript\" src=\"jquery/jquery-1.6.1.min.js\"></script>\
<script type=\"text/javascript\" src=\"jquery/jquery.mousewheel.js\"></script>\
<script language=\"JavaScript\">\n");
oFileViewer.WriteStringUTF8(strViewer1);
CString strInfoDoc = _T("");
strInfoDoc.Format(_T("var dZoomKoef = 1.0;var lWidthDoc = %d; var lHeightPage = %d; var lHeightDoc = %d;var bIsFitToPage = 0;var nPagesCount = %d;\n"),
m_lWidthDocPix, m_lHeightPagePix, m_lHeightDocPix, m_lPagesCount);
CString str1 = _T("var arrayOffsets = [0");
CStringWriter oWriterPagesInfo;
oWriterPagesInfo.WriteString(str1);
size_t offsetOld = 0;
for (LONG i = 1; i < m_lPagesCount; ++i)
{
offsetOld += (size_t)(96 * oDocument.m_arrPages[i - 1].GetHeight() / 25.4);
CString strPage = _T("");
strPage.Format(_T(",%u"), offsetOld + 36);
oWriterPagesInfo.WriteString(strPage);
}
if (m_oDstInfo.m_bIsWeb)
{
CString str2 = _T("];\n\
var bIsIE = /*@cc_on ! @*/ false;\
var bIsOpera = (window.opera != undefined);\
if (bIsIE)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles/css_ie.css\\\"/>\");\
}\
else if (bIsOpera)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles/css_opera.css\\\"/>\");\
}\
else\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles/css_other.css\\\"/>\");\
}</script>\n");
oWriterPagesInfo.WriteString(str2);
}
else
{
CString str2 = _T("];\n\
var bIsIE = /*@cc_on ! @*/ false;\
var bIsOpera = (window.opera != undefined);\
if (bIsIE)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_ie.css\\\"/>\");\
}\
else if (bIsOpera)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_opera.css\\\"/>\");\
}\
else\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_other.css\\\"/>\");\
}</script>\n");
oWriterPagesInfo.WriteString(str2);
}
strInfoDoc += oWriterPagesInfo.GetCString();
oFileViewer.WriteStringUTF8(strInfoDoc);
CString strMainDiv = _T("");
strMainDiv.Format(_T("<script type=\"text/javascript\" src=\"js/dochtmlviewer.js\"></script></head>\n\
<body class=\"viewerbody\">\n\
<div style=\"position:relative;margin:0px;padding:0px;height:16px;background-color:#eef0f2;\"></div>\n<div id=\"maindiv\" style=\"position: relative; width: %dpx; padding: 0; margin: 0 auto;\">\n"), m_lWidthDocPix);
oFileViewer.WriteStringUTF8(strMainDiv);
oFileViewer.WriteStringUTF8(m_oWriter.GetCString());
CString strEndBody = _T("<div style=\"position:relative;margin:0;padding:0;top:0px;width:100%;height: 16px\"></div></div><script type=\"text/javascript\">SetPageCountToMenu();stopTimer();</script></body></html>");
oFileViewer.WriteStringUTF8(strEndBody);
oFileViewer.CloseFile();
}
void WriteEndDocument3(CDocument& oDocument)
{
// docstyles
CDirectory::SaveToFile(m_strDstDirectoryFiles + _T("\\docstyles.css"), m_oWriterCSS.m_oWriterCSS.GetCString());
m_oWriterCSS.WriteStylesForDiffBrowsers(m_strDstDirectoryFiles);
// viewer.html
CFile oFileViewer;
oFileViewer.CreateFile(m_strDstDirectoryFiles + _T("\\viewer.html"));
CString strViewer1 = _T("<!DOCTYPE html><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\
<title></title><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8;IE=9;chrome=1;\"/>\
<link rel=\"stylesheet\" href=\"docstyles.css\" type=\"text/css\"/><script language=\"JavaScript\">");
oFileViewer.WriteStringUTF8(strViewer1);
CString strInfoDoc = _T("");
strInfoDoc.Format(_T("var dZoomKoef = 1.0;var lWidthDoc = %d; var lHeightPage = %d; var lHeightDoc = %d;var bIsFitToPage = 0;var nPagesCount = %d;\n"),
m_lWidthDocPix, m_lHeightPagePix, m_lHeightDocPix, m_lPagesCount);
CString str1 = _T("var arrayOffsets = [0");
CStringWriter oWriterPagesInfo;
oWriterPagesInfo.WriteString(str1);
size_t offsetOld = 0;
for (LONG i = 1; i < m_lPagesCount; ++i)
{
offsetOld += (size_t)(96 * oDocument.m_arrPages[i - 1].GetHeight() / 25.4);
CString strPage = _T("");
strPage.Format(_T(",%u"), offsetOld + 36);
oWriterPagesInfo.WriteString(strPage);
}
if (m_oDstInfo.m_bIsWeb)
{
CString str2 = _T("];\n\
var bIsIE = /*@cc_on ! @*/ false;\
var bIsOpera = (window.opera != undefined);\
if (bIsIE)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles/css_ie.css\\\"/>\");\
}\
else if (bIsOpera)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles/css_opera.css\\\"/>\");\
}\
else\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"styles/css_other.css\\\"/>\");\
}</script>\n");
oWriterPagesInfo.WriteString(str2);
}
else
{
CString str2 = _T("];\n\
var bIsIE = /*@cc_on ! @*/ false;\
var bIsOpera = (window.opera != undefined);\
if (bIsIE)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_ie.css\\\"/>\");\
}\
else if (bIsOpera)\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_opera.css\\\"/>\");\
}\
else\
{\
document.write(\"<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"css_other.css\\\"/>\");\
}</script>\n");
oWriterPagesInfo.WriteString(str2);
}
strInfoDoc += oWriterPagesInfo.GetCString();
oFileViewer.WriteStringUTF8(strInfoDoc);
CString strHead___ = _T("<script type=\"text/javascript\" src=\"common/dochtmlviewer.js\"></script>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/MenuStyle.css\"/>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/docviewer.css\"/>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/clickmenu.css\"/>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/jquery-ui.css\"/>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/jquery-custom.css\"/>\
<!--[if IE 8]>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/IE.css\"/>\
<![endif]-->\
<!--[if IE 9]>\
<link rel=\"stylesheet\" type=\"text/css\" href=\"common/IE9.css\"/>\
<![endif]-->\
<script type=\"text/javascript\" src=\"common/jquery-1.6.1.min.js\"></script>\
<script type=\"text/javascript\" src=\"common/jquery-ui.js\"></script>\
<script type=\"text/javascript\" src=\"common/jquery.clickmenu.js\"></script>\
<script type=\"text/javascript\" src=\"common/jquery.mousewheel.js\"></script>\
<script type=\"text/javascript\" src=\"common/docviewer.js\"></script>\
<script type=\"text/javascript\" src=\"common/common.js\"></script>\
<script type=\"text/javascript\">\n\
var isMobileAgent = /android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent || navigator.vendor || window.opera);\n\
$(function(){\n\
if (isMobileAgent)\n\
$(\"#menu\").hide();\n\
window.onresize = OnResizeBrowser;\n\
$(window).resize();\n\
var windowWidth = $(window).width();\n\
var windowHeight = $(window).height();\n\
startTimer();\n\
});\n\
function OnResizeBrowser()\n\
{\n\
var elemMenu = document.getElementById(\"menu\");\n\
var heightMenu = elemMenu.offsetHeight;\n\
var elemDiv = document.getElementById(\"content\");\n\
\n\
var allheight = 0;\n\
if (this.innerHeight)\n\
allheight = this.innerHeight;\n\
else if (document.documentElement && document.documentElement.clientHeight)\n\
allheight = document.documentElement.clientHeight;\n\
else if (document.body)\n\
allheight = document.body.clientHeight;\n\
\n\
var __height = (allheight - heightMenu) + \"px\";\n\
elemDiv.style.height = __height;\n\
\n\
CheckFitToPage();\n\
}\n\
</script>\
</head>\
<body style=\"padding: 0; margin: 0 auto;overflow:hidden;\">\n\
<table id=\"menu\" class=\"utilFont\" style=\"width:100%\"><tr><td id=\"toolbar\"><table style=\"\"><tr>\n\
<td class=\"ToolbarIconOut selectableIcon\" title=\"ZoomOut\" onclick=\"funZoomOut()\"><div id=\"zoomOut\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarZoomOut\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"ToolbarIconOut selectableIcon\" title=\"ZoomIn\" onclick=\"funZoomIn()\"><div id=\"zoomIn\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarZoomIn\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"ToolbarIconOut selectableIcon\" title=\"ActualSize\" onclick=\"funZoom(0,null)\"><div id=\"actualSize\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarActualSize\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td id=\"td_fitToPage\" class=\"ToolbarIconOut selectableIcon iconPressed2\" title=\"FitToPage\" onclick=\"funZoom(1,this)\"><div id=\"fitToPage\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarFitToPage\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td id=\"td_fitToWidth\" class=\"ToolbarIconOut selectableIcon iconPressed2\" title=\"FitToWidth\" onclick=\"funZoom(2,this)\"><div id=\"fitToWidth\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarFitToWidth\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"ToolbarIconOut\" style=\"min-width: 20px;\"><div><ul id=\"zoomMenu\"><li id=\"zoom\" class=\"item main textSelect textSelectBoard\"><span id=\"zoomValuePercent\">100%</span><ul>\n\
<li id=\"8\" class=\"SubItem\" value=\"8\">8%</li><li id=\"12\" class=\"SubItem\" value=\"12\">12%</li><li id=\"25\" class=\"SubItem\" value=\"25\">25%</li>\
<li id=\"33\" class=\"SubItem\" value=\"33\">33%</li><li id=\"50\" class=\"SubItem\" value=\"50\">50%</li><li id=\"66\" class=\"SubItem\" value=\"66\">66%</li>\
<li id=\"75\" class=\"SubItem\" value=\"75\">75%</li><li id=\"100\" class=\"SubItem\" value=\"100\">100%</li><li id=\"125\" class=\"SubItem\" value=\"125\">125%</li>\
<li id=\"150\" class=\"SubItem\" value=\"150\">150%</li><li id=\"200\" class=\"SubItem\" value=\"200\">200%</li><li id=\"300\" class=\"SubItem\" value=\"300\">300%</li>\
<li id=\"400\" class=\"SubItem\" value=\"400\">400%</li><li id=\"500\" class=\"SubItem\" value=\"500\">500%</li></ul><div class=\"ToolbarDropDown dropdown\"></div></li></ul></div></td>\n\
<td class=\"toolbarSep\"><div class=\"ToolbarIconOut\"><img src=\"common/img/Border.png\"/></div></td>\n\
<td class=\"ToolbarIconOut selectableIcon iconToolbar\" title=\"PrevPage\" onclick=\"OnPagePrev()\"><div id=\"td_prevPage\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarPrevPage\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"ToolbarIconOut selectableIcon iconToolbar\" title=\"NextPage\" onclick=\"OnPageNext()\"><div id=\"td_nextPage\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarNextPage\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"\" id=\"ie8textarea\"><input class=\"txblock\" style=\"width: 28px;text-align: center;\" type=\"text\" id=\"pageNum\" value=\"1\" onkeypress=\"return onlyNumber(this, event)\"/></td>\n\
<td class=\"ToolbarIconOut\" style=\"border: 0 none;\"><p id=\"pageCounts\" class=\"txblock\" style=\"margin: 0 6px 0 0; padding: 0;\">/ 1</p></td>\n\
<td class=\"toolbarSep\" style=\"display:none;\"><div class=\"ToolbarIconOut\"><img src=\"common/img/Border.png\"/></div></td>\n\
<td id=\"downloadButton\" class=\"ToolbarIconOut selectableIcon iconToolbar\" style=\"display:none;\" title=\"LoadDocument\"><div id=\"td_load\" class=\"iconToolbar\"><img class=\"ToolbarIcon ToolbarLoadDoc\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"ToolbarIconOut selectableIcon iconToolbar\" title=\"Print\" style=\"display:none;\"><div id=\"td_print\" class=\"iconToolbar\" style=\"margin-left: 1px;\"><img class=\"ToolbarIcon ToolbarPrint\" src=\"common/img/spacer.gif\"/></div></td>\n\
<td class=\"toolbarSep\" style=\"padding-left: 3px;\"><div class=\"ToolbarIconOut\" style=\"margin-left: -1px;\"><img src=\"common/img/Border.png\"/></div></td>\n\
</tr></table></td></tr><tr><td id=\"topmenuSep\" colspan=\"2\" class=\"separatingLine\"></td></tr></table>\n\
<table id=\"statusbar\" class=\"utilFont layerTop\"><tr><td id=\"netstatus\" style=\"width:177px; text-align: center; color:#FFF;\"></td></tr></table>\n\
<div id=\"content\" onclick=\"closeMenu();\"><div id=\"id_viewer\" class=\"viewerbody\" name=\"viewer\" width=\"100%\" height=\"100%\">\n\
<div style=\"position:relative;margin:0px;padding:0px;height:16px;background-color:#eef0f2;\"></div>");
oFileViewer.WriteStringUTF8(strHead___);
CString strMainDiv = _T("");
strMainDiv.Format(_T("<div id=\"maindiv\" style=\"position: relative; width: %dpx; padding: 0; margin: 0 auto;\">\n"), m_lWidthDocPix);
oFileViewer.WriteStringUTF8(strMainDiv);
oFileViewer.WriteStringUTF8(m_oWriter.GetCString());
CString strEndBody = _T("<div style=\"position:relative;margin:0;padding:0;top:0px;width:100%;height: 16px\"></div></div><script type=\"text/javascript\">SetPageCountToMenu();stopTimer();</script></div>\
</div><div id=\"vertScrollContainer\"><div class=\"spV\" style=\"width:18px\"><div id=\"scrollbarV\">\
<div id=\"ssV\"><img src=\"common/img/spacer.gif\" height=\"1\" width=\"1\"/></div></div></div></div>\
<div id=\"horzScrollContainer\"><div class=\"scH\"><div id=\"scrollbarH\"><div id=\"ssH\"><img src=\"common/img/spacer.gif\" height=\"1\" width=\"1\"/></div></div></div></div>\
<div id=\"blockUI\"></div></body></html>");
oFileViewer.WriteStringUTF8(strEndBody);
oFileViewer.CloseFile();
OfficeUtils::IOfficeUtilsPtr ptrUtils;
ptrUtils.CreateInstance(__uuidof(OfficeUtils::COfficeUtils));
if (NULL != ptrUtils)
{
HINSTANCE hInst = _AtlBaseModule.GetModuleInstance();
CString strCommonFiles = m_strDstDirectoryFiles + _T("\\common.zip");
LoadResourceFile(hInst, MAKEINTRESOURCE(IDB_COMMON_ZIP), _T("HTML2"), strCommonFiles);
CString strCommonDst = m_strDstDirectoryFiles + _T("\\common");
BSTR input = strCommonFiles.AllocSysString();
BSTR output = strCommonDst.AllocSysString();
::CreateDirectoryW(output, NULL);
HRESULT hr = ptrUtils->ExtractToDirectory(input, output, NULL, 0);
ptrUtils.Release();
SysFreeString(input);
SysFreeString(output);
::DeleteFileW(input);
}
// обертка
CString strHtml = _T("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=8;IE=9;chrome=1;\"/>\n<title>document viewer</title>\n\
</head>\n<frameset framespacing=\"0\" frameborder=\"0\">\n<frame id=\"id_viewer\" src=\"") + m_strFileName +
_T("_files/viewer.html\" name=\"viewer\" noresize></frame>\n</frameset>\n</frameset>\n</html>");
CDirectory::SaveToFile(m_strDstDirectory + _T("\\") + m_strFileName + _T(".html"), strHtml);
}
protected:
AVSINLINE void CopyFile(CString& strFileSrc, CString& strFileDst)
{
CDirectory::CopyFile(strFileSrc, strFileDst, NULL, NULL);
}
void SaveImage(CString& strFileSrc, CImageInfo& oInfo)
{
CString strLoadXml = _T("<transforms><ImageFile-LoadImage sourcepath=\"") + strFileSrc + _T("\"/></transforms>");
ImageStudio::IImageTransforms* pTransform = NULL;
CoCreateInstance(ImageStudio::CLSID_ImageTransforms, NULL, CLSCTX_INPROC_SERVER, ImageStudio::IID_IImageTransforms, (void**)&pTransform);
VARIANT_BOOL vbRes = VARIANT_FALSE;
BSTR bsLoad = strLoadXml.AllocSysString();
pTransform->SetXml(bsLoad, &vbRes);
SysFreeString(bsLoad);
pTransform->Transform(&vbRes);
VARIANT var;
var.punkVal = NULL;
pTransform->GetResult(0, &var);
if (NULL == var.punkVal)
{
RELEASEINTERFACE(pTransform);
return;
}
MediaCore::IAVSUncompressedVideoFrame* pFrame = NULL;
var.punkVal->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pFrame);
RELEASEINTERFACE((var.punkVal));
if (NULL == pFrame)
{
RELEASEINTERFACE(pTransform);
return;
}
LONG lWidth = 0;
LONG lHeight = 0;
pFrame->get_Width(&lWidth);
pFrame->get_Height(&lHeight);
oInfo.m_eType = GetImageType(pFrame);
RELEASEINTERFACE(pFrame);
CString strSaveItem = _T("");
strSaveItem.Format(_T("\\image%d."), oInfo.m_lID);
if (itJPG == oInfo.m_eType)
{
strSaveItem = _T("<ImageFile-SaveAsJpeg destinationpath=\"") + m_strDstMedia + strSaveItem + _T("jpg\" format=\"888\"/>");
}
else
{
strSaveItem = _T("<ImageFile-SaveAsPng destinationpath=\"") + m_strDstMedia + strSaveItem + _T("png\" format=\"888\"/>");
}
CString strXml = _T("");
LONG lMaxSizeImage = m_lMaxSizeImage;
if (oInfo.m_lID < 3)
lMaxSizeImage = 1200;
if ((lWidth <= lMaxSizeImage) && (lHeight <= lMaxSizeImage))
{
strXml = _T("<transforms>") + strSaveItem + _T("</transforms>");
}
else
{
LONG lW = 0;
LONG lH = 0;
double dAspect = (double)lWidth / lHeight;
if (lWidth >= lHeight)
{
lW = lMaxSizeImage;
lH = (LONG)((double)lW / dAspect);
}
else
{
lH = lMaxSizeImage;
lW = (LONG)(dAspect * lH);
}
CString strResize = _T("");
strResize.Format(_T("<ImageTransform-TransformResize type=\"65536\" width=\"%d\" height=\"%d\"/>"), lW, lH);
strXml = _T("<transforms>") + strResize + strSaveItem + _T("</transforms>");
}
VARIANT_BOOL vbSuccess = VARIANT_FALSE;
BSTR bsXml = strXml.AllocSysString();
pTransform->SetXml(bsXml, &vbSuccess);
SysFreeString(bsXml);
pTransform->Transform(&vbSuccess);
RELEASEINTERFACE(pTransform);
}
void SaveImage(IUnknown* punkImage, CImageInfo& oInfo)
{
MediaCore::IAVSUncompressedVideoFrame* pFrame = NULL;
punkImage->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pFrame);
if (NULL == pFrame)
return;
LONG lWidth = 0;
LONG lHeight = 0;
pFrame->get_Width(&lWidth);
pFrame->get_Height(&lHeight);
oInfo.m_eType = GetImageType(pFrame);
RELEASEINTERFACE(pFrame);
ImageStudio::IImageTransforms* pTransform = NULL;
CoCreateInstance(ImageStudio::CLSID_ImageTransforms, NULL ,CLSCTX_INPROC_SERVER, ImageStudio::IID_IImageTransforms, (void**)&pTransform);
VARIANT var;
var.vt = VT_UNKNOWN;
var.punkVal = punkImage;
pTransform->SetSource(0, var);
CString strSaveItem = _T("");
strSaveItem.Format(_T("\\image%d."), oInfo.m_lID);
if (itJPG == oInfo.m_eType)
{
strSaveItem = _T("<ImageFile-SaveAsJpeg destinationpath=\"") + m_strDstMedia + strSaveItem + _T("jpg\" format=\"888\"/>");
}
else
{
strSaveItem = _T("<ImageFile-SaveAsPng destinationpath=\"") + m_strDstMedia + strSaveItem + _T("png\" format=\"888\"/>");
}
LONG lMaxSizeImage = m_lMaxSizeImage;
if (oInfo.m_lID < 3)
lMaxSizeImage = 1200;
CString strXml = _T("");
if ((lWidth <= lMaxSizeImage) && (lHeight <= lMaxSizeImage))
{
strXml = _T("<transforms>") + strSaveItem + _T("</transforms>");
}
else
{
LONG lW = 0;
LONG lH = 0;
double dAspect = (double)lWidth / lHeight;
if (lWidth >= lHeight)
{
lW = lMaxSizeImage;
lH = (LONG)((double)lW / dAspect);
}
else
{
lH = lMaxSizeImage;
lW = (LONG)(dAspect * lH);
}
CString strResize = _T("");
strResize.Format(_T("<ImageTransform-TransformResize type=\"65536\" width=\"%d\" height=\"%d\"/>"), lW, lH);
strXml = _T("<transforms>") + strResize + strSaveItem + _T("</transforms>");
}
VARIANT_BOOL vbSuccess = VARIANT_FALSE;
BSTR bsXml = strXml.AllocSysString();
pTransform->SetXml(bsXml, &vbSuccess);
SysFreeString(bsXml);
pTransform->Transform(&vbSuccess);
RELEASEINTERFACE(pTransform);
}
CImageInfo GenerateImageID(IUnknown* punkData)
{
CImageInfo oInfo;
if (NULL == punkData)
return oInfo;
MediaCore::IAVSUncompressedVideoFrame* pFrame = NULL;
punkData->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pFrame);
BYTE* pBuffer = NULL;
LONG lLen = 0;
pFrame->get_Buffer(&pBuffer);
pFrame->get_BufferSize(&lLen);
DWORD dwSum = m_oCRC.Calc(pBuffer, lLen);
CAtlMap<DWORD, CImageInfo>::CPair* pPair = m_mapImageData.Lookup(dwSum);
if (NULL == pPair)
{
// нужно добавить
++m_lNextIDImage;
oInfo.m_lID = m_lNextIDImage;
SaveImage(punkData, oInfo);
m_mapImageData.SetAt(dwSum, oInfo);
}
else
{
oInfo = pPair->m_value;
}
RELEASEINTERFACE(pFrame);
return oInfo;
}
CImageInfo GenerateImageID(CString& strFileName)
{
CImageInfo oInfo;
CAtlMap<CString, CImageInfo>::CPair* pPair = m_mapImagesFile.Lookup(strFileName);
if (NULL == pPair)
{
// нужно добавить
++m_lNextIDImage;
oInfo.m_lID = m_lNextIDImage;
SaveImage(strFileName, oInfo);
m_mapImagesFile.SetAt(strFileName, oInfo);
}
else
{
oInfo = pPair->m_value;
}
return oInfo;
}
ImageType GetImageType(MediaCore::IAVSUncompressedVideoFrame* pFrame)
{
LONG lWidth = 0;
LONG lHeight = 0;
BYTE* pBuffer = NULL;
pFrame->get_Width(&lWidth);
pFrame->get_Height(&lHeight);
pFrame->get_Buffer(&pBuffer);
BYTE* pBufferMem = pBuffer + 3;
LONG lCountPix = lWidth * lHeight;
for (LONG i = 0; i < lCountPix; ++i, pBufferMem += 4)
{
if (255 != *pBufferMem)
return itPNG;
}
return itJPG;
}
void FlipY(IUnknown* punkImage)
{
if (NULL == punkImage)
return;
MediaCore::IAVSUncompressedVideoFrame* pFrame = NULL;
punkImage->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pFrame);
if (NULL == pFrame)
return;
BYTE* pBuffer = NULL;
LONG lWidth = 0;
LONG lHeight = 0;
LONG lStride = 0;
pFrame->get_Buffer(&pBuffer);
pFrame->get_Width(&lWidth);
pFrame->get_Height(&lHeight);
pFrame->get_Stride(0, &lStride);
if (lStride < 0)
lStride = -lStride;
if ((lWidth * 4) != lStride)
{
RELEASEINTERFACE(pFrame);
return;
}
BYTE* pBufferMem = new BYTE[lStride];
BYTE* pBufferEnd = pBuffer + lStride * (lHeight - 1);
LONG lCountV = lHeight / 2;
for (LONG lIndexV = 0; lIndexV < lCountV; ++lIndexV)
{
memcpy(pBufferMem, pBuffer, lStride);
memcpy(pBuffer, pBufferEnd, lStride);
memcpy(pBufferEnd, pBufferMem, lStride);
pBuffer += lStride;
pBufferEnd -= lStride;
}
RELEASEARRAYOBJECTS(pBufferMem);
RELEASEINTERFACE(pFrame);
}
void FlipX(IUnknown* punkImage)
{
if (NULL == punkImage)
return;
MediaCore::IAVSUncompressedVideoFrame* pFrame = NULL;
punkImage->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pFrame);
if (NULL == pFrame)
return;
BYTE* pBuffer = NULL;
LONG lWidth = 0;
LONG lHeight = 0;
LONG lStride = 0;
pFrame->get_Buffer(&pBuffer);
pFrame->get_Width(&lWidth);
pFrame->get_Height(&lHeight);
pFrame->get_Stride(0, &lStride);
if (lStride < 0)
lStride = -lStride;
if ((lWidth * 4) != lStride)
{
RELEASEINTERFACE(pFrame);
return;
}
DWORD* pBufferDWORD = (DWORD*)pBuffer;
LONG lW2 = lWidth / 2;
for (LONG lIndexV = 0; lIndexV < lHeight; ++lIndexV)
{
DWORD* pMem1 = pBufferDWORD;
DWORD* pMem2 = pBufferDWORD + lWidth - 1;
LONG lI = 0;
while (lI < lW2)
{
DWORD dwMem = *pMem1;
*pMem1++ = *pMem2;
*pMem2-- = dwMem;
}
}
RELEASEINTERFACE(pFrame);
}
public:
void LoadResourceFile(HINSTANCE hInst, LPCTSTR sResName, LPCTSTR sResType, const CString& strDstFile)
{
HRSRC hrRes = FindResource(hInst, sResName, sResType);
if (!hrRes)
return;
HGLOBAL hGlobal = LoadResource(hInst, hrRes);
DWORD sz = SizeofResource(hInst, hrRes);
void* ptrRes = LockResource(hGlobal);
CFile oFile;
oFile.CreateFile(strDstFile);
oFile.WriteFile(ptrRes, sz);
UnlockResource(hGlobal);
FreeResource(hGlobal);
}
};
}
\ No newline at end of file
......@@ -7,9 +7,9 @@ namespace NSHtmlRenderer
class CTileInfo
{
/*
_T("<htmltiling x=\"%.2lf\" y=\"%.2lf\" countx=\"%.2lf\" county=\"%.2lf\" stepx=\"%.2lf\" stepy=\"%.2lf\">\
<bbox x=\".2lf\" y=\"%.2lf\" r=\"%.2lf\" b=\"%.2lf\" />\
<transform m1=\"%.2lf\" m2=\"%.2lf\" m3=\"%.2lf\" m4=\"%.2lf\" m5=\"%.2lf\" m6=\"%.2lf\" />\
_T("<htmltiling x=\"%.2lf\" y=\"%.2lf\" countx=\"%.2lf\" county=\"%.2lf\" stepx=\"%.2lf\" stepy=\"%.2lf\">\
<bbox x=\".2lf\" y=\"%.2lf\" r=\"%.2lf\" b=\"%.2lf\" />\
<transform m1=\"%.2lf\" m2=\"%.2lf\" m3=\"%.2lf\" m4=\"%.2lf\" m5=\"%.2lf\" m6=\"%.2lf\" />\
</htmltiling>
*/
......@@ -2117,4 +2117,4 @@ protected:
return true;
}
};
}
\ No newline at end of file
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment