Commit e3b89345 authored by Oleg.Korshul's avatar Oleg.Korshul Committed by Alexander Trofimov

crossplatform version (not worked)

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63549 954022d7-b5bf-4e40-9824-e11837661b57
parent 5de1bdc4
......@@ -15,6 +15,9 @@ ASCHTMLRenderer/Resources/imgtrackbar/b_bg_off.gif svn_mime_002dtype=application
ASCHTMLRenderer/Resources/imgtrackbar/b_bg_on.gif svn_mime_002dtype=application%2Foctet-stream
ASCHTMLRenderer/Resources/imgtrackbar/b_l.gif svn_mime_002dtype=application%2Foctet-stream
ASCHTMLRenderer/Resources/imgtrackbar/b_r.gif svn_mime_002dtype=application%2Foctet-stream
ASCHTMLRenderer/lib svnc_tsvn_003alogminsize=5
ASCHTMLRenderer/lib/include svnc_tsvn_003alogminsize=5
ASCHTMLRenderer/lib/src svnc_tsvn_003alogminsize=5
ASCImageStudio3/ASCGraphics/Expat/lib/libexpat.lib svn_mime_002dtype=application%2Foctet-stream
ASCImageStudio3/ASCGraphics/Objects/Font/FreeType/freetype242_vs2005.lib svn_mime_002dtype=application%2Foctet-stream
ASCImageStudio3/ASCGraphics/OfficeSvmFile/zlibstat.lib svn_mime_002dtype=application%2Foctet-stream
#-------------------------------------------------
#
# Project created by QtCreator 2015-01-19T10:22:14
#
#-------------------------------------------------
QT -= core
QT -= gui
TARGET = aschtmlrenderer
TEMPLATE = lib
CONFIG += staticlib
QMAKE_CXXFLAGS += -std=c++11
#################### WINDOWS #####################
win32 {
DEFINES += \
WIN32
CONFIG(debug, debug|release) {
LIBS += -L../../../DesktopEditor/Qt_build/graphics/Debug/debug -lgraphics
} else {
LIBS += -L../../../DesktopEditor/Qt_build/graphics/Release/release -lgraphics
}
}
##################################################
################### LINUX ########################
linux-g++ | linux-g++-64 | linux-g++-32 {
DEFINES += \
LINUX \
_LINUX \
_LINUX_QT \
LIBS += -L../../../DesktopEditor/Qt_build/graphics/Release -lgraphics
}
linux-g++:contains(QMAKE_HOST.arch, x86_64):{
message(linux64)
}
linux-g++:!contains(QMAKE_HOST.arch, x86_64):{
message(linux32)
}
##################################################
INCLUDEPATH += \
../../DesktopEditor/agg-2.4/include \
../../DesktopEditor/freetype-2.5.2/include
SOURCES += \
src/HTMLRenderer.cpp \
src/HTMLRenderer2.cpp \
src/HTMLRenderer3.cpp
HEADERS += \
src/CanvasWriter.h \
src/Common.h \
src/Document.h \
src/FontManager.h \
src/FontManagerBase.h \
src/StringWriter.h \
src/SVGWriter.h \
src/SVGWriter2.h \
src/Text.h \
src/TextItem.h \
src/VectorGraphicsWriter.h \
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 {
target.path = /usr/lib
INSTALLS += target
}
#ifndef _ASC_HTMLRENDERER1_H_
#define _ASC_HTMLRENDERER1_H_
#include "../../../DesktopEditor/graphics/IRenderer.h"
class CASCHTMLRenderer_Private;
class CASCHTMLRenderer : public IRenderer
{
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType);
//-------- Функции для работы со страницей --------------------------------------------------
virtual HRESULT NewPage();
virtual HRESULT get_Height(double* dHeight);
virtual HRESULT put_Height(const double& dHeight);
virtual HRESULT get_Width(double* dWidth);
virtual HRESULT put_Width(const double& dWidth);
virtual HRESULT get_DpiX(double* dDpiX);
virtual HRESULT get_DpiY(double* dDpiY);
// pen --------------------------------------------------------------------------------------
virtual HRESULT get_PenColor(LONG* lColor);
virtual HRESULT put_PenColor(const LONG& lColor);
virtual HRESULT get_PenAlpha(LONG* lAlpha);
virtual HRESULT put_PenAlpha(const LONG& lAlpha);
virtual HRESULT get_PenSize(double* dSize);
virtual HRESULT put_PenSize(const double& dSize);
virtual HRESULT get_PenDashStyle(BYTE* val);
virtual HRESULT put_PenDashStyle(const BYTE& val);
virtual HRESULT get_PenLineStartCap(BYTE* val);
virtual HRESULT put_PenLineStartCap(const BYTE& val);
virtual HRESULT get_PenLineEndCap(BYTE* val);
virtual HRESULT put_PenLineEndCap(const BYTE& val);
virtual HRESULT get_PenLineJoin(BYTE* val);
virtual HRESULT put_PenLineJoin(const BYTE& val);
virtual HRESULT get_PenDashOffset(double* dOffset);
virtual HRESULT put_PenDashOffset(const double& dOffset);
virtual HRESULT get_PenAlign(LONG* lAlign);
virtual HRESULT put_PenAlign(const LONG& lAlign);
virtual HRESULT get_PenMiterLimit(double* dOffset);
virtual HRESULT put_PenMiterLimit(const double& dOffset);
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount);
// brush ------------------------------------------------------------------------------------
virtual HRESULT get_BrushType(LONG* lType);
virtual HRESULT put_BrushType(const LONG& lType);
virtual HRESULT get_BrushColor1(LONG* lColor);
virtual HRESULT put_BrushColor1(const LONG& lColor);
virtual HRESULT get_BrushAlpha1(LONG* lAlpha);
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha);
virtual HRESULT get_BrushColor2(LONG* lColor);
virtual HRESULT put_BrushColor2(const LONG& lColor);
virtual HRESULT get_BrushAlpha2(LONG* lAlpha);
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha);
virtual HRESULT get_BrushTexturePath(std::wstring* bsPath);
virtual HRESULT put_BrushTexturePath(const std::wstring& bsPath);
virtual HRESULT get_BrushTextureMode(LONG* lMode);
virtual HRESULT put_BrushTextureMode(const LONG& lMode);
virtual HRESULT get_BrushTextureAlpha(LONG* lTxAlpha);
virtual HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha);
virtual HRESULT get_BrushLinearAngle(double* dAngle);
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height);
virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height);
virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount);
// font -------------------------------------------------------------------------------------
virtual HRESULT get_FontName(std::wstring* bsName);
virtual HRESULT put_FontName(const std::wstring& bsName);
virtual HRESULT get_FontPath(std::wstring* bsName);
virtual HRESULT put_FontPath(const std::wstring& bsName);
virtual HRESULT get_FontSize(double* dSize);
virtual HRESULT put_FontSize(const double& dSize);
virtual HRESULT get_FontStyle(LONG* lStyle);
virtual HRESULT put_FontStyle(const LONG& lStyle);
virtual HRESULT get_FontStringGID(INT* bGID);
virtual HRESULT put_FontStringGID(const INT& bGID);
virtual HRESULT get_FontCharSpace(double* dSpace);
virtual HRESULT put_FontCharSpace(const double& dSpace);
virtual HRESULT get_FontFaceIndex(int* lFaceIndex);
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex);
//-------- Функции для вывода текста --------------------------------------------------------
virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Маркеры для команд ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType);
virtual HRESULT EndCommand(const DWORD& lType);
//-------- Функции для работы с Graphics Path -----------------------------------------------
virtual HRESULT PathCommandMoveTo(const double& x, const double& y);
virtual HRESULT PathCommandLineTo(const double& x, const double& y);
virtual HRESULT PathCommandLinesTo(double* points, const int& count);
virtual HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3);
virtual HRESULT PathCommandCurvesTo(double* points, const int& count);
virtual HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle);
virtual HRESULT PathCommandClose();
virtual HRESULT PathCommandEnd();
virtual HRESULT DrawPath(const LONG& nType);
virtual HRESULT PathCommandStart();
virtual HRESULT PathCommandGetCurrentPoint(double* x, double* y);
virtual HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Функции для вывода изображений ---------------------------------------------------
virtual HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h);
virtual HRESULT DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255);
// transform --------------------------------------------------------------------------------
virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6);
virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF);
virtual HRESULT ResetTransform();
// -----------------------------------------------------------------------------------------
virtual HRESULT get_ClipMode(LONG* plMode);
virtual HRESULT put_ClipMode(const LONG& lMode);
// additiaonal params ----------------------------------------------------------------------
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand);
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
// owner params ----------------------------------------------------------------------
virtual HRESULT get_Mode(LONG *plMode);
virtual HRESULT put_Mode(LONG lMode);
virtual HRESULT CreateOfficeFile(std::wstring bsFileName);
virtual HRESULT CloseFile();
virtual HRESULT SetAdditionalParam(std::string sParamName, int nValue);
protected:
CASCHTMLRenderer_Private* m_pInternal;
};
#endif // _ASC_HTMLRENDERER1_H_
#ifndef _ASC_HTMLRENDERER2_H_
#define _ASC_HTMLRENDERER2_H_
#include "../../../DesktopEditor/graphics/IRenderer.h"
class CASCHTMLRenderer2_Private;
class CASCHTMLRenderer2 : public IRenderer
{
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType);
//-------- Функции для работы со страницей --------------------------------------------------
virtual HRESULT NewPage();
virtual HRESULT get_Height(double* dHeight);
virtual HRESULT put_Height(const double& dHeight);
virtual HRESULT get_Width(double* dWidth);
virtual HRESULT put_Width(const double& dWidth);
virtual HRESULT get_DpiX(double* dDpiX);
virtual HRESULT get_DpiY(double* dDpiY);
// pen --------------------------------------------------------------------------------------
virtual HRESULT get_PenColor(LONG* lColor);
virtual HRESULT put_PenColor(const LONG& lColor);
virtual HRESULT get_PenAlpha(LONG* lAlpha);
virtual HRESULT put_PenAlpha(const LONG& lAlpha);
virtual HRESULT get_PenSize(double* dSize);
virtual HRESULT put_PenSize(const double& dSize);
virtual HRESULT get_PenDashStyle(BYTE* val);
virtual HRESULT put_PenDashStyle(const BYTE& val);
virtual HRESULT get_PenLineStartCap(BYTE* val);
virtual HRESULT put_PenLineStartCap(const BYTE& val);
virtual HRESULT get_PenLineEndCap(BYTE* val);
virtual HRESULT put_PenLineEndCap(const BYTE& val);
virtual HRESULT get_PenLineJoin(BYTE* val);
virtual HRESULT put_PenLineJoin(const BYTE& val);
virtual HRESULT get_PenDashOffset(double* dOffset);
virtual HRESULT put_PenDashOffset(const double& dOffset);
virtual HRESULT get_PenAlign(LONG* lAlign);
virtual HRESULT put_PenAlign(const LONG& lAlign);
virtual HRESULT get_PenMiterLimit(double* dOffset);
virtual HRESULT put_PenMiterLimit(const double& dOffset);
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount);
// brush ------------------------------------------------------------------------------------
virtual HRESULT get_BrushType(LONG* lType);
virtual HRESULT put_BrushType(const LONG& lType);
virtual HRESULT get_BrushColor1(LONG* lColor);
virtual HRESULT put_BrushColor1(const LONG& lColor);
virtual HRESULT get_BrushAlpha1(LONG* lAlpha);
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha);
virtual HRESULT get_BrushColor2(LONG* lColor);
virtual HRESULT put_BrushColor2(const LONG& lColor);
virtual HRESULT get_BrushAlpha2(LONG* lAlpha);
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha);
virtual HRESULT get_BrushTexturePath(std::wstring* bsPath);
virtual HRESULT put_BrushTexturePath(const std::wstring& bsPath);
virtual HRESULT get_BrushTextureMode(LONG* lMode);
virtual HRESULT put_BrushTextureMode(const LONG& lMode);
virtual HRESULT get_BrushTextureAlpha(LONG* lTxAlpha);
virtual HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha);
virtual HRESULT get_BrushLinearAngle(double* dAngle);
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height);
virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height);
virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount);
// font -------------------------------------------------------------------------------------
virtual HRESULT get_FontName(std::wstring* bsName);
virtual HRESULT put_FontName(const std::wstring& bsName);
virtual HRESULT get_FontPath(std::wstring* bsName);
virtual HRESULT put_FontPath(const std::wstring& bsName);
virtual HRESULT get_FontSize(double* dSize);
virtual HRESULT put_FontSize(const double& dSize);
virtual HRESULT get_FontStyle(LONG* lStyle);
virtual HRESULT put_FontStyle(const LONG& lStyle);
virtual HRESULT get_FontStringGID(INT* bGID);
virtual HRESULT put_FontStringGID(const INT& bGID);
virtual HRESULT get_FontCharSpace(double* dSpace);
virtual HRESULT put_FontCharSpace(const double& dSpace);
virtual HRESULT get_FontFaceIndex(int* lFaceIndex);
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex);
//-------- Функции для вывода текста --------------------------------------------------------
virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Маркеры для команд ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType);
virtual HRESULT EndCommand(const DWORD& lType);
//-------- Функции для работы с Graphics Path -----------------------------------------------
virtual HRESULT PathCommandMoveTo(const double& x, const double& y);
virtual HRESULT PathCommandLineTo(const double& x, const double& y);
virtual HRESULT PathCommandLinesTo(double* points, const int& count);
virtual HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3);
virtual HRESULT PathCommandCurvesTo(double* points, const int& count);
virtual HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle);
virtual HRESULT PathCommandClose();
virtual HRESULT PathCommandEnd();
virtual HRESULT DrawPath(const LONG& nType);
virtual HRESULT PathCommandStart();
virtual HRESULT PathCommandGetCurrentPoint(double* x, double* y);
virtual HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Функции для вывода изображений ---------------------------------------------------
virtual HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h);
virtual HRESULT DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255);
// transform --------------------------------------------------------------------------------
virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6);
virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF);
virtual HRESULT ResetTransform();
// -----------------------------------------------------------------------------------------
virtual HRESULT get_ClipMode(LONG* plMode);
virtual HRESULT put_ClipMode(const LONG& lMode);
// additiaonal params ----------------------------------------------------------------------
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand);
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
// owner params ----------------------------------------------------------------------
virtual HRESULT get_Mode(LONG *plMode);
virtual HRESULT put_Mode(LONG lMode);
virtual HRESULT CreateOfficeFile(std::wstring bsFileName);
virtual HRESULT CloseFile();
virtual HRESULT SetAdditionalParam(std::string sParamName, int nValue);
protected:
CASCHTMLRenderer2_Private* m_pInternal;
};
#endif // _ASC_HTMLRENDERER2_H_
#ifndef _ASC_HTMLRENDERER3_H_
#define _ASC_HTMLRENDERER3_H_
#include "../../../DesktopEditor/graphics/IRenderer.h"
class CASCHTMLRenderer3_Private;
class CASCHTMLRenderer3 : public IRenderer
{
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType);
//-------- Функции для работы со страницей --------------------------------------------------
virtual HRESULT NewPage();
virtual HRESULT get_Height(double* dHeight);
virtual HRESULT put_Height(const double& dHeight);
virtual HRESULT get_Width(double* dWidth);
virtual HRESULT put_Width(const double& dWidth);
virtual HRESULT get_DpiX(double* dDpiX);
virtual HRESULT get_DpiY(double* dDpiY);
// pen --------------------------------------------------------------------------------------
virtual HRESULT get_PenColor(LONG* lColor);
virtual HRESULT put_PenColor(const LONG& lColor);
virtual HRESULT get_PenAlpha(LONG* lAlpha);
virtual HRESULT put_PenAlpha(const LONG& lAlpha);
virtual HRESULT get_PenSize(double* dSize);
virtual HRESULT put_PenSize(const double& dSize);
virtual HRESULT get_PenDashStyle(BYTE* val);
virtual HRESULT put_PenDashStyle(const BYTE& val);
virtual HRESULT get_PenLineStartCap(BYTE* val);
virtual HRESULT put_PenLineStartCap(const BYTE& val);
virtual HRESULT get_PenLineEndCap(BYTE* val);
virtual HRESULT put_PenLineEndCap(const BYTE& val);
virtual HRESULT get_PenLineJoin(BYTE* val);
virtual HRESULT put_PenLineJoin(const BYTE& val);
virtual HRESULT get_PenDashOffset(double* dOffset);
virtual HRESULT put_PenDashOffset(const double& dOffset);
virtual HRESULT get_PenAlign(LONG* lAlign);
virtual HRESULT put_PenAlign(const LONG& lAlign);
virtual HRESULT get_PenMiterLimit(double* dOffset);
virtual HRESULT put_PenMiterLimit(const double& dOffset);
virtual HRESULT PenDashPattern(double* pPattern, LONG lCount);
// brush ------------------------------------------------------------------------------------
virtual HRESULT get_BrushType(LONG* lType);
virtual HRESULT put_BrushType(const LONG& lType);
virtual HRESULT get_BrushColor1(LONG* lColor);
virtual HRESULT put_BrushColor1(const LONG& lColor);
virtual HRESULT get_BrushAlpha1(LONG* lAlpha);
virtual HRESULT put_BrushAlpha1(const LONG& lAlpha);
virtual HRESULT get_BrushColor2(LONG* lColor);
virtual HRESULT put_BrushColor2(const LONG& lColor);
virtual HRESULT get_BrushAlpha2(LONG* lAlpha);
virtual HRESULT put_BrushAlpha2(const LONG& lAlpha);
virtual HRESULT get_BrushTexturePath(std::wstring* bsPath);
virtual HRESULT put_BrushTexturePath(const std::wstring& bsPath);
virtual HRESULT get_BrushTextureMode(LONG* lMode);
virtual HRESULT put_BrushTextureMode(const LONG& lMode);
virtual HRESULT get_BrushTextureAlpha(LONG* lTxAlpha);
virtual HRESULT put_BrushTextureAlpha(const LONG& lTxAlpha);
virtual HRESULT get_BrushLinearAngle(double* dAngle);
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height);
virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height);
virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount);
// font -------------------------------------------------------------------------------------
virtual HRESULT get_FontName(std::wstring* bsName);
virtual HRESULT put_FontName(const std::wstring& bsName);
virtual HRESULT get_FontPath(std::wstring* bsName);
virtual HRESULT put_FontPath(const std::wstring& bsName);
virtual HRESULT get_FontSize(double* dSize);
virtual HRESULT put_FontSize(const double& dSize);
virtual HRESULT get_FontStyle(LONG* lStyle);
virtual HRESULT put_FontStyle(const LONG& lStyle);
virtual HRESULT get_FontStringGID(INT* bGID);
virtual HRESULT put_FontStringGID(const INT& bGID);
virtual HRESULT get_FontCharSpace(double* dSpace);
virtual HRESULT put_FontCharSpace(const double& dSpace);
virtual HRESULT get_FontFaceIndex(int* lFaceIndex);
virtual HRESULT put_FontFaceIndex(const int& lFaceIndex);
//-------- Функции для вывода текста --------------------------------------------------------
virtual HRESULT CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Маркеры для команд ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType);
virtual HRESULT EndCommand(const DWORD& lType);
//-------- Функции для работы с Graphics Path -----------------------------------------------
virtual HRESULT PathCommandMoveTo(const double& x, const double& y);
virtual HRESULT PathCommandLineTo(const double& x, const double& y);
virtual HRESULT PathCommandLinesTo(double* points, const int& count);
virtual HRESULT PathCommandCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3);
virtual HRESULT PathCommandCurvesTo(double* points, const int& count);
virtual HRESULT PathCommandArcTo(const double& x, const double& y, const double& w, const double& h, const double& startAngle, const double& sweepAngle);
virtual HRESULT PathCommandClose();
virtual HRESULT PathCommandEnd();
virtual HRESULT DrawPath(const LONG& nType);
virtual HRESULT PathCommandStart();
virtual HRESULT PathCommandGetCurrentPoint(double* x, double* y);
virtual HRESULT PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset);
virtual HRESULT PathCommandTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
virtual HRESULT PathCommandTextEx(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset, const DWORD& lFlags);
//-------- Функции для вывода изображений ---------------------------------------------------
virtual HRESULT DrawImage(IGrObject* pImage, const double& x, const double& y, const double& w, const double& h);
virtual HRESULT DrawImageFromFile(const std::wstring&, const double& x, const double& y, const double& w, const double& h, const BYTE& lAlpha = 255);
// transform --------------------------------------------------------------------------------
virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6);
virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF);
virtual HRESULT ResetTransform();
// -----------------------------------------------------------------------------------------
virtual HRESULT get_ClipMode(LONG* plMode);
virtual HRESULT put_ClipMode(const LONG& lMode);
// additiaonal params ----------------------------------------------------------------------
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand);
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
// owner params ----------------------------------------------------------------------
virtual HRESULT get_Mode(LONG *plMode);
virtual HRESULT put_Mode(LONG lMode);
virtual HRESULT CreateOfficeFile(std::wstring bsFileName);
virtual HRESULT CloseFile();
virtual HRESULT SetAdditionalParam(std::string sParamName, int nValue);
virtual HRESULT SetAdditionalParam(std::string sParamName, const std::wstring& sParam);
protected:
CASCHTMLRenderer3_Private* m_pInternal;
};
#endif // _ASC_HTMLRENDERER3_H_
#ifndef _ASC_HTMLRENDERER_CANVASWRITER_H_
#define _ASC_HTMLRENDERER_CANVASWRITER_H_
#include "Common.h"
#include "../../../DesktopEditor/graphics/GraphicsPath.h"
namespace NSHtmlRenderer
{
class CCanvasWriter
{
public:
NSStringUtils::CStringBuilder m_oPath;
NSStringUtils::CStringBuilder m_oDocument;
LONG m_lCurDocumentID;
LONG m_lClippingPath;
bool m_bIsClipping;
LONG m_lClipMode;
bool m_bIsMoveTo;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
double m_lWidth;
double m_lHeight;
double m_dDpiX;
double m_dDpiY;
public:
CCanvasWriter() : m_oPath(), m_oDocument()
{
m_lCurDocumentID = 0;
m_lClippingPath = 0;
m_pPen = NULL;
m_pBrush = NULL;
m_dDpiX = 96;
m_dDpiY = 96;
m_lClipMode = c_nWindingFillMode;
m_bIsClipping = false;
m_bIsMoveTo = false;
}
void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush)
{
m_pPen = pPen;
m_pBrush = pBrush;
}
void CloseFile(std::wstring strFile = L"")
{
if (!strFile.empty())
{
NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData());
}
m_oDocument.ClearNoAttack();
m_oPath.ClearNoAttack();
}
void NewDocument(double& dWidth, double& dHeigth)
{
CloseFile(L"");
m_lWidth = (int)dWidth;
m_lHeight = (int)dHeigth;
}
public:
inline void WritePathEnd()
{
}
inline void WritePathStart()
{
m_bIsMoveTo = false;
m_oDocument.WriteString(L"b(c);\n", 6);
}
void WritePathClose()
{
m_oDocument.WriteString(L"x(c);\n", 6);
}
void WritePathMoveTo(double& x, double& y)
{
m_oDocument.WriteString(L"m(c,", 4);
WriteIntsToStringBuilder(round(x), round(y), &m_oDocument);
m_oDocument.WriteString(L");\n", 3);
m_bIsMoveTo = true;
}
void WritePathLineTo(double& x, double& y)
{
if (false == m_bIsMoveTo)
WritePathMoveTo(x, y);
m_oDocument.WriteString(L"l(c,", 4);
WriteIntsToStringBuilder(round(x), round(y), &m_oDocument);
m_oDocument.WriteString(L");\n", 3);
}
void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
if (false == m_bIsMoveTo)
WritePathMoveTo(x1, y1);
m_oDocument.WriteString(L"cu(c,", 5);
WriteIntsToStringBuilder(round(x1), round(y1), round(x2), round(y2), round(x3), round(y3), &m_oDocument);
m_oDocument.WriteString(L");\n", 3);
}
void WriteDrawPath(LONG lType, Aggplus::CMatrix* pTransform, Aggplus::CGraphicsPathSimpleConverter* pConverter, LONG lTxId)
{
bool bStroke = false;
if (m_pPen->Alpha == 0)
lType &= 0xFF00;
if ((-1 == lTxId) && (0 == m_pBrush->Alpha1))
lType &= 0xFF;
if ((lType & 0x01) == 0x01)
{
SetStrokeColor(m_pPen->Color, m_pPen->Alpha, &m_oDocument);
bStroke = true;
}
if (lType > 0x01)
{
if (-1 != lTxId)
{
// текстура!
double x = 0;
double y = 0;
double w = 0;
double h = 0;
pConverter->PathCommandGetBounds(x, y, w, h);
double r = x + w;
double b = y + h;
pTransform->TransformPoint(x, y);
pTransform->TransformPoint(r, b);
w = r - x;
h = b - y;
m_oDocument.WriteString(L"img", 3);
m_oDocument.AddInt(lTxId);
m_oDocument.WriteString(L".src = \"media\\\\image", 20);
m_oDocument.AddInt(lTxId);
m_oDocument.WriteString(L".jpg\";img", 9);
m_oDocument.AddInt(lTxId);
m_oDocument.WriteString(L".onload = function(){c.drawImage(img", 36);
WriteIntsToStringBuilder(lTxId, round(x), round(y), round(w), round(h), &m_oDocument);
m_oDocument.WriteString(L");drawpage", 10);
m_oDocument.AddInt(m_lCurDocumentID);
m_oDocument.AddCharSafe('_');
m_oDocument.AddInt(lTxId);
m_oDocument.WriteString(L"(c);};\n}\nfunction drawpage", 26);
m_oDocument.AddInt(m_lCurDocumentID);
m_oDocument.AddCharSafe('_');
m_oDocument.AddInt(lTxId);
m_oDocument.WriteString(L"(c)\n{\n", 6);
}
else
{
SetFillColor(m_pBrush->Color1, m_pBrush->Alpha1, &m_oDocument);
m_oDocument.WriteString(L"f(c);\n", 6);
}
}
if (bStroke)
{
m_oDocument.WriteString(L"s(c);\n", 6);
}
}
void WritePathClip()
{
m_bIsClipping = true;
++m_lClippingPath;
}
void WritePathClipEnd()
{
if (!m_bIsClipping)
{
m_oDocument.WriteString(L"c.save();\n", 10);
}
m_bIsClipping = true;
m_oDocument.WriteString(L"c.clip();\n", 10);
}
void WritePathResetClip()
{
if (m_bIsClipping)
{
m_oDocument.WriteString(L"c.restore();\n", 13);
}
m_bIsClipping = false;
}
inline void WriteStyleClip()
{
}
};
}
#endif // _ASC_HTMLRENDERER_CANVASWRITER_H_
#ifndef _ASC_HTMLRENDERER_COMMON_H_
#define _ASC_HTMLRENDERER_COMMON_H_
#include "../../../DesktopEditor/common/Types.h"
#include "../../../DesktopEditor/common/File.h"
#include "../../../DesktopEditor/raster/BgraFrame.h"
#include "../../../DesktopEditor/graphics/Matrix.h"
#include "../../../DesktopEditor/graphics/structures.h"
#include "../../../DesktopEditor/fontengine/ApplicationFonts.h"
#include "../../../DesktopEditor/common/StringBuilder.h"
#include "../../../DesktopEditor/graphics/IRenderer.h"
namespace NSHtmlRenderer
{
class IBaseMatrixUpdater
{
public:
virtual void OnBaseMatrixUpdate(const double& dWidth, const double& dHeight) = 0;
};
class CDstInfo
{
public:
std::wstring m_strDstFilePath;
std::wstring m_strAdditionalPath;
std::wstring m_strDstMedia;
bool m_bIsWeb;
public:
CDstInfo()
{
m_strDstFilePath = L"";
m_strAdditionalPath = L"";
m_strDstMedia = L"";
m_bIsWeb = false;
}
CDstInfo(const CDstInfo& oInfo)
{
*this = oInfo;
}
CDstInfo& operator=(const CDstInfo& oSrc)
{
m_strDstFilePath = oSrc.m_strDstFilePath;
m_strAdditionalPath = oSrc.m_strAdditionalPath;
m_strDstMedia = oSrc.m_strDstMedia;
m_bIsWeb = oSrc.m_bIsWeb;
return *this;
}
};
}
namespace NSHtmlRenderer
{
inline LONG ConvertColor(const LONG& lBGR)
{
return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF)));
}
inline void WriteIntsToStringBuilder(const int& n1, const int& n2, NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->AddSize(21);
pBuilder->AddIntNoCheck(n1);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n2);
}
inline void WriteIntsToStringBuilder(const int& n1, const int& n2,
const int& n3, const int& n4,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->AddSize(65);
pBuilder->AddIntNoCheck(n1);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n2);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n3);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n4);
}
inline void WriteIntsToStringBuilder(const int& n1, const int& n2,
const int& n3, const int& n4,
const int& n5,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->AddSize(65);
pBuilder->AddIntNoCheck(n1);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n2);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n3);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n4);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n5);
}
inline void WriteIntsToStringBuilder(const int& n1, const int& n2,
const int& n3, const int& n4,
const int& n5, const int& n6,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->AddSize(65);
pBuilder->AddIntNoCheck(n1);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n2);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n3);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n4);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n5);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(n6);
}
inline void WriteFormatted(const wchar_t* s1, const int& n1,
const wchar_t* s2,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->WriteString(s1, wcslen(s1));
pBuilder->AddInt(n1);
pBuilder->WriteString(s2, wcslen(s2));
}
inline void WriteFormatted(const wchar_t* s1, const int& n1,
const wchar_t* s2, const int& n2,
const wchar_t* s3,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->WriteString(s1, wcslen(s1));
pBuilder->AddInt(n1);
pBuilder->WriteString(s2, wcslen(s2));
pBuilder->AddInt(n2);
pBuilder->WriteString(s3, wcslen(s3));
}
inline void WriteFormatted(const wchar_t* s1, const int& n1,
const wchar_t* s2, const int& n2,
const wchar_t* s3, const int& n3,
const wchar_t* s4,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->WriteString(s1, wcslen(s1));
pBuilder->AddInt(n1);
pBuilder->WriteString(s2, wcslen(s2));
pBuilder->AddInt(n2);
pBuilder->WriteString(s3, wcslen(s3));
pBuilder->AddInt(n3);
pBuilder->WriteString(s4, wcslen(s4));
}
inline void WriteFormatted(const wchar_t* s1, const int& n1,
const wchar_t* s2, const int& n2,
const wchar_t* s3, const int& n3,
const wchar_t* s4, const int& n4,
const wchar_t* s5,
NSStringUtils::CStringBuilder* pBuilder)
{
pBuilder->WriteString(s1, wcslen(s1));
pBuilder->AddInt(n1);
pBuilder->WriteString(s2, wcslen(s2));
pBuilder->AddInt(n2);
pBuilder->WriteString(s3, wcslen(s3));
pBuilder->AddInt(n3);
pBuilder->WriteString(s4, wcslen(s4));
pBuilder->AddInt(n4);
pBuilder->WriteString(s5, wcslen(s5));
}
inline void SetStringColor(LONG lBGR, NSStringUtils::CStringBuilder* pBuilder)
{
BYTE R = (BYTE)(lBGR & 0xFF);
BYTE G = (BYTE)((lBGR >> 8) & 0xFF);
BYTE B = (BYTE)((lBGR >> 16) & 0xFF);
pBuilder->AddSize(50);
pBuilder->WriteString(L"rgb(", 4);
pBuilder->AddIntNoCheck(R);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(G);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(B);
pBuilder->AddCharSafe(')');
}
inline void SetStrokeColor(LONG lBGR, LONG lA, NSStringUtils::CStringBuilder* pBuilder)
{
BYTE R = (BYTE)(lBGR & 0xFF);
BYTE G = (BYTE)((lBGR >> 8) & 0xFF);
BYTE B = (BYTE)((lBGR >> 16) & 0xFF);
pBuilder->WriteString(L"c.strokeStyle = \"rgba(", 22);
pBuilder->AddSize(70);
pBuilder->AddIntNoCheck(R);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(G);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(B);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheckDel100(100 * lA / 255);
pBuilder->WriteString(L")\";\n", 4);
}
inline void SetFillColor(LONG lBGR, LONG lA, NSStringUtils::CStringBuilder* pBuilder)
{
BYTE R = (BYTE)(lBGR & 0xFF);
BYTE G = (BYTE)((lBGR >> 8) & 0xFF);
BYTE B = (BYTE)((lBGR >> 16) & 0xFF);
pBuilder->WriteString(L"c.fillStyle = \"rgba(", 20);
pBuilder->AddSize(70);
pBuilder->AddIntNoCheck(R);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(G);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheck(B);
pBuilder->AddCharNoSafe(',');
pBuilder->AddIntNoCheckDel100(100 * lA / 255);
pBuilder->WriteString(L")\";\n", 4);
}
struct RECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
};
static RECT GetImageBounds(CBgraFrame* pFrame)
{
BYTE* pBuffer = pFrame->get_Data();
LONG lWidth = (LONG)pFrame->get_Width();
LONG lHeight = (LONG)pFrame->get_Height();
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = lWidth - 1;
rect.bottom = lHeight - 1;
// top
unsigned int* pData = (unsigned int*)pBuffer;
for (; rect.top < lHeight; rect.top++)
{
bool bIsBreak = false;
for (LONG i = 0; i < lWidth; ++i, ++pData)
{
if (*pData != 0x00)
{
bIsBreak = true;
break;
}
}
if (bIsBreak)
break;
}
if (rect.top >= lHeight)
rect.top = (lHeight - 1);
// bottom
for (; rect.bottom >= rect.top; rect.bottom--)
{
pData = (unsigned int*)pBuffer;
pData += (lWidth * rect.bottom);
bool bIsBreak = false;
for (LONG i = 0; i < lWidth; ++i, ++pData)
{
if (*pData != 0x00)
{
bIsBreak = true;
break;
}
}
if (bIsBreak)
break;
}
if (rect.bottom < rect.top)
rect.bottom = rect.top;
LONG lDelta = rect.bottom - rect.top + 1;
// left
for (; rect.left < lWidth; rect.left++)
{
pData = (unsigned int*)(pBuffer + 4 * lWidth * rect.top);
pData += rect.left;
bool bIsBreak = false;
for (LONG i = 0; i < lDelta; ++i, pData += lWidth)
{
if (*pData != 0x00)
{
bIsBreak = true;
break;
}
}
if (bIsBreak)
break;
}
if (rect.left >= lWidth)
rect.left = lWidth - 1;
// right
for (; rect.right >= rect.left; rect.right--)
{
pData = (unsigned int*)(pBuffer + 4 * lWidth * rect.top);
pData += rect.right;
bool bIsBreak = false;
for (LONG i = 0; i < lDelta; ++i, pData += lWidth)
{
if (*pData != 0x00)
{
bIsBreak = true;
break;
}
}
if (bIsBreak)
break;
}
if (rect.right < rect.left)
rect.right = rect.left;
return rect;
}
static RECT GetImageBounds2(CBgraFrame* pFrame, BYTE* pCache)
{
BYTE* pBuffer = pFrame->get_Data();
LONG lWidth = (LONG)pFrame->get_Width();
LONG lHeight = (LONG)pFrame->get_Height();
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = lWidth - 1;
rect.bottom = lHeight - 1;
// top
unsigned int** pData = (unsigned int**)pBuffer;
unsigned int** pDataSrc = (unsigned int**)pCache;
for (; rect.top < lHeight; rect.top++)
{
if (0 != memcmp((void*)pData, (void*)pDataSrc, 4 * lWidth))
break;
pData += lWidth;
pDataSrc += lWidth;
}
if (rect.top >= lHeight)
rect.top = (lHeight - 1);
// bottom
for (; rect.bottom >= rect.top; rect.bottom--)
{
pData = (unsigned int**)pBuffer;
pData += (lWidth * rect.bottom);
pDataSrc = (unsigned int**)pCache;
pDataSrc += (lWidth * rect.bottom);
if (0 != memcmp((void*)pData, (void*)pDataSrc, 4 * lWidth))
break;
}
if (rect.bottom < rect.top)
rect.bottom = rect.top;
LONG lDelta = rect.bottom - rect.top + 1;
// left
for (; rect.left < lWidth; rect.left++)
{
pData = (unsigned int**)(pBuffer + 4 * lWidth * rect.top);
pData += rect.left;
pDataSrc = (unsigned int**)(pCache + 4 * lWidth * rect.top);
pDataSrc += rect.left;
bool bIsBreak = false;
for (LONG i = 0; i < lDelta; ++i, pData += lWidth, pDataSrc += lWidth)
{
if (*pData != *pDataSrc)
{
bIsBreak = true;
break;
}
}
if (bIsBreak)
break;
}
if (rect.left >= lWidth)
rect.left = lWidth - 1;
// right
for (; rect.right >= rect.left; rect.right--)
{
pData = (unsigned int**)(pBuffer + 4 * lWidth * rect.top);
pData += rect.right;
pDataSrc = (unsigned int**)(pCache + 4 * lWidth * rect.top);
pDataSrc += rect.right;
bool bIsBreak = false;
for (LONG i = 0; i < lDelta; ++i, pData += lWidth)
{
if (*pData != *pDataSrc)
{
bIsBreak = true;
break;
}
}
if (bIsBreak)
break;
}
if (rect.right < rect.left)
rect.right = rect.left;
return rect;
}
const double c_ag_Inch_to_MM = 25.4;
const double c_ag_1pxWidth = 25.4 / 96;
enum ImageType
{
itJPG = 0,
itPNG = 1
};
class CImageInfo
{
public:
ImageType m_eType;
LONG m_lID;
CImageInfo()
{
m_eType = itJPG;
m_lID = -1;
}
CImageInfo(const CImageInfo& oSrc)
{
*this = oSrc;
}
CImageInfo& operator=(const CImageInfo& oSrc)
{
m_eType = oSrc.m_eType;
m_lID = oSrc.m_lID;
return *this;
}
};
inline double FABS(double dVal)
{
return (dVal >= 0) ? dVal : -dVal;
}
inline int round(double dVal)
{
return (int)(dVal + 0.5);
}
}
namespace NSHtmlRenderer
{
class CMetafile
{
public:
enum CommandType
{
// pen
ctPenXML = 0,
ctPenColor = 1,
ctPenAlpha = 2,
ctPenSize = 3,
ctPenDashStyle = 4,
ctPenLineStartCap = 5,
ctPenLineEndCap = 6,
ctPenLineJoin = 7,
ctPenDashPatern = 8,
ctPenDashPatternCount = 9,
ctPenDashOffset = 10,
ctPenAlign = 11,
ctPenMiterLimit = 12,
// brush
ctBrushXML = 20,
ctBrushType = 21,
ctBrushColor1 = 22,
ctBrushColor2 = 23,
ctBrushAlpha1 = 24,
ctBrushAlpha2 = 25,
ctBrushTexturePath = 26,
ctBrushTextureAlpha = 27,
ctBrushTextureMode = 28,
ctBrushRectable = 29,
ctBrushAngle = 30,
ctBrushSubColors = 31,
// font
ctFontXML = 40,
ctFontName = 41,
ctFontSize = 42,
ctFontStyle = 43,
ctFontPath = 44,
ctFontGID = 45,
ctFontCharSpace = 46,
// shadow
ctShadowXML = 50,
ctShadowVisible = 51,
ctShadowDistanceX = 52,
ctShadowDistanceY = 53,
ctShadowBlurSize = 54,
ctShadowColor = 55,
ctShadowAlpha = 56,
// edge
ctEdgeXML = 70,
ctEdgeVisible = 71,
ctEdgeDistance = 72,
ctEdgeColor = 73,
ctEdgeAlpha = 74,
// text
ctDrawText = 80,
ctDrawTextEx = 81,
// pathcommands
ctPathCommandMoveTo = 91,
ctPathCommandLineTo = 92,
ctPathCommandLinesTo = 93,
ctPathCommandCurveTo = 94,
ctPathCommandCurvesTo = 95,
ctPathCommandArcTo = 96,
ctPathCommandClose = 97,
ctPathCommandEnd = 98,
ctDrawPath = 99,
ctPathCommandStart = 100,
ctPathCommandGetCurrentPoint = 101,
ctPathCommandText = 102,
ctPathCommandTextEx = 103,
// image
ctDrawImage = 110,
ctDrawImageFromFile = 111,
ctSetParams = 120,
ctBeginCommand = 121,
ctEndCommand = 122,
ctSetTransform = 130,
ctResetTransform = 131,
ctClipMode = 140,
ctCommandLong1 = 150,
ctCommandDouble1 = 151,
ctCommandString1 = 152,
ctCommandLong2 = 153,
ctCommandDouble2 = 154,
ctCommandString2 = 155,
ctCommandTextLine = 160,
ctCommandTextTransform = 161,
ctCommandTextLineEnd = 162,
ctCommandTextClipRectReset = 163,
ctCommandTextClipRect = 164,
ctError = 255
};
private:
// сам метафайл
BYTE* m_pBuffer;
BYTE* m_pBufferMem;
size_t m_lPosition;
size_t m_lSize;
LONG m_lSizeofDouble;
LONG m_lSizeofFloat;
LONG m_lSizeofLONG;
LONG m_lSizeofBYTE;
public:
double m_fWidth;
double m_fHeight;
public:
CMetafile()
{
Clear();
m_lSizeofDouble = sizeof(double);
m_lSizeofFloat = sizeof(float);
m_lSizeofLONG = sizeof(int);
m_lSizeofBYTE = sizeof(BYTE);
}
~CMetafile()
{
RELEASEARRAYOBJECTS(m_pBuffer);
}
public:
inline LONG GetPosition()
{
return (LONG)m_lPosition;
}
inline BYTE* GetData()
{
return m_pBuffer;
}
inline void ClearNoAttack()
{
m_lPosition = 0;
m_pBufferMem = m_pBuffer;
}
inline void Clear()
{
m_lSize = 0;
m_lPosition = 0;
m_pBuffer = NULL;
m_pBufferMem = NULL;
}
inline void Seek(LONG lPos)
{
m_lPosition = (size_t)lPos;
m_pBufferMem = m_pBuffer + m_lPosition;
}
inline void CheckBufferSize(size_t lPlus)
{
if (NULL != m_pBuffer)
{
size_t nNewSize = m_lPosition + lPlus;
if (nNewSize >= m_lSize)
{
while (nNewSize >= m_lSize)
{
m_lSize *= 2;
}
BYTE* pNew = new BYTE[m_lSize];
memcpy(pNew, m_pBuffer, m_lPosition);
RELEASEARRAYOBJECTS(m_pBuffer);
m_pBuffer = pNew;
}
}
else
{
m_lSize = 1000;
m_pBuffer = new BYTE[m_lSize];
CheckBufferSize(lPlus);
}
}
inline void WriteCommandType(const CommandType& eType)
{
CheckBufferSize(m_lSizeofBYTE);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
}
//
inline void WriteBYTE_nocheck(const BYTE& lValue)
{
*(m_pBuffer + m_lPosition) = lValue;
m_lPosition += m_lSizeofBYTE;
}
inline void WriteLONG_nocheck(const int& lValue)
{
*((int*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += m_lSizeofLONG;
}
inline void WriteUSHORT_nocheck(const USHORT& lValue)
{
*((USHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(USHORT);
}
inline void WriteWCHAR_nocheck(const WCHAR& lValue)
{
*((WCHAR*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(WCHAR);
}
inline void WriteDouble_nocheck(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
LONG lValue = (LONG)(dValue * 10000);
WriteLONG_nocheck(lValue);
return;
CheckBufferSize(m_lSizeofDouble);
*((double*)(m_pBuffer + m_lPosition)) = dValue;
m_lPosition += m_lSizeofDouble;
}
inline void WriteDouble2_nocheck(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
SHORT lValue = (SHORT)(dValue * 100);
*((SHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(SHORT);
}
//
inline void WriteBYTE(const BYTE& lValue)
{
CheckBufferSize(m_lSizeofBYTE);
*(m_pBuffer + m_lPosition) = lValue;
m_lPosition += m_lSizeofBYTE;
}
inline void WriteLONG(const int& lValue)
{
CheckBufferSize(m_lSizeofLONG);
*((int*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += m_lSizeofLONG;
}
inline void WriteUSHORT(const USHORT& lValue)
{
CheckBufferSize(sizeof(USHORT));
*((USHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(USHORT);
}
inline void WriteWCHAR(const WCHAR& lValue)
{
CheckBufferSize(sizeof(WCHAR));
*((WCHAR*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(WCHAR);
}
inline void WriteDouble(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
int lValue = (int)(dValue * 10000);
WriteLONG(lValue);
return;
CheckBufferSize(m_lSizeofDouble);
*((double*)(m_pBuffer + m_lPosition)) = dValue;
m_lPosition += m_lSizeofDouble;
}
inline void WriteDouble2(const double& dValue)
{
// здесь никаких даблов. Сплошные округления
SHORT lValue = (SHORT)(dValue * 100);
CheckBufferSize(sizeof(SHORT));
*((SHORT*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += sizeof(SHORT);
}
inline void WriteFloat(const float& fValue)
{
CheckBufferSize(m_lSizeofFloat);
*((float*)(m_pBuffer + m_lPosition)) = fValue;
m_lPosition += m_lSizeofFloat;
}
inline void WriteString(wchar_t* bstrValue)
{
int lSize = (int)wcslen(bstrValue) + 1;
int lSizeMem = lSize * sizeof(wchar_t);
CheckBufferSize(m_lSizeofLONG + lSizeMem);
*((int*)(m_pBuffer + m_lPosition)) = lSizeMem;
m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem);
m_lPosition += lSizeMem;
}
inline void WriteBYTE(const CommandType& eType, const BYTE& lValue)
{
CheckBufferSize(2 * m_lSizeofBYTE);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*(m_pBuffer + m_lPosition) = lValue;
m_lPosition += m_lSizeofBYTE;
}
inline void WriteLONG(const CommandType& eType, const int& lValue)
{
CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lValue;
m_lPosition += m_lSizeofLONG;
}
inline void WriteDouble(const CommandType& eType, const double& dValue)
{
CheckBufferSize(m_lSizeofBYTE + m_lSizeofDouble);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((double*)(m_pBuffer + m_lPosition)) = dValue;
m_lPosition += m_lSizeofDouble;
}
inline void WriteFloat(const CommandType& eType, const float& fValue)
{
CheckBufferSize(m_lSizeofBYTE + m_lSizeofFloat);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((float*)(m_pBuffer + m_lPosition)) = fValue;
m_lPosition += m_lSizeofFloat;
}
inline void WriteString(const CommandType& eType, wchar_t* bstrValue)
{
int lSize = (int)wcslen(bstrValue) + 1;
int lSizeMem = lSize * sizeof(wchar_t);
CheckBufferSize(m_lSizeofBYTE + m_lSizeofLONG + lSizeMem);
*(m_pBuffer + m_lPosition) = (BYTE)eType;
m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lSizeMem;
m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, bstrValue, lSizeMem);
m_lPosition += lSizeMem;
}
inline void Write(const BYTE* pData, const LONG& lLen)
{
CheckBufferSize((size_t)lLen);
memcpy(m_pBuffer + m_lPosition, pData, lLen);
m_lPosition += lLen;
}
inline void Write(const CommandType& eCommand, const double& f1, const double& f2)
{
size_t lMem = m_lSizeofBYTE + 2 * m_lSizeofDouble;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((double*)(m_pBuffer + m_lPosition))= f1; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f2; m_lPosition += m_lSizeofDouble;
}
inline void Write(const CommandType& eCommand, const double& f1, const double& f2, const double& f3, const double& f4, const double& f5, const double& f6)
{
size_t lMem = m_lSizeofBYTE + 6 * m_lSizeofDouble;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((double*)(m_pBuffer + m_lPosition))= f1; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f2; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f3; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f4; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f5; m_lPosition += m_lSizeofDouble;
*((double*)(m_pBuffer + m_lPosition))= f6; m_lPosition += m_lSizeofDouble;
}
inline void Write(const CommandType& eCommand, const int& lCount, float* pData)
{
size_t lFloats = lCount * m_lSizeofFloat;
size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, pData, lFloats);
m_lPosition += lFloats;
}
inline void Write(const CommandType& eCommand, const int& lCount, double* pData)
{
size_t lFloats = lCount * m_lSizeofDouble;
size_t lMem = m_lSizeofBYTE + m_lSizeofLONG + lFloats;
CheckBufferSize(lMem);
*(m_pBuffer + m_lPosition) = (BYTE)eCommand; m_lPosition += m_lSizeofBYTE;
*((int*)(m_pBuffer + m_lPosition)) = lCount; m_lPosition += m_lSizeofLONG;
memcpy(m_pBuffer + m_lPosition, pData, lFloats);
m_lPosition += lFloats;
}
inline void Write(CMetafile& oMeta)
{
LONG lPos = oMeta.GetPosition();
CheckBufferSize(lPos);
memcpy(m_pBuffer + m_lPosition, oMeta.GetData(), lPos);
m_lPosition += lPos;
}
};
}
#endif // _ASC_HTMLRENDERER_COMMON_H_
#pragma once
#include "File.h"
namespace NSHtmlRenderer
{
class CPageInfo
{
private:
double m_dWidthMM;
double m_dHeightMM;
bool m_bInitW;
bool m_bInitH;
IBaseMatrixUpdater* m_pUpdater;
public:
CPageInfo()
{
m_dWidthMM = 190;
m_dHeightMM = 270;
m_bInitW = false;
m_bInitH = false;
m_pUpdater = NULL;
}
CPageInfo(const CPageInfo& oSrc)
{
*this = oSrc;
}
CPageInfo& operator=(const CPageInfo& oSrc)
{
m_dWidthMM = oSrc.m_dWidthMM;
m_dHeightMM = oSrc.m_dHeightMM;
m_bInitW = oSrc.m_bInitW;
m_bInitH = oSrc.m_bInitH;
m_pUpdater = oSrc.m_pUpdater;
}
inline double GetWidth()
{
return m_dWidthMM;
}
inline double GetHeight()
{
return m_dHeightMM;
}
inline void SetWidth(const double& width)
{
m_dWidthMM = width;
m_bInitW = true;
if (m_bInitH && (NULL != m_pUpdater))
{
m_pUpdater->OnBaseMatrixUpdate(m_dWidthMM, m_dHeightMM);
}
}
inline void SetHeight(const double& height)
{
m_dHeightMM = height;
m_bInitH = true;
if (m_bInitW && (NULL != m_pUpdater))
{
m_pUpdater->OnBaseMatrixUpdate(m_dWidthMM, m_dHeightMM);
}
}
inline void SetUpdater(IBaseMatrixUpdater* pUpdater)
{
m_pUpdater = pUpdater;
}
};
class CDocument
{
private:
public:
CAtlArray<CPageInfo> m_arrPages;
IBaseMatrixUpdater* m_pUpdater;
public:
CDocument() : m_arrPages()
{
m_pUpdater = NULL;
}
inline void SetUpdater(IBaseMatrixUpdater* pUpdater)
{
m_pUpdater = pUpdater;
}
public:
inline void NewPage()
{
m_arrPages.Add();
size_t nCount = m_arrPages.GetCount();
m_arrPages[nCount - 1].SetUpdater(m_pUpdater);
}
inline void SetWidth(const double& dValue)
{
size_t nCount = m_arrPages.GetCount();
if (nCount > 0)
{
m_arrPages[nCount - 1].SetWidth(dValue);
}
}
inline void SetHeight(const double& dValue)
{
size_t nCount = m_arrPages.GetCount();
if (nCount > 0)
{
m_arrPages[nCount - 1].SetHeight(dValue);
}
}
// --------------------------------------------------------------------
CString GetThumbnailsHTML()
{
CString strHTML = _T("<html>");
strHTML += GetThumbnailsHeader();
strHTML += GetThumbnailsBody();
strHTML += _T("</html>");
return strHTML;
}
CString GetViewerHTML()
{
CString strHTML = _T("<html>");
strHTML += GetViewerHeader();
strHTML += GetViewerBody();
strHTML += _T("</html>");
return strHTML;
}
CString GetThumbnailBlockHTML(int nPageNum)
{
CString strPage = _T("");
strPage.Format(_T("%d"), nPageNum);
CString strResult = _T("<div class=\"blockpage\"><div class=\"blockthumbnail\" align=\"center\"><img align=\"center\" src=\"thumbnails\\page") +
strPage + _T(".png\" onClick=\"OnChangePage(") + strPage + _T(")\" width=\"100%\" height=\"90%\"/>") + _T("page") + strPage + _T("</div></div>");
return strResult;
}
CString GetThumbnailsBody()
{
CString strBody = _T("<body bgcolor=\"#FEFEFE\">");
size_t nCount = m_arrPages.GetCount();
for (size_t i = 0; i < nCount; ++i)
{
strBody += GetThumbnailBlockHTML((int)(i + 1));
}
strBody += _T("</body>");
return strBody;
}
CString GetThumbnailsHeader()
{
CString strHead = _T("<head>\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\
<title>thumbnails</title>\
<style type=\"text/css\">\
.blockpage {\
width: 80%;\
height: 200px;\
background: #FEFEFE;\
padding: 10px;\
float: none;\
text-align: center;\
}\
.blockthumbnail {\
width: 100%;\
height: 100%;\
background: #FEFEFE;\
padding: 0px;\
float: none;\
}\
</style>\
<script language=\"JavaScript\">\
function OnChangePage(pageNum)\
{\
top.frames['viewer'].OnChangePage(pageNum);\
}\
</script>\
</head>");
return strHead;
}
CString GetViewerHeader()
{
CString strHead = _T("<head>\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\
<title>viewer</title>\
<style type=\"text/css\">\
.blockpage {\
position: relative;\
left: 20%;\
width: 60%;\
height: 1200px;\
background: #FFFFFF;\
padding: 10px;\
border-style: outset;\
border-color: #F0F0F0;\
border-width: 2px 3px 3px 2px;\
float: none;\
text-align: center;\
}\
.blockpagebetween {\
width: 100%;\
height: 20px;\
background: #FEFEFE;\
padding: 0px;\
float: none;\
text-align: center;\
}\
.blockpagenatural {\
width: 100%;\
height: 100%;\
background: #FEFEFE;\
padding: 0px;\
float: none;\
}\
</style>\
<script language=\"JavaScript\">\
function OnChangePage(pageNum)\
{\
var nPage = Number(pageNum);\
var position = ((nPage - 1) * 1225 + (nPage - 1) * 20);\
scroll(0, position);\
}\
</script>\
</head>");
return strHead;
}
CString GetViewerBlockHTML(int nPageNum)
{
CString strPage = _T("");
strPage.Format(_T("%d"), nPageNum);
CString strResult = _T("<div class=\"blockpage\">\n<div class=\"blockpagenatural\" align=\"center\">\n<img align=\"center\" src=\"thumbnails\\page") +
strPage + _T(".png\" onClick=\"OnChangePage(") + strPage + _T(")\" width=\"100%\" height=\"100%\"/>\n") + _T("</div>\n</div>\n") + _T("<div class=\"blockpagebetween\"></div>\n");
return strResult;
}
CString GetViewerBody()
{
CString strBody = _T("<body bgcolor=\"#FEFEFE\">");
size_t nCount = m_arrPages.GetCount();
for (size_t i = 0; i < nCount; ++i)
{
strBody += GetViewerBlockHTML((int)(i + 1));
}
strBody += _T("</body>");
return strBody;
}
CString GetMenuHTML()
{
CString strHtml = _T("<html>\
<head>\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\
<title>menu</title>\
</head>\
<body bgcolor=\"#5F5F5F\">\
</body>\
</html>");
return strHtml;
}
CString GetDocumentHTML()
{
CString strHtml = _T("<html>\
<head>\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></meta>\
<title>document viewer</title>\
</head>\
<frameset rows=\"50,*\" framespacing=\"0\" frameborder=\"0\">\
<frame src=\"menu.html\" name=\"menu\" noresize border=\"1\" bordercolor=\"#F0F0F0\" scrolling=\"no\"></frame>\
<frameset cols=\"*,200\">\
<frame id=\"id_viewer\" src=\"viewer.html\" name=\"viewer\" noresize></frame>\
<frame id=\"id_thumbnails\" src=\"thumbnails.html\" name=\"thumbnail\"></frame>\
</frameset>\
</frameset>\
</html>");
return strHtml;
}
static CStringA ConvertToUTF8 (CStringW aUnicodeXML)
{
// Convert to UTF-8
int iSize = WideCharToMultiByte (CP_UTF8, 0, aUnicodeXML, -1, NULL, 0, NULL, NULL);
if (iSize <= 0)
{
ATLTRACE2 ("ConvertToUTF8() error (size detection): 0x%x\n", GetLastError());
return CStringA(aUnicodeXML); // Conversion to ANSI
}
CStringA sOutXML;
if (0 == WideCharToMultiByte (CP_UTF8, 0, aUnicodeXML, -1, sOutXML.GetBuffer(iSize + 1), iSize, NULL, NULL))
{
ATLTRACE2 ("ConvertToUTF8() error (utf-8 conversion): 0x%x\n", GetLastError());
return CStringA(aUnicodeXML);
}
sOutXML.ReleaseBuffer();
return sOutXML;
}
void CreateDirectories(CString strHTML)
{
CDirectory::CreateDirectory(strHTML);
CDirectory::CreateDirectory(strHTML, _T("thumbnails"));
}
void CreateHTMLs(CString strHTML)
{
CFile oFile;
oFile.CreateFile(strHTML + _T("\\docviewer.html"));
CString strDocHTML = GetDocumentHTML();
CStringA str1 = ConvertToUTF8(strDocHTML);
oFile.WriteFile((void*)str1.GetBuffer(), str1.GetLength());
oFile.CloseFile();
oFile.CreateFile(strHTML + _T("\\menu.html"));
CString strMenuHTML = GetMenuHTML();
CStringA str2 = ConvertToUTF8(strMenuHTML);
oFile.WriteFile((void*)str2.GetBuffer(), str2.GetLength());
oFile.CloseFile();
oFile.CreateFile(strHTML + _T("\\viewer.html"));
CString strViewerHTML = GetViewerHTML();
CStringA str3 = ConvertToUTF8(strViewerHTML);
oFile.WriteFile((void*)str3.GetBuffer(), str3.GetLength());
oFile.CloseFile();
oFile.CreateFile(strHTML + _T("\\thumbnails.html"));
CString strThHTML = GetThumbnailsHTML();
CStringA str4 = ConvertToUTF8(strThHTML);
oFile.WriteFile((void*)str4.GetBuffer(), str4.GetLength());
oFile.CloseFile();
}
};
class CThumbnails
{
private:
Graphics::IASCRenderer* m_pRenderer;
MediaCore::IAVSUncompressedVideoFrame* m_pFrame;
LONG m_lWidth;
LONG m_lHeight;
public:
CThumbnails()
{
m_pRenderer = NULL;
m_pFrame = NULL;
m_lWidth = 0;
m_lHeight = 0;
}
~CThumbnails()
{
RELEASEINTERFACE(m_pRenderer);
RELEASEINTERFACE(m_pFrame);
}
public:
void Create(const double& dWidth, const double& dHeight, LONG lSizeMax = 200)
{
LONG lWidthNew = 0;
LONG lHeightNew = 0;
if (dWidth >= dHeight)
{
lWidthNew = lSizeMax;
lHeightNew = (LONG)((dHeight / dWidth) * lWidthNew);
}
else
{
lHeightNew = lSizeMax;
lWidthNew = (LONG)((dWidth / dHeight) * lHeightNew);
}
if ((m_lWidth == lWidthNew) && (m_lHeight == lHeightNew) && (NULL != m_pFrame))
{
// размер не поменялся - значит и память перевыделять не нужно
BYTE* pBuffer = NULL;
m_pFrame->get_Buffer(&pBuffer);
memset(pBuffer, 0xFF, 4 * m_lWidth * m_lHeight);
CreateRenderer();
return;
}
RELEASEINTERFACE(m_pFrame);
m_lWidth = lWidthNew;
m_lHeight = lHeightNew;
CreateMediaData();
CreateRenderer();
m_pRenderer->put_Width(dWidth);
m_pRenderer->put_Height(dHeight);
}
inline void Save(CString& strFile)
{
SaveFrame(strFile);
}
protected:
void CreateMediaData()
{
RELEASEINTERFACE(m_pFrame);
CoCreateInstance(__uuidof( MediaCore::CAVSUncompressedVideoFrame), NULL ,CLSCTX_INPROC_SERVER,
__uuidof(MediaCore::IAVSUncompressedVideoFrame), (void**)&m_pFrame);
m_pFrame->put_Width(m_lWidth);
m_pFrame->put_Height(m_lHeight);
m_pFrame->put_ColorSpace(64);
m_pFrame->SetDefaultStrides();
m_pFrame->AllocateBuffer(-1);
BYTE* pBuffer = NULL;
m_pFrame->get_Buffer(&pBuffer);
memset(pBuffer, 0xFF, 4 * m_lWidth * m_lHeight);
}
void CreateRenderer()
{
// теперь на всякий случай (сбросить все состояния) - пересоздадим рендерер
RELEASEINTERFACE(m_pRenderer);
Graphics::IASCGraphicsRenderer* pGrRenderer;
CoCreateInstance(__uuidof( Graphics::CASCGraphicsRenderer), NULL, CLSCTX_INPROC_SERVER,
__uuidof(Graphics::IASCGraphicsRenderer), (void**)&pGrRenderer);
//ставим FontManager
VARIANT vtVariant;
vtVariant.vt = VT_UNKNOWN;
vtVariant.punkVal = NULL;
pGrRenderer->SetAdditionalParam( L"FontManager", vtVariant );
IUnknown* punkFrame = NULL;
m_pFrame->QueryInterface(IID_IUnknown, (void**)&punkFrame);
pGrRenderer->CreateFromMediaData(punkFrame, 0, 0, m_lWidth, m_lHeight);
RELEASEINTERFACE(punkFrame);
pGrRenderer->QueryInterface(Graphics::IID_IASCRenderer, (void**)&m_pRenderer);
RELEASEINTERFACE(pGrRenderer);
}
void SaveFrame(const CString& strFile)
{
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 = (IUnknown*)m_pFrame;
pTransform->SetSource(0, var);
CString strXml = _T("<transforms><ImageFile-SaveAsPng destinationpath=\"") + strFile + _T("\" format=\"888\"></ImageFile-SaveAsPng></transforms>");
VARIANT_BOOL vbSuccess = VARIANT_FALSE;
BSTR bsXml = strXml.AllocSysString();
pTransform->SetXml(bsXml, &vbSuccess);
SysFreeString(bsXml);
pTransform->Transform(&vbSuccess);
RELEASEINTERFACE(pTransform);
}
public:
inline HRESULT get_Type(LONG* lType)
{
return m_pRenderer->get_Type(lType);
}
//-------- Функции для работы со страницей --------------------------------------------------
inline HRESULT NewPage()
{
if (NULL == m_pRenderer)
return S_OK;
return m_pRenderer->NewPage();
}
inline HRESULT get_Height(double* dHeight)
{
return m_pRenderer->get_Height(dHeight);
}
inline HRESULT put_Height(double dHeight)
{
if (NULL == m_pRenderer)
return S_OK;
return m_pRenderer->put_Height(dHeight);
}
inline HRESULT get_Width(double* dWidth)
{
return m_pRenderer->get_Width(dWidth);
}
inline HRESULT put_Width(double dWidth)
{
if (NULL == m_pRenderer)
return S_OK;
return m_pRenderer->put_Width(dWidth);
}
inline HRESULT get_DpiX(double* dDpiX)
{
return m_pRenderer->get_DpiX(dDpiX);
}
inline HRESULT get_DpiY(double* dDpiY)
{
return m_pRenderer->get_DpiY(dDpiY);
}
// pen --------------------------------------------------------------------------------------
inline HRESULT SetPen(BSTR bsXML)
{
return m_pRenderer->SetPen(bsXML);
}
inline HRESULT get_PenColor(LONG* lColor)
{
return m_pRenderer->get_PenColor(lColor);
}
inline HRESULT put_PenColor(LONG lColor)
{
return m_pRenderer->put_PenColor(lColor);
}
inline HRESULT get_PenAlpha(LONG* lAlpha)
{
return m_pRenderer->get_PenAlpha(lAlpha);
}
inline HRESULT put_PenAlpha(LONG lAlpha)
{
return m_pRenderer->put_PenAlpha(lAlpha);
}
inline HRESULT get_PenSize(double* dSize)
{
return m_pRenderer->get_PenSize(dSize);
}
inline HRESULT put_PenSize(double dSize)
{
return m_pRenderer->put_PenSize(dSize);
}
inline HRESULT get_PenDashStyle(BYTE* val)
{
return m_pRenderer->get_PenDashStyle(val);
}
inline HRESULT put_PenDashStyle(BYTE val)
{
return m_pRenderer->put_PenDashStyle(val);
}
inline HRESULT get_PenLineStartCap(BYTE* val)
{
return m_pRenderer->get_PenLineStartCap(val);
}
inline HRESULT put_PenLineStartCap(BYTE val)
{
return m_pRenderer->put_PenLineStartCap(val);
}
inline HRESULT get_PenLineEndCap(BYTE* val)
{
return m_pRenderer->get_PenLineEndCap(val);
}
inline HRESULT put_PenLineEndCap(BYTE val)
{
return m_pRenderer->put_PenLineEndCap(val);
}
inline HRESULT get_PenLineJoin(BYTE* val)
{
return m_pRenderer->get_PenLineJoin(val);
}
inline HRESULT put_PenLineJoin(BYTE val)
{
return m_pRenderer->put_PenLineJoin(val);
}
inline HRESULT get_PenDashOffset(double* val)
{
return m_pRenderer->get_PenDashOffset(val);
}
inline HRESULT put_PenDashOffset(double val)
{
return m_pRenderer->put_PenDashOffset(val);
}
inline HRESULT get_PenAlign(LONG* val)
{
return m_pRenderer->get_PenAlign(val);
}
inline HRESULT put_PenAlign(LONG val)
{
return m_pRenderer->put_PenAlign(val);
}
inline HRESULT get_PenMiterLimit(double* val)
{
return m_pRenderer->get_PenMiterLimit(val);
}
inline HRESULT put_PenMiterLimit(double val)
{
return m_pRenderer->put_PenMiterLimit(val);
}
inline HRESULT PenDashPattern(SAFEARRAY* pPattern)
{
return m_pRenderer->PenDashPattern(pPattern);
}
// brush ------------------------------------------------------------------------------------
inline HRESULT SetBrush(BSTR bsXML)
{
return m_pRenderer->SetBrush(bsXML);
}
inline HRESULT get_BrushType(LONG* lType)
{
return m_pRenderer->get_BrushType(lType);
}
inline HRESULT put_BrushType(LONG lType)
{
return m_pRenderer->put_BrushType(lType);
}
inline HRESULT get_BrushColor1(LONG* lColor)
{
return m_pRenderer->get_BrushColor1(lColor);
}
inline HRESULT put_BrushColor1(LONG lColor)
{
return m_pRenderer->put_BrushColor1(lColor);
}
inline HRESULT get_BrushAlpha1(LONG* lAlpha)
{
return m_pRenderer->get_BrushAlpha1(lAlpha);
}
inline HRESULT put_BrushAlpha1(LONG lAlpha)
{
return m_pRenderer->put_BrushAlpha1(lAlpha);
}
inline HRESULT get_BrushColor2(LONG* lColor)
{
return m_pRenderer->get_BrushColor2(lColor);
}
inline HRESULT put_BrushColor2(LONG lColor)
{
return m_pRenderer->put_BrushColor2(lColor);
}
inline HRESULT get_BrushAlpha2(LONG* lAlpha)
{
return m_pRenderer->get_BrushAlpha2(lAlpha);
}
inline HRESULT put_BrushAlpha2(LONG lAlpha)
{
return m_pRenderer->put_BrushAlpha2(lAlpha);
}
inline HRESULT get_BrushTexturePath(BSTR* bsPath)
{
return m_pRenderer->get_BrushTexturePath(bsPath);
}
inline HRESULT put_BrushTexturePath(BSTR bsPath)
{
return m_pRenderer->put_BrushTexturePath(bsPath);
}
inline HRESULT get_BrushTextureMode(LONG* lMode)
{
return m_pRenderer->get_BrushTextureMode(lMode);
}
inline HRESULT put_BrushTextureMode(LONG lMode)
{
return m_pRenderer->put_BrushTextureMode(lMode);
}
inline HRESULT get_BrushTextureAlpha(LONG* lTxAlpha)
{
return m_pRenderer->get_BrushTextureAlpha(lTxAlpha);
}
inline HRESULT put_BrushTextureAlpha(LONG lTxAlpha)
{
return m_pRenderer->put_BrushTextureAlpha(lTxAlpha);
}
inline HRESULT get_BrushLinearAngle(double* dAngle)
{
return m_pRenderer->get_BrushLinearAngle(dAngle);
}
inline HRESULT put_BrushLinearAngle(double dAngle)
{
return m_pRenderer->put_BrushLinearAngle(dAngle);
}
inline HRESULT BrushRect(BOOL val, double left, double top, double width, double height)
{
return m_pRenderer->BrushRect(val, left, top, width, height);
}
// font -------------------------------------------------------------------------------------
inline HRESULT SetFont(BSTR bsXML)
{
return m_pRenderer->SetFont(bsXML);
}
inline HRESULT get_FontName(BSTR* bsName)
{
return m_pRenderer->get_FontName(bsName);
}
inline HRESULT put_FontName(BSTR bsName)
{
return m_pRenderer->put_FontName(bsName);
}
inline HRESULT get_FontPath(BSTR* bsName)
{
return m_pRenderer->get_FontPath(bsName);
}
inline HRESULT put_FontPath(BSTR bsName)
{
return m_pRenderer->put_FontPath(bsName);
}
inline HRESULT get_FontSize(double* dSize)
{
return m_pRenderer->get_FontSize(dSize);
}
inline HRESULT put_FontSize(double dSize)
{
return m_pRenderer->put_FontSize(dSize);
}
inline HRESULT get_FontStyle(LONG* lStyle)
{
return m_pRenderer->get_FontStyle(lStyle);
}
inline HRESULT put_FontStyle(LONG lStyle)
{
return m_pRenderer->put_FontStyle(lStyle);
}
inline HRESULT get_FontStringGID(BOOL* bGID)
{
return m_pRenderer->get_FontStringGID((LONG*)bGID);
}
inline HRESULT put_FontStringGID(BOOL bGID)
{
return m_pRenderer->put_FontStringGID(bGID);
}
inline HRESULT get_FontCharSpace(double* dSpace)
{
return m_pRenderer->get_FontCharSpace(dSpace);
}
inline HRESULT put_FontCharSpace(double dSpace)
{
return m_pRenderer->put_FontCharSpace(dSpace);
}
// shadow -----------------------------------------------------------------------------------
inline HRESULT SetShadow(BSTR bsXML)
{
return m_pRenderer->SetShadow(bsXML);
}
inline HRESULT get_ShadowDistanceX(double* val)
{
return m_pRenderer->get_ShadowDistanceX(val);
}
inline HRESULT put_ShadowDistanceX(double val)
{
return m_pRenderer->put_ShadowDistanceX(val);
}
inline HRESULT get_ShadowDistanceY(double* val)
{
return m_pRenderer->get_ShadowDistanceY(val);
}
inline HRESULT put_ShadowDistanceY(double val)
{
return m_pRenderer->put_ShadowDistanceY(val);
}
inline HRESULT get_ShadowBlurSize(double* val)
{
return m_pRenderer->get_ShadowBlurSize(val);
}
inline HRESULT put_ShadowBlurSize(double val)
{
return m_pRenderer->put_ShadowBlurSize(val);
}
inline HRESULT get_ShadowColor(LONG* val)
{
return m_pRenderer->get_ShadowColor(val);
}
inline HRESULT put_ShadowColor(LONG val)
{
return m_pRenderer->put_ShadowColor(val);
}
inline HRESULT get_ShadowAlpha(LONG* val)
{
return m_pRenderer->get_ShadowAlpha(val);
}
inline HRESULT put_ShadowAlpha(LONG val)
{
return m_pRenderer->put_ShadowAlpha(val);
}
inline HRESULT get_ShadowVisible(BOOL* val)
{
return m_pRenderer->get_ShadowVisible((LONG*)val);
}
inline HRESULT put_ShadowVisible(BOOL val)
{
return m_pRenderer->put_ShadowVisible(val);
}
// edge -------------------------------------------------------------------------------------
inline HRESULT SetEdgeText(BSTR bsXML)
{
return m_pRenderer->SetEdgeText(bsXML);
}
inline HRESULT get_EdgeVisible(LONG* val)
{
return m_pRenderer->get_EdgeVisible(val);
}
inline HRESULT put_EdgeVisible(LONG val)
{
return m_pRenderer->put_EdgeVisible(val);
}
inline HRESULT get_EdgeColor(LONG* val)
{
return m_pRenderer->get_EdgeColor(val);
}
inline HRESULT put_EdgeColor(LONG val)
{
return m_pRenderer->put_EdgeColor(val);
}
inline HRESULT get_EdgeAlpha(LONG* val)
{
return m_pRenderer->get_EdgeAlpha(val);
}
inline HRESULT put_EdgeAlpha(LONG val)
{
return m_pRenderer->put_EdgeAlpha(val);
}
inline HRESULT get_EdgeDist(double* val)
{
return m_pRenderer->get_EdgeDist(val);
}
inline HRESULT put_EdgeDist(double val)
{
return m_pRenderer->put_EdgeDist(val);
}
//-------- Функции для вывода текста --------------------------------------------------------
inline HRESULT CommandDrawText(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
return m_pRenderer->CommandDrawText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
inline HRESULT CommandDrawTextEx(BSTR bsText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
return m_pRenderer->CommandDrawTextEx(bsText, bsGidText, bsSourceCodeText, fX, fY, fWidth, fHeight, fBaseLineOffset, lFlags);
}
//-------- Маркеры для команд ---------------------------------------------------------------
inline HRESULT BeginCommand(DWORD lType)
{
return m_pRenderer->BeginCommand(lType);
}
inline HRESULT EndCommand(DWORD lType)
{
return m_pRenderer->EndCommand(lType);
}
//-------- Функции для работы с Graphics Path -----------------------------------------------
inline HRESULT PathCommandMoveTo(double fX, double fY)
{
return m_pRenderer->PathCommandMoveTo(fX, fY);
}
inline HRESULT PathCommandLineTo(double fX, double fY)
{
return m_pRenderer->PathCommandLineTo(fX, fY);
}
inline HRESULT PathCommandLinesTo(SAFEARRAY* pPoints)
{
return m_pRenderer->PathCommandLinesTo(pPoints);
}
inline HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
{
return m_pRenderer->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
}
inline HRESULT PathCommandCurvesTo(SAFEARRAY* pPoints)
{
return m_pRenderer->PathCommandCurvesTo(pPoints);
}
inline HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
return m_pRenderer->PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle);
}
inline HRESULT PathCommandClose()
{
return m_pRenderer->PathCommandClose();
}
inline HRESULT PathCommandEnd()
{
return m_pRenderer->PathCommandEnd();
}
inline HRESULT DrawPath(long nType)
{
return m_pRenderer->DrawPath(nType);
}
inline HRESULT PathCommandStart()
{
return m_pRenderer->PathCommandStart();
}
inline HRESULT PathCommandGetCurrentPoint(double* fX, double* fY)
{
return m_pRenderer->PathCommandGetCurrentPoint(fX, fY);
}
inline HRESULT PathCommandText(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
return m_pRenderer->PathCommandText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
inline HRESULT PathCommandTextEx(BSTR bsText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
return m_pRenderer->PathCommandTextEx(bsText, bsGidText, bsSourceCodeText, fX, fY, fWidth, fHeight, fBaseLineOffset, lFlags);
}
//-------- Функции для вывода изображений ---------------------------------------------------
inline HRESULT DrawImage(IUnknown* pInterface, double fX, double fY, double fWidth, double fHeight)
{
return m_pRenderer->DrawImage(pInterface, fX, fY, fWidth, fHeight);
}
inline HRESULT DrawImageFromFile(BSTR bstrVal, double fX, double fY, double fWidth, double fHeight)
{
return m_pRenderer->DrawImageFromFile(bstrVal, fX, fY, fWidth, fHeight);
}
// transform --------------------------------------------------------------------------------
inline HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
{
return m_pRenderer->GetCommandParams(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
}
inline HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
return m_pRenderer->SetCommandParams(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
}
inline HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF)
{
return m_pRenderer->SetTransform(dA, dB, dC, dD, dE, dF);
}
inline HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
{
return m_pRenderer->GetTransform(pdA, pdB, pdC, pdD, pdE, pdF);
}
inline HRESULT ResetTransform(void)
{
return m_pRenderer->ResetTransform();
}
// -----------------------------------------------------------------------------------------
inline HRESULT get_ClipMode(LONG* plMode)
{
return m_pRenderer->get_ClipMode(plMode);
}
inline HRESULT put_ClipMode(LONG lMode)
{
return m_pRenderer->put_ClipMode(lMode);
}
// additiaonal params ----------------------------------------------------------------------
inline HRESULT SetAdditionalParam(BSTR ParamName, VARIANT ParamValue)
{
return m_pRenderer->SetAdditionalParam(ParamName, ParamValue);
}
inline HRESULT GetAdditionalParam(BSTR ParamName, VARIANT* ParamValue)
{
return m_pRenderer->GetAdditionalParam(ParamName, ParamValue);
}
};
}
\ No newline at end of file
#pragma once
#include "..\stdafx.h"
#include "Const.h"
#include "Common.h"
#include "StringWriter.h"
#include "..\Graphics\Structures.h"
#include "..\Graphics\Matrix.h"
#include "FontManagerBase.h"
namespace NSHtmlRenderer
{
using namespace NSFontManager;
const long g_lNewNoJustifySpace = 5;
class CFontManager : public CFontManagerBase
{
public:
NSStructures::CFont* m_pFont;
NSHtmlRenderer::CMatrix* m_pTransform;
double m_dSpaceWidthMM;
public:
CFontManager() : m_pFont(NULL), CFontManagerBase()
{
m_pTransform = NULL;
m_dSpaceWidthMM = 0;
}
virtual ~CFontManager()
{
}
public:
virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true)
{
if (NULL == m_pManager)
return;
double dSize = m_pFont->Size;
double dSizeFont = dSize * ((m_pTransform->m_agg_mtx.sx + m_pTransform->m_agg_mtx.sy) / 2);
m_pFont->Size = dSizeFont;
if (m_pFont->IsEqual2(&m_oFont.m_oFont))
{
m_pFont->Size = dSize;
return;
}
m_oFont.m_oFont = *m_pFont;
m_pFont->Size = dSize;
bool bIsPath = false;
if (_T("") == m_pFont->Path)
{
CFontManagerBase::LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle());
}
else
{
CFontManagerBase::LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, lFaceIndex);
m_pFont->SetStyle(m_oFont.m_oProperties.m_lStyle);
m_oFont.m_oFont.SetStyle(m_oFont.m_oProperties.m_lStyle);
bIsPath = true;
}
CalculateSpace();
}
AVSINLINE void CalculateSpace()
{
LONG lGid = 0;
m_pManager->GetStringGID(&lGid);
m_pManager->SetStringGID(FALSE);
m_pManager->LoadString(L" ", 0, 0);
float _x = 0;
float _y = 0;
float _w = 0;
float _h = 0;
m_pManager->MeasureString2(&_x, &_y, &_w, &_h);
m_dSpaceWidthMM = (double)_w * c_dPixToMM;
if (0 >= m_dSpaceWidthMM)
{
m_dSpaceWidthMM = 1.0;
}
m_pManager->SetStringGID(lGid);
}
};
}
\ No newline at end of file
#pragma once
#include "..\stdafx.h"
#include "TextItem.h"
#include "..\Graphics\Structures.h"
#include "..\Graphics\Matrix.h"
namespace NSFontManager
{
const double c_dInchToMM = 25.4;
const double c_dPixToMM = 25.4 / 72.0;
const double c_dPtToMM = 25.4 / 72.0;
const double c_dMMToPt = 72.0 / 25.4;
const double c_dDpi = 72.0;
class CFontProperties
{
public:
CString m_strFamilyName;
CString m_strPANOSE;
LONG m_lStyle;
CAtlArray<DWORD> m_arSignature;
bool m_bIsFixedWidth;
LONG m_lAvgWidth;
public:
CFontProperties()
{
m_strFamilyName = _T("");
m_strPANOSE = _T("");
m_lStyle = 0;
m_arSignature.RemoveAll();
m_bIsFixedWidth = false;
m_lAvgWidth = -1;
}
CFontProperties(const CFontProperties& oSrc)
{
*this = oSrc;
}
CFontProperties& operator=(const CFontProperties& oSrc)
{
m_strFamilyName = oSrc.m_strFamilyName;
m_strPANOSE = oSrc.m_strPANOSE;
m_lStyle = oSrc.m_lStyle;
m_arSignature.Copy(oSrc.m_arSignature);
m_bIsFixedWidth = oSrc.m_bIsFixedWidth;
m_lAvgWidth = oSrc.m_lAvgWidth;
return *this;
}
~CFontProperties()
{
}
};
class CFontAdvanced
{
public:
NSStructures::CFont m_oFont;
// font metrics
double m_dAscent;
double m_dDescent;
double m_dLineSpacing;
double m_dEmHeight;
double m_dBaselineOffsetDOCX;
double m_dBaselineOffsetHTML;
double m_dSpaceWidthMM;
// font params
CFontProperties m_oProperties;
public:
CFontAdvanced(): m_oProperties()
{
m_oFont.SetDefaultParams();
m_dAscent = 0;
m_dDescent = 0;
m_dLineSpacing = 0;
m_dEmHeight = 0;
m_dBaselineOffsetDOCX = 0;
m_dBaselineOffsetHTML = 0;
m_dSpaceWidthMM = 0;
}
CFontAdvanced(const CFontAdvanced& oSrc)
{
*this = oSrc;
}
CFontAdvanced& operator=(const CFontAdvanced& oSrc)
{
m_oFont = oSrc.m_oFont;
m_dAscent = oSrc.m_dAscent;
m_dDescent = oSrc.m_dDescent;
m_dLineSpacing = oSrc.m_dLineSpacing;
m_dEmHeight = oSrc.m_dEmHeight;
m_dBaselineOffsetDOCX = oSrc.m_dBaselineOffsetDOCX;
m_dBaselineOffsetHTML = oSrc.m_dBaselineOffsetHTML;
m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
m_oProperties = oSrc.m_oProperties;
return *this;
}
};
class CFontPickUp
{
public:
CFontAdvanced m_oFont;
BYTE m_lRangeNum;
BYTE m_lRange;
CString m_strPickFont;
LONG m_lPickStyle;
public:
CFontPickUp() : m_oFont()
{
m_lRangeNum = 0xFF;
m_lRange = 0xFF;
m_strPickFont = _T("");
m_lPickStyle = 0;
}
CFontPickUp(const CFontPickUp& oSrc)
{
*this = oSrc;
}
CFontPickUp& operator=(const CFontPickUp& oSrc)
{
m_oFont = oSrc.m_oFont;
m_lRange = oSrc.m_lRange;
m_lRangeNum = oSrc.m_lRangeNum;
m_strPickFont = oSrc.m_strPickFont;
m_lPickStyle = oSrc.m_lPickStyle;
return *this;
}
};
class CFontManagerBase
{
public:
enum MeasureType
{
MeasureTypeGlyph = 0,
MeasureTypePosition = 1
};
protected:
Graphics::IASCWinFonts* m_pWinFonts;
Graphics::IASCFontManager* m_pManager;
CString m_strDefaultFont;
public:
CFontAdvanced m_oFont;
//для подбора шрифтов
BYTE m_pRanges[0xFFFF];
BYTE m_pRangesNums[0xFFFF];
BYTE m_mapUnicode[0xFFFF];
CAtlMap<CString, CFontProperties> m_mapFontPathToProperties;
CFontProperties* m_pCurrentProperties;
CAtlList<CFontPickUp> m_arListPicUps;
CString m_strCurrentPickFont;
LONG m_lCurrentPictFontStyle;
bool m_bIsUseFontWidth;
public:
CFontManagerBase() : m_oFont(), m_mapFontPathToProperties()
{
m_pManager = NULL;
CoCreateInstance(Graphics::CLSID_CASCFontManager, NULL, CLSCTX_ALL, Graphics::IID_IASCFontManager, (void**)&m_pManager);
m_pManager->Initialize(L"");
SetDefaultFont(_T("Arial"));
ClearPickUps();
InitializeRanges();
InitializeUnicodeMap();
ClearPickUps();
m_pCurrentProperties = NULL;
m_bIsUseFontWidth = false;
}
virtual ~CFontManagerBase()
{
RELEASEINTERFACE(m_pManager);
}
AVSINLINE void ClearPickUps()
{
m_arListPicUps.RemoveAll();
m_strCurrentPickFont = _T("");
m_lCurrentPictFontStyle = 0;
}
public:
AVSINLINE void SetDefaultFont(const CString& strName)
{
m_strDefaultFont = strName;
BSTR bsDefault = m_strDefaultFont.AllocSysString();
m_pManager->SetDefaultFont(bsDefault);
SysFreeString(bsDefault);
}
AVSINLINE CString GetDefaultFont()
{
return m_strDefaultFont;
}
virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true)
{
}
AVSINLINE void LoadCurrentFont(long lFaceIndex = 0)
{
if (_T("") == m_oFont.m_oFont.Path)
{
LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle());
}
else
{
LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, lFaceIndex);
m_oFont.m_oFont.SetStyle(m_oFont.m_oProperties.m_lStyle);
}
}
void LoadFontByName(CString& strName, const double& dSize, const LONG& lStyle)
{
BSTR bsName = strName.AllocSysString();
m_pManager->LoadFontByName(bsName, (float)dSize, lStyle, c_dDpi, c_dDpi);
SysFreeString(bsName);
LoadFontMetrics();
m_oFont.m_oProperties.m_strFamilyName = m_oFont.m_oFont.Name;
m_oFont.m_oProperties.m_lStyle = m_oFont.m_oFont.GetStyle();
m_strCurrentPickFont = m_oFont.m_oProperties.m_strFamilyName;
m_lCurrentPictFontStyle = m_oFont.m_oProperties.m_lStyle;
m_oFont.m_oProperties.m_lAvgWidth = -1;
}
void LoadFontByFile(CString& strPath, const double& dSize, const LONG& lFaceIndex)
{
BSTR bsPath = strPath.AllocSysString();
m_pManager->LoadFontFromFile(bsPath, (float)dSize, c_dDpi, c_dDpi, lFaceIndex);
SysFreeString(bsPath);
m_oFont.m_oProperties.m_strFamilyName = m_oFont.m_oFont.Name;
m_oFont.m_oProperties.m_lStyle = m_oFont.m_oFont.GetStyle();
m_strCurrentPickFont = m_oFont.m_oProperties.m_strFamilyName;
m_lCurrentPictFontStyle = m_oFont.m_oProperties.m_lStyle;
m_oFont.m_oProperties.m_lAvgWidth = -1;
LoadFontMetrics();
LoadFontParams();
}
public:
AVSINLINE void MeasureString(const CString& strText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
{
BSTR bsText = strText.AllocSysString();
MeasureString(bsText, x, y, dBoxX, dBoxY, dBoxWidth, dBoxHeight, measureType);
SysFreeString(bsText);
}
AVSINLINE void MeasureString(BSTR bsText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
{
dBoxX = 0;
dBoxY = 0;
dBoxWidth = 0;
dBoxHeight = 0;
if (NULL == m_pManager)
return;
m_pManager->LoadString(bsText, (float)x, (float)y);
float fx = 0;
float fy = 0;
float fwidth = 0;
float fheight = 0;
if (MeasureTypeGlyph == measureType)
{
m_pManager->MeasureString(&fx, &fy, &fwidth, &fheight);
}
else if (MeasureTypePosition == measureType)
{
m_pManager->MeasureString2(&fx, &fy, &fwidth, &fheight);
}
dBoxX = (double)fx;
dBoxY = (double)fy;
dBoxWidth = (double)fwidth;
dBoxHeight = (double)fheight;
// переводим в миллиметры
dBoxX *= c_dPixToMM;
dBoxY *= c_dPixToMM;
dBoxWidth *= c_dPixToMM;
dBoxHeight *= c_dPixToMM;
}
AVSINLINE void MeasureStringPix(const CString& strText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
{
BSTR bsText = strText.AllocSysString();
MeasureString(bsText, x, y, dBoxX, dBoxY, dBoxWidth, dBoxHeight, measureType);
SysFreeString(bsText);
}
AVSINLINE void MeasureStringPix(BSTR bsText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType)
{
dBoxX = 0;
dBoxY = 0;
dBoxWidth = 0;
dBoxHeight = 0;
if (NULL == m_pManager)
return;
m_pManager->LoadString(bsText, (float)x, (float)y);
float fx = 0;
float fy = 0;
float fwidth = 0;
float fheight = 0;
if (MeasureTypeGlyph == measureType)
{
m_pManager->MeasureString(&fx, &fy, &fwidth, &fheight);
}
else if (MeasureTypePosition == measureType)
{
m_pManager->MeasureString2(&fx, &fy, &fwidth, &fheight);
}
dBoxX = (double)fx;
dBoxY = (double)fy;
dBoxWidth = (double)fwidth;
dBoxHeight = (double)fheight;
}
public:
void LoadFontMetrics()
{
unsigned short iTemp = 0;
m_pManager->GetCellAscent(&iTemp);
m_oFont.m_dAscent = iTemp;
m_pManager->GetCellDescent(&iTemp);
m_oFont.m_dDescent = iTemp;
m_pManager->GetLineSpacing(&iTemp);
m_oFont.m_dLineSpacing = iTemp;
m_pManager->GetEmHeight(&iTemp);
m_oFont.m_dEmHeight = iTemp;
m_oFont.m_dBaselineOffsetDOCX = (c_dPtToMM * m_oFont.m_dDescent * m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent;
d1 /= 2.0;
d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight);
m_oFont.m_dBaselineOffsetHTML = d1;
}
void LoadFontParams()
{
// читаем и выставляем все настройки шрифта
if (NULL == m_pManager)
return;
// загрузка была из path
CAtlMap<CString, CFontProperties>::CPair* pPair = m_mapFontPathToProperties.Lookup(m_oFont.m_oFont.Path);
if (NULL != pPair)
{
m_oFont.m_oProperties = pPair->m_value;
return;
}
if (_T("") == m_oFont.m_oFont.Name)
{
// FamilyName
BSTR bsFamilyName = NULL;
m_pManager->GetFamilyNameEx(_bstr_t("<DeletePDFPrefix/>"), &bsFamilyName);
m_oFont.m_oProperties.m_strFamilyName = (CString)bsFamilyName;
SysFreeString(bsFamilyName);
}
else
{
m_oFont.m_oProperties.m_strFamilyName = m_oFont.m_oFont.Name;
}
// StyleName
BSTR bsStyleName = NULL;
m_pManager->GetStyleName(&bsStyleName);
CString strStyle = (CString)bsStyleName;
SysFreeString(bsStyleName);
if (_T("Bold") == strStyle)
{
m_oFont.m_oProperties.m_lStyle = 0x01;
}
else if (_T("Italic") == strStyle)
{
m_oFont.m_oProperties.m_lStyle = 0x02;
}
else if (_T("Bold Italic") == strStyle)
{
m_oFont.m_oProperties.m_lStyle = 0x03;
}
else
{
m_oFont.m_oProperties.m_lStyle = 0x00;
}
Graphics::IASCFontManager2* pManager2 = NULL;
m_pManager->QueryInterface(Graphics::IID_IASCFontManager2, (void**)&pManager2);
BSTR bsPanose = NULL;
if (NULL != pManager2)
{
pManager2->GetPanose2(&bsPanose);
RELEASEINTERFACE(pManager2);
}
if (NULL != bsPanose)
{
m_oFont.m_oProperties.m_strPANOSE = (CString)bsPanose;
SysFreeString(bsPanose);
}
else
{
m_oFont.m_oProperties.m_strPANOSE = _T("");
}
// IsFixed
LONG lIsFixedWidthLong = 0;
m_pManager->IsFixedWidth(&lIsFixedWidthLong);
m_oFont.m_oProperties.m_bIsFixedWidth = (lIsFixedWidthLong != 0) ? true : false;
// Signature
VARIANT_BOOL vbSuccess = VARIANT_FALSE;
m_oFont.m_oProperties.m_arSignature.RemoveAll();
for ( unsigned int i = 0; i < 6; i++ )
{
DWORD value = 0;
for ( unsigned long bit = 0; bit < 32; bit++ )
{
m_pManager->IsUnicodeRangeAvailable( bit, i, &vbSuccess );
if( VARIANT_TRUE == vbSuccess )
{
value |= ( 1 << bit );
}
}
m_oFont.m_oProperties.m_arSignature.Add(value);
}
if (m_bIsUseFontWidth)
{
wchar_t wsDrive[MAX_PATH], wsDir[MAX_PATH], wsFilename[MAX_PATH], wsExt[MAX_PATH];
_wsplitpath( m_oFont.m_oFont.Path.GetBuffer(), wsDrive, wsDir, wsFilename, wsExt );
CString wsEncodingPath = CString(wsDrive) + CString(wsDir) + CString(wsFilename) + CString(_T(".enc"));
bool bIsCID = false;
CString strExt(wsExt);
if (-1 != strExt.Find(_T("cid")))
bIsCID = true;
XmlUtils::CXmlNode oMainNode;
oMainNode.FromXmlFile(wsEncodingPath);
if (_T("PDF-resources") == oMainNode.GetName())
{
if (bIsCID)
{
XmlUtils::CXmlNode oType0Node;
if ( oMainNode.GetNode( _T("Type0"), oType0Node ) )
{
XmlUtils::CXmlNode oNode;
if ( oType0Node.GetNode( _T("DescendantFonts"), oNode ) )
{
XmlUtils::CXmlNode oDescNode;
if ( oNode.GetNode( _T("FontDescriptor"), oDescNode ) )
{
XmlUtils::CXmlNode oCurNode;
if ( oNode.GetNode( _T("AvgWidth"), oCurNode ) )
{
CString sValue = oCurNode.GetAttribute( _T("value") );
m_oFont.m_oProperties.m_lAvgWidth = XmlUtils::GetInteger( sValue );
}
}
}
}
}
else
{
XmlUtils::CXmlNode oNode;
if ( oMainNode.GetNode( _T("FontDescriptor"), oNode ) )
{
XmlUtils::CXmlNode oCurNode;
if ( oNode.GetNode( _T("AvgWidth"), oCurNode ) )
{
CString sValue = oCurNode.GetAttribute( _T("value") );
m_oFont.m_oProperties.m_lAvgWidth = XmlUtils::GetInteger( sValue );
}
else
{
XmlUtils::CXmlNode oNodeWidths;
if (oMainNode.GetNode(_T("Widths"), oNodeWidths))
{
LONG lCount = 0;
double dWidth = 0;
XmlUtils::CXmlNodes oNodesW;
if (oNodeWidths.GetNodes(_T("Width"), oNodesW))
{
int nCountW = oNodesW.GetCount();
for (int i = 0; i < nCountW; ++i)
{
XmlUtils::CXmlNode oNodeMem;
oNodesW.GetAt(i, oNodeMem);
double dMem = XmlUtils::GetDouble(oNodeMem.GetAttribute(_T("value")));
if (0 < dMem)
{
++lCount;
dWidth += dMem;
}
}
}
if (10 < lCount)
{
m_oFont.m_oProperties.m_lAvgWidth = (LONG)(0.8 * dWidth / lCount);
}
}
}
}
}
}
}
m_mapFontPathToProperties.SetAt(m_oFont.m_oFont.Path, m_oFont.m_oProperties);
}
private:
void InitializeRanges()
{
memset(m_pRanges, 0xFF, 0xFFFF);
memset(m_pRangesNums, 0xFF, 0xFFFF);
// теперь просто по порядку заполняем все рэнджи
int nStart = 0;
int nCount = 0;
// rangeNum 0
// case 00: sUCRName = "Basic Latin"; break; /* U+0020-U+007E */
nStart = 0x0020;
nCount = 0x007E - nStart + 1;
memset(m_pRanges + nStart, 0, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 01: sUCRName = "Latin-1 Supplement"; break; /* U+0080-U+00FF */
nStart = 0x0080;
nCount = 0x00FF - nStart + 1;
memset(m_pRanges + nStart, 1, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 02: sUCRName = "Latin Extended-A"; break; /* U+0100-U+017F */
nStart = 0x0100;
nCount = 0x017F - nStart + 1;
memset(m_pRanges + nStart, 2, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 03: sUCRName = "Latin Extended-B"; break; /* U+0180-U+024F */
nStart = 0x0180;
nCount = 0x024F - nStart + 1;
memset(m_pRanges + nStart, 3, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 04: sUCRName = "IPA Extensions"; break; /* U+0250-U+02AF */ /* U+1D00-U+1D7F */ /* U+1D80-U+1DBF */
nStart = 0x0250;
nCount = 0x02AF - nStart + 1;
memset(m_pRanges + nStart, 4, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x1D00;
nCount = 0x1D7F - nStart + 1;
memset(m_pRanges + nStart, 4, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x1D80;
nCount = 0x1DBF - nStart + 1;
memset(m_pRanges + nStart, 4, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 05: sUCRName = "Spacing Modifier Letters"; break; /* U+02B0-U+02FF */ /* U+A700-U+A71F */
nStart = 0x02B0;
nCount = 0x02FF - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0xA700;
nCount = 0xA71F - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 06: sUCRName = "Combining Diacritical Marks"; break; /* U+0300-U+036F */ /* U+1DC0-U+1DFF */
nStart = 0x0300;
nCount = 0x036F - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x1DC0;
nCount = 0x1DFF - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 07: sUCRName = "Greek and Coptic"; break; /* U+0370-U+03FF */
nStart = 0x0370;
nCount = 0x03FF - nStart + 1;
memset(m_pRanges + nStart, 7, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 08: sUCRName = "Coptic"; break; /* U+2C80-U+2CFF */
nStart = 0x2C80;
nCount = 0x2CFF - nStart + 1;
memset(m_pRanges + nStart, 8, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 09: sUCRName = "Cyrillic"; break; /* U+0400-U+04FF */ /* U+0500-U+052F */ /* U+2DE0-U+2DFF */ /* U+A640-U+A69F */
nStart = 0x0400;
nCount = 0x04FF - nStart + 1;
memset(m_pRanges + nStart, 9, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x0500;
nCount = 0x052F - nStart + 1;
memset(m_pRanges + nStart, 9, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x2DE0;
nCount = 0x2DFF - nStart + 1;
memset(m_pRanges + nStart, 9, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0xA640;
nCount = 0xA69F - nStart + 1;
memset(m_pRanges + nStart, 9, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 10: sUCRName = "Armenian"; break; /* U+0530-U+058F */
nStart = 0x0530;
nCount = 0x058F - nStart + 1;
memset(m_pRanges + nStart, 10, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 11: sUCRName = "Hebrew"; break; /* U+0590-U+05FF */
nStart = 0x0590;
nCount = 0x05FF - nStart + 1;
memset(m_pRanges + nStart, 11, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 12: sUCRName = "Vai"; break; /* U+A500-U+A63F */
nStart = 0xA500;
nCount = 0xA63F - nStart + 1;
memset(m_pRanges + nStart, 12, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 13: sUCRName = "Arabic"; break; /* U+0600-U+06FF */ /* U+0750-U+077F */
nStart = 0x0600;
nCount = 0x06FF - nStart + 1;
memset(m_pRanges + nStart, 13, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x0750;
nCount = 0x077F - nStart + 1;
memset(m_pRanges + nStart, 13, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 14: sUCRName = "NKo"; break; /* U+07C0-U+07FF */
nStart = 0x07C0;
nCount = 0x07FF - nStart + 1;
memset(m_pRanges + nStart, 14, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 15: sUCRName = "Devanagari"; break; /* U+0900-U+097F */
nStart = 0x0900;
nCount = 0x097F - nStart + 1;
memset(m_pRanges + nStart, 15, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 16: sUCRName = "Bengali"; break; /* U+0980-U+09FF */
nStart = 0x0980;
nCount = 0x09FF - nStart + 1;
memset(m_pRanges + nStart, 16, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 17: sUCRName = "Gurmukhi"; break; /* U+0A00-U+0A7F */
nStart = 0x0A00;
nCount = 0x0A7F - nStart + 1;
memset(m_pRanges + nStart, 17, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 18: sUCRName = "Gujarati"; break; /* U+0A80-U+0AFF */
nStart = 0x0A80;
nCount = 0x0AFF - nStart + 1;
memset(m_pRanges + nStart, 18, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 19: sUCRName = "Oriya"; break; /* U+0B00-U+0B7F */
nStart = 0x0B00;
nCount = 0x0B7F - nStart + 1;
memset(m_pRanges + nStart, 19, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 20: sUCRName = "Tamil"; break; /* U+0B80-U+0BFF */
nStart = 0x0B80;
nCount = 0x0BFF - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 21: sUCRName = "Telugu"; break; /* U+0C00-U+0C7F */
nStart = 0x0C00;
nCount = 0x0C7F - nStart + 1;
memset(m_pRanges + nStart, 21, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 22: sUCRName = "Kannada"; break; /* U+0C80-U+0CFF */
nStart = 0x0C80;
nCount = 0x0CFF - nStart + 1;
memset(m_pRanges + nStart, 22, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 23: sUCRName = "Malayalam"; break; /* U+0D00-U+0D7F */
nStart = 0x0D00;
nCount = 0x0D7F - nStart + 1;
memset(m_pRanges + nStart, 23, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 24: sUCRName = "Thai"; break; /* U+0E00-U+0E7F */
nStart = 0x0E00;
nCount = 0x0E7F - nStart + 1;
memset(m_pRanges + nStart, 24, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 25: sUCRName = "Lao"; break; /* U+0E80-U+0EFF */
nStart = 0x0E80;
nCount = 0x0EFF - nStart + 1;
memset(m_pRanges + nStart, 25, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 26: sUCRName = "Georgian"; break; /* U+10A0-U+10FF */ /* U+2D00-U+2D2F */
nStart = 0x10A0;
nCount = 0x10FF - nStart + 1;
memset(m_pRanges + nStart, 26, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x2D00;
nCount = 0x2D2F - nStart + 1;
memset(m_pRanges + nStart, 26, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 27: sUCRName = "Balinese"; break; /* U+1B00-U+1B7F */
nStart = 0x1B00;
nCount = 0x1B7F - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 28: sUCRName = "Hangul Jamo"; break; /* U+1100-U+11FF */
nStart = 0x1100;
nCount = 0x11FF - nStart + 1;
memset(m_pRanges + nStart, 28, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 29: sUCRName = "Latin Extended Additional"; break; /* U+1E00-U+1EFF */ /* U+2C60-U+2C7F */ /* U+A720-U+A7FF */
nStart = 0x1E00;
nCount = 0x1EFF - nStart + 1;
memset(m_pRanges + nStart, 29, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x2C60;
nCount = 0x2C7F - nStart + 1;
memset(m_pRanges + nStart, 29, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0xA720;
nCount = 0xA7FF - nStart + 1;
memset(m_pRanges + nStart, 29, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 30: sUCRName = "Greek Extended"; break; /* U+1F00-U+1FFF */
nStart = 0x1F00;
nCount = 0x1FFF - nStart + 1;
memset(m_pRanges + nStart, 30, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
//case 31: sUCRName = "General Punctuation"; break; /* U+2000-U+206F */ /* U+2E00-U+2E7F */
nStart = 0x2000;
nCount = 0x206F - nStart + 1;
memset(m_pRanges + nStart, 31, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
nStart = 0x2E00;
nCount = 0x2E7F - nStart + 1;
memset(m_pRanges + nStart, 31, nCount);
memset(m_pRangesNums + nStart, 0, nCount);
// rangeNum 1
//case 00: sUCRName = "Superscripts And Subscripts"; break; /* U+2070-U+209F */
nStart = 0x2070;
nCount = 0x209F - nStart + 1;
memset(m_pRanges + nStart, 0, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 01: sUCRName = "Currency Symbols"; break; /* U+20A0-U+20CF */
nStart = 0x20A0;
nCount = 0x20CF - nStart + 1;
memset(m_pRanges + nStart, 1, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 02: sUCRName = "Combining Diacritical Marks For Symbols"; break; /* U+20D0-U+20FF */
nStart = 0x20D0;
nCount = 0x20FF - nStart + 1;
memset(m_pRanges + nStart, 2, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 03: sUCRName = "Letterlike Symbols"; break; /* U+2100-U+214F */
nStart = 0x2100;
nCount = 0x214F - nStart + 1;
memset(m_pRanges + nStart, 3, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 04: sUCRName = "Number Forms"; break; /* U+2150-U+218F */
nStart = 0x2150;
nCount = 0x218F - nStart + 1;
memset(m_pRanges + nStart, 4, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 05: sUCRName = "Arrows"; break; /* U+2190-U+21FF */ /* U+27F0-U+27FF */ /* U+2900-U+297F */ /* U+2B00-U+2BFF */
nStart = 0x2190;
nCount = 0x21FF - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x27F0;
nCount = 0x27FF - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2900;
nCount = 0x297F - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2B00;
nCount = 0x2BFF - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 06: sUCRName = "Mathematical Operators"; break; /* U+2200-U+22FF */ /* U+2A00-U+2AFF */ /* U+27C0-U+27EF */ /* U+2980-U+29FF */
nStart = 0x2200;
nCount = 0x22FF - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2A00;
nCount = 0x2AFF - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x27C0;
nCount = 0x27EF - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2980;
nCount = 0x29FF - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 07: sUCRName = "Miscellaneous Technical"; break; /* U+2300-U+23FF */
nStart = 0x2300;
nCount = 0x23FF - nStart + 1;
memset(m_pRanges + nStart, 7, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 08: sUCRName = "Control Pictures"; break; /* U+2400-U+243F */
nStart = 0x2400;
nCount = 0x243F - nStart + 1;
memset(m_pRanges + nStart, 8, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 09: sUCRName = "Optical Character Recognition"; break; /* U+2440-U+245F */
nStart = 0x2440;
nCount = 0x245F - nStart + 1;
memset(m_pRanges + nStart, 9, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 10: sUCRName = "Enclosed Alphanumerics"; break; /* U+2460-U+24FF */
nStart = 0x2460;
nCount = 0x24FF - nStart + 1;
memset(m_pRanges + nStart, 10, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 11: sUCRName = "Box Drawing"; break; /* U+2500-U+257F */
nStart = 0x2500;
nCount = 0x257F - nStart + 1;
memset(m_pRanges + nStart, 11, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 12: sUCRName = "Block Elements"; break; /* U+2580-U+259F */
nStart = 0x2580;
nCount = 0x259F - nStart + 1;
memset(m_pRanges + nStart, 12, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 13: sUCRName = "Geometric Shapes"; break; /* U+25A0-U+25FF */
nStart = 0x25A0;
nCount = 0x25FF - nStart + 1;
memset(m_pRanges + nStart, 13, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 14: sUCRName = "Miscellaneous Symbols"; break; /* U+2600-U+26FF */
nStart = 0x2600;
nCount = 0x26FF - nStart + 1;
memset(m_pRanges + nStart, 14, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 15: sUCRName = "Dingbats"; break; /* U+2700-U+27BF */
nStart = 0x2700;
nCount = 0x27BF - nStart + 1;
memset(m_pRanges + nStart, 15, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 16: sUCRName = "CJK Symbols and Punctuation"; break; /* U+3000-U+303F */
nStart = 0x3000;
nCount = 0x303F - nStart + 1;
memset(m_pRanges + nStart, 16, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 17: sUCRName = "Hiragana"; break; /* U+3040-U+309F */
nStart = 0x3040;
nCount = 0x309F - nStart + 1;
memset(m_pRanges + nStart, 17, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 18: sUCRName = "Katakana"; break; /* U+30A0-U+30FF */ /* U+31F0-U+31FF */
nStart = 0x30A0;
nCount = 0x30FF - nStart + 1;
memset(m_pRanges + nStart, 18, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x31F0;
nCount = 0x31FF - nStart + 1;
memset(m_pRanges + nStart, 18, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 19: sUCRName = "Bopomofo"; break; /* U+3100-U+312F */ /* U+31A0-U+31BF */
nStart = 0x3100;
nCount = 0x312F - nStart + 1;
memset(m_pRanges + nStart, 19, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x31A0;
nCount = 0x31BF - nStart + 1;
memset(m_pRanges + nStart, 19, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 20: sUCRName = "Hangul Compatibility Jamo"; break; /* U+3130-U+318F */
nStart = 0x3130;
nCount = 0x318F - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 21: sUCRName = "Phags-pa"; break; /* U+A840-U+A87F */
nStart = 0xA840;
nCount = 0xA87F - nStart + 1;
memset(m_pRanges + nStart, 21, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 22: sUCRName = "Enclosed CJK Letters and Months"; break; /* U+3200-U+32FF */
nStart = 0x3200;
nCount = 0x32FF - nStart + 1;
memset(m_pRanges + nStart, 22, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 23: sUCRName = "CJK Compatibility"; break; /* U+3300-U+33FF */
nStart = 0x3300;
nCount = 0x33FF - nStart + 1;
memset(m_pRanges + nStart, 23, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 24: sUCRName = "Hangul Syllables"; break; /* U+AC00-U+D7AF */
nStart = 0xAC00;
nCount = 0xD7AF - nStart + 1;
memset(m_pRanges + nStart, 24, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 25: sUCRName = "Non-Plane 0"; break; /* U+D800-U+DB7F */ /* U+DB80-U+DBFF */ /* U+DC00-U+DFFF */ // Не юникодные символы
nStart = 0xD800;
nCount = 0xDB7F - nStart + 1;
memset(m_pRanges + nStart, 25, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0xDB80;
nCount = 0xDBFF - nStart + 1;
memset(m_pRanges + nStart, 25, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0xDC00;
nCount = 0xDFFF - nStart + 1;
memset(m_pRanges + nStart, 25, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 26: sUCRName = "Phoenician"; break; /*U+10900-U+1091F*/
//case 27: sUCRName = "CJK Unified Ideographs"; break; /* U+4E00-U+9FFF */ /* U+2E80-U+2EFF */ /* U+2F00-U+2FDF */ /* U+2FF0-U+2FFF */ /* U+3400-U+4DB5 */ /*U+20000-U+2A6D6*/ /* U+3190-U+319F */
nStart = 0x4E00;
nCount = 0x9FFF - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2E80;
nCount = 0x2EFF - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2F00;
nCount = 0x2FDF - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x2FF0;
nCount = 0x2FFF - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x3400;
nCount = 0x4DB5 - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0x3190;
nCount = 0x319F - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 28: sUCRName = "Private Use Area (plane 0)"; break; /* U+E000-U+F8FF */ // Не юникодные символы
nStart = 0xE000;
nCount = 0xF8FF - nStart + 1;
memset(m_pRanges + nStart, 28, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 29: sUCRName = "CJK Strokes"; break; /* U+31C0-U+31EF */ /* U+F900-U+FAFF */ /*U+2F800-U+2FA1F*/
nStart = 0x31C0;
nCount = 0x31EF - nStart + 1;
memset(m_pRanges + nStart, 29, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
nStart = 0xF900;
nCount = 0xFAFF - nStart + 1;
memset(m_pRanges + nStart, 29, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 30: sUCRName = "Alphabetic Presentation Forms"; break; /* U+FB00-U+FB4F */
nStart = 0xFB00;
nCount = 0xFB4F - nStart + 1;
memset(m_pRanges + nStart, 30, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
//case 31: sUCRName = "Arabic Presentation Forms-A"; break; /* U+FB50-U+FDFF */
nStart = 0xFB50;
nCount = 0xFDFF - nStart + 1;
memset(m_pRanges + nStart, 31, nCount);
memset(m_pRangesNums + nStart, 1, nCount);
// rangeNum 2
//case 00: sUCRName = "Combining Half Marks"; break; /* U+FE20-U+FE2F */
nStart = 0xFE20;
nCount = 0xFE2F - nStart + 1;
memset(m_pRanges + nStart, 0, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 01: sUCRName = "Vertical forms"; break; /* U+FE10-U+FE1F */ /* U+FE30-U+FE4F */
nStart = 0xFE10;
nCount = 0xFE1F - nStart + 1;
memset(m_pRanges + nStart, 1, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0xFE30;
nCount = 0xFE4F - nStart + 1;
memset(m_pRanges + nStart, 1, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 02: sUCRName = "Small Form Variants"; break; /* U+FE50-U+FE6F */
nStart = 0xFE50;
nCount = 0xFE6F - nStart + 1;
memset(m_pRanges + nStart, 2, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 03: sUCRName = "Arabic Presentation Forms-B"; break; /* U+FE70-U+FEFE */
nStart = 0xFE70;
nCount = 0xFEFE - nStart + 1;
memset(m_pRanges + nStart, 3, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 04: sUCRName = "Halfwidth and Fullwidth Forms"; break; /* U+FF00-U+FFEF */
nStart = 0xFF00;
nCount = 0xFFEF - nStart + 1;
memset(m_pRanges + nStart, 4, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 05: sUCRName = "Specials"; break; /* U+FFF0-U+FFFF */
nStart = 0xFFF0;
nCount = 0xFFFF - nStart + 1;
memset(m_pRanges + nStart, 5, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 06: sUCRName = "Tibetan"; break; /* U+0F00-U+0FFF */
nStart = 0x0F00;
nCount = 0x0FFF - nStart + 1;
memset(m_pRanges + nStart, 6, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 07: sUCRName = "Syriac"; break; /* U+0700-U+074F */
nStart = 0x0700;
nCount = 0x074F - nStart + 1;
memset(m_pRanges + nStart, 7, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 08: sUCRName = "Thaana"; break; /* U+0780-U+07BF */
nStart = 0x0780;
nCount = 0x07BF - nStart + 1;
memset(m_pRanges + nStart, 8, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 09: sUCRName = "Sinhala"; break; /* U+0D80-U+0DFF */
nStart = 0x0D80;
nCount = 0x0DFF - nStart + 1;
memset(m_pRanges + nStart, 9, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 10: sUCRName = "Myanmar"; break; /* U+1000-U+109F */
nStart = 0x1000;
nCount = 0x109F - nStart + 1;
memset(m_pRanges + nStart, 10, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 11: sUCRName = "Ethiopic"; break; /* U+1200-U+137F */ /* U+1380-U+139F */ /* U+2D80-U+2DDF */
nStart = 0x1200;
nCount = 0x137F - nStart + 1;
memset(m_pRanges + nStart, 11, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0x1380;
nCount = 0x139F - nStart + 1;
memset(m_pRanges + nStart, 11, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0x2D80;
nCount = 0x2DDF - nStart + 1;
memset(m_pRanges + nStart, 11, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 12: sUCRName = "Cherokee"; break; /* U+13A0-U+13FF */
nStart = 0x13A0;
nCount = 0x13FF - nStart + 1;
memset(m_pRanges + nStart, 12, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 13: sUCRName = "Unified Canadian Aboriginal Syllabics"; break; /* U+1400-U+167F */
nStart = 0x1400;
nCount = 0x167F - nStart + 1;
memset(m_pRanges + nStart, 13, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 14: sUCRName = "Ogham"; break; /* U+1680-U+169F */
nStart = 0x1680;
nCount = 0x169F - nStart + 1;
memset(m_pRanges + nStart, 14, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 15: sUCRName = "Runic"; break; /* U+16A0-U+16FF */
nStart = 0x16A0;
nCount = 0x16FF - nStart + 1;
memset(m_pRanges + nStart, 15, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 16: sUCRName = "Khmer"; break; /* U+1780-U+17FF */ /* U+19E0-U+19FF */
nStart = 0x1780;
nCount = 0x17FF - nStart + 1;
memset(m_pRanges + nStart, 16, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0x19E0;
nCount = 0x19FF - nStart + 1;
memset(m_pRanges + nStart, 16, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 17: sUCRName = "Mongolian"; break; /* U+1800-U+18AF */
nStart = 0x1800;
nCount = 0x18AF - nStart + 1;
memset(m_pRanges + nStart, 17, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 18: sUCRName = "Braille Patterns"; break; /* U+2800-U+28FF */
nStart = 0x2800;
nCount = 0x28FF - nStart + 1;
memset(m_pRanges + nStart, 18, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 19: sUCRName = "Yi Syllables"; break; /* U+A000-U+A48F */ /* U+A490-U+A4CF */
nStart = 0xA000;
nCount = 0xA48F - nStart + 1;
memset(m_pRanges + nStart, 19, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0xA490;
nCount = 0xA4CF - nStart + 1;
memset(m_pRanges + nStart, 19, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 20: sUCRName = "Tagalog"; break; /* U+1700-U+171F */ /* U+1720-U+173F */ /* U+1740-U+175F */ /* U+1760-U+177F */
nStart = 0x1700;
nCount = 0x171F - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0x1720;
nCount = 0x173F - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0x1740;
nCount = 0x175F - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
nStart = 0x1760;
nCount = 0x177F - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 21: sUCRName = "Old Italic"; break; /*U+10300-U+1032F*/
//case 22: sUCRName = "Gothic"; break; /*U+10330-U+1034F*/
//case 23: sUCRName = "Deseret"; break; /*U+10400-U+1044F*/
//case 24: sUCRName = "Byzantine Musical Symbols"; break; /*U+1D000-U+1D0FF*/ /*U+1D100-U+1D1FF*/ /*U+1D200-U+1D24F*/
//case 25: sUCRName = "Mathematical Alphanumeric Symbols"; break; /*U+1D400-U+1D7FF*/
//case 26: sUCRName = "Private Use (plane 15)"; break; /*U+F0000-U+FFFFD*/ /*U+100000-U+10FFFD*/ // Не юникодные символы
//case 27: sUCRName = "Variation Selectors"; break; /* U+FE00-U+FE0F */ /*U+E0100-U+E01EF*/
nStart = 0xFE00;
nCount = 0xFE0F - nStart + 1;
memset(m_pRanges + nStart, 27, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 28: sUCRName = "Tags"; break; /*U+E0000-U+E007F*/
//case 29: sUCRName = "Limbu"; break; /* U+1900-U+194F */
nStart = 0x1900;
nCount = 0x194F - nStart + 1;
memset(m_pRanges + nStart, 29, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 30: sUCRName = "Tai Le"; break; /* U+1950-U+197F */
nStart = 0x1950;
nCount = 0x197F - nStart + 1;
memset(m_pRanges + nStart, 30, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
//case 31: sUCRName = "New Tai Lue"; break; /* U+1980-U+19DF */
nStart = 0x1980;
nCount = 0x19DF - nStart + 1;
memset(m_pRanges + nStart, 31, nCount);
memset(m_pRangesNums + nStart, 2, nCount);
// rangeNum 3
//case 00: sUCRName = "Buginese"; break; /* U+1A00-U+1A1F */
nStart = 0x1A00;
nCount = 0x1A1F - nStart + 1;
memset(m_pRanges + nStart, 0, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 01: sUCRName = "Glagolitic"; break; /* U+2C00-U+2C5F */
nStart = 0x2C00;
nCount = 0x2C5F - nStart + 1;
memset(m_pRanges + nStart, 1, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 02: sUCRName = "Tifinagh"; break; /* U+2D30-U+2D7F */
nStart = 0x2D30;
nCount = 0x2D7F - nStart + 1;
memset(m_pRanges + nStart, 2, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 03: sUCRName = "Yijing Hexagram Symbols"; break; /* U+4DC0-U+4DFF */
nStart = 0x4DC0;
nCount = 0x4DFF - nStart + 1;
memset(m_pRanges + nStart, 3, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 04: sUCRName = "Syloti Nagri"; break; /* U+A800-U+A82F */
nStart = 0xA800;
nCount = 0xA82F - nStart + 1;
memset(m_pRanges + nStart, 4, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 05: sUCRName = "Linear B Syllabary"; break; /*U+10000-U+1007F*/ /*U+10080-U+100FF*/ /*U+10100-U+1013F*/
//case 06: sUCRName = "Ancient Greek Numbers"; break; /*U+10140-U+1018F*/
//case 07: sUCRName = "Ugaritic"; break; /*U+10380-U+1039F*/
//case 08: sUCRName = "Old Persian"; break; /*U+103A0-U+103DF*/
//case 09: sUCRName = "Shavian"; break; /*U+10450-U+1047F*/
//case 10: sUCRName = "Osmanya"; break; /*U+10480-U+104AF*/
//case 11: sUCRName = "Cypriot Syllabary"; break; /*U+10800-U+1083F*/
//case 12: sUCRName = "Kharoshthi"; break; /*U+10A00-U+10A5F*/
//case 13: sUCRName = "Tai Xuan Jing Symbols"; break; /*U+1D300-U+1D35F*/
//case 14: sUCRName = "Cuneiform"; break; /*U+12000-U+123FF*/ /*U+12400-U+1247F*/
//case 15: sUCRName = "Counting Rod Numerals"; break; /*U+1D360-U+1D37F*/
//case 16: sUCRName = "Sundanese"; break; /* U+1B80-U+1BBF */
nStart = 0x1B80;
nCount = 0x1BBF - nStart + 1;
memset(m_pRanges + nStart, 16, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 17: sUCRName = "Lepcha"; break; /* U+1C00-U+1C4F */
nStart = 0x1C00;
nCount = 0x1C4F - nStart + 1;
memset(m_pRanges + nStart, 17, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 18: sUCRName = "Ol Chiki"; break; /* U+1C50-U+1C7F */
nStart = 0x1C50;
nCount = 0x1C7F - nStart + 1;
memset(m_pRanges + nStart, 18, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 19: sUCRName = "Saurashtra"; break; /* U+A880-U+A8DF */
nStart = 0xA880;
nCount = 0xA8DF - nStart + 1;
memset(m_pRanges + nStart, 19, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 20: sUCRName = "Kayah Li"; break; /* U+A900-U+A92F */
nStart = 0xA900;
nCount = 0xA92F - nStart + 1;
memset(m_pRanges + nStart, 20, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 21: sUCRName = "Rejang"; break; /* U+A930-U+A95F */
nStart = 0xA930;
nCount = 0xA95F - nStart + 1;
memset(m_pRanges + nStart, 21, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 22: sUCRName = "Cham"; break; /* U+AA00-U+AA5F */
nStart = 0xAA00;
nCount = 0xAA5F - nStart + 1;
memset(m_pRanges + nStart, 22, nCount);
memset(m_pRangesNums + nStart, 3, nCount);
//case 23: sUCRName = "Ancient Symbols"; break; /*U+10190-U+101CF*/
//case 24: sUCRName = "Phaistos Disc"; break; /*U+101D0-U+101FF*/
//case 25: sUCRName = "Carian"; break; /*U+102A0-U+102DF*/ /*U+10280-U+1029F*/ /*U+10920-U+1093F*/
//case 26: sUCRName = "Domino Tiles"; break; /*U+1F030-U+1F09F*/ /*U+1F000-U+1F02F*/
//case 27: sUCRName = "Reserved for process-internal usage"; break;
//case 28: sUCRName = "Reserved for process-internal usage"; break;
//case 29: sUCRName = "Reserved for process-internal usage"; break;
//case 30: sUCRName = "Reserved for process-internal usage"; break;
//case 31: sUCRName = "Reserved for process-internal usage"; break;
}
AVSINLINE void InitializeUnicodeMap()
{
memset(m_mapUnicode, 0, 0xFFFF);
m_mapUnicode[0x0009] = 1;
m_mapUnicode[0x000A] = 1;
m_mapUnicode[0x000D] = 1;
memset(m_mapUnicode + 0x0020, 1, 0xD7FF - 0x0020 + 1);
memset(m_mapUnicode + 0xE000, 1, 0xFFFD - 0xE000 + 1);
}
AVSINLINE bool GetRange(const WCHAR& symbol, BYTE& lRangeNum, BYTE& lRange)
{
lRangeNum = m_pRangesNums[symbol];
lRange = m_pRanges[symbol];
return (0xFF != lRangeNum);
}
AVSINLINE void CheckRanges(DWORD& lRange1, DWORD& lRange2, DWORD& lRange3, DWORD& lRange4, CString strText)
{
int lCount = strText.GetLength();
WCHAR* pData = strText.GetBuffer();
BYTE lRangeNum = 0xFF;
BYTE lRange = 0xFF;
for (int i = 0; i < lCount; ++i, ++pData)
{
if (GetRange(*pData, lRangeNum, lRange))
{
if (0 == lRangeNum)
lRange1 |= 1 << lRange;
else if (1 == lRangeNum)
lRange2 |= 1 << lRange;
else if (2 == lRangeNum)
lRange3 |= 1 << lRange;
else
lRange4 |= 1 << lRange;
}
}
}
AVSINLINE void CheckRanges(DWORD& lRange1, DWORD& lRange2, DWORD& lRange3, DWORD& lRange4, BYTE& lRangeNum, BYTE& lRange)
{
if (0 == lRangeNum)
lRange1 |= 1 << lRange;
else if (1 == lRangeNum)
lRange2 |= 1 << lRange;
else if (2 == lRangeNum)
lRange3 |= 1 << lRange;
else
lRange4 |= 1 << lRange;
}
public:
AVSINLINE bool GenerateFontName(NSStrings::CTextItem& oTextItem, bool bIsFontChanged)
{
if (_T("") == m_oFont.m_oFont.Path)
return false;
BYTE lRangeNum = 0xFF;
BYTE lRange = 0xFF;
GetRange(oTextItem[0], lRangeNum, lRange);
if (!bIsFontChanged && (0 != m_arListPicUps.GetCount()))
{
CFontPickUp& oPick = m_arListPicUps.GetHead();
if ((lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange))
{
// по идее не надо приравнивать, они должны были быть выставлены ещ раньше
//m_strCurrentPickFont = oPick.m_strPickFont;
//m_lCurrentPictFontStyle = oPick.m_lPickStyle;
return false;
}
}
POSITION posStart = m_arListPicUps.GetHeadPosition();
POSITION pos = posStart;
while (NULL != pos)
{
POSITION posOld = pos;
CFontPickUp& oPick = m_arListPicUps.GetNext(pos);
if ((oPick.m_oFont.m_oFont.IsEqual3(&m_oFont.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange))
{
// нашли! ничего подбирать не нужно
// нужно просто выкинуть этот шрифт наверх
m_arListPicUps.MoveToHead(posOld);
m_strCurrentPickFont = oPick.m_strPickFont;
m_lCurrentPictFontStyle = oPick.m_lPickStyle;
return false;
}
}
// не нашли...
m_arListPicUps.AddHead();
CFontPickUp& oPick = m_arListPicUps.GetHead();
oPick.m_lRangeNum = lRangeNum;
oPick.m_lRange = lRange;
oPick.m_oFont = m_oFont;
oPick.m_strPickFont = m_oFont.m_oProperties.m_strFamilyName;
oPick.m_lPickStyle = m_oFont.m_oProperties.m_lStyle;
Graphics::IASCFontManager2* pManager2 = NULL;
m_pManager->QueryInterface(Graphics::IID_IASCFontManager2, (void**)&pManager2);
BSTR bsFontName = m_oFont.m_oProperties.m_strFamilyName.AllocSysString();
BSTR bsNewFontName = NULL;
LONG lCountSigs = (LONG)m_oFont.m_oProperties.m_arSignature.GetCount();
DWORD dwR1 = 0;
if (0 < lCountSigs)
dwR1 = m_oFont.m_oProperties.m_arSignature[0];
DWORD dwR2 = 0;
if (1 < lCountSigs)
dwR2 = m_oFont.m_oProperties.m_arSignature[1];
DWORD dwR3 = 0;
if (2 < lCountSigs)
dwR3 = m_oFont.m_oProperties.m_arSignature[2];
DWORD dwR4 = 0;
if (3 < lCountSigs)
dwR4 = m_oFont.m_oProperties.m_arSignature[3];
DWORD dwCodePage1 = 0;
DWORD dwCodePage2 = 0;
if ((lRangeNum == 1) && (lRange == 28))
{
dwCodePage1 = 0x80000000;
//strText = (WCHAR)(strText[0] - 0xF000);
}
else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13)))
{
// ебаный арабский язык!!!
dwR1 = 1 << 13;
dwR2 = 1 << 31;
dwR3 = 1 << 3;
}
else
{
CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange);
}
BSTR bsPanose = m_oFont.m_oProperties.m_strPANOSE.AllocSysString();
LONG lFontStyle = m_oFont.m_oFont.GetStyle();
pManager2->GetWinFontByParams2(&bsNewFontName, bsFontName, -1, NULL, &lFontStyle, m_oFont.m_oProperties.m_bIsFixedWidth ? 1 : 0, bsPanose,
dwR1, dwR2, dwR3, dwR4, dwCodePage1, dwCodePage2, m_oFont.m_oProperties.m_lAvgWidth);
oPick.m_strPickFont = (CString)bsNewFontName;
oPick.m_lPickStyle = lFontStyle;
m_strCurrentPickFont = oPick.m_strPickFont;
m_lCurrentPictFontStyle = oPick.m_lPickStyle;
SysFreeString(bsFontName);
SysFreeString(bsPanose);
SysFreeString(bsNewFontName);
RELEASEINTERFACE(pManager2);
return true;
}
AVSINLINE void SetStringGid(const LONG& lGid)
{
if (NULL != m_pManager)
m_pManager->SetStringGID(lGid);
}
AVSINLINE LONG GetStringGid()
{
LONG lGid = 0;
if (NULL != m_pManager)
m_pManager->GetStringGID(&lGid);
return lGid;
}
AVSINLINE wchar_t* GetUnicodeString(BSTR bsText)
{
wchar_t* start = (wchar_t*)bsText;
wchar_t* s = start;
for (; *s != 0; ++s);
LONG lLen = (LONG)(s - start);
wchar_t* pData = new wchar_t[lLen + 1];
for (LONG i = 0; i < lLen; ++i, ++start)
{
if (m_mapUnicode[*start])
pData[i] = *start;
else
pData[i] = (wchar_t)(' ');
}
return pData;
}
CString GetFontPath(NSStructures::CFont* pFont)
{
CString strXml = _T("<FontProperties><Name value=\"") + pFont->Name + _T("\"/>");
CString strStyle = _T("");
strStyle.Format(_T("<Style bold=\"%d\" italic=\"%d\"/>"), pFont->Bold ? 1 : 0, pFont->Italic ? 1 : 0);
strXml += strStyle;
strXml += _T("</FontProperties>");
BSTR bsResult = NULL;
LONG lFontIndex = NULL;
BSTR bsInput = strXml.AllocSysString();
m_pManager->GetWinFontByParams(bsInput, &bsResult, &lFontIndex);
CString strPath = (CString)bsResult;
SysFreeString(bsInput);
SysFreeString(bsResult);
return strPath;
}
};
}
\ No newline at end of file
#include "../include/HTMLRenderer.h"
#include "./Common.h"
// TEST
#include "VectorGraphicsWriter2.h"
#include "CanvasWriter.h"
#include "SVGWriter2.h"
class CASCHTMLRenderer_Private
{
public:
};
#include "../include/HTMLRenderer2.h"
#include "./Common.h"
#include "../include/HTMLRenderer3.h"
#include "./Common.h"
#ifndef _ASC_HTMLRENDERER_SVGWRITER_H_
#define _ASC_HTMLRENDERER_SVGWRITER_H_
#include "Common.h"
#include <vector>
#include "../../../DesktopEditor/graphics/GraphicsPath.h"
namespace NSHtmlRenderer
{
class CClipSVG
{
public:
std::vector<std::wstring> m_arPaths;
std::vector<LONG> m_arTypes;
LONG m_lWidth;
LONG m_lHeight;
CClipSVG() : m_arPaths(), m_arTypes()
{
m_lWidth = 0;
m_lHeight = 0;
}
~CClipSVG()
{
}
void Write(NSStringUtils::CStringBuilder& oWriter, LONG& lCurrentClipPath)
{
// сначала запишем все пути
size_t nCount = m_arPaths.size();
for (size_t i = 0; i < nCount; ++i)
{
oWriter.WriteString(L"<clipPath id=\"clip", 18);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\"><path id=\"path", 16);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\" d=\"", 5);
oWriter.WriteString(m_arPaths[i]);
if (c_nClipRegionTypeWinding == m_arTypes[i])
oWriter.WriteString(L"\" clip-rule=\"nonzero\" /></clipPath>", 35);
else
oWriter.WriteString(L"\" clip-rule=\"evenodd\" /></clipPath>", 35);
++lCurrentClipPath;
}
LONG lWritePathID = (LONG)lCurrentClipPath - 2;
// теперь запишем пересечения
for (size_t i = 1; i < nCount; ++i)
{
oWriter.WriteString(L"<clipPath id=\"clip", 18);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\" clip-path=\"url(#clip", 22);
oWriter.AddInt(lCurrentClipPath - 1);
WriteFormatted(L")\"><use x=\"0\" y=\"0\" width=\"", (int)m_lWidth, L"\" height=\"", (int)m_lHeight, L"\" xlink:href=\"#path", (int)lWritePathID, L"\"/></clipPath>", &oWriter);
++lCurrentClipPath;
--lWritePathID;
}
}
void Write2(NSStringUtils::CStringBuilder& oWriter, LONG& lCurrentClipPath)
{
// сначала запишем все пути
size_t nCount = m_arPaths.size();
double dMemoryClipTypes = 0;
for (size_t i = 0; i < nCount; ++i)
{
dMemoryClipTypes += m_arTypes[i];
}
dMemoryClipTypes /= nCount;
if (0 != dMemoryClipTypes && 1 != dMemoryClipTypes)
return Write(oWriter, lCurrentClipPath);
oWriter.WriteString(L"<clipPath id=\"clip", 18);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\"><path id=\"path", 16);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\" d=\"", 5);
for (size_t i = 0; i < nCount; ++i)
{
oWriter.WriteString(m_arPaths[i]);
}
if (dMemoryClipTypes == 0)
oWriter.WriteString(L"\" clip-rule=\"nonzero\" /></clipPath>", 35);
else
oWriter.WriteString(L"\" clip-rule=\"evenodd\" /></clipPath>", 35);
++lCurrentClipPath;
}
inline void Clear()
{
m_arPaths.clear();
m_arTypes.clear();
}
inline bool IsInit()
{
return (0 != m_arPaths.size());
}
};
class CClipSVG2
{
public:
std::vector<std::wstring> m_arPaths;
std::vector<LONG> m_arTypes;
LONG m_lWidth;
LONG m_lHeight;
LONG m_lCountWriteClips;
CClipSVG2() : m_arPaths(), m_arTypes()
{
m_lWidth = 0;
m_lHeight = 0;
m_lCountWriteClips = 0;
}
~CClipSVG2()
{
}
void Write(NSStringUtils::CStringBuilder& oWriter, LONG& lCurrentClipPath)
{
// сначала запишем все пути
size_t nCount = m_arPaths.size();
LONG lOld = lCurrentClipPath;
for (size_t i = 0; i < nCount; ++i)
{
oWriter.WriteString(L"<clipPath id=\"clip", 18);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\"><path id=\"path", 16);
oWriter.AddInt(lCurrentClipPath);
oWriter.WriteString(L"\" d=\"", 5);
oWriter.WriteString(m_arPaths[i]);
if (c_nClipRegionTypeWinding == m_arTypes[i])
oWriter.WriteString(L"\" clip-rule=\"nonzero\" /></clipPath>", 35);
else
oWriter.WriteString(L"\" clip-rule=\"evenodd\" /></clipPath>", 35);
++lCurrentClipPath;
}
m_lCountWriteClips = (LONG)nCount;
for (LONG i = 0; i < m_lCountWriteClips; i++)
{
oWriter.WriteString(L"<g clip-path=\"url(#clip", 23);
oWriter.AddInt(lOld++);
oWriter.WriteString(L")\">", 3);
}
}
void WriteEnd(NSStringUtils::CStringBuilder& oWriter)
{
while (m_lCountWriteClips > 0)
{
oWriter.WriteString(L"</g>\n", 5);
--m_lCountWriteClips;
}
}
inline void Clear()
{
m_arPaths.clear();
m_arTypes.clear();
}
inline bool IsInit()
{
return (0 != m_arPaths.size());
}
};
class CSVGWriter
{
public:
NSStringUtils::CStringBuilder m_oPath;
NSStringUtils::CStringBuilder m_oDocument;
LONG m_lCurDocumentID;
LONG m_lClippingPath;
LONG m_lPatternID;
bool m_bIsClipping;
bool m_bIsNeedUpdateClip;
LONG m_lClipMode;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
int m_lWidth;
int m_lHeight;
double m_dDpiX;
double m_dDpiY;
CClipSVG m_oClip;
public:
CSVGWriter() : m_oPath(), m_oDocument()
{
m_lCurDocumentID = 0;
m_lClippingPath = 0;
m_lPatternID = 0;
m_pPen = NULL;
m_pBrush = NULL;
m_dDpiX = 96;
m_dDpiY = 96;
m_lClipMode = c_nClipRegionTypeWinding;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
}
void ReInit()
{
m_oClip.Clear();
m_oPath.ClearNoAttack();
m_oDocument.ClearNoAttack();
m_lCurDocumentID = 0;
m_lClippingPath = 0;
m_lPatternID = 0;
m_dDpiX = 96;
m_dDpiY = 96;
m_lClipMode = c_nClipRegionTypeWinding;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
}
void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush)
{
m_pPen = pPen;
m_pBrush = pBrush;
}
void CloseFile(std::wstring strFile = L"")
{
if (!strFile.empty())
{
m_oDocument.WriteString(L"</svg>", 5);
NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData());
}
if (3000000 < m_oDocument.GetSize())
m_oDocument.Clear();
m_oDocument.ClearNoAttack();
m_oPath.ClearNoAttack();
m_oClip.Clear();
m_lClippingPath = 0;
m_lPatternID = 0;
m_bIsClipping = false;
}
void NewDocument(double& dWidth, double& dHeigth, LONG& lPageNumber)
{
m_lWidth = (int)dWidth;
m_lHeight = (int)dHeigth;
m_oClip.m_lWidth = m_lWidth;
m_oClip.m_lHeight = m_lHeight;
m_lCurDocumentID = lPageNumber;
WriteFormatted(L"<svg width=\"", m_lWidth, L"px\" height=\"", m_lHeight, L"px\" viewBox=\"0 0 ", m_lWidth, L" ", m_lHeight,
L"\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", &m_oDocument);
m_oClip.Clear();
m_lClippingPath = 0;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
}
void NewDocument(int& lWidth, int& lHeigth)
{
m_lWidth = lWidth;
m_lHeight = lHeigth;
m_oClip.m_lWidth = m_lWidth;
m_oClip.m_lHeight = m_lHeight;
WriteFormatted(L"<svg width=\"", m_lWidth, L"px\" height=\"", m_lHeight, L"px\" viewBox=\"0 0 ", m_lWidth, L" ", m_lHeight,
L"\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", &m_oDocument);
m_oClip.Clear();
m_lClippingPath = 0;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
}
public:
inline void WritePathEnd()
{
m_oPath.ClearNoAttack();
}
inline void WritePathStart()
{
m_oPath.ClearNoAttack();
}
void WritePathClose()
{
m_oPath.AddSize(2);
m_oPath.AddCharNoCheck('Z');
m_oPath.AddSpaceNoCheck();
}
void WritePathMoveTo(double& x, double& y)
{
m_oPath.AddSize(30);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y));
m_oPath.AddSpaceNoCheck();
}
void WritePathLineTo(double& x, double& y)
{
if (0 == m_oPath.GetCurSize())
{
WritePathMoveTo(x, y);
}
m_oPath.AddSize(30);
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y));
m_oPath.AddSpaceNoCheck();
}
void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
if (0 == m_oPath.GetCurSize())
{
WritePathMoveTo(x1, y1);
}
m_oPath.AddSize(80);
m_oPath.AddCharNoCheck('C');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x1));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y1));
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x2));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y2));
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x3));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y3));
m_oPath.AddSpaceNoCheck();
}
void WriteDrawPath(LONG nType, Aggplus::CMatrix* pTransform, Aggplus::CGraphicsPathSimpleConverter* pConverter, CImageInfo& oInfo, const double& dAngle)
{
if (m_oPath.GetCurSize() < 3)
return;
WriteClip();
double dScaleTransform = (pTransform->m_agg_mtx.sx + pTransform->m_agg_mtx.sy) / 2.0;
int nPenW = int(m_pPen->Size * dScaleTransform);
if (0 == nPenW)
nPenW = 1;
if (0 == m_pPen->Alpha)
nType &= 0xFF00;
if (c_BrushTypeTexture == m_pBrush->Type)
{
if (0 == m_pBrush->TextureAlpha)
nType &= 0xFF;
}
else
{
if (0 == m_pBrush->Alpha1)
nType &= 0xFF;
}
bool bStroke = (0x01 == (0x01 & nType));
bool bFill = (0x01 < nType);
if (!bFill)
{
// stroke
m_oDocument.WriteString(L"<path ", 6);
m_oDocument.WriteString(L"style=\"fill:none;stroke:", 24);
m_oDocument.WriteHexColor3(m_pPen->Color);
m_oDocument.WriteString(L";stroke-width:", 14);
m_oDocument.AddInt(nPenW);
m_oDocument.WriteString(L"px;stroke-opacity:", 18);
m_oDocument.AddIntDel100(100 * m_pPen->Alpha / 255);
m_oDocument.WriteString(L";\" ", 3);
if (m_pPen->DashStyle == 0)
{
m_oDocument.WriteString(L";\" ", 3);
}
else
{
m_oDocument.WriteString(L";stroke-dasharray: 2,2;\" ", 25);
}
WriteStyleClip();
m_oDocument.WriteString(L" d=\"", 4);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\" />\n", 5);
return;
}
else if (c_BrushTypeTexture == m_pBrush->Type)
{
double x = 0;
double y = 0;
double r = 0;
double b = 0;
pConverter->PathCommandGetBounds(x, y, r, b);
r += x;
b += y;
if (0 == dAngle)
{
pTransform->TransformPoint(x, y);
pTransform->TransformPoint(r, b);
}
else
{
Aggplus::CMatrix oTemp = *pTransform;
double dCx = (x + r) / 2;
double dCy = (y + b) / 2;
pTransform->TransformPoint(dCx, dCy);
oTemp.RotateAt(-dAngle, dCx, dCy, Aggplus::MatrixOrderAppend);
oTemp.TransformPoint(x, y);
oTemp.TransformPoint(r, b);
}
int _x = round(x);
int _y = round(y);
int _w = round(r - x);
int _h = round(b - y);
// пока заглушка
return WriteImage(oInfo, _x, _y, _w, _h, dAngle);
#if 0
CString strPattern = _T("");
/*
if (itJPG == oInfo.m_eType)
{
strPattern.Format(g_svg_string_pattern_jpg, m_lPatternID, _w, _h, _w, _h, _x, _y, _w, _h, oInfo.m_lID);
}
else
{
strPattern.Format(g_svg_string_pattern_png, m_lPatternID, _w, _h, _w, _h, _x, _y, _w, _h, oInfo.m_lID);
}
*/
m_oDocument.WriteString(strPattern);
CString strMode = _T("nonzero");
if (nType & c_nEvenOddFillMode)
strMode = _T("evenodd");
if (!bStroke)
{
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_StyleFillTx, m_lPatternID, (double)m_pBrush->Alpha1 / 255, strMode);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
}
else
{
int nPenColor = ConvertColor(m_pPen->Color);
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_StyleTx, m_lPatternID, (double)m_pBrush->Alpha1 / 255, strMode, nPenColor, nPenW, (double)m_pPen->Alpha / 255);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
}
++m_lPatternID;
return;
#endif
}
if (!bStroke)
{
m_oDocument.WriteString(L"<path ", 6);
m_oDocument.WriteString(L"style=\"fill:", 12);
m_oDocument.WriteHexColor3(m_pBrush->Color1);
m_oDocument.WriteString(L";fill-opacity:", 14);
m_oDocument.AddIntDel100(100 * m_pBrush->Alpha1 / 255);
if (nType & c_nEvenOddFillMode)
m_oDocument.WriteString(L";fill-rule:evenodd;stroke:none\"", 31);
else
m_oDocument.WriteString(L";fill-rule:nonzero;stroke:none\"", 31);
WriteStyleClip();
m_oDocument.WriteString(L" d=\"", 4);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\" />\n", 5);
return;
}
m_oDocument.WriteString(L"<path ", 6);
m_oDocument.WriteString(L"style=\"fill:", 12);
m_oDocument.WriteHexColor3(m_pBrush->Color1);
m_oDocument.WriteString(L";fill-opacity:", 14);
m_oDocument.AddIntDel100(100 * m_pBrush->Alpha1 / 255);
if (nType & c_nEvenOddFillMode)
m_oDocument.WriteString(L";fill-rule:evenodd;stroke:", 26);
else
m_oDocument.WriteString(L";fill-rule:nonzero;stroke:", 26);
m_oDocument.WriteHexColor3(m_pPen->Color);
m_oDocument.WriteString(L";stroke-width:", 14);
m_oDocument.AddInt(nPenW);
m_oDocument.WriteString(L";stroke-opacity:", 16);
m_oDocument.AddIntDel100(100 * m_pPen->Alpha / 255);
m_oDocument.WriteString(L"\" ", 2);
WriteStyleClip();
m_oDocument.WriteString(L" d=\"", 4);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\" />\n", 5);
}
void WritePathClip()
{
m_bIsClipping = true;
m_bIsNeedUpdateClip = true;
}
void WritePathClipEnd()
{
if (0 == m_oPath.GetCurSize())
return;
m_oClip.m_arPaths.push_back(m_oPath.GetData());
m_oClip.m_arTypes.push_back(m_lClipMode);
}
void WritePathResetClip()
{
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
m_oClip.Clear();
}
void WriteImage(CImageInfo& oInfo, const double& x, const double& y, const double& w, const double& h, const double& dAngle)
{
bool bIsClipping = false;
if ((1 < h) && (1 < w) && (1 > fabs(dAngle)))
{
WriteClip();
bIsClipping = m_bIsClipping;
}
double dCentreX = x + w / 2.0;
double dCentreY = y + h / 2.0;
bool bIsRotate = (abs(dAngle) > 1) ? true : false;
if (itJPG == oInfo.m_eType)
{
if (bIsClipping)
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddInt(round(x));
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddInt(round(y));
m_oDocument.WriteString(L"\" width=\"", 10);
m_oDocument.AddInt(round(w));
m_oDocument.WriteString(L"\" height=\"", 11);
m_oDocument.AddInt(round(h));
m_oDocument.WriteString(L"\" clip-path=\"url(#clip", 22);
m_oDocument.AddInt(m_lClippingPath - 1);
m_oDocument.WriteString(L")\" xlink:href=\"media/image", 26);
m_oDocument.AddInt(oInfo.m_lID);
if (!bIsRotate)
{
m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\"/>", 34);
}
else
{
m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\" transform=\"rotate(", 51);
m_oDocument.AddDouble(dAngle, 4);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreX, 2);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreY, 2);
m_oDocument.WriteString(L")\"/>", 4);
}
}
else
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddInt(round(x));
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddInt(round(y));
m_oDocument.WriteString(L"\" width=\"", 10);
m_oDocument.AddInt(round(w));
m_oDocument.WriteString(L"\" height=\"", 11);
m_oDocument.AddInt(round(h));
m_oDocument.WriteString(L"\" xlink:href=\"media/image", 25);
m_oDocument.AddInt(oInfo.m_lID);
if (!bIsRotate)
{
m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\"/>", 34);
}
else
{
m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\" transform=\"rotate(", 51);
m_oDocument.AddDouble(dAngle, 4);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreX, 2);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreY, 2);
m_oDocument.WriteString(L")\"/>", 4);
}
}
}
else
{
if (bIsClipping)
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddInt(round(x));
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddInt(round(y));
m_oDocument.WriteString(L"\" width=\"", 10);
m_oDocument.AddInt(round(w));
m_oDocument.WriteString(L"\" height=\"", 11);
m_oDocument.AddInt(round(h));
m_oDocument.WriteString(L"\" clip-path=\"url(#clip", 22);
m_oDocument.AddInt(m_lClippingPath - 1);
m_oDocument.WriteString(L")\" xlink:href=\"media/image", 26);
m_oDocument.AddInt(oInfo.m_lID);
if (!bIsRotate)
{
m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\"/>", 34);
}
else
{
m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\" transform=\"rotate(", 51);
m_oDocument.AddDouble(dAngle, 4);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreX, 2);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreY, 2);
m_oDocument.WriteString(L")\"/>", 4);
}
}
else
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddInt(round(x));
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddInt(round(y));
m_oDocument.WriteString(L"\" width=\"", 10);
m_oDocument.AddInt(round(w));
m_oDocument.WriteString(L"\" height=\"", 11);
m_oDocument.AddInt(round(h));
m_oDocument.WriteString(L"\" xlink:href=\"media/image", 25);
m_oDocument.AddInt(oInfo.m_lID);
if (!bIsRotate)
{
m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\"/>", 34);
}
else
{
m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\" transform=\"rotate(", 51);
m_oDocument.AddDouble(dAngle, 4);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreX, 2);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(dCentreY, 2);
m_oDocument.WriteString(L")\"/>", 4);
}
}
}
}
inline void WriteClip()
{
if (m_bIsClipping && m_bIsNeedUpdateClip && (m_oClip.IsInit()))
{
m_oClip.Write(m_oDocument, m_lClippingPath);
//m_oClip.Clear();
m_bIsNeedUpdateClip = false;
}
}
inline void WriteToMainHtml_1(NSStringUtils::CStringBuilder* pWriter, const CDstInfo& oInfo)
{
if (!oInfo.m_bIsWeb)
{
pWriter->WriteString(L"<object class=\"_svg\" data=\"page", 31);
pWriter->AddInt(m_lCurDocumentID);
pWriter->WriteString(L".svg\" type=\"image/svg+xml\">", 27);
CloseFile(oInfo.m_strDstFilePath + L"/page" + std::to_wstring(m_lCurDocumentID) + L".svg");
}
else
{
pWriter->WriteString(L"<object class=\"_svg\" data=\"", 27);
pWriter->WriteString(oInfo.m_strAdditionalPath);
pWriter->WriteString(L"/page", 5);
pWriter->AddInt(m_lCurDocumentID);
pWriter->WriteString(L".svg\" type=\"image/svg+xml\">", 27);
CloseFile(oInfo.m_strDstFilePath + L"/page" + std::to_wstring(m_lCurDocumentID) + L".svg");
}
}
inline void WriteToMainHtml_2(NSStringUtils::CStringBuilder* pWriter)
{
pWriter->WriteString(L"</object>", 9);
}
inline void WriteStyleClip()
{
if (m_bIsClipping)
{
m_oDocument.WriteString(L"clip-path=\"url(#clip", 20);
m_oDocument.AddInt(m_lClippingPath - 1);
m_oDocument.WriteString(L")\" ", 3);
}
}
};
}
#endif // _ASC_HTMLRENDERER_SVGWRITER_H_
#ifndef _ASC_HTMLRENDERER_SVGWRITER2_H_
#define _ASC_HTMLRENDERER_SVGWRITER2_H_
#include "SVGWriter.h"
#include "../../../DesktopEditor/graphics/GraphicsRenderer.h"
#define SVG_INLINE_MAX_SIZE 500000 // 500Kb
#define SVG_TO_RASTER_MIN_SIZE 50000000 // 1Mb
namespace NSHtmlRenderer
{
#define USE_SIMPLE_GRAPHICS_NOSVG
#define USE_BIG_GRAPHICS_TORASTER
class CRendererGr
{
public:
CGraphicsRenderer* m_pRenderer;
CBgraFrame* m_pFrame;
double m_dWidth;
double m_dHeight;
LONG m_lWidthPix;
LONG m_lHeightPix;
bool m_bIsRasterNeed;
public:
CRendererGr()
{
m_pRenderer = NULL;
m_pFrame = NULL;
m_dWidth = -1;
m_dHeight = -1;
m_lWidthPix = -1;
m_lHeightPix = -1;
}
~CRendererGr()
{
RELEASEOBJECT(m_pRenderer);
RELEASEOBJECT(m_pFrame);
}
inline void UncheckRaster()
{
m_bIsRasterNeed = false;
}
inline void CheckRasterNeed(const bool& bIsRaster)
{
if (!m_bIsRasterNeed)
m_bIsRasterNeed = bIsRaster;
}
void CheckRaster(double dWidth, double dHeight)
{
if (dWidth != m_dWidth || dHeight != m_dHeight)
{
RELEASEOBJECT(m_pFrame);
m_dWidth = dWidth;
m_dHeight = dHeight;
}
RELEASEOBJECT(m_pRenderer);
m_lWidthPix = (LONG)(96 * m_dWidth / 25.4);
m_lHeightPix = (LONG)(96 * m_dHeight / 25.4);
if (NULL == m_pFrame)
{
m_pFrame = new CBgraFrame();
m_pFrame->put_Width((int)m_lWidthPix);
m_pFrame->put_Height((int)m_lHeightPix);
m_pFrame->put_Stride(4 * ((int)m_lWidthPix));
BYTE* pData = new BYTE[4 * m_lWidthPix * m_lHeightPix];
memset(pData, 0xFF, 4 * m_lWidthPix * m_lHeightPix);
m_pFrame->put_Data(pData);
}
m_pRenderer = new CGraphicsRenderer();
m_pRenderer->put_Width(m_dWidth);
m_pRenderer->put_Height(m_dHeight);
m_pRenderer->CreateFromBgraFrame(m_pFrame);
}
template<typename T>
void CheckRasterData(T pPage, double& dWidth, double& dHeight)
{
if (m_bIsRasterNeed)
{
CheckRaster(dWidth, dHeight);
GetRasterData(pPage);
}
UncheckRaster();
}
template<typename T>
void GetRasterData(T pPage)
{
// определ¤ем размеры картинки
if (NULL == m_pFrame)
return NULL;
BYTE* pBuffer = m_pFrame->get_Data();
RECT rect = GetImageBounds(m_pFrame);
if (((rect.right - rect.left) < 5) && ((rect.bottom - rect.top) < 5))
return NULL;
BYTE* pBufferSrcMem = pBuffer + 4 * rect.top * m_lWidthPix + 4 * rect.left;
LONG lWidthShape = rect.right - rect.left + 1;
LONG lHeightShape = rect.bottom - rect.top + 1;
pShapePicture = new CBgraFrame();
pShapePicture->put_Width((int)lWidthShape);
pShapePicture->put_Height((int)lHeightShape);
pShapePicture->put_Stride(4 * ((int)lWidthShape));
BYTE* pBufferDst = new BYTE[4 * lWidthShape * lHeightShape];
m_pFrame->put_Data(pBufferDst);
for (LONG lLine = 0; lLine < lHeightShape; ++lLine)
{
memcpy(pBufferDst, pBufferSrcMem, 4 * lWidthShape);
pBufferDst += 4 * lWidthShape;
pBufferSrcMem += 4 * m_lWidthPix;
}
double dL = 25.4 * rect.left / 96.0;
double dT = 25.4 * rect.top / 96.0;
double dW = 25.4 * lWidthShape / 96.0;
double dH = 25.4 * lHeightShape / 96.0;
double dHeightMM = 25.4 * m_lHeight / 96.0;
dT = (dHeightMM - dT - dH);
pPage->WriteImage(pShapePicture, dL, dT, dW, dH);
RELEASEOBJECT(pShapePicture);
}
};
class CDoubleBounds
{
public:
bool IsCleared;
double x;
double y;
double r;
double b;
public:
CDoubleBounds()
{
Clear();
}
void Clear()
{
IsCleared = true;
x = 10000000.0;
y = 10000000.0;
r = -10000000.0;
b = -10000000.0;
}
inline void CheckPoint(const double& _x, const double& _y)
{
IsCleared = false;
if (x > _x)
x = _x;
if (y > _y)
y = _y;
if (r < _x)
r = _x;
if (b < _y)
b = _y;
}
inline void Intersect(const CDoubleBounds& oBounds)
{
if (IsCleared)
{
x = oBounds.x;
y = oBounds.y;
r = oBounds.r;
b = oBounds.b;
IsCleared = false;
}
else
{
if (oBounds.x > x)
x = oBounds.x;
if (oBounds.y > y)
y = oBounds.y;
if (oBounds.r < r)
r = oBounds.r;
if (oBounds.b < b)
b = oBounds.b;
}
}
};
class CSVGWriter2
{
public:
NSStringUtils::CStringBuilder m_oPath;
NSStringUtils::CStringBuilder m_oDocument;
LONG m_lCurDocumentID;
LONG m_lClippingPath;
LONG m_lPatternID;
bool m_bIsClipping;
bool m_bIsNeedUpdateClip;
LONG m_lClipMode;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CPen* m_pLastPen;
NSStructures::CBrush* m_pLastBrush;
Aggplus::CMatrix* m_pTransform;
int m_lWidth;
int m_lHeight;
double m_dDpiX;
double m_dDpiY;
CClipSVG2 m_oClip;
// здесь храним пат в координатах не трансформированных
// (чтобы, если заливки сложные - можно было делать трансформы
// непосредственно при использовании графического пути).
double* m_pCoordsArray;
unsigned int m_lCoordsSize;
double* m_pCoordsArrayCur;
unsigned int m_lCoordsSizeCur;
bool m_bIsCurveToExist;
BYTE* m_pPathTypes;
unsigned int m_lPathTypesSize;
BYTE* m_pPathTypesCur;
unsigned int m_lPathTypesSizeCur;
double m_dCoordsScaleX;
double m_dCoordsScaleY;
unsigned int m_lEmtyDocChecker;
BYTE* m_pBase64Code;
CDoubleBounds m_oTextClipBounds;
// переменная говорит о том, какой клип дл¤ текста записан сейчас
// если true - то послана команда ResetTextClipRect
// если false - то нет
bool m_bIsTextClipWriteCleared;
// были ли новые clip'ы
bool m_bIsIntersectNewClipRect;
// сохранение в растр. (если сложная заливка, или слишком большая векторная графика)
//CRendererGr m_oGrRenderer;
//Graphics::IASCMetafile* m_pGrRenderer;
// клип для картинок. для конвертации сложной векторной графики в растр
CMetafile m_oClipMetafile;
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
CMetafile m_oVectors;
bool m_bIsSimpleGraphics;
bool m_bIsSimpleSetupBrush;
LONG m_lBrushColorOld;
LONG m_lBrushAlphaOld;
#endif
public:
CSVGWriter2() : m_oPath(), m_oDocument()
{
m_lCurDocumentID = 0;
m_lClippingPath = 0;
m_lPatternID = 0;
m_pPen = NULL;
m_pBrush = NULL;
m_pLastPen = NULL;
m_pLastBrush = NULL;
m_dDpiX = 96;
m_dDpiY = 96;
m_dCoordsScaleX = m_dDpiX / 25.4;
m_dCoordsScaleY = m_dDpiY / 25.4;
m_lClipMode = c_nClipRegionTypeWinding;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
m_pCoordsArray = NULL;
m_lCoordsSize = 0;
m_pCoordsArrayCur = NULL;
m_lCoordsSizeCur = 0;
m_pPathTypes = NULL;
m_lPathTypesSize = 0;
m_pPathTypesCur = NULL;
m_lPathTypesSizeCur = 0;
m_lEmtyDocChecker = 0;
m_pBase64Code = new BYTE[2 * SVG_INLINE_MAX_SIZE];
m_bIsTextClipWriteCleared = true;
m_bIsIntersectNewClipRect = false;
m_bIsCurveToExist = false;
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
m_bIsSimpleGraphics = true;
m_bIsSimpleSetupBrush = false;
m_lBrushColorOld = 0;
m_lBrushAlphaOld = 255;
#endif
}
~CSVGWriter2()
{
RELEASEARRAYOBJECTS(m_pBase64Code);
}
void ReInit()
{
m_bIsTextClipWriteCleared = true;
m_bIsIntersectNewClipRect = false;
m_oTextClipBounds.Clear();
m_oClip.Clear();
m_oPath.ClearNoAttack();
m_oDocument.ClearNoAttack();
m_lCurDocumentID = 0;
m_lClippingPath = 0;
m_lPatternID = 0;
m_dDpiX = 96;
m_dDpiY = 96;
m_lClipMode = c_nClipRegionTypeWinding;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
}
void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush)
{
m_pPen = pPen;
m_pBrush = pBrush;
}
void CloseFile(std::wstring strFile = L"")
{
if (!strFile.empty())
{
m_oDocument.WriteString(L"</svg>", 6);
NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData());
}
if (3000000 < m_oDocument.GetSize())
m_oDocument.Clear();
m_oDocument.ClearNoAttack();
m_oPath.ClearNoAttack();
m_oClip.Clear();
m_lClippingPath = 0;
m_lPatternID = 0;
m_bIsClipping = false;
}
std::wstring GetSVGXml()
{
m_oClip.WriteEnd(m_oDocument);
m_oDocument.WriteString(L"</svg>", 6);
return m_oDocument.GetData();
}
void CloseFile2(std::wstring strFile, bool bIsNeedEnd = true)
{
if (bIsNeedEnd)
{
m_oClip.WriteEnd(m_oDocument);
m_oDocument.WriteString(L"</svg>", 6);
}
NSFile::CFileBinary::SaveToFile(strFile, m_oDocument.GetData());
m_oDocument.ClearNoAttack();
m_oPath.ClearNoAttack();
if (m_bIsClipping)
{
m_bIsNeedUpdateClip = true;
}
m_lPatternID = 0;
}
int CloseFile3(NSHtmlRenderer::CMetafile* m_pMeta, bool bIsNeedEnd = true)
{
if (bIsNeedEnd)
{
m_oClip.WriteEnd(m_oDocument);
m_oDocument.WriteString(L"</svg>", 6);
}
BYTE* pDataSrc = NULL;
LONG nLenSrc = 0;
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(m_oDocument.GetBuffer(), (LONG)m_oDocument.GetCurSize(), pDataSrc, nLenSrc);
char* pBase64 = NULL;
int nLenDst = 2 * SVG_INLINE_MAX_SIZE;
NSBase64::Base64Encode(pDataSrc, (int)nLenSrc, m_pBase64Code, &nLenDst);
RELEASEARRAYOBJECTS(pDataSrc);
m_pMeta->WriteLONG(nLenDst);
m_pMeta->Write(m_pBase64Code, nLenDst);
m_oDocument.ClearNoAttack();
m_oPath.ClearNoAttack();
if (m_bIsClipping)
{
m_bIsNeedUpdateClip = true;
}
m_lPatternID = 0;
return nLenDst;
}
void NewDocument(const double& dWidth, const double& dHeigth, const LONG& lPageNumber)
{
m_lWidth = (int)(dWidth * m_dCoordsScaleX);
m_lHeight = (int)(dHeigth * m_dCoordsScaleY);
m_oClip.m_lWidth = m_lWidth;
m_oClip.m_lHeight = m_lHeight;
m_lCurDocumentID = lPageNumber;
m_oDocument.ClearNoAttack();
m_oDocument.WriteString(L"<svg width=\"", 12);
m_oDocument.AddInt(m_lWidth);
m_oDocument.WriteString(L"px\" height=\"", 12);
m_oDocument.AddInt(m_lHeight);
m_oDocument.WriteString(L"px\" viewBox=\"0 0 ", 17);
m_oDocument.AddInt(m_lWidth);
m_oDocument.AddCharSafe(' ');
m_oDocument.AddInt(m_lHeight);
m_oDocument.WriteString(L"\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", 95);
m_oClip.Clear();
m_lClippingPath = 0;
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
m_lEmtyDocChecker = (unsigned int)m_oDocument.GetCurSize();
}
public:
inline void WritePathEnd()
{
m_bIsCurveToExist = false;
m_oPath.ClearNoAttack();
ClearVectorCoords();
}
inline void WritePathStart()
{
m_bIsCurveToExist = false;
m_oPath.ClearNoAttack();
ClearVectorCoords();
}
void WritePathClose()
{
CheckSizeVectorB();
*m_pPathTypesCur++ = 3;
++m_lPathTypesSizeCur;
/*
m_oPath.AddSize(2);
m_oPath.AddCharNoCheck('Z');
m_oPath.AddSpaceNoCheck();
*/
}
void WritePathMoveTo(const double& x, const double& y)
{
CheckSizeVectorB();
*m_pPathTypesCur++ = 0;
++m_lPathTypesSizeCur;
CheckSizeVectorD(2);
m_pCoordsArrayCur[0] = x;
m_pCoordsArrayCur[1] = y;
m_pTransform->TransformPoint(m_pCoordsArrayCur[0], m_pCoordsArrayCur[1]);
m_pCoordsArrayCur += 2;
m_lCoordsSizeCur += 2;
/*
m_oPath.AddSize(30);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y));
m_oPath.AddSpaceNoCheck();
*/
}
void WritePathLineTo(const double& x, const double& y)
{
if (0 == m_lPathTypesSizeCur)
{
WritePathMoveTo(x, y);
return;
}
CheckSizeVectorB();
*m_pPathTypesCur++ = 1;
++m_lPathTypesSizeCur;
CheckSizeVectorD(2);
m_pCoordsArrayCur[0] = x;
m_pCoordsArrayCur[1] = y;
m_pTransform->TransformPoint(m_pCoordsArrayCur[0], m_pCoordsArrayCur[1]);
if (fabs(m_pCoordsArray[m_lCoordsSizeCur - 2] - m_pCoordsArrayCur[0]) < 0.1 &&
fabs(m_pCoordsArray[m_lCoordsSizeCur - 1] - m_pCoordsArrayCur[1]) < 0.1)
{
// попали в текущую точку. не добавл¤ем
--m_pPathTypesCur;
--m_lPathTypesSizeCur;
return;
}
m_pCoordsArrayCur += 2;
m_lCoordsSizeCur += 2;
/*
m_oPath.AddSize(30);
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y));
m_oPath.AddSpaceNoCheck();
*/
}
void WritePathCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3)
{
if (0 == m_lPathTypesSizeCur)
WritePathMoveTo(x1, y1);
CheckSizeVectorB();
*m_pPathTypesCur++ = 2;
++m_lPathTypesSizeCur;
CheckSizeVectorD(6);
m_pCoordsArrayCur[0] = x1;
m_pCoordsArrayCur[1] = y1;
m_pCoordsArrayCur[2] = x2;
m_pCoordsArrayCur[3] = y2;
m_pCoordsArrayCur[4] = x3;
m_pCoordsArrayCur[5] = y3;
m_pTransform->TransformPoint(m_pCoordsArrayCur[0], m_pCoordsArrayCur[1]);
m_pTransform->TransformPoint(m_pCoordsArrayCur[2], m_pCoordsArrayCur[3]);
m_pTransform->TransformPoint(m_pCoordsArrayCur[4], m_pCoordsArrayCur[5]);
m_pCoordsArrayCur += 6;
m_lCoordsSizeCur += 6;
m_bIsCurveToExist = true;
/*
m_oPath.AddSize(80);
m_oPath.AddCharNoCheck('C');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x1));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y1));
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x2));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y2));
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheck(round(x3));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheck(round(y3));
m_oPath.AddSpaceNoCheck();
*/
}
void WriteDrawPath(LONG nType, Aggplus::CGraphicsPathSimpleConverter* pConverter, CImageInfo& oInfo)
{
if (m_lPathTypesSizeCur == 0)
return;
WriteClip();
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
if (m_bIsClipping)
m_bIsSimpleGraphics = false;
#endif
if (0 == m_pPen->Alpha)
nType &= 0xFF00;
if (c_BrushTypeTexture == m_pBrush->Type)
{
if (0 == m_pBrush->TextureAlpha)
nType &= 0xFF;
}
else
{
if (0 == m_pBrush->Alpha1)
nType &= 0xFF;
}
bool bIsNeedTransform = true;
// первым делом нужно пон¤ть, будем ли мы трансформировать пути
if (nType > 0xFF && m_pBrush->Type == c_BrushTypeTexture)
{
bIsNeedTransform = false;
}
int nPenW = 1;
if (0 != m_pPen->Size)
{
if (!bIsNeedTransform)
{
nPenW = (int)(m_pPen->Size);
}
else
{
double _x1 = 0;
double _y1 = 0;
double _x2 = 1;
double _y2 = 1;
m_pTransform->TransformPoint(_x1, _y1);
m_pTransform->TransformPoint(_x2, _y2);
double dScaleTransform = sqrt(((_x2 - _x1) * (_x2 - _x1) + (_y2 - _y1) * (_y2 - _y1)) / 2) * m_dCoordsScaleX;
nPenW = (int)(m_pPen->Size * dScaleTransform);
}
}
BOOL bStroke = (0x01 == (0x01 & nType));
if (nPenW == 0 && bStroke)
nPenW = 1;
BOOL bFill = (0x01 < nType);
bool bIsLine = false;
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
if (m_bIsSimpleGraphics)
{
if (bFill && ((0 != (nType & c_nEvenOddFillMode)) || m_pBrush->Type != c_BrushTypeSolid))
m_bIsSimpleGraphics = false;
if (bStroke && m_pPen->DashStyle != 0)
m_bIsSimpleGraphics = false;
}
if (m_bIsSimpleGraphics)
{
// пишем вектор и настройки brush/pen
m_oVectors.WriteCommandType(CMetafile::ctPathCommandStart);
WriteToPathToSimpleVector();
bIsLine = WriteToPathToSVGPath(false, (bFill && !bStroke) ? true : false);
if (bFill && !bIsLine)
{
if (!m_pLastBrush->IsEqual(m_pBrush))
{
if (!m_bIsSimpleSetupBrush)
{
m_lBrushColorOld = m_pLastBrush->Color1;
m_lBrushAlphaOld = m_pLastBrush->Alpha1;
m_bIsSimpleSetupBrush = true;
}
*m_pLastBrush = *m_pBrush;
m_oVectors.WriteCommandType(CMetafile::ctBrushColor1);
LONG lBGR = m_pBrush->Color1;
m_oVectors.WriteBYTE((BYTE)(lBGR & 0xFF));
m_oVectors.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF));
m_oVectors.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF));
m_oVectors.WriteBYTE((BYTE)m_pBrush->Alpha1);
}
}
else if (bIsLine)
{
LONG _C = m_pPen->Color;
LONG _A = m_pPen->Alpha;
double _W = m_pPen->Size;
m_pPen->Color = m_pBrush->Color1;
m_pPen->Alpha = m_pBrush->Alpha1;
m_pPen->Size = 1 / m_dCoordsScaleX;
if (!m_pLastPen->IsEqual(m_pPen))
{
*m_pLastPen = *m_pPen;
m_oVectors.WriteCommandType(CMetafile::ctPenColor);
LONG lBGR = m_pPen->Color;
m_oVectors.WriteBYTE((BYTE)(lBGR & 0xFF));
m_oVectors.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF));
m_oVectors.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF));
m_oVectors.WriteBYTE((BYTE)m_pPen->Alpha);
m_oVectors.WriteCommandType(CMetafile::ctPenSize);
m_oVectors.WriteDouble((double)nPenW / m_dCoordsScaleX);
}
m_pPen->Color = _C;
m_pPen->Alpha = _A;
m_pPen->Size = _W;
}
if (bStroke)
{
if (!m_pLastPen->IsEqual(m_pPen))
{
*m_pLastPen = *m_pPen;
m_oVectors.WriteCommandType(CMetafile::ctPenColor);
LONG lBGR = m_pPen->Color;
m_oVectors.WriteBYTE((BYTE)(lBGR & 0xFF));
m_oVectors.WriteBYTE((BYTE)((lBGR >> 8) & 0xFF));
m_oVectors.WriteBYTE((BYTE)((lBGR >> 16) & 0xFF));
m_oVectors.WriteBYTE((BYTE)m_pPen->Alpha);
m_oVectors.WriteCommandType(CMetafile::ctPenSize);
m_oVectors.WriteDouble((double)nPenW / m_dCoordsScaleX);
}
}
m_oVectors.WriteCommandType(CMetafile::ctDrawPath);
m_oVectors.WriteLONG(bIsLine ? 1 : nType);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandStart);
}
else
{
bIsLine = WriteToPathToSVGPath(false, (bFill && !bStroke) ? true : false);
}
#else
bIsLine = WriteToPathToSVGPath(false, (bFill && !bStroke) ? true : false);
#endif
#if 0
if (!bFill)
{
// stroke
int nColorPen = ConvertColor(m_pPen->Color);
CString strStyle = _T("");
if (m_pPen->DashStyle == 0)
{
strStyle.Format(g_svg_string_vml_StyleStroke, nColorPen, nPenW, (double)m_pPen->Alpha / 255);
}
else
{
strStyle.Format(g_svg_string_vml_StyleStrokeDash, nColorPen, nPenW, (double)m_pPen->Alpha / 255);
}
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
return;
}
else if (c_BrushTypeTexture == m_pBrush->Type)
{
double x = 0;
double y = 0;
double w = 0;
double h = 0;
pConverter->PathCommandGetBounds(&x, &y, &w, &h);
if (m_pBrush->TextureMode == c_BrushTextureModeStretch || true)
{
// 1) пишем паттерн
agg::trans_affine* mtx = &m_pTransform->m_agg_mtx;
double _tx = mtx->tx * m_dCoordsScaleX;
double _ty = mtx->ty * m_dCoordsScaleY;
CString strPatt = _T("");
double _w = w * m_dCoordsScaleX;
double _h = h * m_dCoordsScaleY;
if (itJPG == oInfo.m_eType)
{
strPatt.Format(g_svg_string_pattern_jpg_mtx, m_lPatternID, round(_w), round(_h), round(_w), round(_h),
mtx->sx, mtx->shy, mtx->shx, mtx->sy, _tx, _ty, round(_w), round(_h), oInfo.m_lID);
}
else
{
strPatt.Format(g_svg_string_pattern_png_mtx, m_lPatternID, round(_w), round(_h), round(_w), round(_h),
mtx->sx, mtx->shy, mtx->shx, mtx->sy, _tx, _ty, round(_w), round(_h), oInfo.m_lID);
}
m_oDocument.WriteString(strPatt);
}
else
{
// TODO:
}
CString strMode = _T("nonzero");
if (nType & c_nEvenOddFillMode)
strMode = _T("evenodd");
if (!bStroke)
{
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_StyleFillTx, m_lPatternID, (double)m_pBrush->Alpha1 / 255, strMode);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
}
else
{
int nPenColor = ConvertColor(m_pPen->Color);
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_StyleTx, m_lPatternID, (double)m_pBrush->Alpha1 / 255, strMode, nPenColor, nPenW, (double)m_pPen->Alpha / 255);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
}
++m_lPatternID;
return;
}
int nColorBrush = ConvertColor(m_pBrush->Color1);
CString strMode = _T("nonzero");
if (nType & c_nEvenOddFillMode)
{
strMode = _T("evenodd");
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
m_bIsSimpleGraphics = false;
#endif
}
if (!bStroke)
{
if (bIsLine)
{
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_StyleStroke, nColorBrush, 1, (double)m_pBrush->Alpha1 / 255);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
return;
}
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_StyleFill, nColorBrush, (double)m_pBrush->Alpha1 / 255, strMode);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
return;
}
int nPenColor = ConvertColor(m_pPen->Color);
CString strStyle = _T("");
strStyle.Format(g_svg_string_vml_Style, nColorBrush, (double)m_pBrush->Alpha1 / 255, strMode, nPenColor, nPenW, (double)m_pPen->Alpha / 255);
m_oDocument.WriteString(g_svg_bstr_vml_Path);
m_oDocument.WriteString(strStyle);
WriteStyleClip();
m_oDocument.WriteString(g_svg_bstr_path_d);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(g_svg_bstr_path_d_end);
m_oDocument.WriteString(g_svg_bstr_nodeClose);
#endif
}
void WritePathClip()
{
m_bIsClipping = true;
m_bIsNeedUpdateClip = true;
}
void WritePathClipEnd()
{
/*
if (1 == m_lPathTypesSizeCur && m_pPathTypes[0] <= 1)
{
// не надо клип делать. пат странен)
return;
}
else if (2 == m_lPathTypesSizeCur &&
((m_pPathTypes[0] == 0 || m_pPathTypes[1] == 0) && (m_pPathTypes[0] <= 1 && m_pPathTypes[1] <= 1)))
{
// пат все еще странен
return;
}
*/
m_oClip.WriteEnd(m_oDocument);
m_bIsIntersectNewClipRect = true;
WriteToPathToSVGPath(true);
if (0 == m_oPath.GetCurSize())
return;
m_oClip.m_arPaths.push_back(m_oPath.GetData());
m_oClip.m_arTypes.push_back(m_lClipMode);
}
void WritePathResetClip()
{
m_bIsClipping = false;
m_bIsNeedUpdateClip = false;
m_oClip.Clear();
m_oTextClipBounds.Clear();
m_oClipMetafile.ClearNoAttack();
m_oClip.WriteEnd(m_oDocument);
}
void WriteImage(CImageInfo& oInfo, const double& x, const double& y, const double& w, const double& h)
{
bool bIsClipping = false;
if ((1 < h) && (1 < w))
{
WriteClip();
bIsClipping = m_bIsClipping;
}
double dCentreX = x + w / 2.0;
double dCentreY = y + h / 2.0;
agg::trans_affine* mtx = &m_pTransform->m_agg_mtx;
bool bIsNoNeedTransform = agg::is_equal_eps(mtx->sx, 1.0, 0.0001) &&
agg::is_equal_eps(mtx->shy, 0.0, 0.0001) &&
agg::is_equal_eps(mtx->shx, 0.0, 0.0001) &&
agg::is_equal_eps(mtx->sy, 1.0, 0.0001);
if (bIsNoNeedTransform)
{
double _x = x + m_pTransform->m_agg_mtx.tx;
double _y = y + m_pTransform->m_agg_mtx.ty;
_x *= m_dCoordsScaleX;
_y *= m_dCoordsScaleY;
double _w = w * m_dCoordsScaleX;
double _h = h * m_dCoordsScaleY;
if (itJPG == oInfo.m_eType)
{
/*if (bIsClipping)
{
//("<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" clip-path=\"url(#clip%d)\" xlink:href=\"image%d.jpg\" preserveAspectRatio=\"none\"/>");
strImage.Format(g_svg_string_image_clip_jpg1, round(_x), round(_y), round(_w), round(_h), m_lClippingPath - 1, oInfo.m_lID);
}
else*/
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddInt(round(_x));
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddInt(round(_y));
m_oDocument.WriteString(L"\" width=\"", 9);
m_oDocument.AddInt( round(_w));
m_oDocument.WriteString(L"\" height=\"", 10);
m_oDocument.AddInt( round(_h));
m_oDocument.WriteString(L"\" xlink:href=\"image", 19);
m_oDocument.AddInt(oInfo.m_lID);
m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\"/>", 34);
}
}
else
{
/*if (bIsClipping)
{
//("<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" clip-path=\"url(#clip%d)\" xlink:href=\"image%d.png\" preserveAspectRatio=\"none\"/>");
strImage.Format(g_svg_string_image_clip_png1, round(_x), round(_y), round(_w), round(_h), m_lClippingPath - 1, oInfo.m_lID);
}
else*/
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddInt(round(_x));
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddInt(round(_y));
m_oDocument.WriteString(L"\" width=\"", 9);
m_oDocument.AddInt( round(_w));
m_oDocument.WriteString(L"\" height=\"", 10);
m_oDocument.AddInt( round(_h));
m_oDocument.WriteString(L"\" xlink:href=\"image", 19);
m_oDocument.AddInt(oInfo.m_lID);
m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\"/>", 34);
}
}
}
else
{
double _tx = m_pTransform->m_agg_mtx.tx * m_dCoordsScaleX;
double _ty = m_pTransform->m_agg_mtx.ty * m_dCoordsScaleY;
double _x = x * m_dCoordsScaleX;
double _y = y * m_dCoordsScaleY;
double _w = w * m_dCoordsScaleX;
double _h = h * m_dCoordsScaleY;
if (itJPG == oInfo.m_eType)
{
/*if (bIsClipping)
{
//_T("<image x=\"%.3lf\" y=\"%.3lf\" width=\"%.3lf\" height=\"%.3lf\" clip-path=\"url(#clip%d)\" xlink:href=\"image%d.jpg\" preserveAspectRatio=\"none\" transform=\"matrix(%.3lf, %.3lf,%.3lf,%.3lf, %.3lf,%.3lf)\"/>");
strImage.Format(g_svg_string_image_clip_jpg_mtx, _x, _y, _w, _h, m_lClippingPath - 1, oInfo.m_lID, mtx->sx, mtx->shy, mtx->shx, mtx->sy, _tx, _ty);
}
else*/
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddDouble(_x, 3);
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddDouble(_y, 3);
m_oDocument.WriteString(L"\" width=\"", 9);
m_oDocument.AddDouble(_w, 3);
m_oDocument.WriteString(L"\" height=\"", 10);
m_oDocument.AddDouble(_h, 3);
m_oDocument.WriteString(L"\" xlink:href=\"image", 19);
m_oDocument.AddInt(oInfo.m_lID);
m_oDocument.WriteString(L".jpg\" preserveAspectRatio=\"none\" transform=\"matrix(/>", 53);
m_oDocument.AddDouble(mtx->sx, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(mtx->shy, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(mtx->shx, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(mtx->sy, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(_tx, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(_ty, 3);
m_oDocument.WriteString(L")\"/>", 4);
}
}
else
{
/*if (bIsClipping)
{
//_T("<image x=\"%.3lf\" y=\"%.3lf\" width=\"%.3lf\" height=\"%.3lf\" clip-path=\"url(#clip%d)\" xlink:href=\"image%d.jpg\" preserveAspectRatio=\"none\" transform=\"matrix(%.3lf, %.3lf,%.3lf,%.3lf, %.3lf,%.3lf)\"/>");
strImage.Format(g_svg_string_image_clip_png_mtx, _x, _y, _w, _h, m_lClippingPath - 1, oInfo.m_lID, mtx->sx, mtx->shy, mtx->shx, mtx->sy, _tx, _ty);
}
else*/
{
m_oDocument.WriteString(L"<image x=\"", 10);
m_oDocument.AddDouble(_x, 3);
m_oDocument.WriteString(L"\" y=\"", 5);
m_oDocument.AddDouble(_y, 3);
m_oDocument.WriteString(L"\" width=\"", 9);
m_oDocument.AddDouble(_w, 3);
m_oDocument.WriteString(L"\" height=\"", 10);
m_oDocument.AddDouble(_h, 3);
m_oDocument.WriteString(L"\" xlink:href=\"image", 19);
m_oDocument.AddInt(oInfo.m_lID);
m_oDocument.WriteString(L".png\" preserveAspectRatio=\"none\" transform=\"matrix(/>", 53);
m_oDocument.AddDouble(mtx->sx, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(mtx->shy, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(mtx->shx, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(mtx->sy, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(_tx, 3);
m_oDocument.AddCharSafe(',');
m_oDocument.AddDouble(_ty, 3);
m_oDocument.WriteString(L")\"/>", 4);
}
}
}
}
inline void WriteClip()
{
if (m_bIsClipping && m_bIsNeedUpdateClip && (m_oClip.IsInit()))
{
m_oClip.Write(m_oDocument, m_lClippingPath);
//m_oClip.Clear();
m_bIsNeedUpdateClip = false;
}
}
inline void WriteStyleClip()
{
// сейчас не пишем (оборачиваем в g)
return;
if (m_bIsClipping)
{
//_T("clip-path=\"url(#clip%d)\" ");
m_oDocument.WriteString(L"clip-path=\"url(#clip", 20);
m_oDocument.AddInt(m_lClippingPath - 1);
m_oDocument.WriteString(L")\" ", 3);
}
}
void CheckSizeVectorB(const int& len = 1)
{
if (NULL != m_pPathTypes)
{
unsigned int nNewSize = (unsigned int)(m_lPathTypesSizeCur + len);
if (nNewSize >= m_lPathTypesSize)
{
if (nNewSize >= m_lPathTypesSize)
{
while (nNewSize >= m_lPathTypesSize)
{
m_lPathTypesSize *= 2;
}
BYTE* pNew = new BYTE[m_lPathTypesSize];
memcpy(pNew, m_pPathTypes, m_lPathTypesSizeCur);
RELEASEARRAYOBJECTS(m_pPathTypes);
m_pPathTypes = pNew;
m_pPathTypesCur = m_pPathTypes + m_lPathTypesSizeCur;
}
}
}
else
{
m_lPathTypesSize = 1000;
m_pPathTypes = new BYTE[m_lPathTypesSize];
m_pPathTypesCur = m_pPathTypes;
m_lPathTypesSizeCur = 0;
}
}
void CheckSizeVectorD(const int& len)
{
if (NULL != m_pCoordsArray)
{
unsigned int nNewSize = (unsigned int)(m_lCoordsSizeCur + len);
if (nNewSize >= m_lCoordsSize)
{
while (nNewSize >= m_lCoordsSize)
{
m_lCoordsSize *= 2;
}
double* pNew = new double[m_lCoordsSize];
memcpy(pNew, m_pCoordsArray, m_lCoordsSizeCur * sizeof(double));
RELEASEARRAYOBJECTS(m_pCoordsArray);
m_pCoordsArray = pNew;
m_pCoordsArrayCur = m_pCoordsArray + m_lCoordsSizeCur;
}
}
else
{
m_lCoordsSize = 1000;
m_pCoordsArray = new double[m_lCoordsSize];
m_pCoordsArrayCur = m_pCoordsArray;
m_lCoordsSizeCur = 0;
}
}
void ClearVectorCoords()
{
m_lCoordsSizeCur = 0;
m_pCoordsArrayCur = m_pCoordsArray;
m_lPathTypesSizeCur = 0;
m_pPathTypesCur = m_pPathTypes;
}
bool WriteToPathToSVGPath(bool bIsClipping = false, bool bIsNeedAnalyzeLine = false)
{
m_oPath.ClearNoAttack();
CDoubleBounds oBounds;
if (!bIsNeedAnalyzeLine)
{
unsigned int lSize = m_lCoordsSizeCur;
for (unsigned int i = 0; i < lSize; i += 2)
{
if (bIsClipping)
{
oBounds.CheckPoint(m_pCoordsArray[i], m_pCoordsArray[i + 1]);
}
m_pCoordsArray[i] *= m_dCoordsScaleX;
m_pCoordsArray[i + 1] *= m_dCoordsScaleY;
}
}
else
{
if (!bIsClipping && m_lPathTypesSizeCur <= 4 && !m_bIsCurveToExist)
{
unsigned int lSize = m_lCoordsSizeCur;
for (unsigned int i = 0; i < lSize; i += 2)
{
m_pCoordsArray[i] *= m_dCoordsScaleX;
m_pCoordsArray[i + 1] *= m_dCoordsScaleY;
}
switch (m_lPathTypesSizeCur)
{
case 2:
{
if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1])
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3]));
m_oPath.AddSpaceNoCheck();
return true;
}
break;
}
case 3:
{
if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1])
{
if (3 == m_pPathTypes[2])
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3]));
m_oPath.AddSpaceNoCheck();
return true;
}
else
{
if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2))
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3]));
m_oPath.AddSpaceNoCheck();
return true;
}
else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2))
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[4]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[5]));
m_oPath.AddSpaceNoCheck();
return true;
}
}
}
break;
}
case 4:
{
if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1] && 1 == m_pPathTypes[2])
{
if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2))
{
if (3 == m_pPathTypes[3])
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3]));
m_oPath.AddSpaceNoCheck();
return true;
}
else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) &&
(fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2)))
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[2]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[3]));
m_oPath.AddSpaceNoCheck();
return true;
}
}
else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2))
{
if (3 == m_pPathTypes[3])
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[4]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[5]));
m_oPath.AddSpaceNoCheck();
return true;
}
else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) &&
(fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2)))
{
m_oPath.AddSize(60);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[0]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[1]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[4]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[5]));
m_oPath.AddSpaceNoCheck();
return true;
}
}
}
break;
}
default:
break;
}
}
else
{
unsigned int lSize = m_lCoordsSizeCur;
for (unsigned int i = 0; i < lSize; i += 2)
{
if (bIsClipping)
{
oBounds.CheckPoint(m_pCoordsArray[i], m_pCoordsArray[i + 1]);
}
m_pCoordsArray[i] *= m_dCoordsScaleX;
m_pCoordsArray[i + 1] *= m_dCoordsScaleY;
}
}
}
if (bIsClipping)
m_oTextClipBounds.Intersect(oBounds);
unsigned int lCurrentCoord = 0;
for (unsigned int nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand)
{
switch (m_pPathTypes[nCommand])
{
case 0:
{
m_oPath.AddSize(30);
m_oPath.AddCharNoCheck('M');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddSpaceNoCheck();
break;
}
case 1:
{
m_oPath.AddSize(30);
m_oPath.AddCharNoCheck('L');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddSpaceNoCheck();
break;
}
case 2:
{
m_oPath.AddSize(80);
m_oPath.AddCharNoCheck('C');
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddSpaceNoCheck();
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddCharNoCheck(',');
m_oPath.AddIntNoCheckDel10(round(10 * m_pCoordsArray[lCurrentCoord++]));
m_oPath.AddSpaceNoCheck();
break;
}
case 3:
{
m_oPath.AddSize(2);
m_oPath.AddCharNoCheck('Z');
m_oPath.AddSpaceNoCheck();
break;
}
default:
break;
}
}
if (bIsClipping)
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandStart);
m_oClipMetafile.WriteLONG(CMetafile::ctBeginCommand, c_nClipType);
lCurrentCoord = 0;
for (ULONG nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand)
{
switch (m_pPathTypes[nCommand])
{
case 0:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY);
break;
}
case 1:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY);
break;
}
case 2:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandCurveTo);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleX);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++] / m_dCoordsScaleY);
break;
}
case 3:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandClose);
break;
}
default:
break;
}
}
m_oClipMetafile.WriteLONG(CMetafile::ctEndCommand, c_nClipType);
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandEnd);
}
return false;
}
LONG WriteTempClip()
{
LONG nRet = m_oClipMetafile.GetPosition();
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandStart);
m_oClipMetafile.WriteLONG(CMetafile::ctBeginCommand, c_nClipType);
LONG lCurrentCoord = 0;
for (ULONG nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand)
{
switch (m_pPathTypes[nCommand])
{
case 0:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
break;
}
case 1:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
break;
}
case 2:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandCurveTo);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oClipMetafile.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
break;
}
case 3:
{
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandClose);
break;
}
default:
break;
}
}
m_oClipMetafile.WriteLONG(CMetafile::ctEndCommand, c_nClipType);
m_oClipMetafile.WriteCommandType(CMetafile::ctPathCommandEnd);
return nRet;
}
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
void WriteToPathToSimpleVector()
{
if (m_lPathTypesSizeCur <= 4 && !m_bIsCurveToExist)
{
switch (m_lPathTypesSizeCur)
{
case 2:
{
if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1])
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[2]);
m_oVectors.WriteDouble(m_pCoordsArray[3]);
return;
}
break;
}
case 3:
{
if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1])
{
if (3 == m_pPathTypes[2])
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[2]);
m_oVectors.WriteDouble(m_pCoordsArray[3]);
return;
}
else
{
if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2))
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[2]);
m_oVectors.WriteDouble(m_pCoordsArray[3]);
return;
}
else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2))
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[4]);
m_oVectors.WriteDouble(m_pCoordsArray[5]);
return;
}
}
}
break;
}
case 4:
{
if (0 == m_pPathTypes[0] && 1 == m_pPathTypes[1] && 1 == m_pPathTypes[2])
{
if ((fabs(m_pCoordsArray[4] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[5] - m_pCoordsArray[1]) < 0.2))
{
if (3 == m_pPathTypes[3])
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[2]);
m_oVectors.WriteDouble(m_pCoordsArray[3]);
return;
}
else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) &&
(fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2)))
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[2]);
m_oVectors.WriteDouble(m_pCoordsArray[3]);
return;
}
}
else if ((fabs(m_pCoordsArray[2] - m_pCoordsArray[0]) < 0.2) &&
(fabs(m_pCoordsArray[3] - m_pCoordsArray[1]) < 0.2))
{
if (3 == m_pPathTypes[3])
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[4]);
m_oVectors.WriteDouble(m_pCoordsArray[5]);
return;
}
else if (1 == m_pPathTypes[3] && ((fabs(m_pCoordsArray[6] - m_pCoordsArray[2]) < 0.2) &&
(fabs(m_pCoordsArray[7] - m_pCoordsArray[3]) < 0.2)))
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[0]);
m_oVectors.WriteDouble(m_pCoordsArray[1]);
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[4]);
m_oVectors.WriteDouble(m_pCoordsArray[5]);
return;
}
}
}
break;
}
default:
break;
}
}
unsigned int lCurrentCoord = 0;
for (unsigned int nCommand = 0; nCommand < m_lPathTypesSizeCur; ++nCommand)
{
switch (m_pPathTypes[nCommand])
{
case 0:
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
break;
}
case 1:
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
break;
}
case 2:
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandCurveTo);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
m_oVectors.WriteDouble(m_pCoordsArray[lCurrentCoord++]);
break;
}
case 3:
{
m_oVectors.WriteCommandType(CMetafile::ctPathCommandClose);
break;
}
default:
break;
}
}
}
#endif
void CheckPathTextRect(CDoubleBounds& oBounds)
{
unsigned int lSize = m_lCoordsSizeCur;
for (unsigned int i = 0; i < lSize; i += 2)
{
oBounds.CheckPoint(m_pCoordsArray[i] * m_dCoordsScaleX, m_pCoordsArray[i + 1] * m_dCoordsScaleY);
}
}
inline void NewSVG()
{
m_oDocument.SetCurSize(m_lEmtyDocChecker);
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
if (m_bIsSimpleSetupBrush && !m_bIsSimpleGraphics)
{
m_pLastBrush->Color1 = m_lBrushColorOld;
m_pLastBrush->Alpha1 = m_lBrushAlphaOld;
}
m_oVectors.ClearNoAttack();
m_bIsSimpleGraphics = true;
m_bIsSimpleSetupBrush = false;
#endif
}
};
}
#endif // _ASC_HTMLRENDERER_SVGWRITER2_H_
#pragma once
#include "../../DesktopEditor/common/File.h"
#include "TextItem.h"
#include "Common.h"
class CDstInfo
{
public:
CString m_strDstFilePath;
CString m_strAdditionalPath;
CString m_strDstMedia;
bool m_bIsWeb;
public:
CDstInfo()
{
m_strDstFilePath = _T("");
m_strAdditionalPath = _T("");
m_strDstMedia = _T("");
m_bIsWeb = false;
}
CDstInfo(const CDstInfo& oInfo)
{
*this = oInfo;
}
CDstInfo& operator=(const CDstInfo& oSrc)
{
m_strDstFilePath = oSrc.m_strDstFilePath;
m_strAdditionalPath = oSrc.m_strAdditionalPath;
m_strDstMedia = oSrc.m_strDstMedia;
m_bIsWeb = oSrc.m_bIsWeb;
return *this;
}
};
namespace NSStrings
{
class CStringWriter : public CTextItem
{
public:
CStringWriter() : CTextItem()
{
}
virtual ~CStringWriter()
{
}
public:
AVSINLINE void WriteString(CString& sString)
{
size_t nLen = (size_t)sString.GetLength();
#ifdef _UNICODE
CTextItem::WriteString(sString.GetBuffer(), nLen);
#else
CStringW str = (CStringW)sString;
WriteString(str.GetBuffer(), nLen);
#endif
}
AVSINLINE void WriteString(wchar_t* pString, const size_t& nLen)
{
CTextItem::WriteString(pString, nLen);
}
AVSINLINE void Write(CStringWriter& oWriter)
{
CTextItem::WriteString(oWriter.m_pData, oWriter.m_lSizeCur);
}
};
}
#pragma once
#include "..\stdafx.h"
#include "Const.h"
#include "StringWriter.h"
#include "..\Graphics\Structures.h"
#include "..\Graphics\Matrix.h"
#include "FontManager.h"
namespace NSHtmlRenderer
{
static wchar_t g_wc_amp = wchar_t('&');
static wchar_t g_wc_apos = wchar_t('\'');
static wchar_t g_wc_lt = wchar_t('<');
static wchar_t g_wc_qt = wchar_t('>');
static wchar_t g_wc_quot = wchar_t('\"');
static _bstr_t g_bstr_amp = L"&amp;";
static _bstr_t g_bstr_apos = L"&apos;";
static _bstr_t g_bstr_lt = L"&lt;";
static _bstr_t g_bstr_qt = L"&gt;";
static _bstr_t g_bstr_quot = L"\"";
class CStyles
{
private:
CAtlMap<CString, LONG> m_mapStyles;
LONG m_lNexrID;
public:
NSStrings::CStringWriter m_oWriterCSS;
double m_dDpiY;
public:
CStyles() : m_mapStyles(), m_lNexrID(0)
{
}
~CStyles()
{
m_mapStyles.RemoveAll();
}
public:
void NewDocument()
{
m_mapStyles.RemoveAll();
m_lNexrID = 0;
m_oWriterCSS.Clear();
CString strCSS =
_T(".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.RemoveAll();
m_lNexrID = 0;
m_oWriterCSS.Clear();
}
void WriteStylesForDiffBrowsers(const CString& strDir)
{
CString strIE = _T(".bp { position: absolute; z-index:100; margin-left: 0px; margin-top: 0px; padding: 0px; float: none; text-align: justify; text-align-last: justify; }");
CString strOp = _T(".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; }");
CString strOt = _T(".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; }");
CDirectory::SaveToFile(strDir + _T("\\css_ie.css"), strIE);
CDirectory::SaveToFile(strDir + _T("\\css_opera.css"), strOp);
CDirectory::SaveToFile(strDir + _T("\\css_other.css"), strOt);
}
LONG GetClassID(NSStructures::CFont* pFont, NSStructures::CBrush* pBrush)
{
CString strFormat = _T("");
int nSize = round(m_dDpiY * pFont->Size / 72);
if (nSize >= 10)
--nSize;
if (pFont->Italic && pFont->Bold)
{
strFormat.Format(g_string_text_css_ib, pFont->Name, nSize, ConvertColor(pBrush->Color1));
}
else if (pFont->Italic)
{
strFormat.Format(g_string_text_css_i, pFont->Name, nSize, ConvertColor(pBrush->Color1));
}
else if (pFont->Bold)
{
strFormat.Format(g_string_text_css_b, pFont->Name, nSize, ConvertColor(pBrush->Color1));
}
else
{
strFormat.Format(g_string_text_css, pFont->Name, nSize, ConvertColor(pBrush->Color1));
}
CAtlMap<CString, LONG>::CPair* pPair = m_mapStyles.Lookup(strFormat);
if (NULL == pPair)
{
// новый стиль
++m_lNexrID;
m_mapStyles.SetAt(strFormat, m_lNexrID);
CString strCSS = _T("");
strCSS.Format(g_string_style_name, m_lNexrID);
m_oWriterCSS.WriteString(strCSS);
m_oWriterCSS.WriteString(strFormat);
m_oWriterCSS.WriteString(g_bstr_script_close);
return m_lNexrID;
}
return pPair->m_value;
}
};
class CWord
{
public:
NSStructures::CFont m_oFont;
NSStructures::CBrush m_oBrush;
NSStrings::CTextItem 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(10)
{
m_dX = 0;
m_dY = 0;
m_dWidth = 0;
m_dHeight = 0;
m_dBaseLinePos = 0;
m_dWidthWithoutSpaces = 0;
}
CWord(CFontManager* pFontManager, NSStructures::CBrush* pBrush, NSStrings::CTextItem& 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 (_T("") != 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;
}
AVSINLINE void GetCorrectString(CString& strText)
{
strText.Replace(_T("&"), _T("&amp;"));
strText.Replace(_T("'"), _T("&apos;"));
strText.Replace(_T("<"), _T("&lt;"));
strText.Replace(_T(">"), _T("&gt;"));
strText.Replace(_T("\""), _T("&quot;"));
}
AVSINLINE void WriteToStringWriter(NSStrings::CStringWriter& oWriter)
{
size_t nCurrent = 0;
size_t nCount = m_oText.GetCurSize();
size_t nCurrentOld = nCurrent;
wchar_t* pData = m_oText.GetBuffer();
wchar_t* pStartData = pData;
while (nCurrent < nCount)
{
wchar_t c = *pData++;
if (g_wc_amp == c)
{
if (nCurrentOld != nCurrent)
oWriter.WriteString(pStartData, nCurrent - nCurrentOld);
oWriter.WriteString(g_bstr_amp);
++nCurrent;
nCurrentOld = nCurrent;
pStartData = pData;
}
/*else if (g_wc_apos == c)
{
if (nCurrentOld != nCurrent)
oWriter.WriteString(pStartData, nCurrent - nCurrentOld);
oWriter.WriteString(g_bstr_apos);
++nCurrent;
nCurrentOld = nCurrent;
pStartData = pData;
}*/
else if (g_wc_lt == c)
{
if (nCurrentOld != nCurrent)
oWriter.WriteString(pStartData, nCurrent - nCurrentOld);
oWriter.WriteString(g_bstr_lt);
++nCurrent;
nCurrentOld = nCurrent;
pStartData = pData;
}
else if (g_wc_qt == c)
{
if (nCurrentOld != nCurrent)
oWriter.WriteString(pStartData, nCurrent - nCurrentOld);
oWriter.WriteString(g_bstr_qt);
++nCurrent;
nCurrentOld = nCurrent;
pStartData = pData;
}
else if (g_wc_quot == c)
{
if (nCurrentOld != nCurrent)
oWriter.WriteString(pStartData, nCurrent - nCurrentOld);
oWriter.WriteString(g_bstr_quot);
++nCurrent;
nCurrentOld = nCurrent;
pStartData = pData;
}
else
{
++nCurrent;
}
}
if (nCurrentOld != nCurrent)
oWriter.WriteString(pStartData, nCurrent - nCurrentOld);
}
};
class CTextLine
{
public:
NSStrings::CStringWriter* m_pTextMeasurer;
CAtlList<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();
POSITION pos = oSrc.m_arWords.GetHeadPosition();
while (NULL != pos)
{
CWord* pWord = oSrc.m_arWords.GetNext(pos);
CWord* pWordNew = new CWord(*pWord);
m_arWords.AddTail(pWordNew);
}
return *this;
}
public:
void Clear()
{
POSITION pos = m_arWords.GetHeadPosition();
while (NULL != pos)
{
CWord* pWord = m_arWords.GetNext(pos);
RELEASEOBJECT(pWord);
}
m_arWords.RemoveAll();
m_dMinTop = 10000000;
}
void AddWord(CWord* pWord)
{
// смотрим, какое слово предыдущее.
// если оно - полностью пробел - то он прищел из пдф. а значит он любой длины может быть.
// зачем он нужен?? непонятно. Поэтому удаляем такое слово
POSITION pos = m_arWords.GetTailPosition();
if (NULL != pos)
{
CWord* pTail = m_arWords.GetNext(pos);
if (pTail->GetCountSpaceLast() == pTail->m_oText.GetCurSize())
{
m_arWords.RemoveTail();
RELEASEOBJECT(pTail);
}
}
if (m_dMinTop > pWord->m_dY)
m_dMinTop = pWord->m_dY;
m_arWords.AddTail(pWord);
}
CWord* GetLast()
{
return m_arWords.GetTail();
}
CWord* GetHead()
{
return m_arWords.GetHead();
}
size_t GetCount()
{
return m_arWords.GetCount();
}
public:
inline void Write(NSStrings::CStringWriter* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles, const LONG& lIndexZ)
{
return Write3(pWriter, dDpiX, dDpiY, pStyles, lIndexZ);
}
void Write1(NSStrings::CStringWriter* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles)
{
// временно
//return Write2(pWriter, dDpiX, dDpiY);
size_t nCountWords = m_arWords.GetCount();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = m_arWords.GetTail();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
CString strPar = _T("");
strPar.Format(g_string_paragraph2, pWord->m_oFont.Name, (int)(dDpiY * pWord->m_oFont.Size / 72), ConvertColor(pWord->m_oBrush.Color1));
pWriter->WriteString(strPar);
POSITION pos = m_arWords.GetHeadPosition();
POSITION posOld = m_arWords.GetTailPosition();
while (NULL != pos)
{
pWord = m_arWords.GetNext(pos);
if (pWord->m_oFont.IsEqual(pFont0) && (pWord->m_oBrush.IsEqual(pBrush0)))
{
CString strSpan = _T("");
strSpan.Format(g_string_span1, (int)pWord->m_dX, (int)pWord->m_dY);
pWriter->WriteString(strSpan);
}
else
{
CString strSpan = _T("");
strSpan.Format(g_string_span3, pWord->m_oFont.Name, (int)(dDpiY * pWord->m_oFont.Size / 72), ConvertColor(pWord->m_oBrush.Color1));
pWriter->WriteString(strSpan);
}
//pWriter->WriteString(pWord->m_strText);
pWord->WriteToStringWriter(*pWriter);
if (pos != posOld)
{
pWriter->WriteString(g_bstr_space);
}
pWriter->WriteString(g_bstr_span_end);
}
pWriter->WriteString(g_bstr_paragraph_end);
}
void Write2(NSStrings::CStringWriter* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles)
{
size_t nCountWords = m_arWords.GetCount();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = m_arWords.GetHead();
NSStructures::CFont* pFont0 = &pWord->m_oFont;
NSStructures::CBrush* pBrush0 = &pWord->m_oBrush;
CString strPar = _T("");
strPar.Format(g_string_paragraph3, (int)pWord->m_dX, (int)pWord->m_dY, pWord->m_oFont.Name, (int)(dDpiY * pWord->m_oFont.Size / 72), ConvertColor(pWord->m_oBrush.Color1));
pWriter->WriteString(strPar);
CString strText = _T("");
POSITION pos = m_arWords.GetHeadPosition();
while (NULL != pos)
{
pWord = m_arWords.GetNext(pos);
strText += pWord->m_oText.GetCString();
if (NULL != pos)
strText += _T(" ");
}
pWriter->WriteString(strText);
pWriter->WriteString(g_bstr_paragraph_end);
}
void Write3(NSStrings::CStringWriter* pWriter, double& dDpiX, double& dDpiY, CStyles* pStyles, const LONG& lIndexZ)
{
DeleteEmptyWords();
size_t nCountWords = m_arWords.GetCount();
if (0 == nCountWords)
return;
// генерим параграф, один на строку
CWord* pWord = m_arWords.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;
POSITION pos = m_arWords.GetHeadPosition();
m_arWords.GetNext(pos);
while (NULL != pos)
{
pWord = m_arWords.GetNext(pos);
pWord->m_dWidth = pWord->m_dWidthWithoutSpaces;
nRight = (int)(pWord->m_dX + pWord->m_dWidth);
}
pos = m_arWords.GetHeadPosition();
pWord = m_arWords.GetHead();
pStyles->m_dDpiY = dDpiY;
LONG lID = pStyles->GetClassID(&pWord->m_oFont, &pWord->m_oBrush);
LONG lDecoration = pWord->m_oFont.GetTextDecorationStyle();
CString strPar = _T("");
strPar.Format(g_string_paragraph_style, lID, (int)pWord->m_dX, (int)m_dMinTop, nRight - nLeft);
pWriter->WriteString(strPar);
pWriter->WriteString(g_bstr_nobr_start);
if ((0 == lDecoration) || (3 < lDecoration))
{
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
}
else
{
switch (lDecoration)
{
case 1:
pWriter->WriteString(g_string_span_style_underline2);
break;
case 2:
pWriter->WriteString(g_string_span_style_strike2);
break;
case 3:
pWriter->WriteString(g_string_span_style_underline_strike2);
break;
default:
break;
}
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
pWriter->WriteString(g_bstr_span_end);
}
m_arWords.GetNext(pos);
bool bSpanClose = false;
while (NULL != pos)
{
pWord = m_arWords.GetNext(pos);
if (1.0 < (pWord->m_dX - dRight))
{
pWriter->WriteString(g_bstr_space2);
}
dRight = pWord->m_dX + pWord->m_dWidthWithoutSpaces;
if (bSpanClose)
pWriter->WriteString(g_bstr_span_end);
bSpanClose = true;
lID = pStyles->GetClassID(&pWord->m_oFont, &pWord->m_oBrush);
CString strSpan = _T("");
lDecoration = pWord->m_oFont.GetTextDecorationStyle();
switch (lDecoration)
{
case 0:
strSpan.Format(g_string_span_style, lID);
break;
case 1:
strSpan.Format(g_string_span_style_underline, lID);
break;
case 2:
strSpan.Format(g_string_span_style_strike, lID);
break;
case 3:
strSpan.Format(g_string_span_style_underline_strike, lID);
break;
default:
strSpan.Format(g_string_span_style, lID);
break;
}
pWriter->WriteString(strSpan);
//pWriter->WriteString(pWord->GetCorrectString());
pWord->WriteToStringWriter(*pWriter);
}
if (bSpanClose)
pWriter->WriteString(g_bstr_span_end);
pWriter->WriteString(g_bstr_nobr_end);
pWriter->WriteString(g_bstr_paragraph_end);
//CString strLine = _T("");
//strLine.Format(g_string_lineFunc, m_lNextID++, nRight - nLeft);
//m_pTextMeasurer->WriteString(strLine);
}
void DeleteEmptyWords()
{
POSITION pos = m_arWords.GetHeadPosition();
CWord* pWord = NULL;
while (NULL != pos)
{
POSITION posOld = pos;
pWord = m_arWords.GetNext(pos);
if (pWord->GetCountSpaceLast() == pWord->m_oText.GetCurSize())
{
m_arWords.RemoveAt(posOld);
RELEASEOBJECT(pWord);
}
}
if (0 != m_arWords.GetCount())
{
// удалим последние пробелы линии.
pWord = m_arWords.GetTail();
pWord->m_oText.RemoveLastSpaces();
}
}
void Merge()
{
POSITION pos = m_arWords.GetHeadPosition();
if (NULL == pos)
return;
POSITION posCur = pos;
CWord* pWordPrev = m_arWords.GetNext(posCur);
double dRightPos = pWordPrev->m_dX + pWordPrev->m_dWidth;
while (NULL != posCur)
{
POSITION posCurOld = posCur;
CWord* pWord = m_arWords.GetNext(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.AddSpace();
}
pWordPrev->m_oText += pWord->m_oText;
m_arWords.RemoveAt(posCurOld);
RELEASEOBJECT(pWord);
}
else
{
if (bNextWord)
pWordPrev->m_oText.AddSpace();
pos = posCur;
pWordPrev = pWord;
}
}
}
};
class CText
{
public:
CFontManager m_oFontManager;
CTextLine m_oCurrentLine;
NSStrings::CStringWriter* 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;
NSHtmlRenderer::CMatrix* m_pTransform;
LONG m_lIndexZ;
bool m_bIsNewLine;
bool m_bIsPDFTextStyle;
NSStrings::CTextItem m_oTextItem;
private:
double m_dEpsX;
double m_dEpsY;
public:
CText() : m_oFontManager(), m_oCurrentLine(), m_oTextItem(10)//, 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, NSHtmlRenderer::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:
AVSINLINE 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 = !m_oFontManager.m_oFont.m_oFont.IsEqual2(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 = _T("");
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.GetCString(), 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.AddSpace();
}
pTail->m_oText += 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(BSTR 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 = !m_oFontManager.m_oFont.m_oFont.IsEqual2(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 (NULL == bsGid)
{
m_oFontManager.SetStringGid(0);
BSTR bsText = m_oTextItem.GetCString().AllocSysString();
m_oFontManager.MeasureStringPix(bsText, x, y, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
SysFreeString(bsText);
}
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 += m_oTextItem;
pWordLast->m_dWidth = x + width - pWordLast->m_dX;
}
return;
}
if (dDelta > dSpace)
pWordLast->m_oText.AddSpace();
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 += 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 += 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:
AVSINLINE void CommandText(BSTR& bsText, BSTR& bsGid, double& x, double& y, double& width, double& height, double& baselineoffset, LONG& lIndexZ)
{
if (NULL == bsText)
return;
m_lIndexZ = lIndexZ;
m_oTextItem.SetText(bsText);
if (0 == m_oTextItem.GetCurSize())
return;
if (bsGid != NULL)
{
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);
}
};
}
\ No newline at end of file
#pragma once
//#include "../stdafx.h"
#if defined(_WIN32) || defined (_WIN64)
#include <atlbase.h>
#include <atlstr.h>
#else
#include "../../Common/DocxFormat/Source/Base/ASCString.h"
#endif
#ifndef AVSINLINE
#if defined(_MSC_VER)
#define AVSINLINE __forceinline
#else
#define AVSINLINE inline
#endif
#endif
namespace NSStrings
{
class CTextItem
{
protected:
wchar_t* m_pData;
size_t m_lSize;
wchar_t* m_pDataCur;
size_t m_lSizeCur;
public:
CTextItem()
{
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = m_lSize;
}
CTextItem(const CTextItem& oSrc)
{
m_pData = NULL;
*this = oSrc;
}
CTextItem& operator=(const CTextItem& oSrc)
{
RELEASEMEM(m_pData);
m_lSize = oSrc.m_lSize;
m_lSizeCur = oSrc.m_lSizeCur;
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
memcpy(m_pData, oSrc.m_pData, m_lSizeCur * sizeof(wchar_t));
m_pDataCur = m_pData + m_lSizeCur;
return *this;
}
CTextItem(const size_t& nLen)
{
m_lSize = nLen;
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
m_lSizeCur = 0;
m_pDataCur = m_pData;
}
CTextItem(wchar_t* pData, const size_t& nLen)
{
m_lSize = nLen;
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
memcpy(m_pData, pData, m_lSize * sizeof(wchar_t));
m_lSizeCur = m_lSize;
m_pDataCur = m_pData + m_lSize;
}
CTextItem(wchar_t* pData, BYTE* pUnicodeChecker = NULL)
{
size_t nLen = GetStringLen(pData);
m_lSize = nLen;
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
memcpy(m_pData, pData, m_lSize * sizeof(wchar_t));
m_lSizeCur = m_lSize;
m_pDataCur = m_pData + m_lSize;
if (NULL != pUnicodeChecker)
{
wchar_t* pMemory = m_pData;
while (pMemory < m_pDataCur)
{
if (!pUnicodeChecker[*pMemory])
*pMemory = wchar_t(' ');
++pMemory;
}
}
}
virtual ~CTextItem()
{
RELEASEMEM(m_pData);
}
AVSINLINE void AddSize(const size_t& nSize)
{
if (NULL == m_pData)
{
m_lSize = nSize > 1000 ? nSize : 1000;
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
m_lSizeCur = 0;
m_pDataCur = m_pData;
return;
}
if ((m_lSizeCur + nSize) > m_lSize)
{
while ((m_lSizeCur + nSize) > m_lSize)
{
m_lSize *= 2;
}
wchar_t* pRealloc = (wchar_t*)realloc(m_pData, m_lSize * sizeof(wchar_t));
if (NULL != pRealloc)
{
// реаллок сработал
m_pData = pRealloc;
m_pDataCur = m_pData + m_lSizeCur;
}
else
{
wchar_t* pMalloc = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(wchar_t));
free(m_pData);
m_pData = pMalloc;
m_pDataCur = m_pData + m_lSizeCur;
}
}
}
public:
AVSINLINE void operator+=(const CTextItem& oTemp)
{
WriteString(oTemp.m_pData, oTemp.m_lSizeCur);
}
AVSINLINE void operator+=(CString& oTemp)
{
size_t nLen = (size_t)oTemp.GetLength();
#ifdef _UNICODE
WriteString(oTemp.GetBuffer(), nLen);
#else
CStringW str = (CStringW)oTemp;
WriteString(str.GetBuffer(), nLen);
#endif
}
AVSINLINE wchar_t operator[](const size_t& nIndex)
{
if (nIndex < m_lSizeCur)
return m_pData[nIndex];
return 0;
}
AVSINLINE void SetText(BSTR& bsText)
{
ClearNoAttack();
size_t nLen = GetStringLen(bsText);
WriteString(bsText, nLen);
for (size_t i = 0; i < nLen; ++i)
{
if (WCHAR(8233) == m_pData[i])
m_pData[i] = WCHAR(' ');
}
}
AVSINLINE void AddSpace()
{
AddSize(1);
*m_pDataCur = wchar_t(' ');
++m_lSizeCur;
++m_pDataCur;
}
AVSINLINE void CorrectUnicode(const BYTE* pUnicodeChecker)
{
if (NULL != pUnicodeChecker)
{
wchar_t* pMemory = m_pData;
while (pMemory < m_pDataCur)
{
if (!pUnicodeChecker[*pMemory])
*pMemory = wchar_t(' ');
++pMemory;
}
}
}
AVSINLINE void RemoveLastSpaces()
{
wchar_t* pMemory = m_pDataCur - 1;
while ((pMemory > m_pData) && (wchar_t(' ') == *pMemory))
{
--pMemory;
--m_lSizeCur;
--m_pDataCur;
}
}
AVSINLINE bool IsSpace()
{
if (1 != m_lSizeCur)
return false;
return (wchar_t(' ') == *m_pData);
}
public:
AVSINLINE void WriteString(const wchar_t* pString, const size_t& nLen)
{
AddSize(nLen);
memcpy(m_pDataCur, pString, nLen * sizeof(wchar_t));
m_pDataCur += nLen;
m_lSizeCur += nLen;
}
AVSINLINE size_t GetCurSize()
{
return m_lSizeCur;
}
AVSINLINE void SetCurSize(ULONG lCurSize)
{
m_lSizeCur = (size_t)lCurSize;
m_pDataCur = m_pData + m_lSizeCur;
}
AVSINLINE size_t GetSize()
{
return m_lSize;
}
AVSINLINE void Clear()
{
RELEASEMEM(m_pData);
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
AVSINLINE void ClearNoAttack()
{
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
AVSINLINE size_t GetStringLen(const wchar_t* pData)
{
const wchar_t* s = pData;
for (; *s != 0; ++s);
return (size_t)(s - pData);
}
AVSINLINE CString GetCString()
{
CString str(m_pData, (int)m_lSizeCur);
return str;
}
AVSINLINE wchar_t* GetBuffer()
{
return m_pData;
}
AVSINLINE void AddCharNoCheck(const WCHAR& wc)
{
*m_pDataCur++ = wc;
++m_lSizeCur;
}
AVSINLINE void AddIntNoCheck(int val)
{
if (0 == val)
{
*m_pDataCur++ = (WCHAR)'0';
++m_lSizeCur;
return;
}
if (val < 0)
{
val = -val;
*m_pDataCur++ = (WCHAR)'-';
++m_lSizeCur;
}
int len = 0;
int oval = val;
while (oval > 0)
{
oval /= 10;
++len;
}
oval = 1;
while (val > 0)
{
m_pDataCur[len - oval] = (WCHAR)('0' + (val % 10));
++oval;
val /= 10;
}
m_pDataCur += len;
m_lSizeCur += len;
}
AVSINLINE void AddIntNoCheckDel10(int val)
{
if (0 == val)
{
*m_pDataCur++ = (WCHAR)'0';
++m_lSizeCur;
return;
}
if (val < 0)
{
val = -val;
*m_pDataCur++ = (WCHAR)'-';
++m_lSizeCur;
}
int len = 0;
int oval = val;
while (oval > 0)
{
oval /= 10;
++len;
}
oval = 1;
int nLastS = (val % 10);
if (0 != nLastS)
{
++len;
m_pDataCur[len - oval] = (WCHAR)('0' + nLastS);
++oval;
m_pDataCur[len - oval] = (WCHAR)('.');
++oval;
val /= 10;
}
else
{
--len;
val /= 10;
}
while (val > 0)
{
m_pDataCur[len - oval] = (WCHAR)('0' + (val % 10));
++oval;
val /= 10;
}
m_pDataCur += len;
m_lSizeCur += len;
}
AVSINLINE void AddStringNoCheck(const wchar_t* pData, const int& len)
{
memcpy(m_pDataCur, pData, len * sizeof(wchar_t));
m_pDataCur += len;
m_lSizeCur += len;
}
AVSINLINE void AddSpaceNoCheck()
{
*m_pDataCur = WCHAR(' ');
++m_pDataCur;
++m_lSizeCur;
}
};
}
#ifndef _ASC_HTMLRENDERER_VMLWRITER_H_
#define _ASC_HTMLRENDERER_VMLWRITER_H_
#include "Common.h"
namespace NSHtmlRenderer
{
class CVMLWriter
{
public:
NSStringUtils::CStringBuilder m_oPath;
NSStringUtils::CStringBuilder m_oDocument;
LONG m_lCurDocumentID;
LONG m_lClippingPath;
bool m_bIsClipping;
LONG m_lClipMode;
bool m_bIsClippingNow;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
double m_lWidth;
double m_lHeight;
double m_dDpiX;
double m_dDpiY;
public:
CVMLWriter() : m_oPath(), m_oDocument()
{
m_lCurDocumentID = 0;
m_lClippingPath = 0;
m_pPen = NULL;
m_pBrush = NULL;
m_dDpiX = 96;
m_dDpiY = 96;
m_lClipMode = c_nWindingFillMode;
m_bIsClipping = false;
m_bIsClippingNow = false;
}
void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush)
{
m_pPen = pPen;
m_pBrush = pBrush;
}
void CloseFile(std::wstring strFile = L"")
{
if (L"" != strFile)
{
m_oDocument.WriteString(L"</v:group>\n</xml>", 17);
NSFile::CFileBinary oFile;
oFile.CreateFileW(strFile);
BYTE* pData;
LONG nDataSize;
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(m_oDocument.GetBuffer(), m_oDocument.GetCurSize(), pData, nDataSize);
oFile.WriteFile(pData, nDataSize);
RELEASEARRAYOBJECTS(pData);
}
if (3000000 < m_oDocument.GetSize())
m_oDocument.Clear();
m_oDocument.ClearNoAttack();
m_oPath.ClearNoAttack();
}
void NewDocument(double& dWidth, double& dHeigth, LONG& lPageNumber)
{
CloseFile(L"");
m_lWidth = (int)dWidth;
m_lHeight = (int)dHeigth;
m_lCurDocumentID = lPageNumber;
m_oDocument.AddSize(150);
m_oDocument.WriteString(L"<xml xmlns:v=\"urn:schemas-microsoft-com:vml\">\n<v:group id=\"page", 63);
m_oDocument.AddIntNoCheck((int)m_lCurDocumentID);
m_oDocument.WriteString(L"\" style=\"position: absolute; width:1; height:1;\" coordsize=\"1 1\">\n", 66);
}
public:
inline void WritePathEnd()
{
m_oPath.ClearNoAttack();
}
inline void WritePathStart()
{
m_oPath.ClearNoAttack();
}
void WritePathClose()
{
if (m_bIsClippingNow)
return;
m_oPath.AddCharSafe('x');
}
void WritePathMoveTo(double& x, double& y)
{
if (m_bIsClippingNow)
return;
m_oPath.AddSize(30);
m_oPath.AddCharNoSafe('m');
m_oPath.AddIntNoCheck(round(x));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(y));
m_oPath.AddCharNoSafe(' ');
}
void WritePathLineTo(double& x, double& y)
{
if (m_bIsClippingNow)
return;
if (0 == m_oPath.GetCurSize())
{
WritePathMoveTo(x, y);
}
m_oPath.AddSize(30);
m_oPath.AddCharNoSafe('l');
m_oPath.AddIntNoCheck(round(x));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(y));
m_oPath.AddCharNoSafe(' ');
}
void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
if (0 == m_oPath.GetCurSize())
{
WritePathMoveTo(x1, y1);
}
m_oPath.AddSize(80);
m_oPath.AddCharNoSafe('c');
m_oPath.AddIntNoCheck(round(x1));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(y1));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(x2));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(y2));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(x3));
m_oPath.AddCharNoSafe(',');
m_oPath.AddIntNoCheck(round(y3));
m_oPath.AddCharNoSafe(' ');
}
void WriteDrawPath(LONG lType, Aggplus::CMatrix* pTransform, Aggplus::CGraphicsPathSimpleConverter* pConverter, CImageInfo& oInfo, const double& dAngle)
{
if (m_oPath.GetCurSize() < 3)
return;
int nStrokeColor = ConvertColor(m_pPen->Color);
m_oDocument.WriteString(L"<v:shape style=\"position:absolute; width:1; height:1\" stroked=\"", 63);
bool bStroke = false;
bool bFilled = false;
if (m_pPen->Alpha == 0)
lType &= 0xFF00;
if ((-1 == oInfo.m_lID) && (0 == m_pBrush->Alpha1))
lType &= 0xFF;
// canvas
if ((lType & 0x01) == 0x01)
{
bStroke = true;
}
if (lType > 0x01)
{
bFilled = true;
}
if (bStroke)
m_oDocument.WriteString(L"true", 4);
else
m_oDocument.WriteString(L"false", 5);
m_oDocument.WriteString(L"\" strokecolor=\"", 15);
m_oDocument.WriteHexColor3(nStrokeColor);
m_oDocument.WriteString(L"\" filled=\"", 10);
if (bFilled)
m_oDocument.WriteString(L"true", 4);
else
m_oDocument.WriteString(L"false", 5);
m_oDocument.WriteString(L"\" ", 2);
if (-1 != oInfo.m_lID)
{
if (itJPG == oInfo.m_eType)
{
m_oDocument.WriteString(L"path=\"", 6);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\"><v:fill src=\"media/image", 26);
m_oDocument.AddSize(10);
m_oDocument.AddIntNoCheck(oInfo.m_lID);
m_oDocument.WriteString(L".jpg\" type=\"frame\" opacity=\"", 28);
m_oDocument.AddIntNoCheckDel100((100 * m_pBrush->TextureAlpha) / 255);
m_oDocument.WriteString(L"\"/></v:shape>\n", 14);
}
else
{
m_oDocument.WriteString(L"path=\"", 6);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\"><v:fill src=\"media/image", 26);
m_oDocument.AddSize(10);
m_oDocument.AddIntNoCheck(oInfo.m_lID);
m_oDocument.WriteString(L".png\" type=\"frame\" opacity=\"", 28);
m_oDocument.AddIntNoCheckDel100((100 * m_pBrush->TextureAlpha) / 255);
m_oDocument.WriteString(L"\"/></v:shape>\n", 14);
}
}
else if (0xFF == m_pBrush->Alpha1)
{
if (0x00 == (lType & 0xFF) || (0 == m_pPen->DashStyle))
{
m_oDocument.WriteString(L"fillcolor=\"", 11);
m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1));
m_oDocument.WriteString(L"\" path=\"", 8);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\" />\n", 5);
}
else
{
m_oDocument.WriteString(L"fillcolor=\"", 11);
m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1));
m_oDocument.WriteString(L"\" path=\"", 8);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\"><v:stroke dashstyle=\"dot\"/></v:shape>\n", 40);
}
}
else
{
if (0x00 == (lType & 0xFF) || (0 == m_pPen->DashStyle))
{
m_oDocument.WriteString(L"fillcolor=\"", 11);
m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1));
m_oDocument.WriteString(L"\" path=\"", 8);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\"><v:fill opacity=\"", 19);
m_oDocument.AddIntNoCheckDel100((100 * m_pBrush->Alpha1) / 255);
m_oDocument.WriteString(L"\" />\n", 5);
}
else
{
m_oDocument.WriteString(L"fillcolor=\"", 11);
m_oDocument.WriteHexColor3(ConvertColor(m_pBrush->Color1));
m_oDocument.WriteString(L"\" path=\"", 8);
m_oDocument.Write(m_oPath);
m_oDocument.WriteString(L"\"><v:fill opacity=\"", 19);
m_oDocument.AddIntNoCheckDel100((100 * m_pBrush->Alpha1) / 255);
m_oDocument.WriteString(L"\"><v:stroke dashstyle=\"dot\"/></v:shape>\n", 40);
}
}
}
void WriteImage(CImageInfo oInfo, const double& x, const double& y, const double& w, const double& h, const double& dAngle)
{
m_oDocument.WriteString(L"<v:image src=\"media/image", 25);
m_oDocument.AddSize(100);
m_oDocument.AddIntNoCheck(oInfo.m_lID);
if (itJPG == oInfo.m_eType)
m_oDocument.WriteString(L".jpg\" style=\"left:", 18);
else
m_oDocument.WriteString(L".png\" style=\"left:", 18);
m_oDocument.AddIntNoCheck(round(x));
m_oDocument.WriteString(L";top:", 5);
m_oDocument.AddIntNoCheck(round(y));
m_oDocument.WriteString(L";width:", 7);
m_oDocument.AddIntNoCheck(round(w));
m_oDocument.WriteString(L";height:", 8);
m_oDocument.AddIntNoCheck(round(h));
m_oDocument.WriteString(L";\"/>", 4);
}
void WritePathClip()
{
m_bIsClipping = true;
m_bIsClippingNow = true;
++m_lClippingPath;
}
void WritePathClipEnd()
{
m_bIsClippingNow = false;
}
void WritePathResetClip()
{
m_bIsClipping = false;
}
inline void WriteStyleClip()
{
}
void WriteToMainHtml(NSStringUtils::CStringBuilder* pWriter, const CDstInfo& oInfo)
{
if (!oInfo.m_bIsWeb)
{
pWriter->WriteString(L"<v:vmlframe clip=\"true\" origin=\"0,0\" size=\"", 43);
pWriter->AddSize(100);
pWriter->AddIntNoCheck((int)m_lWidth);
pWriter->AddCharNoSafe(',');
pWriter->AddIntNoCheck((int)m_lHeight);
pWriter->WriteString(L"\" src=\"page", 11);
pWriter->AddIntNoCheck(m_lCurDocumentID);
pWriter->WriteString(L".vml#page", 9);
pWriter->AddIntNoCheck(m_lCurDocumentID);
pWriter->WriteString(L"\" unselectable=\"on\"/>\n", 22);
std::wstring sPath = oInfo.m_strDstFilePath + L"\\page" + std::to_wstring(m_lCurDocumentID) + L".vml";
CloseFile(sPath);
}
else
{
pWriter->WriteString(L"<v:vmlframe clip=\"true\" origin=\"0,0\" size=\"", 43);
pWriter->AddSize(100);
pWriter->AddIntNoCheck((int)m_lWidth);
pWriter->AddCharNoSafe(',');
pWriter->AddIntNoCheck((int)m_lHeight);
pWriter->WriteString(L"\" src=\"", 7);
pWriter->WriteString(oInfo.m_strAdditionalPath);
pWriter->WriteString(L"/page", 5);
pWriter->AddIntNoCheck(m_lCurDocumentID);
pWriter->WriteString(L".vml#page", 9);
pWriter->AddIntNoCheck(m_lCurDocumentID);
pWriter->WriteString(L"\" unselectable=\"on\"/>\n", 22);
std::wstring sPath = oInfo.m_strDstFilePath + L"\\page" + std::to_wstring(m_lCurDocumentID) + L".vml";
CloseFile(sPath);
}
}
};
}
#endif // _ASC_HTMLRENDERER_VMLWRITER_H_
#ifndef _ASC_HTMLRENDERER_VGW_H_
#define _ASC_HTMLRENDERER_VGW_H_
#include "Common.h"
#include "../../../DesktopEditor/graphics/GraphicsPath.h"
#include <vector>
namespace NSHtmlRenderer
{
// приходится в html разруливать простую графику.
// (линии (горизонтальные/вектикальные), ректы (не повернутые)).
// для них не нужно генерить html5-код, который генерит тяжелую картинку
// и подгружает ее в память
const LONG g_lSimpleCommandsCountMax = 100;
class CVectorGraphicsWriter
{
public:
enum SimpleCommand
{
scMoveTo = 0,
scLineTo = 1,
scClose = 2
};
class CSimpleCommand
{
public:
SimpleCommand m_eType;
double m_dX;
double m_dY;
};
public:
NSStringUtils::CStringBuilder m_oWriterSimpleGraphics;
NSStringUtils::CStringBuilder m_oWriterVMLPath;
NSStringUtils::CStringBuilder m_oWriterCanvas;
NSStringUtils::CStringBuilder m_oWriterVML;
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
Aggplus::CMatrix* m_pFullTransform;
double m_dCurrentMoveToX;
double m_dCurrentMoveToY;
bool m_bIsSimpleGraphics;
public:
bool m_bIsSimple;
bool m_bIsClip;
bool m_bIsClipping;
CSimpleCommand* m_arSimpleCommands;
LONG m_lCountSC;
public:
CVectorGraphicsWriter() : m_oWriterVML(), m_oWriterCanvas(), m_oWriterSimpleGraphics(), m_oWriterVMLPath()
{
m_bIsClip = FALSE;
m_bIsClipping = FALSE;
m_bIsSimple = TRUE;
m_pSimpleConverter = NULL;
m_pPen = NULL;
m_pBrush = NULL;
m_pFullTransform = NULL;
m_dCurrentMoveToX = 0;
m_dCurrentMoveToY = 0;
m_lCountSC = 0;
m_bIsSimpleGraphics = true;
m_arSimpleCommands = new CSimpleCommand[g_lSimpleCommandsCountMax];
}
~CVectorGraphicsWriter()
{
RELEASEARRAYOBJECTS(m_arSimpleCommands);
}
inline void EndPage()
{
m_oWriterSimpleGraphics.ClearNoAttack();
m_oWriterVMLPath.ClearNoAttack();
m_oWriterCanvas.ClearNoAttack();
m_oWriterVML.ClearNoAttack();
m_bIsSimpleGraphics = true;
}
inline void WriteBeginPath()
{
m_oWriterCanvas.WriteString(L"b(c);\n", 6);
}
inline void WriteEndPath()
{
m_oWriterVMLPath.ClearNoAttack();
m_bIsSimple = true;
m_lCountSC = 0;
}
void WritePathStart()
{
m_oWriterCanvas.WriteString(L"b(c);\n", 6);
}
void WritePathClose()
{
m_oWriterCanvas.WriteString(L"x(c);\n", 6);
if (!m_bIsClipping)
{
m_oWriterVMLPath.AddCharSafe('x');
}
if (m_bIsSimple)
{
if (0 < m_lCountSC)
{
m_arSimpleCommands[m_lCountSC].m_eType = scLineTo;
m_arSimpleCommands[m_lCountSC].m_dX = m_dCurrentMoveToX;
m_arSimpleCommands[m_lCountSC].m_dY = m_dCurrentMoveToY;
++m_lCountSC;
if (m_lCountSC == g_lSimpleCommandsCountMax)
{
m_bIsSimple = false;
}
}
}
}
void WritePathMoveTo(double& x, double& y)
{
m_oWriterCanvas.WriteString(L"m(c,", 4);
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L");\n", 3);
if (!m_bIsClipping)
{
m_oWriterVMLPath.AddCharSafe('m');
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath);
m_oWriterVMLPath.AddCharSafe(' ');
}
if (m_bIsSimple)
{
m_arSimpleCommands[m_lCountSC].m_eType = scMoveTo;
m_arSimpleCommands[m_lCountSC].m_dX = x;
m_arSimpleCommands[m_lCountSC].m_dY = y;
m_dCurrentMoveToX = x;
m_dCurrentMoveToY = y;
++m_lCountSC;
if (m_lCountSC == g_lSimpleCommandsCountMax)
{
m_bIsSimple = false;
}
}
}
void WritePathLineTo(double& x, double& y)
{
if (0 == m_oWriterVMLPath.GetCurSize())
{
m_oWriterCanvas.WriteString(L"m(c,", 4);
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L");\n", 3);
m_oWriterVMLPath.AddCharSafe('m');
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath);
m_oWriterVMLPath.AddCharSafe(' ');
}
m_oWriterCanvas.WriteString(L"l(c,", 4);
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L");\n", 3);
if (!m_bIsClipping)
{
m_oWriterVMLPath.AddCharSafe('l');
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath);
m_oWriterVMLPath.AddCharSafe(' ');
}
if (m_bIsSimple)
{
if (0 == m_lCountSC)
{
m_arSimpleCommands[m_lCountSC].m_eType = scMoveTo;
m_arSimpleCommands[m_lCountSC].m_dX = x;
m_arSimpleCommands[m_lCountSC].m_dY = y;
m_dCurrentMoveToX = x;
m_dCurrentMoveToY = y;
++m_lCountSC;
}
else
{
double _x = m_arSimpleCommands[m_lCountSC - 1].m_dX;
double _y = m_arSimpleCommands[m_lCountSC - 1].m_dY;
if ((FABS(_x - x) < 0.01) || (FABS(_y - y) < 0.01))
{
// продолжаем симпл!
m_arSimpleCommands[m_lCountSC].m_eType = scLineTo;
m_arSimpleCommands[m_lCountSC].m_dX = x;
m_arSimpleCommands[m_lCountSC].m_dY = y;
++m_lCountSC;
if (m_lCountSC == g_lSimpleCommandsCountMax)
{
m_bIsSimple = false;
}
}
}
}
}
void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
if (0 == m_oWriterVMLPath.GetCurSize())
{
m_oWriterCanvas.WriteString(L"m(c,", 4);
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L");\n", 3);
m_oWriterVMLPath.AddCharSafe('m');
WriteIntsToStringBuilder(round(x), round(y), &m_oWriterVMLPath);
m_oWriterVMLPath.AddCharSafe(' ');
}
m_oWriterCanvas.WriteString(L"cu(c,", 5);
WriteIntsToStringBuilder(round(x1), round(y1), round(x2), round(y2), round(x3), round(y3), &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L");\n", 3);
if (!m_bIsClipping)
{
m_oWriterVMLPath.AddCharSafe('c');
WriteIntsToStringBuilder(round(x1), round(y1), round(x2), round(y2), round(x3), round(y3), &m_oWriterVMLPath);
m_oWriterVMLPath.AddCharSafe(' ');
}
m_bIsSimple = false;
}
void WriteDrawPath(LONG lType, LONG lIDTx, LONG& lCurTxNumber, LONG& lPageNumber)
{
if (m_bIsSimple && (-1 == lIDTx))
{
// пишем по-крутому
double x = 0;
double y = 0;
double w = 0;
double h = 0;
bool bIsRect = IsRect(x, y, w, h);
if (bIsRect)
{
if ((0 == w && 0 == h))
return;
w = max(1, w);
h = max(1, h);
if (bIsRect)
{
CString strLineColor = GetStringColor(m_pPen->Color);
CString strFillColor = GetStringColor(m_pBrush->Color1);
if (0 == m_pBrush->Alpha1)
strFillColor = _T("transparent");
if ((1 >= w) || (1 >= h) && (lType < 0xFF))
{
m_oWriterSimpleGraphics.WriteString(L"<div class=\"rt\" style=\"border-width: 0px; background-color: ", 60);
SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16);
SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10);
m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pPen->Alpha / 255);
m_oWriterSimpleGraphics.AddSize(100);
m_oWriterSimpleGraphics.WriteString(L"; left: ", 8);
m_oWriterSimpleGraphics.AddIntNoCheck(round(x));
m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9);
m_oWriterSimpleGraphics.AddIntNoCheck(round(y));
m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11);
m_oWriterSimpleGraphics.AddIntNoCheck(round(w));
m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12);
m_oWriterSimpleGraphics.AddIntNoCheck(round(h));
m_oWriterSimpleGraphics.WriteString(L"px;\"></div>\n");
}
else
{
if (0x00 == (lType & 0xFF))
{
m_oWriterSimpleGraphics.WriteString(L"<div class=\"rt\" style=\"border-width: 0px; background-color: ", 60);
if (0 == m_pBrush->Alpha1)
m_oWriterSimpleGraphics.WriteString(L"transparent", 11);
else
SetStringColor(m_pBrush->Color1, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16);
SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10);
m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pBrush->Alpha1 / 255);
m_oWriterSimpleGraphics.AddSize(100);
m_oWriterSimpleGraphics.WriteString(L"; left: ", 8);
m_oWriterSimpleGraphics.AddIntNoCheck(round(x));
m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9);
m_oWriterSimpleGraphics.AddIntNoCheck(round(y));
m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11);
m_oWriterSimpleGraphics.AddIntNoCheck(round(w));
m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12);
m_oWriterSimpleGraphics.AddIntNoCheck(round(h));
m_oWriterSimpleGraphics.WriteString(L"px;\"></div>\n");
}
else if (lType < 0xFF)
{
m_oWriterSimpleGraphics.WriteString(L"<div class=\"rt\" style=\"border-width: 1px; background-color: ", 60);
if (0 == m_pBrush->Alpha1)
m_oWriterSimpleGraphics.WriteString(L"transparent", 11);
else
SetStringColor(m_pBrush->Color1, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16);
SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10);
m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pPen->Alpha / 255);
m_oWriterSimpleGraphics.AddSize(100);
m_oWriterSimpleGraphics.WriteString(L"; left: ", 8);
m_oWriterSimpleGraphics.AddIntNoCheck(round(x));
m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9);
m_oWriterSimpleGraphics.AddIntNoCheck(round(y));
m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11);
m_oWriterSimpleGraphics.AddIntNoCheck(round(w));
m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12);
m_oWriterSimpleGraphics.AddIntNoCheck(round(h));
m_oWriterSimpleGraphics.WriteString(L"px;\"></div>\n");
}
else
{
m_oWriterSimpleGraphics.WriteString(L"<div class=\"rt\" style=\"border-width: 1px; background-color: ", 60);
if (0 == m_pBrush->Alpha1)
m_oWriterSimpleGraphics.WriteString(L"transparent", 11);
else
SetStringColor(m_pBrush->Color1, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; border-color: ", 16);
SetStringColor(m_pPen->Color, &m_oWriterSimpleGraphics);
m_oWriterSimpleGraphics.WriteString(L"; opacity:", 10);
m_oWriterSimpleGraphics.AddIntNoCheckDel100(100 * m_pBrush->Alpha1 / 255);
m_oWriterSimpleGraphics.AddSize(100);
m_oWriterSimpleGraphics.WriteString(L"; left: ", 8);
m_oWriterSimpleGraphics.AddIntNoCheck(round(x));
m_oWriterSimpleGraphics.WriteString(L"px; top: ", 9);
m_oWriterSimpleGraphics.AddIntNoCheck(round(y));
m_oWriterSimpleGraphics.WriteString(L"px; width: ", 11);
m_oWriterSimpleGraphics.AddIntNoCheck(round(w));
m_oWriterSimpleGraphics.WriteString(L"px; height: ", 12);
m_oWriterSimpleGraphics.AddIntNoCheck(round(h));
m_oWriterSimpleGraphics.WriteString(L"px;\"></div>\n");
}
}
}
}
else
{
m_bIsSimpleGraphics = false;
}
}
else
{
m_bIsSimpleGraphics = false;
}
std::wstring strStroked = L"false";
std::wstring strFilled = L"false";
//if (0x00 != (0x02 & (lType >> 8)) && ((lType & 0xFF) == 0x00))
//{
// lType = 1;
// m_pPen->Color = m_pBrush->Color1;
// m_pPen->Alpha = m_pBrush->Alpha1;
//}
bool bStroke = false;
if (m_pPen->Alpha == 0)
lType &= 0xFF00;
if ((-1 == lIDTx) && (0 == m_pBrush->Alpha1))
lType &= 0xFF;
// canvas
if ((lType & 0x01) == 0x01)
{
SetStrokeColor(m_pPen->Color, m_pPen->Alpha, &m_oWriterCanvas);
bStroke = true;
if (0x00 != m_pPen->Alpha)
{
strStroked = L"true";
}
}
if (lType > 0x01)
{
if (-1 != lIDTx)
{
double x = 0;
double y = 0;
double w = 0;
double h = 0;
m_pSimpleConverter->PathCommandGetBounds(&x, &y, &w, &h);
double r = x + w;
double b = y + h;
m_pFullTransform->TransformPoint(x, y);
m_pFullTransform->TransformPoint(r, b);
w = r - x;
h = b - y;
m_oWriterCanvas.WriteString(L"img", 3);
m_oWriterCanvas.AddInt(lIDTx);
m_oWriterCanvas.WriteString(L".src = \"media\\\\image", 20);
m_oWriterCanvas.AddInt(lIDTx);
m_oWriterCanvas.WriteString(L".jpg\";img", 9);
m_oWriterCanvas.AddInt(lIDTx);
m_oWriterCanvas.WriteString(L".onload = function(){c.drawImage(img", 36);
WriteIntsToStringBuilder(lIDTx, round(x), round(y), round(w), round(h), &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L");drawpage", 10);
m_oWriterCanvas.AddInt(lPageNumber);
m_oWriterCanvas.AddCharSafe('_');
m_oWriterCanvas.AddInt(lCurTxNumber);
m_oWriterCanvas.WriteString(L"(c);};\n}\nfunction drawpage", 26);
m_oWriterCanvas.AddInt(lPageNumber);
m_oWriterCanvas.AddCharSafe('_');
m_oWriterCanvas.AddInt(lCurTxNumber);
m_oWriterCanvas.WriteString(L"(c)\n{\n", 6);
}
else
{
SetFillColor(m_pBrush->Color1, m_pBrush->Alpha1, &m_oWriterCanvas);
m_oWriterCanvas.WriteString(L"f(c);\n", 6);
}
strFilled = L"true";
}
if (bStroke)
{
m_oWriterCanvas.WriteString(L"s(c);\n", 6);
}
if (-1 != lIDTx)
{
m_oWriterVML.WriteString(L"<v:shape style=\"position:absolute; width:1; height:1\" coordsize=\"1 1\" stroked=\"", 79);
m_oWriterVML.WriteString(strStroked);
m_oWriterVML.WriteString(L"\" strokecolor=\"", 15);
m_oWriterVML.WriteHexColor3(ConvertColor(m_pPen->Color));
m_oWriterVML.WriteString(L"\" filled=\"", 10);
m_oWriterVML.WriteString(strFilled);
m_oWriterVML.WriteString(L"\" path=\"", 8);
m_oWriterVML.Write(m_oWriterVMLPath);
m_oWriterVML.WriteString(L"\"><v:fill src=\"media\\image", 26);
m_oWriterVML.AddInt(lIDTx);
m_oWriterVML.WriteString(L".jpg\" type=\"frame\" opacity=\"", 28);
m_oWriterVML.AddIntDel100(100 * m_pBrush->Alpha1 / 255);
m_oWriterVML.WriteString(L"\"/></v:shape>\n", 14);
}
else if (0xFF == m_pBrush->Alpha1)
{
m_oWriterVML.WriteString(L"<v:shape style=\"position:absolute; width:1; height:1\" coordsize=\"1 1\" stroked=\"", 79);
m_oWriterVML.WriteString(strStroked);
m_oWriterVML.WriteString(L"\" strokecolor=\"", 15);
m_oWriterVML.WriteHexColor3(ConvertColor(m_pPen->Color));
m_oWriterVML.WriteString(L"\" filled=\"", 10);
m_oWriterVML.WriteString(strFilled);
m_oWriterVML.WriteString(L"\" fillcolor=\"", 13);
m_oWriterVML.WriteHexColor3(ConvertColor(m_pBrush->Color1));
m_oWriterVML.WriteString(L"\" path=\"", 8);
m_oWriterVML.Write(m_oWriterVMLPath);
m_oWriterVML.WriteString(L"\" />\n", 5);
}
else
{
m_oWriterVML.WriteString(L"<v:shape style=\"position:absolute; width:1; height:1\" coordsize=\"1 1\" stroked=\"", 79);
m_oWriterVML.WriteString(strStroked);
m_oWriterVML.WriteString(L"\" strokecolor=\"", 15);
m_oWriterVML.WriteHexColor3(ConvertColor(m_pPen->Color));
m_oWriterVML.WriteString(L"\" filled=\"", 10);
m_oWriterVML.WriteString(strFilled);
m_oWriterVML.WriteString(L"\" fillcolor=\"", 13);
m_oWriterVML.WriteHexColor3(ConvertColor(m_pBrush->Color1));
m_oWriterVML.WriteString(L"\" path=\"", 8);
m_oWriterVML.Write(m_oWriterVMLPath);
m_oWriterVML.WriteString(L"\"><v:fill opacity=\"", 19);
m_oWriterVML.AddIntDel100(100 * m_pBrush->Alpha1 / 255);
m_oWriterVML.WriteString(L"\"/></v:shape>\n", 14);
}
m_oWriterVML.WriteString(strVML);
if (-1 != lIDTx)
{
++lCurTxNumber;
}
}
void WritePathClip()
{
m_bIsClipping = true;
}
void WritePathClipEnd()
{
m_bIsClipping = false;
double x = 0;
double y = 0;
double w = 0;
double h = 0;
m_pSimpleConverter->PathCommandGetBounds(&x, &y, &w, &h);
if ((0 > w) || (0 > h))
{
// никакого клипа нет!
return;
}
else
{
if (!m_bIsClip)
{
m_oWriterCanvas.WriteString(L"c.save();\n", 10);
}
m_bIsClip = true;
m_oWriterCanvas.WriteString(L"c.clip();\n", 10);
}
}
void WritePathResetClip()
{
if (m_bIsClip)
{
m_oWriterCanvas.WriteString(L"c.restore();\n", 13);
}
m_bIsClip = false;
m_bIsClipping = false;
}
protected:
bool IsRect(double& x, double& y, double& w, double& h)
{
if (1 >= m_lCountSC)
return false;
double dPrevX = m_arSimpleCommands[0].m_dX;
double dPrevY = m_arSimpleCommands[0].m_dY;
long lCurDirection = 0;
std::vector<double> arX;
std::vector<double> arY;
arX.push_back(dPrevX);
arY.push_back(dPrevY);
double dXmin = dPrevX;
double dXmax = dPrevX;
double dYmin = dPrevY;
double dYmax = dPrevY;
double _dX = m_arSimpleCommands[m_lCountSC - 1].m_dX;
double _dY = m_arSimpleCommands[m_lCountSC - 1].m_dY;
for (LONG i = 1; i < m_lCountSC; ++i)
{
CSimpleCommand* pComm = &m_arSimpleCommands[i];
if (scLineTo != pComm->m_eType)
return false;
long lDir = SkipCurDirection(lCurDirection, i, dPrevX, dPrevY);
double dX = _dX;
double dY = _dY;
if (i < m_lCountSC)
{
dX = m_arSimpleCommands[i - 1].m_dX;
dY = m_arSimpleCommands[i - 1].m_dY;
}
if (dX > dXmax)
dXmax = dX;
else if (dX < dXmin)
dXmin = dX;
if (dY > dYmax)
dYmax = dY;
else if (dY < dYmin)
dYmin = dY;
arX.push_back(dX);
arY.push_back(dY);
lCurDirection = lDir;
}
// все, массивы заполнены.
// теперь осталось определить, рект ли это
// должно:
// 1) кроме минимумов и максимумов ничего не может быть.
// 2) все точки ректа должны присутствовать
bool b1 = false;
bool b2 = false;
bool b3 = false;
bool b4 = false;
int lCount = (int)arX.size();
for (int i = 0; i < lCount; ++i)
{
double ___x = arX[i];
double ___y = arY[i];
bool bBreak = false;
if (IsEqualPoint(___x, ___y, dXmin, dYmin))
b1 = true;
else if (IsEqualPoint(___x, ___y, dXmax, dYmin))
b2 = true;
else if (IsEqualPoint(___x, ___y, dXmin, dYmax))
b4 = true;
else if (IsEqualPoint(___x, ___y, dXmax, dYmax))
b3 = true;
else
return false;
}
x = dXmin;
y = dYmin;
w = dXmax - dXmin;
h = dYmax - dYmin;
if (b1 && b2 && !b3 && !b4)
return true;
if (b1 && !b2 && !b3 && b4)
return true;
if (!b1 && b2 && b3 && !b4)
return true;
if (!b1 && !b2 && b3 && b4)
return true;
if (b1 && b2 && b3 && b4)
return true;
return false;
}
// direction: (0 - вправо, 1 - вниз, 2 - влево, 3 - вверх)
inline long SkipCurDirection(const long& lDirection, long& lIndexCur, double& dPrevX, double& dPrevY)
{
for (; lIndexCur < m_lCountSC; ++lIndexCur)
{
long lDir = GetCurDirection(lIndexCur, dPrevX, dPrevY);
dPrevX = m_arSimpleCommands[lIndexCur].m_dX;
dPrevY = m_arSimpleCommands[lIndexCur].m_dY;
if ((-1 == lDir) || (lDir == lDirection))
continue;
return lDir;
}
return -1;
}
inline long GetCurDirection(const long& lIndex, const double& dPrevX, const double& dPrevY)
{
double x = m_arSimpleCommands[lIndex].m_dX;
double y = m_arSimpleCommands[lIndex].m_dY;
if (FABS(y - dPrevY) < 0.01)
{
if (FABS(x - dPrevX) < 0.01)
{
return -1;
}
return (x >= dPrevX) ? 0 : 2;
}
else
{
return (y >= dPrevY) ? 1 : 3;
}
}
inline bool IsEqualPoint(double& x, double&y, double& _x, double& _y)
{
if ((FABS(x - _x) < 0.1) && (FABS(y - _y) < 0.1))
return true;
return false;
}
bool IsTwoRectOneDirection()
{
return true;
}
LONG SkipRect(LONG& lStart, LONG& lEnd)
{
}
};
}
#endif // _ASC_HTMLRENDERER_VGW_H_
#ifndef _ASC_HTMLRENDERER_VGW2_H_
#define _ASC_HTMLRENDERER_VGW2_H_
#include "Common.h"
#include "SVGWriter.h"
#include "VMLWriter.h"
#include "../../DesktopEditor/graphics/GraphicsPath.h"
namespace NSHtmlRenderer
{
class CVectorGraphicsWriter
{
public:
CSVGWriter m_oSVG;
CVMLWriter m_oVML;
//CCanvasWriter m_oCanvas;
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
Aggplus::CMatrix* m_pFullTransform;
LONG m_lCurrentObjectInPage;
LONG m_lCurrentPageNumber;
double m_dWidth;
double m_dHeight;
public:
CVectorGraphicsWriter() : m_oSVG(), m_oVML()/*, m_oCanvas()*/
{
m_pSimpleConverter = NULL;
m_lCurrentObjectInPage = 0;
}
~CVectorGraphicsWriter()
{
}
void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, Aggplus::CGraphicsPathSimpleConverter* pSimpleConverter)
{
m_pPen = pPen;
m_pBrush = pBrush;
m_pSimpleConverter = pSimpleConverter;
m_oSVG.SetSettings(m_pPen, m_pBrush);
m_oVML.SetSettings(m_pPen, m_pBrush);
//m_oCanvas.SetSettings(m_pPen, m_pBrush, m_pSimpleConverter);
}
inline void NewPage(double& dW, double& dH, const LONG& lPageNumber)
{
m_lCurrentPageNumber = lPageNumber;
m_dWidth = dW;
m_dHeight = dH;
m_oSVG.NewDocument(m_dWidth, m_dHeight, m_lCurrentPageNumber);
m_oVML.NewDocument(m_dWidth, m_dHeight, m_lCurrentPageNumber);
}
inline void EndPage()
{
m_oSVG.CloseFile();
m_oVML.CloseFile();
//m_oCanvas.CloseFile();
m_lCurrentObjectInPage = 0;
}
inline void WriteEndPath()
{
m_oSVG.WritePathEnd();
m_oVML.WritePathEnd();
//m_oCanvas.WritePathEnd();
}
inline void WritePathStart()
{
m_oSVG.WritePathStart();
m_oVML.WritePathStart();
//m_oCanvas.WritePathStart();
}
inline void WritePathClose()
{
m_oSVG.WritePathClose();
m_oVML.WritePathClose();
//m_oCanvas.WritePathClose();
}
inline void WritePathMoveTo(double& x, double& y)
{
m_oSVG.WritePathMoveTo(x, y);
m_oVML.WritePathMoveTo(x, y);
//m_oCanvas.WritePathMoveTo(x,y);
}
inline void WritePathLineTo(double& x, double& y)
{
m_oSVG.WritePathLineTo(x, y);
m_oVML.WritePathLineTo(x, y);
//m_oCanvas.WritePathLineTo(x, y);
}
inline void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
m_oSVG.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
m_oVML.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
//m_oCanvas.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
}
inline void WriteDrawPath(LONG lType, CImageInfo& oInfo, const double& dAngle)
{
// вот мега заглушка под некоторые таблицы из pdf
// проблема в том, что приходит path нулевой толщины - а след-но он не рисуется.
// здесь это отслеживаем и правим пат. Не очень хорошо, так как всякие пунктирности
// в таких патах - теряются при таком подходе
if (0x00 == (lType & 0xFF))
{
double x = 0;
double y = 0;
double r = 0;
double b = 0;
m_pSimpleConverter->PathCommandGetBounds(x, y, r, b);
r += x;
b += y;
if ((fabs(r - x) < 0.5) || (fabs(b - y) < 0.5))
{
m_pFullTransform->TransformPoint(x, y);
m_pFullTransform->TransformPoint(r, b);
int _x = round(x);
int _y = round(y);
int _r = round(r);
int _b = round(b);
if ((_x == _r) || (_y == _b))
{
LONG lPenColor = m_pPen->Color;
LONG lPenAlpha = m_pPen->Alpha;
double dPenW = m_pPen->Size;
m_pPen->Color = m_pBrush->Color1;
m_pPen->Alpha = m_pBrush->Alpha1;
m_pPen->Size = c_ag_1pxWidth;
WriteEndPath();
WritePathStart();
WritePathMoveTo(x, y);
WritePathLineTo(r, b);
WriteDrawPath(0x01, oInfo, dAngle);
m_pPen->Color = lPenColor;
m_pPen->Alpha = lPenAlpha;
m_pPen->Size = dPenW;
return;
}
}
}
m_oSVG.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, oInfo, dAngle);
m_oVML.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, oInfo, dAngle);
m_pSimpleConverter->PathCommandEnd();
//m_oCanvas.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, lIdTx);
}
inline void WritePathClip()
{
m_oSVG.WritePathClip();
m_oVML.WritePathClip();
//m_oCanvas.WritePathClip();
}
inline void WritePathClipEnd()
{
m_oSVG.WritePathClipEnd();
m_oVML.WritePathClipEnd();
//m_oCanvas.WritePathClipEnd();
}
inline void SetClipMode(LONG lClipMode)
{
m_oSVG.m_lClipMode = lClipMode;
m_oVML.m_lClipMode = lClipMode;
}
inline void WriteImage(double& x, double& y, double& width, double& height, CImageInfo& oInfo, double dAngle)
{
m_oSVG.WriteImage(oInfo, x, y, width, height, dAngle);
m_oVML.WriteImage(oInfo, x, y, width, height, dAngle);
}
inline void WritePathResetClip()
{
m_oSVG.WritePathResetClip();
m_oVML.WritePathResetClip();
//m_oCanvas.WritePathResetClip();
}
inline bool IsGraphics()
{
// 10 цифр на номер страницы
// LEN(<xml xmlns:v=\"urn:schemas-microsoft-com:vml\">\n<v:group id=\"page%d\" style=\"position: absolute; width:1; height:1;\" coordsize=\"1 1\">\n) = 131
return ((131 + 10) < (int)m_oVML.m_oDocument.GetCurSize());
}
inline void WriteToDocument(NSStringUtils::CStringBuilder* pDocument, const CDstInfo& oInfo)
{
m_oSVG.WriteToMainHtml_1(pDocument, oInfo);
m_oVML.WriteToMainHtml(pDocument, oInfo);
m_oSVG.WriteToMainHtml_2(pDocument);
}
};
class CSVGGraphicsWriter
{
public:
CSVGWriter m_oSVG;
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleConverter;
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
Aggplus::CMatrix* m_pFullTransform;
double m_dWidth;
double m_dHeight;
public:
CSVGGraphicsWriter() : m_oSVG()
{
m_pSimpleConverter = NULL;
}
~CSVGGraphicsWriter()
{
}
void SetSettings(NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, Aggplus::CGraphicsPathSimpleConverter* pSimpleConverter)
{
m_pPen = pPen;
m_pBrush = pBrush;
m_pSimpleConverter = pSimpleConverter;
m_oSVG.SetSettings(m_pPen, m_pBrush);
}
inline void NewPage(double& dW, double& dH)
{
m_dWidth = dW;
m_dHeight = dH;
}
inline void EndPage()
{
m_oSVG.CloseFile();
}
inline void WriteEndPath()
{
m_oSVG.WritePathEnd();
}
inline void WritePathStart()
{
m_oSVG.WritePathStart();
}
inline void WritePathClose()
{
m_oSVG.WritePathClose();
}
inline void WritePathMoveTo(double& x, double& y)
{
m_oSVG.WritePathMoveTo(x, y);
}
inline void WritePathLineTo(double& x, double& y)
{
m_oSVG.WritePathLineTo(x, y);
}
inline void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
m_oSVG.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
}
inline void WriteDrawPath(LONG lType)
{
CImageInfo oInfo;
m_oSVG.WriteDrawPath(lType, m_pFullTransform, m_pSimpleConverter, oInfo, 0.0);
m_pSimpleConverter->PathCommandEnd();
}
inline void WritePathClip()
{
m_oSVG.WritePathClip();
}
inline void WritePathClipEnd()
{
m_oSVG.WritePathClipEnd();
}
inline void SetClipMode(LONG lClipMode)
{
m_oSVG.m_lClipMode = lClipMode;
}
inline void WriteImage(double& x, double& y, double& width, double& height, CImageInfo& oInfo, double dAngle)
{
m_oSVG.WriteImage(oInfo, x, y, width, height, dAngle);
}
inline void WritePathResetClip()
{
m_oSVG.WritePathResetClip();
}
inline bool IsGraphics()
{
// 10 цифр на номер страницы
// LEN(<xml xmlns:v=\"urn:schemas-microsoft-com:vml\">\n<v:group id=\"page%d\" style=\"position: absolute; width:1; height:1;\" coordsize=\"1 1\">\n) = 131
return ((131 + 10) < (int)m_oSVG.m_oDocument.GetCurSize());
}
};
}
#endif // _ASC_HTMLRENDERER_VGW2_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
#pragma once
#include "Text.h"
#include "Document.h"
#include "CalculatorCRC32.h"
#include "..\Graphics\Matrix.h"
namespace NSHtmlRenderer
{
static _bstr_t _g_canvas_bstr_StartPath = L"c.beginPath();";
static _bstr_t _g_canvas_bstr_ClosePath = L"c.closePath();";
static CString _g_canvas_string_MoveToD = _T("c.moveTo(%d,%d);");
static CString _g_canvas_string_LineToD = _T("c.lineTo(%d,%d);");
static CString _g_canvas_string_CurveToD = _T("c.bezierCurveTo(%d,%d,%d,%d,%d,%d);");
static _bstr_t _g_canvas_bstr_Stroke = L"c.stroke();";
static _bstr_t _g_canvas_bstr_Fill = L"c.fill();";
static _bstr_t _g_canvas_bstr_Save = L"c.save();\n";
static _bstr_t _g_canvas_bstr_Restore = L"c.restore();\n";
static _bstr_t _g_canvas_bstr_Clip = L"c.clip();\n";
static CString _g_canvas_string_css_color = _T("rgb(%d,%d,%d)");
static CString _g_canvas_string_FillColor = _T("c.fillStyle = \"#%06x\";");
static CString _g_canvas_string_FillColorA = _T("c.fillStyle = \"rgba(%d,%d,%d,%.2lf)\";");
static CString _g_canvas_string_StrokeColor = _T("c.strokeStyle = \"#%06x\";");
static CString _g_canvas_string_StrokeColorA = _T("c.strokeStyle = \"rgba(%d,%d,%d,%.2lf)\";");
static CString _g_canvas_string_drawImageJPG = _T("var img = new Image();img.src = \"media\\\\image%d.jpg\";img.onload = function(){c.drawImage(img,%d,%d,%d,%d);doc.p%d_%d(doc,page,c);};\n}\nthis.p%d_%d = function(doc,page,c)\n{\n");
static CString _g_canvas_string_drawImagePNG = _T("var img = new Image();img.src = \"media\\\\image%d.png\";img.onload = function(){c.drawImage(img,%d,%d,%d,%d);doc.p%d_%d(doc,page,c);};\n}\nthis.p%d_%d = function(doc,page,c)\n{\n");
using namespace NSStrings;
class CWriter2
{
private:
CStringWriter m_oWriterPage;
public:
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
NSStructures::CPen m_oLastPen;
NSStructures::CBrush m_oLastBrush;
NSStructures::CFont m_oLastFont;
double m_dDpiX;
double m_dDpiY;
BOOL m_bPathClosed;
CAtlMap<CString, CImageInfo> m_mapImagesFile;
CAtlMap<DWORD, CImageInfo> m_mapImageData;
CCalculatorCRC32 m_oCRC;
LONG m_lWidthDocPix;
LONG m_lHeightDocPix;
LONG m_lHeightPagePix;
Graphics::IASCGraphicSimpleComverter* m_pSimpleConverter;
CFile m_oFileWriter;
public:
double m_dWidthPix;
double m_dHeigthPix;
private:
LONG m_lNextIDShape;
LONG m_lNextIDImage;
LONG m_lCurrentPage;
LONG m_lCurrentFunctionPage;
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:
CWriter2()
{
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_lPagesCount = 0;
}
void CreateFile(CString& strDir, CString& strFileName)
{
m_lPagesCount = 0;
m_lCurrentPage = -1;
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);
CString strFileScript = m_strDstDirectoryFiles + _T("\\scripts");
CDirectory::CreateDirectory(strFileScript);
CString strDocRendererS = strFileScript + _T("\\documentrenderer.js");
m_oFileWriter.CreateFile(strDocRendererS);
CStringA strStart = "function CDocumentRenderer(){\nthis.bIsRepaint = 0;\nthis.sendRepaint = function(){\nthis.bIsRepaint = 1;\n}\nthis.checkRepaint = function(){\nif (this.bIsRepaint == 1){\nthis.bIsRepaint = 0;return 1;\n}\nreturn 0;\n}\n";
m_oFileWriter.WriteFile((void*)strStart.GetBuffer(), strStart.GetLength());
m_oWriterPage.Clear();
}
void SetSimpleConverter(Graphics::IASCGraphicSimpleComverter* pSimpleConverter, CMatrix* pMatrix)
{
m_pSimpleConverter = pSimpleConverter;
}
AVSINLINE void WriteText(BSTR bsText, BSTR bsGid, double x, double y, double width, double height, double baselineoffset)
{
if (!m_oLastBrush.IsEqual(m_pBrush))
{
m_oLastBrush = *m_pBrush;
SetFillColor();
}
if (!m_oLastFont.IsEqual(m_pFont))
{
m_oLastFont = *m_pFont;
SetFontStyle();
}
CString strText = (CString)bsText;
strText.Replace(_T("\\"), _T("\\\\"));
strText.Replace(_T("\""), _T("\\\""));
CString str = _T("c.fillText(\"") + strText;
CString strPos = _T("");
strPos.Format(_T("\",%d,%d);\n"), (int)x, (int)(y + (baselineoffset * 96 / 25.4)));
str += strPos;
m_oWriterPage.WriteString(str);
}
void WriteImage(IUnknown* punkImage, double x, double y, double width, double height, double dAngle)
{
if (height < 0)
{
FlipY(punkImage);
height = -height;
y -= height;
}
CImageInfo oID = GenerateImageID(punkImage);
if (oID.m_eType == itJPG)
{
CString strW = _T("");
strW.Format(_g_canvas_string_drawImageJPG, oID.m_lID, (int)x, (int)y, (int)width, (int)height, m_lCurrentPage, m_lCurrentFunctionPage,
m_lCurrentPage, m_lCurrentFunctionPage);
m_oWriterPage.WriteString(strW);
++m_lCurrentFunctionPage;
}
else
{
CString strW = _T("");
strW.Format(_g_canvas_string_drawImagePNG, oID.m_lID, (int)x, (int)y, (int)width, (int)height, m_lCurrentPage, m_lCurrentFunctionPage,
m_lCurrentPage, m_lCurrentFunctionPage);
m_oWriterPage.WriteString(strW);
++m_lCurrentFunctionPage;
}
}
AVSINLINE void WriteImage(CString& strFile, double x, double y, double width, double height, double dAngle)
{
CImageInfo oID = GenerateImageID(strFile);
if (oID.m_eType == itJPG)
{
CString strW = _T("");
strW.Format(_g_canvas_string_drawImageJPG, oID.m_lID, (int)x, (int)y, (int)width, (int)height, m_lCurrentPage, m_lCurrentFunctionPage,
m_lCurrentPage, m_lCurrentFunctionPage);
m_oWriterPage.WriteString(strW);
++m_lCurrentFunctionPage;
}
else
{
CString strW = _T("");
strW.Format(_g_canvas_string_drawImagePNG, oID.m_lID, (int)x, (int)y, (int)width, (int)height, m_lCurrentPage, m_lCurrentFunctionPage,
m_lCurrentPage, m_lCurrentFunctionPage);
m_oWriterPage.WriteString(strW);
++m_lCurrentFunctionPage;
}
}
AVSINLINE void WriteBeginPath()
{
m_oWriterPage.WriteString(_g_canvas_bstr_StartPath);
}
AVSINLINE void WriteEndPath()
{
m_oWriterPage.WriteString(_g_canvas_bstr_StartPath);
}
AVSINLINE void WritePathStart()
{
}
AVSINLINE void WritePathClose()
{
m_oWriterPage.WriteString(_g_canvas_bstr_ClosePath);
}
AVSINLINE void WritePathMoveTo(double& x, double& y)
{
CString str = _T("");
str.Format(_g_canvas_string_MoveToD, (int)x, (int)y);
m_oWriterPage.WriteString(str);
}
AVSINLINE void WritePathLineTo(double& x, double& y)
{
CString str = _T("");
str.Format(_g_canvas_string_LineToD, (int)x, (int)y);
m_oWriterPage.WriteString(str);
}
AVSINLINE void WritePathCurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
{
CString str = _T("");
str.Format(_g_canvas_string_CurveToD, (int)x1, (int)y1, (int)x2, (int)y2, (int)x3, (int)y3);
m_oWriterPage.WriteString(str);
}
AVSINLINE void WriteDrawPath(LONG lType, const double& dAngle)
{
if (lType > 0xFF)
{
if (!m_oLastBrush.IsEqual(m_pBrush))
{
m_oLastBrush = *m_pBrush;
SetFillColor();
}
m_oWriterPage.WriteString(_g_canvas_bstr_Fill);
}
if (lType & 0x01)
{
if (!m_oLastPen.IsEqual(m_pPen))
{
m_oLastPen = *m_pPen;
SetStrokeColor();
}
m_oWriterPage.WriteString(_g_canvas_bstr_Stroke);
}
}
AVSINLINE void WritePathClip()
{
}
AVSINLINE void WritePathClipEnd()
{
}
AVSINLINE void WritePathResetClip()
{
}
AVSINLINE void SetStrokeColor()
{
LONG lBGR = m_pPen->Color;
LONG lA = m_pPen->Alpha;
BYTE R = (BYTE)(lBGR & 0xFF);
BYTE G = (BYTE)((lBGR >> 8) & 0xFF);
BYTE B = (BYTE)((lBGR >> 16) & 0xFF);
CString strTemp = _T("");
strTemp.Format(_g_canvas_string_StrokeColorA, R, G, B, (double)lA / 255);
m_oWriterPage.WriteString(strTemp);
}
AVSINLINE void SetFillColor()
{
LONG lBGR = m_pBrush->Color1;
LONG lA = m_pBrush->Alpha1;
BYTE R = (BYTE)(lBGR & 0xFF);
BYTE G = (BYTE)((lBGR >> 8) & 0xFF);
BYTE B = (BYTE)((lBGR >> 16) & 0xFF);
CString strTemp = _T("");
strTemp.Format(_g_canvas_string_FillColorA, R, G, B, (double)lA / 255);
m_oWriterPage.WriteString(strTemp);
}
AVSINLINE void SetFontStyle()
{
CString strFormat = _T("");
if (m_pFont->Bold && m_pFont->Italic)
strFormat = _T("bold italic ");
else if (m_pFont->Bold)
strFormat = _T("bold ");
else if (m_pFont->Italic)
strFormat = _T("italic ");
CString strSize = _T("");
strSize.Format(_T("%dpt "), (int)m_pFont->Size);
strFormat += strSize;
strFormat += m_pFont->Name;
strFormat = _T("c.font=\"") + strFormat + _T("\";");
m_oWriterPage.WriteString(strFormat);
}
void NewPage(double& dWidthPix, double& dHeightPix)
{
++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_lCurrentFunctionPage = 0;
CString strStartPage = _T("");
strStartPage.Format(_T("this.p%d = function(doc,page){var c = page.cachedImage.image.ctx;c.setTransform(1,0,0,1,0,0);\n"), m_lCurrentPage);
m_oWriterPage.WriteString(strStartPage);
m_oLastBrush.Color1 = -1;
m_oLastPen.Color = -1;
m_oLastFont.Name = _T("");
}
void EndPage()
{
CString strEndPage = _T("\nif (true) {page.stopRendering();} doc.sendRepaint();}\n");
m_oWriterPage.WriteString(strEndPage);
CString strData = (CString)m_oWriterPage.GetCString();
m_oFileWriter.WriteStringUTF8(strData);
m_oWriterPage.ClearNoAttack();
}
void WriteStartDocument()
{
m_dHeightDoc = 0;
}
void WriteEndDocument(CDocument& oDocument)
{
CString strDst = _T("");
strDst.Format(_T("\n// ------------------------------------\nthis.pagesCount = %d;\nthis.arrayMethods = new Array(this.pagesCount);\n\
// ------------------------------------\nthis.drawpage = function(page){this.arrayMethods[page.pageIndex](this,page);}\n// ------------------------------------\n"), (int)oDocument.m_arrPages.GetCount());
CString strInitDoc = _T("function InitDocumentPages(_arrayPages){\n");
int nPagesCount = (int)oDocument.m_arrPages.GetCount();
for (int i = 0; i < nPagesCount; ++i)
{
CString str1 = _T("");
str1.Format(_T("this.arrayMethods[%d] = this.p%d;\n"), i, i);
strDst += str1;
CString str2 = _T("");
str2.Format(_T("_arrayPages[%d] = new CPage(%.1lf, %.1lf, %d);\n"), i, oDocument.m_arrPages[i].GetWidth(), oDocument.m_arrPages[i].GetHeight(), i);
strInitDoc += str2;
}
strDst += _T("}");
strInitDoc += _T("\n}");
strDst += strInitDoc;
CStringA strMemory = (CStringA)strDst;
m_oFileWriter.WriteFile(strMemory.GetBuffer(), strMemory.GetLength());
m_oFileWriter.CloseFile();
HINSTANCE hInst = _AtlBaseModule.GetModuleInstance();
LoadResourceFile(hInst, MAKEINTRESOURCE(IDB_SCRIPT_PAGE), _T("HTML2"), m_strDstDirectoryFiles + _T("\\scripts\\page.js"));
LoadResourceFile(hInst, MAKEINTRESOURCE(IDB_SCRIPT_IM), _T("HTML2"), m_strDstDirectoryFiles + _T("\\scripts\\images.js"));
LoadResourceFile(hInst, MAKEINTRESOURCE(IDB_SCRIPT_MAIN), _T("HTML2"), m_strDstDirectoryFiles + _T("\\scripts\\main.js"));
LoadResourceFile(hInst, MAKEINTRESOURCE(IDB_SCRIPT_CM), _T("HTML2"), m_strDstDirectoryFiles + _T("\\scripts\\cachemanager.js"));
LoadResourceFile(hInst, MAKEINTRESOURCE(IDB_SCRIPT_VIEW), _T("HTML2"), m_strDstDirectoryFiles + _T("\\viewer.html"));
}
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("");
if ((lWidth <= m_lMaxSizeImage) && (lHeight <= m_lMaxSizeImage))
{
strXml = _T("<transforms>") + strSaveItem + _T("</transforms>");
}
else
{
LONG lW = 0;
LONG lH = 0;
double dAspect = (double)lWidth / lHeight;
if (lWidth >= lHeight)
{
lW = m_lMaxSizeImage;
lH = (LONG)((double)lW / dAspect);
}
else
{
lH = m_lMaxSizeImage;
lW = (LONG)(dAspect * lH);
}
CString strResize = _T("");
strResize.Format(_T("<ImageTransform-TransformResize 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\"/>");
}
CString strXml = _T("");
if ((lWidth <= m_lMaxSizeImage) && (lHeight <= m_lMaxSizeImage))
{
strXml = _T("<transforms>") + strSaveItem + _T("</transforms>");
}
else
{
LONG lW = 0;
LONG lH = 0;
double dAspect = (double)lWidth / lHeight;
if (lWidth >= lHeight)
{
lW = m_lMaxSizeImage;
lH = (LONG)((double)lW / dAspect);
}
else
{
lH = m_lMaxSizeImage;
lW = (LONG)(dAspect * lH);
}
CString strResize = _T("");
strResize.Format(_T("<ImageTransform-TransformResize 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
This source diff could not be displayed because it is too large. You can view the blob instead.
#pragma once
#include "Writer3.h"
#include "SVGWriter2.h"
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\" />\
</htmltiling>
*/
public:
double x;
double y;
double countx;
double county;
double stepx;
double stepy;
double bbox_x;
double bbox_y;
double bbox_r;
double bbox_b;
double transform_1;
double transform_2;
double transform_3;
double transform_4;
double transform_5;
double transform_6;
public:
CTileInfo()
{
Clear();
}
public:
void Clear()
{
x = 0;
y = 0;
countx = 0;
county = 0;
stepx = 0;
stepy = 0;
bbox_x = 0;
bbox_y = 0;
bbox_r = 0;
bbox_b = 0;
transform_1 = 1;
transform_2 = 0;
transform_3 = 0;
transform_4 = 1;
transform_5 = 0;
transform_6 = 0;
}
void LoadFromXml(const CString& strXml)
{
XmlUtils::CXmlNode oNode;
if (oNode.FromXmlString(strXml))
{
x = XmlUtils::GetDouble(oNode.GetAttribute(_T("x"), _T("0")));
y = XmlUtils::GetDouble(oNode.GetAttribute(_T("y"), _T("0")));
countx = XmlUtils::GetDouble(oNode.GetAttribute(_T("countx"), _T("0")));
county = XmlUtils::GetDouble(oNode.GetAttribute(_T("county"), _T("0")));
stepx = XmlUtils::GetDouble(oNode.GetAttribute(_T("stepx"), _T("0")));
stepy = XmlUtils::GetDouble(oNode.GetAttribute(_T("stepy"), _T("0")));
XmlUtils::CXmlNode oNodeBox;
if (oNode.GetNode(_T("bbox"), oNodeBox))
{
bbox_x = XmlUtils::GetDouble(oNodeBox.GetAttribute(_T("x"), _T("0")));
bbox_y = XmlUtils::GetDouble(oNodeBox.GetAttribute(_T("y"), _T("0")));
bbox_r = XmlUtils::GetDouble(oNodeBox.GetAttribute(_T("r"), _T("0")));
bbox_b = XmlUtils::GetDouble(oNodeBox.GetAttribute(_T("b"), _T("0")));
}
XmlUtils::CXmlNode oNodeTr;
if (oNode.GetNode(_T("transform"), oNodeTr))
{
transform_1 = XmlUtils::GetDouble(oNodeTr.GetAttribute(_T("m1"), _T("0")));
transform_2 = XmlUtils::GetDouble(oNodeTr.GetAttribute(_T("m2"), _T("0")));
transform_3 = XmlUtils::GetDouble(oNodeTr.GetAttribute(_T("m3"), _T("0")));
transform_4 = XmlUtils::GetDouble(oNodeTr.GetAttribute(_T("m4"), _T("0")));
transform_5 = XmlUtils::GetDouble(oNodeTr.GetAttribute(_T("m5"), _T("0")));
transform_6 = XmlUtils::GetDouble(oNodeTr.GetAttribute(_T("m6"), _T("0")));
}
}
}
};
class CGraphicsDumper
{
public:
Graphics::IASCGraphicsRenderer* m_pRenderer;
MediaCore::IAVSUncompressedVideoFrame* m_pFrame;
double m_dWidth;
double m_dHeight;
LONG m_lWidthPix;
LONG m_lHeightPix;
RECT m_oBounds;
CTileInfo m_oTile;
public:
CGraphicsDumper()
{
m_pRenderer = NULL;
m_pFrame = NULL;
m_dWidth = -1;
m_dHeight = -1;
m_lWidthPix = -1;
m_lHeightPix = -1;
m_oBounds.left = 0;
m_oBounds.top = 0;
m_oBounds.right = 0;
m_oBounds.bottom = 0;
}
~CGraphicsDumper()
{
RELEASEINTERFACE(m_pRenderer);
RELEASEINTERFACE(m_pFrame);
}
void NewPage(double dWidth, double dHeight)
{
if (dWidth != m_dWidth || dHeight != m_dHeight)
{
RELEASEINTERFACE(m_pFrame);
m_dWidth = dWidth;
m_dHeight = dHeight;
}
RELEASEINTERFACE(m_pRenderer);
m_lWidthPix = (LONG)(96 * dWidth / 25.4);
m_lHeightPix = (LONG)(96 * dHeight / 25.4);
if (NULL == m_pFrame)
{
CoCreateInstance(MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&m_pFrame);
m_pFrame->put_ColorSpace( ( 1 << 6) | ( 1 << 31) ); // CPS_BGRA | CPS_FLIP
m_pFrame->put_Width( m_lWidthPix );
m_pFrame->put_Height( m_lHeightPix );
m_pFrame->put_AspectRatioX( m_lWidthPix );
m_pFrame->put_AspectRatioY( m_lHeightPix );
m_pFrame->put_Interlaced( VARIANT_FALSE );
m_pFrame->put_Stride( 0, 4 * m_lWidthPix );
m_pFrame->AllocateBuffer( -1 );
}
BYTE* pBuffer = NULL;
m_pFrame->get_Buffer(&pBuffer);
memset(pBuffer, 0xFF, 4 * m_lWidthPix * m_lHeightPix);
CoCreateInstance(Graphics::CLSID_CASCGraphicsRenderer, NULL, CLSCTX_ALL, Graphics::IID_IASCGraphicsRenderer, (void**)&m_pRenderer);
//ставим FontManager
VARIANT vtVariant;
vtVariant.vt = VT_UNKNOWN;
vtVariant.punkVal = NULL;
m_pRenderer->SetAdditionalParam( L"FontManager", vtVariant );
m_pRenderer->put_Width(m_dWidth);
m_pRenderer->put_Height(m_dHeight);
m_pRenderer->CreateFromMediaData((IUnknown*)m_pFrame, 0, 0, m_lWidthPix, m_lHeightPix);
}
IUnknown* ConvertVectorGraphics()
{
BYTE* pBuffer = NULL;
m_pFrame->get_Buffer(&pBuffer);
BYTE* pBufferSrcMem = pBuffer + 4 * m_oBounds.top * m_lWidthPix + 4 * m_oBounds.left;
LONG lWidthShape = m_oBounds.right - m_oBounds.left + 1;
LONG lHeightShape = m_oBounds.bottom - m_oBounds.top + 1;
MediaCore::IAVSUncompressedVideoFrame* pShapePicture = NULL;
CoCreateInstance(MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL,
MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pShapePicture);
pShapePicture->put_ColorSpace( ( 1 << 6) | ( 1 << 31) ); // CPS_BGRA | CPS_FLIP
pShapePicture->put_Width( lWidthShape );
pShapePicture->put_Height( lHeightShape );
pShapePicture->put_AspectRatioX( lWidthShape );
pShapePicture->put_AspectRatioY( lHeightShape );
pShapePicture->put_Interlaced( VARIANT_FALSE );
pShapePicture->put_Stride( 0, 4 * lWidthShape );
pShapePicture->AllocateBuffer( -1 );
BYTE* pBufferDst = NULL;
pShapePicture->get_Buffer(&pBufferDst);
for (LONG lLine = 0; lLine < lHeightShape; ++lLine)
{
memcpy(pBufferDst, pBufferSrcMem, 4 * lWidthShape);
pBufferDst += 4 * lWidthShape;
pBufferSrcMem += 4 * m_lWidthPix;
}
IUnknown* pReturn = NULL;
pShapePicture->QueryInterface(IID_IUnknown, (void**)&pReturn);
RELEASEINTERFACE(pShapePicture);
return pReturn;
}
public:
// pen --------------------------------------------------------------------------------------
AVSINLINE HRESULT SetPen(BSTR bsXML)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetPen(bsXML);
}
return S_OK;
}
AVSINLINE HRESULT put_PenColor(LONG lColor)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenColor(lColor);
}
return S_OK;
}
AVSINLINE HRESULT put_PenAlpha(LONG lAlpha)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenAlpha(lAlpha);
}
return S_OK;
}
AVSINLINE HRESULT put_PenSize(double dSize)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenSize(dSize);
}
return S_OK;
}
AVSINLINE HRESULT put_PenDashStyle(BYTE val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenDashStyle(val);
}
return S_OK;
}
AVSINLINE HRESULT put_PenLineStartCap(BYTE val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenLineStartCap(val);
}
return S_OK;
}
AVSINLINE HRESULT put_PenLineEndCap(BYTE val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenLineEndCap(val);
}
return S_OK;
}
AVSINLINE HRESULT put_PenLineJoin(BYTE val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenLineJoin(val);
}
return S_OK;
}
AVSINLINE HRESULT put_PenDashOffset(double val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenDashOffset(val);
}
return S_OK;
}
AVSINLINE HRESULT put_PenAlign(LONG val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenAlign(val);
}
return S_OK;
}
AVSINLINE HRESULT put_PenMiterLimit(double val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenMiterLimit(val);
}
return S_OK;
}
AVSINLINE HRESULT PenDashPattern(SAFEARRAY* pPattern)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PenDashPattern(pPattern);
}
return S_OK;
}
// brush ------------------------------------------------------------------------------------
AVSINLINE HRESULT SetBrush(BSTR bsXML)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetBrush(bsXML);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushType(LONG lType)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushType(lType);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushColor1(LONG lColor)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushColor1(lColor);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushAlpha1(LONG lAlpha)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushAlpha1(lAlpha);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushColor2(LONG lColor)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushColor2(lColor);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushAlpha2(LONG lAlpha)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushAlpha2(lAlpha);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushTexturePath(BSTR bsPath)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushTexturePath(bsPath);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushTextureMode(LONG lMode)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushTextureMode(lMode);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushTextureAlpha(LONG lTxAlpha)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushTextureAlpha(lTxAlpha);
}
return S_OK;
}
AVSINLINE HRESULT put_BrushLinearAngle(double dAngle)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_BrushLinearAngle(dAngle);
}
return S_OK;
}
AVSINLINE HRESULT BrushRect(BOOL val, double left, double top, double width, double height)
{
if (NULL != m_pRenderer)
{
m_pRenderer->BrushRect(val, left, top, width, height);
}
return S_OK;
}
// font -------------------------------------------------------------------------------------
AVSINLINE HRESULT SetFont(BSTR bsXML)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetFont(bsXML);
}
return S_OK;
}
AVSINLINE HRESULT put_FontName(BSTR bsName)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_FontName(bsName);
}
return S_OK;
}
AVSINLINE HRESULT put_FontPath(BSTR bsName)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_FontPath(bsName);
}
return S_OK;
}
AVSINLINE HRESULT put_FontSize(double dSize)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_FontSize(dSize);
}
return S_OK;
}
AVSINLINE HRESULT put_FontStyle(LONG lStyle)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_FontStyle(lStyle);
}
return S_OK;
}
AVSINLINE HRESULT put_FontStringGID(BOOL bGID)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_FontStringGID(bGID);
}
return S_OK;
}
AVSINLINE HRESULT put_FontCharSpace(double dSpace)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_FontCharSpace(dSpace);
}
return S_OK;
}
// shadow -----------------------------------------------------------------------------------
AVSINLINE HRESULT SetShadow(BSTR bsXML)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetShadow(bsXML);
}
return S_OK;
}
AVSINLINE HRESULT put_ShadowDistanceX(double val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ShadowDistanceX(val);
}
return S_OK;
}
AVSINLINE HRESULT put_ShadowDistanceY(double val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ShadowDistanceY(val);
}
return S_OK;
}
AVSINLINE HRESULT put_ShadowBlurSize(double val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ShadowBlurSize(val);
}
return S_OK;
}
AVSINLINE HRESULT put_ShadowColor(LONG val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ShadowColor(val);
}
return S_OK;
}
AVSINLINE HRESULT put_ShadowAlpha(LONG val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ShadowAlpha(val);
}
return S_OK;
}
AVSINLINE HRESULT put_ShadowVisible(BOOL val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ShadowVisible(val);
}
return S_OK;
}
// edge -------------------------------------------------------------------------------------
AVSINLINE HRESULT SetEdgeText(BSTR bsXML)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetEdgeText(bsXML);
}
return S_OK;
}
AVSINLINE HRESULT put_EdgeVisible(LONG val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_EdgeVisible(val);
}
return S_OK;
}
AVSINLINE HRESULT put_EdgeColor(LONG val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_EdgeColor(val);
}
return S_OK;
}
AVSINLINE HRESULT put_EdgeAlpha(LONG val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_EdgeAlpha(val);
}
return S_OK;
}
AVSINLINE HRESULT put_EdgeDist(double val)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_EdgeDist(val);
}
return S_OK;
}
//-------- Функции для вывода текста --------------------------------------------------------
AVSINLINE HRESULT CommandDrawText(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
if (NULL != m_pRenderer)
{
m_pRenderer->CommandDrawText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
return S_OK;
}
AVSINLINE HRESULT CommandDrawTextEx(BSTR bsUnicodeText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (NULL != m_pRenderer)
{
m_pRenderer->CommandDrawTextEx(bsUnicodeText, bsGidText, bsSourceCodeText, fX, fY, fWidth, fHeight, fBaseLineOffset, lFlags);
}
return S_OK;
}
//-------- Маркеры для команд ---------------------------------------------------------------
AVSINLINE HRESULT BeginCommand(DWORD lType)
{
if (NULL != m_pRenderer)
{
m_pRenderer->BeginCommand(lType);
}
return S_OK;
}
AVSINLINE HRESULT EndCommand(DWORD lType)
{
if (NULL != m_pRenderer)
{
m_pRenderer->EndCommand(lType);
}
return S_OK;
}
//-------- Функции для работы с Graphics Path -----------------------------------------------
AVSINLINE HRESULT PathCommandMoveTo(double fX, double fY)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandMoveTo(fX, fY);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandLineTo(double fX, double fY)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandLineTo(fX, fY);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandLinesTo(SAFEARRAY* pPoints)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandLinesTo(pPoints);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandCurvesTo(SAFEARRAY* pPoints)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandCurvesTo(pPoints);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandClose()
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandClose();
}
return S_OK;
}
AVSINLINE HRESULT PathCommandEnd()
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandEnd();
}
return S_OK;
}
AVSINLINE HRESULT DrawPath(long nType)
{
if (NULL != m_pRenderer)
{
m_pRenderer->DrawPath(nType);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandStart()
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandStart();
}
return S_OK;
}
AVSINLINE HRESULT PathCommandText(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
return S_OK;
}
AVSINLINE HRESULT PathCommandTextEx(BSTR bsUnicodeText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (NULL != m_pRenderer)
{
m_pRenderer->PathCommandTextEx(bsUnicodeText, bsGidText, bsSourceCodeText, fX, fY, fWidth, fHeight, fBaseLineOffset, lFlags);
}
return S_OK;
}
AVSINLINE HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetCommandParams(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
}
return S_OK;
}
//-------- Функции для вывода изображений --------------------------------------------------
AVSINLINE HRESULT DrawImage(IUnknown* pInterface, double fX, double fY, double fWidth, double fHeight)
{
if (NULL != m_pRenderer)
{
m_pRenderer->DrawImage(pInterface, fX, fY, fWidth, fHeight);
}
return S_OK;
}
AVSINLINE HRESULT DrawImageFromFile(BSTR bstrVal, double fX, double fY, double fWidth, double fHeight)
{
if (NULL != m_pRenderer)
{
m_pRenderer->DrawImageFromFile(bstrVal, fX, fY, fWidth, fHeight);
}
return S_OK;
}
//------------------------------------------------------------------------------------------
AVSINLINE HRESULT SetAdditionalParam(BSTR ParamName, VARIANT ParamValue)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetAdditionalParam(ParamName, ParamValue);
}
return S_OK;
}
AVSINLINE HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF)
{
if (NULL != m_pRenderer)
{
m_pRenderer->SetTransform(dA, dB, dC, dD, dE, dF);
}
return S_OK;
}
AVSINLINE HRESULT ResetTransform(void)
{
if (NULL != m_pRenderer)
{
m_pRenderer->ResetTransform();
}
return S_OK;
}
AVSINLINE HRESULT put_ClipMode(LONG lMode)
{
if (NULL != m_pRenderer)
{
m_pRenderer->put_ClipMode(lMode);
}
return S_OK;
}
};
using namespace NSStrings;
class CWriter4
{
public:
CMetafile m_oPage;
CSVGWriter2 m_oSVGWriter;
CAtlArray<CPageMeta> m_arrPages;
bool m_bIsBigPicture;
LONG m_lTilingCounter;
public:
NSStructures::CPen* m_pPen;
NSStructures::CBrush* m_pBrush;
NSStructures::CFont* m_pFont;
NSStructures::CPen m_oLastPen;
NSStructures::CBrush m_oLastBrush;
NSStructures::CFont m_oLastFont;
LONG m_lCurrentFont;
double m_dCurrentFontSize;
CFontDstGenerator m_oDstFontGenerator;
CFontManager m_oFontManager;
CHText m_oSmartText;
double m_dDpiX;
double m_dDpiY;
BOOL m_bPathClosed;
CAtlMap<CString, CImageInfo> m_mapImagesFile;
CAtlMap<DWORD, CImageInfo> m_mapImageData;
CCalculatorCRC32 m_oCRC;
double m_dWidthDocMM;
double m_dHeightDocMM;
double m_dHeightPageMM;
Graphics::IASCGraphicSimpleComverter* m_pSimpleConverter;
CFile m_oFileWriter;
bool m_bIsGids;
public:
double m_dWidth;
double m_dHeight;
bool m_bIsImageFromVectors;
private:
LONG m_lNextIDShape;
LONG m_lNextIDImage;
LONG m_lCurrentPage;
LONG m_lCurrentFunctionPage;
LONG m_lPagesCount;
LONG m_lMaxSizeImage;
public:
CString m_strDstDirectory;
CString m_strDstMedia;
CString m_strDstDirectoryFiles;
CString m_strFileName;
CMatrix* m_pTransform;
CMatrix m_oLastTransform;
LONG m_lCurrentDumpSize;
LONG m_lSrcFileType;
bool m_bIsClipping;
bool m_bIsSimpleGraphics;
public:
CWriter4()
{
m_dDpiX = 96.0;
m_dDpiY = 96.0;
m_dWidth = 0;
m_dHeight = 0;
m_lNextIDImage = 0;
m_lNextIDShape = 0;
m_lCurrentPage = -1;
m_bPathClosed = TRUE;
m_pSimpleConverter = NULL;
m_lMaxSizeImage = 800;
m_dWidthDocMM = 0;
m_dHeightDocMM = 0;
m_dHeightPageMM = 0;
m_lPagesCount = 0;
m_bIsImageFromVectors = false;
m_lSrcFileType = 0;
m_bIsClipping = false;
m_bIsSimpleGraphics = false;
m_lTilingCounter = 0;
}
void CreateFile(CString& strDir, CString& strFileName)
{
m_lPagesCount = 0;
m_lCurrentPage = -1;
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);
CString strFileFonts = m_strDstDirectoryFiles + _T("\\fonts");
CDirectory::CreateDirectory(strFileFonts);
CString strDocRendererS = m_strDstDirectoryFiles + _T("\\document_temp.bin");
m_oFileWriter.CreateFile(strDocRendererS);
m_oPage.Clear();
m_arrPages.RemoveAll();
m_bIsGids = false;
m_lCurrentDumpSize = 0;
m_oSmartText.SetParams(this);
m_oSmartText.m_lCountParagraphs = 0;
m_oSmartText.m_lCountWords = 0;
m_oSmartText.m_lCountSymbols = 0;
m_oSmartText.m_lCountSpaces = 0;
}
void SetSimpleConverter(Graphics::IASCGraphicSimpleComverter* pSimpleConverter, CMatrix* pMatrix)
{
m_pSimpleConverter = pSimpleConverter;
m_pTransform = pMatrix;
m_oSVGWriter.m_pTransform = m_pTransform;
m_oSVGWriter.m_pPen = m_pPen;
m_oSVGWriter.m_pBrush = m_pBrush;
m_oSVGWriter.m_pLastPen = &m_oLastPen;
m_oSVGWriter.m_pLastBrush = &m_oLastBrush;
}
AVSINLINE void WriteText(BSTR bsText, BSTR bsGid, double x, double y, double width, double height, double baselineoffset, const bool& bIsChangedFontParamBetweenDrawText)
{
if (m_lSrcFileType == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU)
{
// не нужно ничего писать из djvu
return;
}
CheckVectorGraphics();
CheckTectClipRect();
bool bIsT = true;
if (NULL == bsText || bsText[0] == 0)
bIsT = false;
bool bIsG = true;
if (NULL == bsGid || bsGid[0] == 0)
bIsG = false;
if (!bIsT && !bIsG)
return;
bool bIsDumpFont = false;
if (m_lCurrentFont == -1 || bIsChangedFontParamBetweenDrawText)
{
BSTR bsFontsSymbols = (NULL == bsGid) ? bsText : bsGid;
LONG lCurrentFontIndex = m_oDstFontGenerator.AddFont(m_pFont, &m_oFontManager, bsFontsSymbols);
if ((lCurrentFontIndex != m_lCurrentFont) || (m_pFont->Size != m_dCurrentFontSize))
{
m_lCurrentFont = lCurrentFontIndex;
m_dCurrentFontSize = m_pFont->Size;
bIsDumpFont = true;
}
}
else
{
BSTR bsFontsSymbols = (NULL == bsGid) ? bsText : bsGid;
m_oDstFontGenerator.m_pFonts[m_lCurrentFont].AddBSTR(bsFontsSymbols);
}
if (NULL != bsGid)
m_bIsGids = true;
if (!bsText)
bsText = bsGid;
m_oSmartText.CommandText(bsText, bsGid, x, y, width, height, bIsDumpFont, this);
return;
}
AVSINLINE void WriteImage(IUnknown* punkImage, double x, double y, double width, double height)
{
/*
if (m_lTilingCounter > 0)
{
NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(punkImage);
m_oSVGWriter.WriteImage(oInfo, x, y, width, height);
return;
}
*/
CheckVectorGraphics();
m_oSmartText.DumpLine();
SetTransformToDocument(true);
bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false;
if (bIsClip)
m_oPage.Write(m_oSVGWriter.m_oClipMetafile);
NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(punkImage);
//m_oSVGWriter.WriteImage(oInfo, x, y, width, height);
WriteImage2(oInfo, x, y, width, height);
if (bIsClip)
m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType);
}
AVSINLINE void WritePattern(IUnknown* pPattern, CTileInfo& oTile)
{
CheckVectorGraphics();
m_oSmartText.DumpLine();
SetTransformToDocument(true);
NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(pPattern);
bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false;
if (bIsClip)
m_oPage.Write(m_oSVGWriter.m_oClipMetafile);
WriteImagePattrern(oInfo, oTile);
if (bIsClip)
m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType);
}
AVSINLINE void WriteImage(CString& strFile, double x, double y, double width, double height)
{
if (m_lTilingCounter > 0)
{
NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(strFile);
m_oSVGWriter.WriteImage(oInfo, x, y, width, height);
return;
}
CheckVectorGraphics();
m_oSmartText.DumpLine();
SetTransformToDocument(true);
bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false;
if (bIsClip)
m_oPage.Write(m_oSVGWriter.m_oClipMetafile);
NSHtmlRenderer::CImageInfo oInfo = GenerateImageID(strFile);
//m_oSVGWriter.WriteImage(oInfo, x, y, width, height);
WriteImage2(oInfo, x, y, width, height);
if (bIsClip)
m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType);
}
AVSINLINE void WriteImage2(NSHtmlRenderer::CImageInfo& oID, const double& x, const double& y, const double& w, const double& h)
{
SetTransformToDocument(true);
if (fabs(m_pTransform->m_agg_mtx.shx) < 0.0000001 && fabs(m_pTransform->m_agg_mtx.shy) < 0.0000001 &&
m_pTransform->m_agg_mtx.sx >= 0 && m_pTransform->m_agg_mtx.sy >= 0)
{
double xx = x;
double yy = y;
double rr = x + w;
double bb = y + h;
m_pTransform->TransformPoint(xx, yy);
m_pTransform->TransformPoint(rr, bb);
if (oID.m_eType == itJPG)
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(0);
m_oPage.WriteLONG(oID.m_lID);
m_oPage.WriteDouble(xx);
m_oPage.WriteDouble(yy);
m_oPage.WriteDouble(rr - xx);
m_oPage.WriteDouble(bb - yy);
}
else
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(1);
m_oPage.WriteLONG(oID.m_lID);
m_oPage.WriteDouble(xx);
m_oPage.WriteDouble(yy);
m_oPage.WriteDouble(rr - xx);
m_oPage.WriteDouble(bb - yy);
}
}
else
{
if (oID.m_eType == itJPG)
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(10);
m_oPage.WriteLONG(oID.m_lID);
m_oPage.WriteDouble(x);
m_oPage.WriteDouble(y);
m_oPage.WriteDouble(w);
m_oPage.WriteDouble(h);
agg::trans_affine* t = &m_pTransform->m_agg_mtx;
m_oPage.WriteDouble(t->sx);
m_oPage.WriteDouble(t->shy);
m_oPage.WriteDouble(t->shx);
m_oPage.WriteDouble(t->sy);
m_oPage.WriteDouble(t->tx);
m_oPage.WriteDouble(t->ty);
}
else
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(11);
m_oPage.WriteLONG(oID.m_lID);
m_oPage.WriteDouble(x);
m_oPage.WriteDouble(y);
m_oPage.WriteDouble(w);
m_oPage.WriteDouble(h);
agg::trans_affine* t = &m_pTransform->m_agg_mtx;
m_oPage.WriteDouble(t->sx);
m_oPage.WriteDouble(t->shy);
m_oPage.WriteDouble(t->shx);
m_oPage.WriteDouble(t->sy);
m_oPage.WriteDouble(t->tx);
m_oPage.WriteDouble(t->ty);
}
}
}
AVSINLINE void WriteImagePattrern(NSHtmlRenderer::CImageInfo& oID, CTileInfo& oTile)
{
SetTransformToDocument(true);
double dKoef = 25.4 / m_dDpiX;
double xx = oTile.bbox_x * dKoef;
double yy = oTile.bbox_y * dKoef;
double rr = oTile.bbox_r * dKoef;
double bb = oTile.bbox_b * dKoef;
if (oID.m_eType == itJPG)
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(0);
m_oPage.WriteLONG(oID.m_lID);
m_oPage.WriteDouble(xx);
m_oPage.WriteDouble(yy);
m_oPage.WriteDouble(rr - xx);
m_oPage.WriteDouble(bb - yy);
}
else
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(1);
m_oPage.WriteLONG(oID.m_lID);
m_oPage.WriteDouble(xx);
m_oPage.WriteDouble(yy);
m_oPage.WriteDouble(rr - xx);
m_oPage.WriteDouble(bb - yy);
}
}
AVSINLINE void WriteBeginPath()
{
//m_oVectors.WriteCommandType(CMetafile::ctPathCommandStart);
}
AVSINLINE void WriteEndPath()
{
//m_oVectors.WriteCommandType(CMetafile::ctPathCommandStart);
m_oSVGWriter.WritePathEnd();
}
AVSINLINE void WritePathStart()
{
}
AVSINLINE void WritePathClose()
{
//m_oVectors.WriteCommandType(CMetafile::ctPathCommandClose);
m_oSVGWriter.WritePathClose();
}
AVSINLINE void WritePathMoveTo(const double& x, const double& y)
{
/*
m_oVectors.WriteCommandType(CMetafile::ctPathCommandMoveTo);
m_oVectors.WriteDouble(x);
m_oVectors.WriteDouble(y);
*/
m_oSVGWriter.WritePathMoveTo(x, y);
}
AVSINLINE void WritePathLineTo(const double& x, const double& y)
{
/*
m_oVectors.WriteCommandType(CMetafile::ctPathCommandLineTo);
m_oVectors.WriteDouble(x);
m_oVectors.WriteDouble(y);
*/
m_oSVGWriter.WritePathLineTo(x, y);
}
AVSINLINE void WritePathCurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3)
{
/*
m_oVectors.WriteCommandType(CMetafile::ctPathCommandCurveTo);
m_oVectors.WriteDouble(x1);
m_oVectors.WriteDouble(y1);
m_oVectors.WriteDouble(x2);
m_oVectors.WriteDouble(y2);
m_oVectors.WriteDouble(x3);
m_oVectors.WriteDouble(y3);
*/
m_oSVGWriter.WritePathCurveTo(x1, y1, x2, y2, x3, y3);
}
AVSINLINE void WriteDrawPath(LONG lType)
{
/*
if (lType > 0xFF)
{
if (!m_oLastBrush.IsEqual(m_pBrush))
{
m_oLastBrush = *m_pBrush;
SetFillColor(true);
}
}
if (lType & 0x01)
{
if (!m_oLastPen.IsEqual(m_pPen))
{
m_oLastPen = *m_pPen;
SetStrokeColor(true);
SetLineWidth(true);
}
}
m_oVectors.WriteCommandType(CMetafile::ctDrawPath);
m_oVectors.WriteLONG(lType);
*/
CImageInfo oInfo;
if ((lType > 0xFF) && (c_BrushTypeTexture == m_pBrush->Type))
{
oInfo = GenerateImageID(m_pBrush->TexturePath);
if (TRUE)
{
// пока делаем так
double x = 0;
double y = 0;
double w = 0;
double h = 0;
m_pSimpleConverter->PathCommandGetBounds(&x, &y, &w, &h);
CheckVectorGraphics();
/*
bool bIsClip = (m_oSVGWriter.m_oClipMetafile.GetPosition() > 0) ? true : false;
if (bIsClip)
m_oPage.Write(m_oSVGWriter.m_oClipMetafile);
*/
LONG _oldPos = m_oSVGWriter.WriteTempClip();
m_oPage.Write(m_oSVGWriter.m_oClipMetafile);
WriteImage2(oInfo, x, y, w, h);
m_oSVGWriter.m_oClipMetafile.Seek(_oldPos);
/*
if (bIsClip)
m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType);
*/
m_oPage.WriteLONG(CMetafile::ctBeginCommand, c_nResetClipType);
lType &= 0xFF;
}
}
m_oSVGWriter.WriteDrawPath(lType, m_pSimpleConverter, oInfo);
}
AVSINLINE void WritePathClip()
{
m_oSVGWriter.WritePathClip();
}
AVSINLINE void WritePathClipEnd()
{
m_oSVGWriter.WritePathClipEnd();
}
AVSINLINE void WritePathResetClip()
{
m_oSVGWriter.WritePathResetClip();
}
AVSINLINE void SetFontStyle()
{
m_oPage.WriteCommandType(CMetafile::ctFontName);
m_oPage.WriteLONG(m_lCurrentFont);
m_oPage.WriteLONG(m_pFont->GetStyle());
m_oPage.WriteDouble(m_dCurrentFontSize);
}
AVSINLINE void SetTransformToDocument(bool bIsFromGraphics)
{
if (NULL == m_pTransform)
return;
if (bIsFromGraphics)
{
if ((fabs(1 - m_oLastTransform.m_agg_mtx.sx) < __g_matrix_eps) &&
(fabs(0 - m_oLastTransform.m_agg_mtx.shx) < __g_matrix_eps) &&
(fabs(0 - m_oLastTransform.m_agg_mtx.shy) < __g_matrix_eps) &&
(fabs(1 - m_oLastTransform.m_agg_mtx.sy) < __g_matrix_eps))
{
// ничего делать не нужно
}
else
{
m_oPage.WriteCommandType(CMetafile::ctResetTransform);
m_oLastTransform.Reset();
}
}
else
{
if (true)
{
m_oLastTransform = *m_pTransform;
agg::trans_affine* m = &m_pTransform->m_agg_mtx;
//m_oPage.Write(CMetafile::ctSetTransform, m->sx, m->shy, m->shx, m->sy, m->tx, m->ty);
m_oPage.WriteCommandType(CMetafile::ctSetTransform);
m_oPage.WriteDouble(m->sx);
m_oPage.WriteDouble(m->shy);
m_oPage.WriteDouble(m->shx);
m_oPage.WriteDouble(m->sy);
m_oPage.WriteDouble(m->tx);
m_oPage.WriteDouble(m->ty);
return;
}
if ((fabs(m_pTransform->m_agg_mtx.sx - m_oLastTransform.m_agg_mtx.sx) < __g_matrix_eps) &&
(fabs(m_pTransform->m_agg_mtx.shx - m_oLastTransform.m_agg_mtx.shx) < __g_matrix_eps) &&
(fabs(m_pTransform->m_agg_mtx.shy - m_oLastTransform.m_agg_mtx.shy) < __g_matrix_eps) &&
(fabs(m_pTransform->m_agg_mtx.sy - m_oLastTransform.m_agg_mtx.sy) < __g_matrix_eps) &&
(fabs(m_pTransform->m_agg_mtx.tx - m_oLastTransform.m_agg_mtx.tx) < __g_matrix_eps) &&
(fabs(m_pTransform->m_agg_mtx.ty - m_oLastTransform.m_agg_mtx.ty) < __g_matrix_eps))
{
// ничего делать не нужно
return;
}
if ((fabs(1 - m_pTransform->m_agg_mtx.sx) < __g_matrix_eps) &&
(fabs(0 - m_pTransform->m_agg_mtx.shx) < __g_matrix_eps) &&
(fabs(0 - m_pTransform->m_agg_mtx.shy) < __g_matrix_eps) &&
(fabs(1 - m_pTransform->m_agg_mtx.sy) < __g_matrix_eps) &&
(fabs(1 - m_oLastTransform.m_agg_mtx.sx) < __g_matrix_eps) &&
(fabs(0 - m_oLastTransform.m_agg_mtx.shx) < __g_matrix_eps) &&
(fabs(0 - m_oLastTransform.m_agg_mtx.shy) < __g_matrix_eps) &&
(fabs(1 - m_oLastTransform.m_agg_mtx.sy) < __g_matrix_eps))
{
// ничего делать не нужно
m_oLastTransform.Reset();
}
else
{
if ((fabs(1 - m_pTransform->m_agg_mtx.sx) < __g_matrix_eps) &&
(fabs(0 - m_pTransform->m_agg_mtx.shx) < __g_matrix_eps) &&
(fabs(0 - m_pTransform->m_agg_mtx.shy) < __g_matrix_eps) &&
(fabs(1 - m_pTransform->m_agg_mtx.sy) < __g_matrix_eps))
{
// ничего делать не нужно
m_oPage.WriteCommandType(CMetafile::ctResetTransform);
m_oLastTransform.Reset();
return;
}
m_oLastTransform = *m_pTransform;
agg::trans_affine* m = &m_pTransform->m_agg_mtx;
//m_oPage.Write(CMetafile::ctSetTransform, m->sx, m->shy, m->shx, m->sy, m->tx, m->ty);
m_oPage.WriteCommandType(CMetafile::ctSetTransform);
m_oPage.WriteDouble(m->sx);
m_oPage.WriteDouble(m->shy);
m_oPage.WriteDouble(m->shx);
m_oPage.WriteDouble(m->sy);
m_oPage.WriteDouble(m->tx);
m_oPage.WriteDouble(m->ty);
}
}
}
void NewPage(const double& dWidthMM, const double& dHeightMM)
{
++m_lPagesCount;
CPageMeta oInfo;
oInfo.m_dWidth = dWidthMM;
oInfo.m_dHeight = dHeightMM;
oInfo.m_lStart = m_lCurrentDumpSize;
oInfo.m_lEnd = 0;
m_dWidth = dWidthMM;
m_dHeight = dHeightMM;
m_arrPages.Add(oInfo);
m_oLastBrush.Color1 = -1;
m_oLastPen.Color = -1;
m_oLastFont.Name = _T("");
m_lCurrentFont = -1;
m_dCurrentFontSize = 0.0;
m_oLastTransform.Reset();
m_pTransform->Reset();
m_bIsBigPicture = false;
m_oSVGWriter.NewDocument(m_dWidth, m_dHeight, m_lPagesCount - 1);
}
void EndPage()
{
m_oSmartText.ClosePage();
CheckVectorGraphics();
m_arrPages[m_arrPages.GetCount() - 1].m_lEnd = m_lCurrentDumpSize + m_oPage.GetPosition();
m_lCurrentDumpSize += m_oPage.GetPosition();
m_oFileWriter.WriteFile((void*)m_oPage.GetData(), m_oPage.GetPosition());
m_oPage.Clear();
}
void WriteStartDocument()
{
m_bIsGids = false;
}
void WriteEndDocument(CDocument& oDocument)
{
CMetafile oDocInfo;
oDocInfo.WriteLONG(m_lPagesCount);
oDocInfo.WriteLONG(m_oSmartText.m_lCountParagraphs);
oDocInfo.WriteLONG(m_oSmartText.m_lCountWords);
oDocInfo.WriteLONG(m_oSmartText.m_lCountSymbols);
oDocInfo.WriteLONG(m_oSmartText.m_lCountSpaces);
oDocInfo.WriteLONG(m_oDstFontGenerator.m_lCountFonts);
LONG lOffset = (6 + 4 * m_lPagesCount) * sizeof(LONG);
for (LONG i = 0; i < m_lPagesCount; i++)
{
CPageMeta& oMeta = m_arrPages[i];
oDocInfo.WriteDouble(oMeta.m_dWidth);
oDocInfo.WriteDouble(oMeta.m_dHeight);
oDocInfo.WriteLONG(oMeta.m_lStart + lOffset);
oDocInfo.WriteLONG(oMeta.m_lEnd + lOffset);
}
m_oFileWriter.CloseFile();
CFile oFilePages;
oFilePages.OpenFile(m_strDstDirectoryFiles + _T("\\document_temp.bin"));
LONG lMetaSize = (LONG)oFilePages.GetFileSize();
LONG lSizeAll = oDocInfo.GetPosition() + lMetaSize;
BYTE* pData = new BYTE[lSizeAll];
memcpy(pData, oDocInfo.GetData(), oDocInfo.GetPosition());
oFilePages.ReadFile(pData + oDocInfo.GetPosition(), lMetaSize);
oFilePages.CloseFile();
::DeleteFile(m_strDstDirectoryFiles + _T("\\document_temp.bin"));
int nOutputLen = Base64EncodeGetRequiredLength(lSizeAll, ATL_BASE64_FLAG_NOCRLF);
BYTE* pOutput = new BYTE[nOutputLen];
Base64Encode(pData, lSizeAll, (LPSTR)pOutput, &nOutputLen, ATL_BASE64_FLAG_NOCRLF);
CFile _file;
_file.CreateFile(m_strDstDirectoryFiles + _T("\\document.js"));
CStringA sDstLen = "";
//#ifdef _DEBUG
//sDstLen.Format("window[\"document_base64\"] = \"%d;", lSizeAll);
//#else
sDstLen.Format("%d;", lSizeAll);
//#endif
_file.WriteFile((void*)sDstLen.GetBuffer(), sDstLen.GetLength());
_file.WriteFile((void*)pOutput, nOutputLen);
//#ifdef _DEBUG
//sDstLen = "\";";
//_file.WriteFile((void*)sDstLen.GetBuffer(), sDstLen.GetLength());
//#endif
_file.CloseFile();
m_oDstFontGenerator.WriteFonts(m_strDstDirectoryFiles + _T("\\fonts"), m_bIsGids);
}
AVSINLINE void CheckVectorGraphics()
{
/*
if (0 < m_oVectors.GetPosition() && m_bIsSimpleGraphics && !m_oSVGWriter.m_bIsClipping)
{
m_oPage.Write(m_oVectors);
}
else if (m_oSVGWriter.m_oDocument.GetCurSize() > 0)
{
WriteImageID_SVG();
}
m_oVectors.ClearNoAttack();
*/
if (m_oSVGWriter.m_lEmtyDocChecker < (ULONG)m_oSVGWriter.m_oDocument.GetCurSize())
WriteImageID_SVG();
}
AVSINLINE void CheckTectClipRect()
{
// смотрим, нужно ли обновить рект для клиппирования текста
if (m_oSVGWriter.m_bIsTextClipWriteCleared)
{
if (!m_oSVGWriter.m_oTextClipBounds.IsCleared)
{
m_oSmartText.DumpLine();
// записать клип
m_oPage.WriteCommandType(CMetafile::ctCommandTextClipRect);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.x);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.y);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.r);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.b);
m_oSVGWriter.m_bIsTextClipWriteCleared = false;
}
}
else
{
if (m_oSVGWriter.m_oTextClipBounds.IsCleared)
{
m_oSmartText.DumpLine();
// записать команду сброса клипа текстректа
m_oPage.WriteCommandType(CMetafile::ctCommandTextClipRectReset);
m_oSVGWriter.m_bIsTextClipWriteCleared = true;
return;
}
else if (m_oSVGWriter.m_bIsIntersectNewClipRect)
{
m_oSmartText.DumpLine();
// записать клип
m_oPage.WriteCommandType(CMetafile::ctCommandTextClipRect);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.x);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.y);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.r);
m_oPage.WriteDouble(m_oSVGWriter.m_oTextClipBounds.b);
m_oSVGWriter.m_bIsIntersectNewClipRect = false;
}
}
}
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("");
// не ресайзим картинки. Они рисуются теперь у нас с dpi 96
if (true || (lWidth <= m_lMaxSizeImage) && (lHeight <= m_lMaxSizeImage))
{
strXml = _T("<transforms>") + strSaveItem + _T("</transforms>");
}
else
{
LONG lW = 0;
LONG lH = 0;
double dAspect = (double)lWidth / lHeight;
if (lWidth >= lHeight)
{
lW = m_lMaxSizeImage;
lH = (LONG)((double)lW / dAspect);
}
else
{
lH = m_lMaxSizeImage;
lW = (LONG)(dAspect * lH);
}
CString strResize = _T("");
strResize.Format(_T("<ImageTransform-TransformResize 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\"/>");
}
CString strXml = _T("");
// не ресайзим картинки. Они рисуются теперь у нас с dpi 96
if (true || (lWidth <= m_lMaxSizeImage) && (lHeight <= m_lMaxSizeImage))
{
strXml = _T("<transforms>") + strSaveItem + _T("</transforms>");
}
else
{
LONG lW = 0;
LONG lH = 0;
double dAspect = (double)lWidth / lHeight;
if (lWidth >= lHeight)
{
lW = m_lMaxSizeImage;
lH = (LONG)((double)lW / dAspect);
}
else
{
lH = m_lMaxSizeImage;
lW = (LONG)(dAspect * lH);
}
CString strResize = _T("");
strResize.Format(_T("<ImageTransform-TransformResize 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 SaveImage2(IUnknown* punkImage, CString strDst)
{
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("<ImageFile-SaveAsPng destinationpath=\"") + strDst + _T(".png\" format=\"888\"/>");
CString strXml = _T("<transforms>") + 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;
}
void WriteImageID_SVG()
{
m_oSmartText.DumpLine();
SetTransformToDocument(true);
bool bIsBIG = false;
#ifdef USE_SIMPLE_GRAPHICS_NOSVG
if (m_oSVGWriter.m_bIsSimpleGraphics)
{
if (m_oSVGWriter.m_oVectors.GetPosition() > SVG_TO_RASTER_MIN_SIZE)
bIsBIG = true;
if (!bIsBIG)
{
m_oPage.Write(m_oSVGWriter.m_oVectors);
m_oSVGWriter.NewSVG();
return;
}
}
#endif
if (!bIsBIG)
{
if (m_oSVGWriter.m_oDocument.GetCurSize() > SVG_TO_RASTER_MIN_SIZE)
bIsBIG = true;
}
bool bIsNeedWriteEndSVG = true;
if (bIsBIG)
{
#ifdef USE_BIG_GRAPHICS_TORASTER
bool bIsBIGWrite = WriteSVGAsBitmap();
bIsNeedWriteEndSVG = false;
if (bIsBIGWrite)
{
m_oSVGWriter.NewSVG();
return;
}
#endif
}
if ((m_oSVGWriter.m_oDocument.GetCurSize() > SVG_INLINE_MAX_SIZE))
{
++m_lNextIDImage;
CString strSaveItem = _T("");
strSaveItem.Format(_T("\\image%d.svg"), m_lNextIDImage);
strSaveItem = m_strDstMedia + strSaveItem;
m_oSVGWriter.CloseFile2(strSaveItem, bIsNeedWriteEndSVG);
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(2);
m_oPage.WriteLONG(m_lNextIDImage);
}
else
{
m_oPage.WriteCommandType(CMetafile::ctDrawImage);
m_oPage.WriteBYTE(3);
m_oSVGWriter.CloseFile3(&m_oPage, bIsNeedWriteEndSVG);
}
m_oSVGWriter.NewSVG();
}
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);
}
bool WriteSVGAsBitmap()
{
BSTR bsXml = m_oSVGWriter.GetSVGXml();
LONG nWidth = m_oSVGWriter.m_lWidth;
LONG nHeight = m_oSVGWriter.m_lHeight;
MediaCore::IAVSUncompressedVideoFrame* pFrame = NULL;
CoCreateInstance( MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pFrame) );
if( !pFrame )
{
SysFreeString(bsXml);
return false;
}
pFrame->put_Width( nWidth );
pFrame->put_Height( nHeight );
pFrame->put_ColorSpace( CSP_BGRA );
pFrame->SetDefaultStrides();
pFrame->AllocateBuffer( -1 );
BYTE* pBuffer = NULL;
pFrame->get_Buffer( &pBuffer );
if( !pBuffer )
{
pFrame->Release();
SysFreeString(bsXml);
return false;
}
DWORD* dst = (DWORD*)pBuffer;
DWORD dwColor = 0x00FFFFFF;
LONG nCountPixels = nWidth * nHeight;
for(LONG i = 0; i < nCountPixels; ++i)
{
*dst++ = dwColor;
}
long lBufSize;
pFrame->get_BufferSize( &lBufSize );
pFrame->put_DataSize( lBufSize );
pFrame->put_AspectRatioX( nWidth );
pFrame->put_AspectRatioY( nHeight );
Graphics::IASCGraphicsRenderer* pGrRenderer;
CoCreateInstance( Graphics::CLSID_CASCGraphicsRenderer, NULL, CLSCTX_ALL, Graphics::IID_IASCGraphicsRenderer, (void**)(&pGrRenderer) );
if( !pGrRenderer )
{
pFrame->Release();
SysFreeString(bsXml);
return false;
}
pGrRenderer->put_Width ( (double)nWidth );
pGrRenderer->put_Height( (double)nHeight );
HRESULT hr = pGrRenderer->CreateFromMediaData( (IUnknown*)pFrame, 0, 0, nWidth, nHeight );
if ( FAILED(hr) )
{
pFrame->Release();
pGrRenderer->Release();
SysFreeString(bsXml);
return false;
}
Graphics::ISVGTransformer* pTransformer;
CoCreateInstance( Graphics::CLSID_SVGTransformer, NULL, CLSCTX_ALL, Graphics::IID_ISVGTransformer, (void**)(&pTransformer) );
if( !pTransformer )
{
pFrame->Release();
pGrRenderer->Release();
SysFreeString(bsXml);
return false;
}
hr = pTransformer->Load(bsXml);
SysFreeString(bsXml);
if ( FAILED(hr) )
{
pFrame->Release();
pGrRenderer->Release();
pTransformer->Release();
return false;
}
hr = pTransformer->Draw((IUnknown*)pGrRenderer, 0, 0, nWidth, nHeight);
if ( FAILED(hr) )
{
pFrame->Release();
pGrRenderer->Release();
pTransformer->Release();
return false;
}
NSHtmlRenderer::CImageInfo oInfo = GenerateImageID((IUnknown*)pFrame);
agg::trans_affine* m = &m_pTransform->m_agg_mtx;
double _sx = m->sx;
double _sy = m->sy;
double _shx = m->shx;
double _shy = m->shy;
double _tx = m->tx;
double _ty = m->ty;
m->sx = 1;
m->sy = 1;
m->shx = 0;
m->shy = 0;
m->tx = 0;
m->ty = 0;
WriteImage2(oInfo, 0, 0, m_dWidth, m_dHeight);
m->sx = _sx;
m->sy = _sy;
m->shx = _shx;
m->shy = _shy;
m->tx = _tx;
m->ty = _ty;
pFrame->Release();
pGrRenderer->Release();
pTransformer->Release();
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