#include "CASCSVGRenderer.h" #include "../DesktopEditor/graphics/GraphicsPath.h" #include "Writer/StringWriter.h" #include "CMetafile.h" //#include "ASCMetafile.h" //#include "StringWriter.h" //#include "..\Objects\Structures.h" //#include "ASCGraphicsSimpleConverter.h" //#include "..\Objects\ASCWinFonts.h" //#include "..\Objects\ASCFontManager.h" //#include "GdiplusEx.h" namespace NSSVG { inline static double FABS(double dVal) { return (dVal >= 0) ? dVal : -dVal; } inline static int round(double dVal) { return (int)(dVal + 0.5); } inline static LONG ConvertColor(LONG lBGR) { return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); } } namespace NSHtmlRenderer { static CString g_string_svgOpen = _T("\n"); static CString g_bstr_svgClose = L""; static CString g_string_image = _T("\n"); static CString g_bstr_graphicOpen = L"\n"; static CString g_bstr_graphicClose = L"\n"; static CString g_bstr_path_d = L" d=\""; static CString g_bstr_path_d_end = L"\" "; static CString g_bstr_vml_ClosePath = L"Z "; static CString g_string_vml_MoveTo = _T("M %d,%d "); static CString g_string_vml_LineTo = _T("L %d,%d "); static CString g_string_vml_CurveTo = _T("C %d,%d %d,%d %d,%d "); static CString g_bstr_vml_Path = L"\n"; static CString g_string_vml_StyleStroke = _T("style=\"fill:none;stroke:#%06x;stroke-width:%dpx;stroke-opacity:%.2lf\" "); static CString g_string_vml_StyleStroke_class = _T("class=\"stroke%d\" style=\"fill:none;stroke-width:%dpx;stroke-opacity:%.2lf\" "); static CString g_string_vml_StyleFill = _T("style=\"fill:#%06x;fill-opacity:%.2lf;fill-rule:%ls;stroke:none\" "); static CString g_string_vml_StyleFill_class = _T("class=\"fill%d\" style=\"fill-opacity:%.2lf;fill-rule:%ls;stroke:none\" "); static CString g_string_vml_Style = _T("style=\"fill:#%06x;fill-opacity:%.2lf;fill-rule:%ls;stroke:#%06x;stroke-width:%dpx;stroke-opacity:%.2lf\" "); static CString g_string_vml_Style1 = _T("class=\"stroke%d\" style=\"fill:#%06x;fill-opacity:%.2lf;fill-rule:%ls;stroke-width:%dpx;stroke-opacity:%.2lf\" "); static CString g_string_vml_Style2 = _T("class=\"fill%d\" style=\"fill-opacity:%.2lf;fill-rule:%ls;stroke:#%06x;stroke-width:%dpx;stroke-opacity:%.2lf\" "); static CString g_string_vml_Style3 = _T("class=\"stroke%d fill%d\" style=\"fill-opacity:%.2lf;fill-rule:%ls;stroke-width:%dpx;stroke-opacity:%.2lf\" "); CASCSVGRenderer::CASCSVGRenderer() { m_dDpiX = 96.0; m_dDpiY = 96.0; m_dWidth = -1; m_dHeight = -1; m_lClipMode = c_nClipRegionTypeWinding; m_pSimpleGraphicsConverter = new Aggplus::CGraphicsPathSimpleConverter(); m_pSimpleGraphicsConverter->SetRenderer(this); m_pFontManager = NULL; m_bDeleteFontManager = true; m_pPen = new NSStructures::CPen(); m_pBrush = new NSStructures::CBrush(); m_pFont = new NSStructures::CFont(); m_pInstalledFont = new NSStructures::CFont(); m_pInstalledFont->Name = _T(""); m_pBaseTransform = new Aggplus::CMatrix(); m_pTransform = new Aggplus::CMatrix(); m_pFullTransform = new Aggplus::CMatrix(); m_pWriter = new NSStrings::CStringWriter(); m_pWriterVML = new NSStrings::CStringWriter(); } CASCSVGRenderer::~CASCSVGRenderer() { RELEASEOBJECT(m_pSimpleGraphicsConverter); if(m_bDeleteFontManager) RELEASEOBJECT(m_pFontManager); RELEASEOBJECT(m_pPen); RELEASEOBJECT(m_pBrush); RELEASEOBJECT(m_pFont); RELEASEOBJECT(m_pInstalledFont); RELEASEOBJECT(m_pBaseTransform); RELEASEOBJECT(m_pTransform); RELEASEOBJECT(m_pFullTransform); RELEASEOBJECT(m_pWriter); RELEASEOBJECT(m_pWriterVML); } HRESULT CASCSVGRenderer::get_Type(LONG* lType) { if (NULL == lType) return S_FALSE; *lType = c_nSVGRendrerer; return S_OK; } //-------- Функции для работы со страницей -------------------------------------------------- HRESULT CASCSVGRenderer::NewPage() { return S_OK; } HRESULT CASCSVGRenderer::get_Height(double* dHeight) { *dHeight = m_dHeight; return S_OK; } HRESULT CASCSVGRenderer::put_Height(const double& dHeight) { m_dHeight = dHeight; if (-1 != m_dWidth) OnBaseMatrixUpdate(); return S_OK; } HRESULT CASCSVGRenderer::get_Width(double* dWidth) { *dWidth = m_dWidth; return S_OK; } HRESULT CASCSVGRenderer::put_Width(const double& dWidth) { m_dWidth = dWidth; if (-1 != m_dHeight) OnBaseMatrixUpdate(); return S_OK; } HRESULT CASCSVGRenderer::get_DpiX(double* dDpiX) { if (NULL != dDpiX) *dDpiX = m_dDpiX; return S_OK; } HRESULT CASCSVGRenderer::get_DpiY(double* dDpiY) { if (NULL != dDpiY) *dDpiY = m_dDpiY; return S_OK; } // pen -------------------------------------------------------------------------------------- HRESULT CASCSVGRenderer::get_PenColor(LONG* lColor) { *lColor = m_pPen->Color; return S_OK; } HRESULT CASCSVGRenderer::put_PenColor(const LONG& lColor) { m_pPen->Color = (lColor & 0x00FFFFFF); DWORD dwVal = (DWORD)lColor; LONG lSchemeIndex = ((BYTE)(dwVal >> 24) - 100); if (lSchemeIndex >= 0) m_lColorSchemeIndexPen1 = lSchemeIndex; else m_lColorSchemeIndexPen1 = -1; return S_OK; } HRESULT CASCSVGRenderer::get_PenAlpha(LONG* lAlpha) { *lAlpha = m_pPen->Alpha; return S_OK; } HRESULT CASCSVGRenderer::put_PenAlpha(const LONG& lAlpha) { m_pPen->Alpha = lAlpha; return S_OK; } HRESULT CASCSVGRenderer::get_PenSize(double* dSize) { *dSize = m_pPen->Size; return S_OK; } HRESULT CASCSVGRenderer::put_PenSize(const double& dSize) { m_pPen->Size = dSize; return S_OK; } HRESULT CASCSVGRenderer::get_PenDashStyle(BYTE* val) { *val = m_pPen->DashStyle; return S_OK; } HRESULT CASCSVGRenderer::put_PenDashStyle(const BYTE& val) { m_pPen->DashStyle = val; return S_OK; } HRESULT CASCSVGRenderer::get_PenLineStartCap(BYTE* val) { *val = m_pPen->LineStartCap; return S_OK; } HRESULT CASCSVGRenderer::put_PenLineStartCap(const BYTE& val) { m_pPen->LineStartCap = val; return S_OK; } HRESULT CASCSVGRenderer::get_PenLineEndCap(BYTE* val) { *val = m_pPen->LineEndCap; return S_OK; } HRESULT CASCSVGRenderer::put_PenLineEndCap(const BYTE& val) { m_pPen->LineEndCap = val; return S_OK; } HRESULT CASCSVGRenderer::get_PenLineJoin(BYTE* val) { *val = m_pPen->LineJoin; return S_OK; } HRESULT CASCSVGRenderer::put_PenLineJoin(const BYTE& val) { m_pPen->LineJoin = val; return S_OK; } HRESULT CASCSVGRenderer::get_PenDashOffset(double* val) { *val = m_pPen->DashOffset; return S_OK; } HRESULT CASCSVGRenderer::put_PenDashOffset(const double& val) { m_pPen->DashOffset = val; return S_OK; } HRESULT CASCSVGRenderer::get_PenAlign(LONG* val) { *val = m_pPen->Align; return S_OK; } HRESULT CASCSVGRenderer::put_PenAlign(const LONG& val) { m_pPen->Align = val; return S_OK; } HRESULT CASCSVGRenderer::get_PenMiterLimit(double* val) { *val = m_pPen->MiterLimit; return S_OK; } HRESULT CASCSVGRenderer::put_PenMiterLimit(const double& val) { m_pPen->MiterLimit = val; return S_OK; } HRESULT CASCSVGRenderer::PenDashPattern(double* pPattern, LONG lCount) { if (NULL != pPattern) { m_pPen->SetDashPattern(pPattern, lCount); } return S_OK; } // brush ------------------------------------------------------------------------------------ HRESULT CASCSVGRenderer::get_BrushType(LONG* lType) { *lType = m_pBrush->Type; return S_OK; } HRESULT CASCSVGRenderer::put_BrushType(const LONG& lType) { m_pBrush->Type = lType; return S_OK; } HRESULT CASCSVGRenderer::get_BrushColor1(LONG* lColor) { *lColor = m_pBrush->Color1; return S_OK; } HRESULT CASCSVGRenderer::put_BrushColor1(const LONG& lColor) { m_pBrush->Color1 = (lColor & 0x00FFFFFF); DWORD dwVal = (DWORD)lColor; LONG lSchemeIndex = ((BYTE)(dwVal >> 24) - 100); if (lSchemeIndex >= 0) m_lColorSchemeIndexBrush1 = lSchemeIndex; else m_lColorSchemeIndexBrush1 = -1; return S_OK; } HRESULT CASCSVGRenderer::get_BrushAlpha1(LONG* lAlpha) { *lAlpha = m_pBrush->Alpha1; return S_OK; } HRESULT CASCSVGRenderer::put_BrushAlpha1(const LONG& lAlpha) { m_pBrush->Alpha1 = lAlpha; return S_OK; } HRESULT CASCSVGRenderer::get_BrushColor2(LONG* lColor) { *lColor = m_pBrush->Color2; return S_OK; } HRESULT CASCSVGRenderer::put_BrushColor2(const LONG& lColor) { m_pBrush->Color2 = lColor; return S_OK; } HRESULT CASCSVGRenderer::get_BrushAlpha2(LONG* lAlpha) { *lAlpha = m_pBrush->Alpha2; return S_OK; } HRESULT CASCSVGRenderer::put_BrushAlpha2(const LONG& lAlpha) { m_pBrush->Alpha2 = lAlpha; return S_OK; } HRESULT CASCSVGRenderer::get_BrushTexturePath(std::wstring* bsPath) { *bsPath = m_pBrush->TexturePath; return S_OK; } HRESULT CASCSVGRenderer::put_BrushTexturePath(const std::wstring& bsPath) { m_pBrush->TexturePath = bsPath; return S_OK; } HRESULT CASCSVGRenderer::get_BrushTextureMode(LONG* lMode) { *lMode = m_pBrush->TextureMode; return S_OK; } HRESULT CASCSVGRenderer::put_BrushTextureMode(const LONG& lMode) { m_pBrush->TextureMode = lMode; return S_OK; } HRESULT CASCSVGRenderer::get_BrushTextureAlpha(LONG* lTxAlpha) { *lTxAlpha = m_pBrush->TextureAlpha; return S_OK; } HRESULT CASCSVGRenderer::put_BrushTextureAlpha(const LONG& lTxAlpha) { m_pBrush->TextureAlpha = lTxAlpha; return S_OK; } HRESULT CASCSVGRenderer::get_BrushLinearAngle(double* dAngle) { *dAngle = m_pBrush->LinearAngle; return S_OK; } HRESULT CASCSVGRenderer::put_BrushLinearAngle(const double& dAngle) { m_pBrush->LinearAngle = dAngle; return S_OK; } HRESULT CASCSVGRenderer::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height) { m_pBrush->Rectable = val; m_pBrush->Rect.X = (float)left; m_pBrush->Rect.Y = (float)top; m_pBrush->Rect.Width = (float)width; m_pBrush->Rect.Height = (float)height; return S_OK; } HRESULT CASCSVGRenderer::BrushBounds(const double& left, const double& top, const double& width, const double& height) { //todo new command return S_OK; } HRESULT CASCSVGRenderer::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) { //todo new command return S_OK; } // font ------------------------------------------------------------------------------------- HRESULT CASCSVGRenderer::get_FontName(std::wstring* bsName) { *bsName = m_pFont->Name; return S_OK; } HRESULT CASCSVGRenderer::put_FontName(const std::wstring& bsName) { m_pFont->Name = bsName; return S_OK; } HRESULT CASCSVGRenderer::get_FontPath(std::wstring* bsName) { *bsName = m_pFont->Path; return S_OK; } HRESULT CASCSVGRenderer::put_FontPath(const std::wstring& bsName) { m_pFont->Path = bsName; return S_OK; } HRESULT CASCSVGRenderer::get_FontSize(double* dSize) { *dSize = m_pFont->Size; return S_OK; } HRESULT CASCSVGRenderer::put_FontSize(const double& dSize) { m_pFont->Size = dSize; return S_OK; } HRESULT CASCSVGRenderer::get_FontStyle(LONG* lStyle) { *lStyle = m_pFont->GetStyle(); return S_OK; } HRESULT CASCSVGRenderer::put_FontStyle(const LONG& lStyle) { m_pFont->SetStyle(lStyle); return S_OK; } HRESULT CASCSVGRenderer::get_FontStringGID(INT* bGID) { *bGID = m_pFont->StringGID; return S_OK; } HRESULT CASCSVGRenderer::put_FontStringGID(const INT& bGID) { m_pFont->StringGID = bGID; return S_OK; } HRESULT CASCSVGRenderer::get_FontCharSpace(double* dSpace) { *dSpace = m_pFont->CharSpace; return S_OK; } HRESULT CASCSVGRenderer::put_FontCharSpace(const double& dSpace) { m_pFont->CharSpace = dSpace; return S_OK; } HRESULT CASCSVGRenderer::get_FontFaceIndex(int* lFaceIndex) { *lFaceIndex = m_pFont->FaceIndex; return S_OK; } HRESULT CASCSVGRenderer::put_FontFaceIndex(const int& lFaceIndex) { m_pFont->FaceIndex = lFaceIndex; return S_OK; } //-------- Функции для вывода текста -------------------------------------------------------- HRESULT CASCSVGRenderer::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) { //todo new command return S_OK; } HRESULT CASCSVGRenderer::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) { if (c_nHyperlinkType == m_lCurrentCommandType) return S_OK; PathCommandStart(); PathCommandText(bsText, x, y, w, h, baselineOffset); //double dOldPenW = m_pPen->Size; //long lOldPenC = m_pPen->Color; //long lOldPenA = m_pPen->Alpha; //m_pPen->Size = 25.4 / 96; //m_pPen->Color = m_pBrush->Color1; //m_pPen->Alpha = m_pBrush->Alpha1; DrawPath(0x0100); //m_pPen->Size = dOldPenW; //m_pPen->Color = lOldPenC; //m_pPen->Alpha = lOldPenA; PathCommandEnd(); //double x = fX; //double y = fY; //m_pFullTransform->TransformPoint(x, y); //double r = fX + fWidth; //double b = fY + fHeight; //m_pFullTransform->TransformPoint(r, b); //m_pWriter->WriteText(bsText, NULL, x, y, r - x, b - y, fBaseLineOffset); return S_OK; } HRESULT CASCSVGRenderer::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) { //todo new command return S_OK; } HRESULT CASCSVGRenderer::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) { if (!bsGidText.empty()) { m_pFont->StringGID = TRUE; return CommandDrawText(bsGidText, x, y, w, h, baselineOffset); } m_pFont->StringGID = FALSE; return CommandDrawText(bsUnicodeText, x, y, w, h, baselineOffset); } //-------- Маркеры для команд --------------------------------------------------------------- HRESULT CASCSVGRenderer::BeginCommand(const DWORD& lType) { if (c_nClipType == lType) { //m_pWriter->WritePathClip(); } else if (c_nPathType == lType) { //m_pWriter->WriteBeginPath(); } m_lCurrentCommandType = lType; return S_OK; } HRESULT CASCSVGRenderer::EndCommand(const DWORD& lType) { if (c_nPageType == lType) { EndPage(); } else if (c_nClipType == lType) { //m_pWriter->WritePathClipEnd(); } else if (c_nResetClipType == lType) { //m_pWriter->WritePathResetClip(); } m_lCurrentCommandType = -1; return S_OK; } //-------- Функции для работы с Graphics Path ----------------------------------------------- HRESULT CASCSVGRenderer::PathCommandMoveTo(const double& fX, const double& fY) { if (c_nSimpleGraphicType == m_lCurrentCommandType) { MoveTo(fX, fY); } else { m_pSimpleGraphicsConverter->PathCommandMoveTo(fX, fY); } return S_OK; } HRESULT CASCSVGRenderer::PathCommandLineTo(const double& fX, const double& fY) { if (c_nSimpleGraphicType == m_lCurrentCommandType) { LineTo(fX, fY); } else { m_pSimpleGraphicsConverter->PathCommandLineTo(fX, fY); } return S_OK; } HRESULT CASCSVGRenderer::PathCommandLinesTo(double* points, const int& count) { m_pSimpleGraphicsConverter->PathCommandLinesTo(points, count); return S_OK; } HRESULT CASCSVGRenderer::PathCommandCurveTo(const double& fX1, const double& fY1, const double& fX2, const double& fY2, const double& fX3, const double& fY3) { if (c_nSimpleGraphicType == m_lCurrentCommandType) { CurveTo(fX1, fY1, fX2, fY2, fX3, fY3); } else { m_pSimpleGraphicsConverter->PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); } return S_OK; } HRESULT CASCSVGRenderer::PathCommandCurvesTo(double* points, const int& count) { m_pSimpleGraphicsConverter->PathCommandCurvesTo(points, count); return S_OK; } HRESULT CASCSVGRenderer::PathCommandArcTo(const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fStartAngle, const double& fSweepAngle) { m_pSimpleGraphicsConverter->PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); return S_OK; } HRESULT CASCSVGRenderer::PathCommandClose() { if (c_nSimpleGraphicType == m_lCurrentCommandType) { Close(); } else { m_pSimpleGraphicsConverter->PathCommandClose(); } return S_OK; } HRESULT CASCSVGRenderer::PathCommandEnd() { if (c_nSimpleGraphicType == m_lCurrentCommandType) { End(); } else { m_pSimpleGraphicsConverter->PathCommandEnd(); } return S_OK; } HRESULT CASCSVGRenderer::DrawPath(const long& nType) { if (m_pWriterVML->GetCurSize() < 3) return S_OK; //m_pWriter->WriteDrawPath(nType); bool bStroke = (0x01 == (0x01 & nType)); bool bFill = (0x01 < nType); if (0 == m_pPen->Alpha) bStroke = false; if ((0 == m_pBrush->Alpha1) && (c_BrushTypeSolid == m_pBrush->Type)) bFill = false; else if ((0 == m_pBrush->TextureAlpha) && (c_BrushTypeTexture == m_pBrush->Type || c_BrushTypePattern == m_pBrush->Type)) bFill = false; if (!bFill) { // stroke int nColorPen = NSSVG::ConvertColor(m_pPen->Color); int nPenW = NSSVG::round(m_pPen->Size * m_dDpiY / c_ag_Inch_to_MM); CString strStyle = _T(""); if (-1 == m_lColorSchemeIndexPen1) strStyle.Format(g_string_vml_StyleStroke, nColorPen, nPenW, (double)m_pPen->Alpha / 255); else strStyle.Format(g_string_vml_StyleStroke_class, m_lColorSchemeIndexPen1, nPenW, (double)m_pPen->Alpha / 255); m_pWriter->WriteString(g_bstr_vml_Path); m_pWriter->WriteString(strStyle); m_pWriter->WriteString(g_bstr_path_d); m_pWriter->Write(*m_pWriterVML); m_pWriter->WriteString(g_bstr_path_d_end); m_pWriter->WriteString(g_bstr_nodeClose); return S_OK; } else if (c_BrushTypeTexture == m_pBrush->Type || c_BrushTypePattern == m_pBrush->Type) { double x = 0; double y = 0; double w = 0; double h = 0; m_pSimpleGraphicsConverter->PathCommandGetBounds(x, y, w, h); DrawImageFromFile(m_pBrush->TexturePath, x, y, w, h, 255); return S_OK; //double x = 0; //double y = 0; //double r = 0; //double b = 0; //m_pSimpleGraphicsConverter->PathCommandGetBounds(&x, &y, &r, &b); //r += x; //b += y; //m_pFullTransform->TransformPoint(x, y); //m_pFullTransform->TransformPoint(r, b); //CString str = _T(""); //str.Format(g_string_image, NSSVG::round(x), NSSVG::round(y), NSSVG::round(r - x), NSSVG::round(b - y), m_pBrush->TexturePath); //m_pWriter->WriteString(str); //return S_OK; } int nColorBrush = NSSVG::ConvertColor(m_pBrush->Color1); CString strMode = _T("nonzero"); if (nType & c_nEvenOddFillMode) strMode = _T("evenodd"); if (!bStroke) { CString strStyle = _T(""); if (-1 == m_lColorSchemeIndexBrush1) strStyle.Format(g_string_vml_StyleFill, nColorBrush, (double)m_pBrush->Alpha1 / 255, strMode); else strStyle.Format(g_string_vml_StyleFill_class, m_lColorSchemeIndexBrush1, (double)m_pBrush->Alpha1 / 255, strMode); m_pWriter->WriteString(g_bstr_vml_Path); m_pWriter->WriteString(strStyle); m_pWriter->WriteString(g_bstr_path_d); m_pWriter->Write(*m_pWriterVML); m_pWriter->WriteString(g_bstr_path_d_end); m_pWriter->WriteString(g_bstr_nodeClose); return S_OK; } int nPenColor = NSSVG::ConvertColor(m_pPen->Color); int nPenW = NSSVG::round(m_pPen->Size * m_dDpiY / c_ag_Inch_to_MM); CString strStyle = _T(""); if (-1 != m_lColorSchemeIndexPen1 && -1 != m_lColorSchemeIndexBrush1) strStyle.Format(g_string_vml_Style3, m_lColorSchemeIndexPen1, m_lColorSchemeIndexBrush1, (double)m_pBrush->Alpha1 / 255, strMode, nPenW, (double)m_pPen->Alpha / 255); else if (-1 != m_lColorSchemeIndexPen1) strStyle.Format(g_string_vml_Style1, m_lColorSchemeIndexPen1, nColorBrush, (double)m_pBrush->Alpha1 / 255, strMode, nPenW, (double)m_pPen->Alpha / 255); else if (-1 != m_lColorSchemeIndexBrush1) strStyle.Format(g_string_vml_Style2, m_lColorSchemeIndexBrush1, (double)m_pBrush->Alpha1 / 255, strMode, nPenColor, nPenW, (double)m_pPen->Alpha / 255); else strStyle.Format(g_string_vml_Style, nColorBrush, (double)m_pBrush->Alpha1 / 255, strMode, nPenColor, nPenW, (double)m_pPen->Alpha / 255); m_pWriter->WriteString(g_bstr_vml_Path); m_pWriter->WriteString(strStyle); m_pWriter->WriteString(g_bstr_path_d); m_pWriter->Write(*m_pWriterVML); m_pWriter->WriteString(g_bstr_path_d_end); m_pWriter->WriteString(g_bstr_nodeClose); return S_OK; } HRESULT CASCSVGRenderer::PathCommandStart() { if (c_nSimpleGraphicType == m_lCurrentCommandType) { Start(); } else { m_pSimpleGraphicsConverter->PathCommandStart(); } return S_OK; } HRESULT CASCSVGRenderer::PathCommandGetCurrentPoint(double* fX, double* fY) { m_pSimpleGraphicsConverter->PathCommandGetCurrentPoint(fX, fY); return S_OK; } HRESULT CASCSVGRenderer::PathCommandTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h, const double& baselineOffset) { //todo new command return S_OK; } HRESULT CASCSVGRenderer::PathCommandText(const std::wstring& bsText, const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fBaseLineOffset) { if (NULL == m_pFontManager) { m_pFontManager = new CFontManager(); m_pFontManager->Initialize(); } _SetFont(); m_pSimpleGraphicsConverter->PathCommandText(bsText, m_pFontManager, fX, fY, fWidth, fHeight, fBaseLineOffset); return S_OK; } HRESULT CASCSVGRenderer::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) { //todo new command return S_OK; } HRESULT CASCSVGRenderer::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) { if (!bsGidText.empty()) { m_pFont->StringGID = TRUE; return PathCommandText(bsGidText, x, y, w, h, baselineOffset); } m_pFont->StringGID = FALSE; return PathCommandText(bsUnicodeText, x, y, w, h, baselineOffset); } //-------- Функции для вывода изображений --------------------------------------------------- HRESULT CASCSVGRenderer::DrawImage(IGrObject* pImage, const double& fX, const double& fY, const double& fWidth, const double& fHeight) { double x = fX; double y = fY; m_pFullTransform->TransformPoint(x, y); double r = fX + fWidth; double b = fY + fHeight; m_pFullTransform->TransformPoint(r, b); //m_pWriter->WriteImage(pInterface, x, y, r - x, b - y); return S_OK; } HRESULT CASCSVGRenderer::DrawImageFromFile(const std::wstring& sVal, const double& fX, const double& fY, const double& fWidth, const double& fHeight, const BYTE& lAlpha = 255) { double x = fX; double y = fY; m_pFullTransform->TransformPoint(x, y); double r = fX + fWidth; double b = fY + fHeight; m_pFullTransform->TransformPoint(r, b); CImageExt oExt; LONG lFileType = oExt.GetImageType(sVal); if ((1 == lFileType) || (2 == lFileType)) { // метафайл oExt.DrawOnRenderer(this, sVal, fX, fY, fWidth, fHeight, TRUE); return S_OK; } CString str = _T(""); str.Format(g_string_image, NSSVG::round(x), NSSVG::round(y), NSSVG::round(r - x), NSSVG::round(b - y), sVal.c_str()); m_pWriter->WriteString(str); return S_OK; } // transform -------------------------------------------------------------------------------- HRESULT CASCSVGRenderer::SetTransform(const double& dA, const double& dB, const double& dC, const double& dD, const double& dE, const double& dF) { Aggplus::CMatrix oTrans(dA, dB, dC, dD, dE, dF); *m_pTransform = oTrans; CalculateFullTransform(); return S_OK; } HRESULT CASCSVGRenderer::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) { return S_OK; } HRESULT CASCSVGRenderer::ResetTransform(void) { m_pTransform->Reset(); CalculateFullTransform(); return S_OK; } // ----------------------------------------------------------------------------------------- HRESULT CASCSVGRenderer::get_ClipMode(LONG* plMode) { *plMode = m_lClipMode; return S_OK; } HRESULT CASCSVGRenderer::put_ClipMode(const LONG& lMode) { m_lClipMode = lMode; return S_OK; } // -------------------------------------------------------------------------------------------- HRESULT CASCSVGRenderer::CommandLong(const LONG& lType, const LONG& lCommand) { //todo new command; return S_OK; } HRESULT CASCSVGRenderer::CommandDouble(const LONG& lType, const double& dCommand) { //todo new command; return S_OK; } HRESULT CASCSVGRenderer::CommandString(const LONG& lType, const std::wstring& sCommand) { //todo new command; return S_OK; } // file HRESULT CASCSVGRenderer::CreateOfficeFile(const std::wstring& bsFilePath, const LONG& lFonts) { m_strDstFile = bsFilePath; m_pWriter->Clear(); if (0 != lFonts) { //todo //if (NULL == m_pFonts) //{ // CoCreateInstance(__uuidof(CASCWinFonts), NULL, CLSCTX_ALL, __uuidof(IASCWinFonts), (void**)&m_pFonts); //} if (NULL == m_pFontManager) { m_pFontManager = new CFontManager(); m_pFontManager->Initialize(); //m_pFontManager->SetDefaultFont(L"Arial"); } } double dW = m_dWidth; double dH = m_dHeight; m_pFullTransform->TransformPoint(dW, dH); int w = NSSVG::round(dW); int h = NSSVG::round(dH); CString strSVG = _T(""); strSVG.Format(g_string_svgOpen, w, h, w, h); m_pWriter->WriteString(strSVG); m_pWriter->WriteString(g_bstr_graphicOpen); m_lColorSchemeIndexBrush1 = -1; m_lColorSchemeIndexPen1 = -1; return S_OK; } HRESULT CASCSVGRenderer::CloseFile(const LONG& lSave) { m_pWriter->WriteString(g_bstr_graphicClose); m_pWriter->WriteString(g_bstr_svgClose); if (0 == lSave) return S_OK; NSFile::CFileBinary oFile; if (S_OK == oFile.CreateFileW(m_strDstFile)) { CString strData = m_pWriter->GetCString(); oFile.WriteFile((BYTE*)strData.GetBuffer(), sizeof(WCHAR) * strData.GetLength()); } return S_OK; } HRESULT CASCSVGRenderer::get_Data(std::wstring* bsData) { *bsData = std::wstring(m_pWriter->GetCString().GetString()); return S_OK; } void CASCSVGRenderer::SetFontManager(CFontManager* pFontManager) { if(m_bDeleteFontManager) RELEASEOBJECT(m_pFontManager); m_pFontManager = pFontManager; m_bDeleteFontManager = false; } void CASCSVGRenderer::CalculateFullTransform() { *m_pFullTransform = *m_pBaseTransform; m_pFullTransform->Multiply(m_pTransform, Aggplus::MatrixOrderPrepend); } inline void CASCSVGRenderer::MoveTo(const double& dX, const double& dY) { double x = dX; double y = dY; m_pFullTransform->TransformPoint(x, y); CString str = _T(""); str.Format(g_string_vml_MoveTo, (int)x, (int)y); m_pWriterVML->WriteString(str); } inline void CASCSVGRenderer::LineTo(const double& dX, const double& dY) { double x = dX; double y = dY; m_pFullTransform->TransformPoint(x, y); CString str = _T(""); str.Format(g_string_vml_LineTo, (int)x, (int)y); m_pWriterVML->WriteString(str); } inline void CASCSVGRenderer::CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3) { double _x1 = x1; double _y1 = y1; m_pFullTransform->TransformPoint(_x1, _y1); double _x2 = x2; double _y2 = y2; m_pFullTransform->TransformPoint(_x2, _y2); double _x3 = x3; double _y3 = y3; m_pFullTransform->TransformPoint(_x3, _y3); CString str = _T(""); str.Format(g_string_vml_CurveTo, (int)_x1, (int)_y1, (int)_x2, (int)_y2, (int)_x3, (int)_y3); m_pWriterVML->WriteString(str); } inline void CASCSVGRenderer::Start() { } void CASCSVGRenderer::End() { m_pWriterVML->ClearNoAttack(); } void CASCSVGRenderer::Close() { m_pWriterVML->WriteString(g_bstr_vml_ClosePath); } void CASCSVGRenderer::StartPage(double& dWidth, double& dHeight) { m_dWidth = dWidth; m_dHeight = dHeight; } void CASCSVGRenderer::EndPage() { } void CASCSVGRenderer::OnBaseMatrixUpdate() { m_pBaseTransform->Reset(); double dScaleX = m_dDpiX / c_ag_Inch_to_MM; double dScaleY = m_dDpiY / c_ag_Inch_to_MM; m_pBaseTransform->Scale(dScaleX, dScaleY, Aggplus::MatrixOrderAppend); CalculateFullTransform(); } void CASCSVGRenderer::_SetFont() { double dPix = m_pFont->CharSpace * m_dDpiX / 25.4; if (m_pInstalledFont->IsEqual(m_pFont)) { if (1 < m_dWidth) { m_pFontManager->SetCharSpacing(dPix); } return; } m_pFontManager->SetStringGID(m_pFont->StringGID); if (1 < m_dWidth) { m_pFontManager->SetCharSpacing(dPix); } if (_T("") == m_pFont->Path) { m_pFontManager->LoadFontByName(m_pFont->Name, (float)m_pFont->Size, m_pFont->GetStyle(), m_dDpiX, m_dDpiY); } else { m_pFontManager->LoadFontFromFile(m_pFont->Path, m_pFont->FaceIndex, (float)m_pFont->Size, m_dDpiX, m_dDpiY); } *m_pInstalledFont = *m_pFont; } }