diff --git a/DesktopEditor/graphics/pro/Graphics.h b/DesktopEditor/graphics/pro/Graphics.h index 296a3c9050..1fb1ba7c13 100644 --- a/DesktopEditor/graphics/pro/Graphics.h +++ b/DesktopEditor/graphics/pro/Graphics.h @@ -130,6 +130,10 @@ namespace NSGraphics }; GRAPHICS_DECL IGraphicsRenderer* Create(); + + GRAPHICS_DECL std::string GetHatchBase64(const std::wstring& name, + unsigned char r1, unsigned char g1, unsigned char b1, unsigned char a1, + unsigned char r2, unsigned char g2, unsigned char b2, unsigned char a2); } diff --git a/DesktopEditor/graphics/pro/pro_Graphics.cpp b/DesktopEditor/graphics/pro/pro_Graphics.cpp index 3d8724a985..45b589e8e8 100644 --- a/DesktopEditor/graphics/pro/pro_Graphics.cpp +++ b/DesktopEditor/graphics/pro/pro_Graphics.cpp @@ -38,4 +38,34 @@ namespace NSGraphics { return new CGraphicsRenderer(); } + + std::string GetHatchBase64(const std::wstring& name, + unsigned char r1, unsigned char g1, unsigned char b1, unsigned char a1, + unsigned char r2, unsigned char g2, unsigned char b2, unsigned char a2) + { + agg::rgba8 c1 = agg::rgba8(r1, g1, b1, a1); + agg::rgba8 c2 = agg::rgba8(r2, g2, b2, a2); + + BYTE* pPattern = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE * 4]; + agg::GetHatchPattern(name, (agg::rgba8*)pPattern, c1, c2); + + CBgraFrame oFrame; + oFrame.put_Data(pPattern); + oFrame.put_Width(HATCH_TX_SIZE); + oFrame.put_Height(HATCH_TX_SIZE); + oFrame.put_Stride(4 * HATCH_TX_SIZE); + + BYTE* pPngBuffer = NULL; + int nPngSize = 0; + oFrame.Encode(pPngBuffer, nPngSize, 4); + + char* cData64 = NULL; + int nData64Dst = 0; + NSFile::CBase64Converter::Encode(pPngBuffer, nPngSize, cData64, nData64Dst, NSBase64::B64_BASE64_FLAG_NOCRLF); + + std::string sRet(cData64, (size_t)nData64Dst); + RELEASEARRAYOBJECTS(cData64); + + return sRet; + } } diff --git a/HtmlRenderer/src/ASCSVGWriter.cpp b/HtmlRenderer/src/ASCSVGWriter.cpp index f1f0f0ad10..aa5ea2c68b 100644 --- a/HtmlRenderer/src/ASCSVGWriter.cpp +++ b/HtmlRenderer/src/ASCSVGWriter.cpp @@ -33,6 +33,7 @@ #include "../../DesktopEditor/graphics/GraphicsPath.h" #include "VectorGraphicsWriter2.h" +#include "../../DesktopEditor/graphics/pro/Graphics.h" namespace NSHtmlRenderer { @@ -677,7 +678,6 @@ namespace NSHtmlRenderer switch (m_pBrush->Type) { case c_BrushTypeTexture: - case c_BrushTypeHatch1: { m_bIsRaster = true; break; @@ -722,7 +722,7 @@ namespace NSHtmlRenderer int _c = (int)c; _SetFont(); - m_pSimpleGraphicsConverter->PathCommandText2(&_c, NULL, 0, m_pFontManager, x, y, w, h); + m_pSimpleGraphicsConverter->PathCommandText2(&_c, NULL, 1, m_pFontManager, x, y, w, h); return S_OK; } HRESULT CASCSVGWriter::PathCommandText(const std::wstring& bsText, const double& fX, const double& fY, const double& fWidth, const double& fHeight) diff --git a/HtmlRenderer/src/SVGWriter.h b/HtmlRenderer/src/SVGWriter.h index 553e789fb5..33acbab51f 100644 --- a/HtmlRenderer/src/SVGWriter.h +++ b/HtmlRenderer/src/SVGWriter.h @@ -36,778 +36,818 @@ #include #include #include "../../DesktopEditor/graphics/GraphicsPath.h" +#include "../../DesktopEditor/graphics/pro/Graphics.h" namespace NSHtmlRenderer { - class CClipSVG - { - public: - std::vector m_arPaths; - std::vector 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"", 35); - else - oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); - - ++lCurrentClipPath; - } - - LONG lWritePathID = (LONG)lCurrentClipPath - 2; - // теперь запишем пересечения - for (size_t i = 1; i < nCount; ++i) - { - oWriter.WriteString(L"", &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"", 35); - else - oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); - - ++lCurrentClipPath; - } - - inline void Clear() - { - m_arPaths.clear(); - m_arTypes.clear(); - } - inline bool IsInit() - { - return (0 != m_arPaths.size()); - } - }; - - class CClipSVG2 - { - public: - std::vector m_arPaths; - std::vector 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"", 35); - else - oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); - - ++lCurrentClipPath; - } - - m_lCountWriteClips = (LONG)nCount; - - for (LONG i = 0; i < m_lCountWriteClips; i++) - { - oWriter.WriteString(L"", 3); - } - } - - void WriteEnd(NSStringUtils::CStringBuilder& oWriter) - { - while (m_lCountWriteClips > 0) - { - oWriter.WriteString(L"\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"", 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"\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"\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(round2(x)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(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(round2(x)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(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(round2(x1)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y1)); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x2)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(y2)); - m_oPath.AddSpaceNoCheck(); - - m_oPath.AddIntNoCheck(round2(x3)); - m_oPath.AddCharNoCheck(','); - m_oPath.AddIntNoCheck(round2(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->sx() + pTransform->sy()) / 2.0; - int nPenW = int(m_pPen->Size * dScaleTransform * SVG_WRITER_SCALE); - - 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"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); - - 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); - } - - // пока заглушка - return WriteImage(oInfo, x, y, r - x, b - y, dAngle); + class CClipSVG + { + public: + std::vector m_arPaths; + std::vector 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"", 35); + else + oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); + + ++lCurrentClipPath; + } + + LONG lWritePathID = (LONG)lCurrentClipPath - 2; + // теперь запишем пересечения + for (size_t i = 1; i < nCount; ++i) + { + oWriter.WriteString(L"", &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"", 35); + else + oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); + + ++lCurrentClipPath; + } + + inline void Clear() + { + m_arPaths.clear(); + m_arTypes.clear(); + } + inline bool IsInit() + { + return (0 != m_arPaths.size()); + } + }; + + class CClipSVG2 + { + public: + std::vector m_arPaths; + std::vector 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"", 35); + else + oWriter.WriteString(L"\" clip-rule=\"evenodd\" />", 35); + + ++lCurrentClipPath; + } + + m_lCountWriteClips = (LONG)nCount; + + for (LONG i = 0; i < m_lCountWriteClips; i++) + { + oWriter.WriteString(L"", 3); + } + } + + void WriteEnd(NSStringUtils::CStringBuilder& oWriter) + { + while (m_lCountWriteClips > 0) + { + oWriter.WriteString(L"\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"", 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"\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"\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(round2(x)); + m_oPath.AddCharNoCheck(','); + m_oPath.AddIntNoCheck(round2(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(round2(x)); + m_oPath.AddCharNoCheck(','); + m_oPath.AddIntNoCheck(round2(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(round2(x1)); + m_oPath.AddCharNoCheck(','); + m_oPath.AddIntNoCheck(round2(y1)); + m_oPath.AddSpaceNoCheck(); + + m_oPath.AddIntNoCheck(round2(x2)); + m_oPath.AddCharNoCheck(','); + m_oPath.AddIntNoCheck(round2(y2)); + m_oPath.AddSpaceNoCheck(); + + m_oPath.AddIntNoCheck(round2(x3)); + m_oPath.AddCharNoCheck(','); + m_oPath.AddIntNoCheck(round2(y3)); + m_oPath.AddSpaceNoCheck(); + } + void WriteHatchPattern() + { + std::wstring sPatternId = std::to_wstring(m_lPatternID++); + + m_oDocument.WriteString(L""); + m_oDocument.WriteString(L"TexturePath, + m_pBrush->Color1 & 0xFF, (m_pBrush->Color1 >> 8) & 0xFF, (m_pBrush->Color1 >> 16) & 0xFF, m_pBrush->Alpha1 & 0xFF, + m_pBrush->Color2 & 0xFF, (m_pBrush->Color2 >> 8) & 0xFF, (m_pBrush->Color2 >> 16) & 0xFF, m_pBrush->Alpha2 & 0xFF); + + m_oDocument.WriteString(UTF8_TO_U(sHatchPattern)); + + m_oDocument.WriteString(L"\" />"); + } + 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->sx() + pTransform->sy()) / 2.0; + int nPenW = int(m_pPen->Size * dScaleTransform * SVG_WRITER_SCALE); + + 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"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); + + 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); + } + + // пока заглушка + return WriteImage(oInfo, x, y, r - x, b - y, dAngle); #if 0 - CString strPattern = _T(""); + 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); - } - */ + /* + 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); + m_oDocument.WriteString(strPattern); - CString strMode = _T("nonzero"); - if (nType & c_nEvenOddFillMode) - strMode = _T("evenodd"); + 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); + 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); + 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); + 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_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; + ++m_lPatternID; + return; #endif - } + } - if (!bStroke) - { - m_oDocument.WriteString(L"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); + if (!bStroke) + { + if (c_BrushTypeHatch1 == m_pBrush->Type) + WriteHatchPattern(); - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - return; - } + m_oDocument.WriteString(L"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); + if (c_BrushTypeHatch1 == m_pBrush->Type) + { + m_oDocument.WriteString(L"url(#hatch" + std::to_wstring(m_lPatternID - 1) + L")"); + } + else + { + m_oDocument.WriteHexColor3(m_pBrush->Color1); + m_oDocument.WriteString(L";fill-opacity:", 14); + m_oDocument.AddIntDel100(100 * m_pBrush->Alpha1 / 255); + } - WriteStyleClip(); - m_oDocument.WriteString(L" d=\"", 4); - m_oDocument.Write(m_oPath); - m_oDocument.WriteString(L"\" />\n", 5); - } + 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); - void WritePathClip() - { - m_bIsClipping = true; - m_bIsNeedUpdateClip = true; - } - void WritePathClipEnd() - { - if (0 == m_oPath.GetCurSize()) - return; + WriteStyleClip(); + m_oDocument.WriteString(L" d=\"", 4); + m_oDocument.Write(m_oPath); + m_oDocument.WriteString(L"\" />\n", 5); + return; + } - std::wstring sNewClip = m_oPath.GetData(); - int nSizeCurrent = m_oClip.m_arPaths.size(); - if (nSizeCurrent != 0) - { - if (m_oClip.m_arTypes[nSizeCurrent - 1] == m_lClipMode && m_oClip.m_arPaths[nSizeCurrent - 1] == sNewClip) - return; - } + if (c_BrushTypeHatch1 == m_pBrush->Type) + WriteHatchPattern(); - m_oClip.m_arPaths.push_back(sNewClip); - m_oClip.m_arTypes.push_back(m_lClipMode); - } - void WritePathResetClip() - { - m_bIsClipping = false; - m_bIsNeedUpdateClip = false; - m_oClip.Clear(); - } + m_oDocument.WriteString(L" fabs(dAngle))) - { - WriteClip(); - bIsClipping = m_bIsClipping; - } + if (c_BrushTypeHatch1 == m_pBrush->Type) + { + m_oDocument.WriteString(L"url(#hatch" + std::to_wstring(m_lPatternID - 1) + L")"); + } + else + { + m_oDocument.WriteHexColor3(m_pBrush->Color1); + m_oDocument.WriteString(L";fill-opacity:", 14); + m_oDocument.AddIntDel100(100 * m_pBrush->Alpha1 / 255); + } - double dCentreX = x + w / 2.0; - double dCentreY = y + h / 2.0; + 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); - dCentreX *= SVG_WRITER_SCALE; - dCentreY *= SVG_WRITER_SCALE; + WriteStyleClip(); + m_oDocument.WriteString(L" d=\"", 4); + m_oDocument.Write(m_oPath); + m_oDocument.WriteString(L"\" />\n", 5); + } - bool bIsRotate = (abs(dAngle) > 1) ? true : false; + void WritePathClip() + { + m_bIsClipping = true; + m_bIsNeedUpdateClip = true; + } + void WritePathClipEnd() + { + if (0 == m_oPath.GetCurSize()) + return; - if (itJPG == oInfo.m_eType) - { - if (bIsClipping) - { - m_oDocument.WriteString(L"", 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"", 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"", 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"", 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); - } - } - } - } + 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; + } - inline void WriteClip() - { - if (m_bIsClipping && m_bIsNeedUpdateClip && (m_oClip.IsInit())) - { - m_oClip.Write(m_oDocument, m_lClippingPath); - //m_oClip.Clear(); - m_bIsNeedUpdateClip = false; - } - } + double dCentreX = x + w / 2.0; + double dCentreY = y + h / 2.0; - inline void WriteToMainHtml_1(NSStringUtils::CStringBuilder* pWriter, const CDstInfo& oInfo) - { - if (!oInfo.m_bIsWeb) - { - pWriter->WriteString(L"AddInt(m_lCurDocumentID); - pWriter->WriteString(L".svg\" type=\"image/svg+xml\">", 27); + dCentreX *= SVG_WRITER_SCALE; + dCentreY *= SVG_WRITER_SCALE; - CloseFile(oInfo.m_strDstFilePath + L"/page" + std::to_wstring(m_lCurDocumentID) + L".svg"); - } - else - { - pWriter->WriteString(L"WriteString(oInfo.m_strAdditionalPath); - pWriter->WriteString(L"/page", 5); - pWriter->AddInt(m_lCurDocumentID); - pWriter->WriteString(L".svg\" type=\"image/svg+xml\">", 27); + bool bIsRotate = (abs(dAngle) > 1) ? true : false; - CloseFile(oInfo.m_strDstFilePath + L"/page" + std::to_wstring(m_lCurDocumentID) + L".svg"); - } - } - inline void WriteToMainHtml_2(NSStringUtils::CStringBuilder* pWriter) - { - pWriter->WriteString(L"", 9); - } + if (itJPG == oInfo.m_eType) + { + if (bIsClipping) + { + m_oDocument.WriteString(L"", 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"", 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"", 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"", 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"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"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"", 9); + } + + inline void WriteStyleClip() + { + if (m_bIsClipping) + { + if (!m_oDocument.IsSpace()) + m_oDocument.AddCharSafe(' '); + + 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_