diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h
index 0972389254..4865c88d3f 100644
--- a/DocxRenderer/DocxRenderer.h
+++ b/DocxRenderer/DocxRenderer.h
@@ -62,7 +62,7 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer
{
public:
CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts);
- ~CDocxRenderer();
+ virtual ~CDocxRenderer();
HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true);
HRESULT Close();
diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro
index f2ba455e25..15d2d681c6 100644
--- a/DocxRenderer/DocxRenderer.pro
+++ b/DocxRenderer/DocxRenderer.pro
@@ -40,6 +40,9 @@ HEADERS += \
DocxRenderer.h
SOURCES += \
+ src/logic/Document.cpp \
+ src/logic/ElementParagraph.cpp \
+ src/logic/Page.cpp \
src/resources/resources.cpp \
\
DocxRenderer.cpp
diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp
new file mode 100644
index 0000000000..498a5e65e9
--- /dev/null
+++ b/DocxRenderer/src/logic/Document.cpp
@@ -0,0 +1,952 @@
+#include "Document.h"
+
+namespace NSDocxRenderer
+{
+ CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) :
+ m_oCurrentPage(pFonts), m_oWriter()
+ {
+ m_pAppFonts = pFonts;
+ m_oSimpleGraphicsConverter.SetRenderer(pRenderer);
+ m_lCurrentCommandType = 0;
+
+ m_dWidth = 0;
+ m_dHeight = 0;
+
+ m_dDpiX = 72;
+ m_dDpiY = 72;
+
+ m_strTempDirectory = L"";
+ m_lPagesCount = 0;
+
+ m_bIsNeedPDFTextAnalyzer = false;
+ m_pFontManager = NULL;
+
+ m_bIsDisablePageCommand = false;
+ }
+ void CDocument::Clear()
+ {
+ m_lClipMode = 0;
+ }
+
+ CDocument::~CDocument()
+ {
+ m_lClipMode = 0;
+ RELEASEINTERFACE(m_pFontManager);
+ }
+
+ HRESULT CDocument::NewPage()
+ {
+ if (0 != m_lPagesCount)
+ {
+ m_oCurrentPage.WriteSectionToFile(false, m_oWriter);
+ m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData());
+ m_oWriter.ClearNoAttack();
+ }
+
+ m_oPen.SetDefaultParams();
+ m_oBrush.SetDefaultParams();
+ m_oFont.SetDefaultParams();
+ m_oShadow.SetDefaultParams();
+ m_oEdge.SetDefaultParams();
+
+ m_oTransform.Reset();
+
+ ++m_lPagesCount;
+ m_oCurrentPage.Clear();
+
+ return S_OK;
+ }
+ HRESULT CDocument::get_Height(double* dHeight)
+ {
+ *dHeight = m_dHeight;
+ return S_OK;
+ }
+ HRESULT CDocument::put_Height(double dHeight)
+ {
+ m_dHeight = dHeight;
+ m_oCurrentPage.m_dHeight = dHeight;
+ return S_OK;
+ }
+ HRESULT CDocument::get_Width(double* dWidth)
+ {
+ *dWidth = m_dWidth;
+ return S_OK;
+ }
+ HRESULT CDocument::put_Width(double dWidth)
+ {
+ m_dWidth = dWidth;
+ m_oCurrentPage.m_dWidth = dWidth;
+ return S_OK;
+ }
+ HRESULT CDocument::get_DpiX(double* dDpiX)
+ {
+ *dDpiX = m_dDpiX;
+ return S_OK;
+ }
+ HRESULT CDocument::get_DpiY(double* dDpiY)
+ {
+ *dDpiY = m_dDpiY;
+ return S_OK;
+ }
+ //-------- Функции для задания настроек текста ----------------------------------------------
+ // pen --------------------------------------------------------------------------------------
+ HRESULT CDocument::get_PenColor(LONG* lColor)
+ {
+ *lColor = m_oPen.Color;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenColor(LONG lColor)
+ {
+ m_oPen.Color = lColor;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenAlpha(LONG* lAlpha)
+ {
+ *lAlpha = m_oPen.Alpha;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenAlpha(LONG lAlpha)
+ {
+ m_oPen.Alpha = lAlpha;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenSize(double* dSize)
+ {
+ *dSize = m_oPen.Size;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenSize(double dSize)
+ {
+ m_oPen.Size = dSize;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenDashStyle(BYTE* val)
+ {
+ *val = m_oPen.DashStyle;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenDashStyle(BYTE val)
+ {
+ m_oPen.DashStyle = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenLineStartCap(BYTE* val)
+ {
+ *val = m_oPen.LineStartCap;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenLineStartCap(BYTE val)
+ {
+ m_oPen.LineStartCap = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenLineEndCap(BYTE* val)
+ {
+ *val = m_oPen.LineEndCap;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenLineEndCap(BYTE val)
+ {
+ m_oPen.LineEndCap = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenLineJoin(BYTE* val)
+ {
+ *val = m_oPen.LineJoin;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenLineJoin(BYTE val)
+ {
+ m_oPen.LineJoin = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenDashOffset(double* val)
+ {
+ *val = m_oPen.DashOffset;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenDashOffset(double val)
+ {
+ m_oPen.DashOffset = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenAlign(LONG* val)
+ {
+ *val = m_oPen.Align;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenAlign(LONG val)
+ {
+ m_oPen.Align = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_PenMiterLimit(double* val)
+ {
+ *val = m_oPen.MiterLimit;
+ return S_OK;
+ }
+ HRESULT CDocument::put_PenMiterLimit(double val)
+ {
+ m_oPen.MiterLimit = val;
+ return S_OK;
+ }
+ HRESULT CDocument::PenDashPattern(double* pPattern, LONG lCount)
+ {
+ if (NULL != pPattern)
+ {
+ m_oPen.SetDashPattern(pPattern, lCount);
+ }
+
+ return S_OK;
+ }
+ // brush ------------------------------------------------------------------------------------
+ HRESULT CDocument::get_BrushType(LONG* lType)
+ {
+ *lType = m_oBrush.Type;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushType(LONG lType)
+ {
+ m_oBrush.Type = lType;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushColor1(LONG* lColor)
+ {
+ *lColor = m_oBrush.Color1;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushColor1(LONG lColor)
+ {
+ m_oBrush.Color1 = lColor;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushAlpha1(LONG* lAlpha)
+ {
+ *lAlpha = m_oBrush.Alpha1;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushAlpha1(LONG lAlpha)
+ {
+ m_oBrush.Alpha1 = lAlpha;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushColor2(LONG* lColor)
+ {
+ *lColor = m_oBrush.Color2;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushColor2(LONG lColor)
+ {
+ m_oBrush.Color2 = lColor;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushAlpha2(LONG* lAlpha)
+ {
+ *lAlpha = m_oBrush.Alpha2;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushAlpha2(LONG lAlpha)
+ {
+ m_oBrush.Alpha2 = lAlpha;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushTexturePath(std::wstring* sPath)
+ {
+ *sPath = m_oBrush.TexturePath;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushTexturePath(const std::wstring& sPath)
+ {
+ m_oBrush.TexturePath = sPath;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushTextureMode(LONG* lMode)
+ {
+ *lMode = m_oBrush.TextureMode;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushTextureMode(LONG lMode)
+ {
+ m_oBrush.TextureMode = lMode;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushTextureAlpha(LONG* lTxAlpha)
+ {
+ *lTxAlpha = m_oBrush.TextureAlpha;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushTextureAlpha(LONG lTxAlpha)
+ {
+ m_oBrush.TextureAlpha = lTxAlpha;
+ return S_OK;
+ }
+ HRESULT CDocument::get_BrushLinearAngle(double* dAngle)
+ {
+ *dAngle = m_oBrush.LinearAngle;
+ return S_OK;
+ }
+ HRESULT CDocument::put_BrushLinearAngle(double dAngle)
+ {
+ m_oBrush.LinearAngle = dAngle;
+ return S_OK;
+ }
+ HRESULT CDocument::BrushRect(bool val, double left, double top, double width, double height)
+ {
+ m_oBrush.Rectable = val ? 1 : 0;
+ m_oBrush.Rect.X = (float)left;
+ m_oBrush.Rect.Y = (float)top;
+ m_oBrush.Rect.Width = (float)width;
+ m_oBrush.Rect.Height = (float)height;
+
+ return S_OK;
+ }
+ // font -------------------------------------------------------------------------------------
+ HRESULT CDocument::get_FontName(std::wstring* sName)
+ {
+ *sName = m_oFont.Name;
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontName(std::wstring sName)
+ {
+ m_oFont.Name = sName;
+ return S_OK;
+ }
+ HRESULT CDocument::get_FontPath(std::wstring* sPath)
+ {
+ *sPath = m_oFont.Path;
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontPath(std::wstring sPath)
+ {
+ m_oFont.Path = sPath;
+ return S_OK;
+ }
+ HRESULT CDocument::get_FontSize(double* dSize)
+ {
+ *dSize = m_oFont.Size;
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontSize(double dSize)
+ {
+ m_oFont.Size = dSize;
+ return S_OK;
+ }
+ HRESULT CDocument::get_FontStyle(LONG* lStyle)
+ {
+ *lStyle = m_oFont.GetStyle();
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontStyle(LONG lStyle)
+ {
+ m_oFont.SetStyle(lStyle);
+ return S_OK;
+ }
+ HRESULT CDocument::get_FontStringGID(INT* bGID)
+ {
+ *bGID = m_oFont.StringGID;
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontStringGID(INT bGID)
+ {
+ m_oFont.StringGID = bGID;
+ return S_OK;
+ }
+ HRESULT CDocument::get_FontCharSpace(double* dSpace)
+ {
+ *dSpace = m_oFont.CharSpace;
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontCharSpace(double dSpace)
+ {
+ m_oFont.CharSpace = dSpace;
+ return S_OK;
+ }
+ HRESULT CDocument::get_FontFaceIndex(int* lFaceIndex)
+ {
+ *lFaceIndex = m_oFont.FaceIndex;
+ return S_OK;
+ }
+ HRESULT CDocument::put_FontFaceIndex(const int& lFaceIndex)
+ {
+ m_oFont.FaceIndex = lFaceIndex;
+ return S_OK;
+ }
+ // shadow -----------------------------------------------------------------------------------
+ HRESULT CDocument::get_ShadowDistanceX(double* val)
+ {
+ *val = m_oShadow.DistanceX;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ShadowDistanceX(double val)
+ {
+ m_oShadow.DistanceX = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_ShadowDistanceY(double* val)
+ {
+ *val = m_oShadow.DistanceY;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ShadowDistanceY(double val)
+ {
+ m_oShadow.DistanceY = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_ShadowBlurSize(double* val)
+ {
+ *val = m_oShadow.BlurSize;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ShadowBlurSize(double val)
+ {
+ m_oShadow.BlurSize = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_ShadowColor(LONG* val)
+ {
+ *val = m_oShadow.Color;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ShadowColor(LONG val)
+ {
+ m_oShadow.Color = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_ShadowAlpha(LONG* val)
+ {
+ *val = m_oShadow.Alpha;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ShadowAlpha(LONG val)
+ {
+ m_oShadow.Alpha = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_ShadowVisible(INT* val)
+ {
+ *val = m_oShadow.Visible;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ShadowVisible(INT val)
+ {
+ m_oShadow.Visible = val;
+ return S_OK;
+ }
+ // edge -------------------------------------------------------------------------------------
+ HRESULT CDocument::get_EdgeVisible(LONG* val)
+ {
+ *val = m_oEdge.Visible;
+ return S_OK;
+ }
+ HRESULT CDocument::put_EdgeVisible(LONG val)
+ {
+ m_oEdge.Visible = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_EdgeColor(LONG* val)
+ {
+ *val = m_oEdge.Color;
+ return S_OK;
+ }
+ HRESULT CDocument::put_EdgeColor(LONG val)
+ {
+ m_oEdge.Color = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_EdgeAlpha(LONG* val)
+ {
+ *val = m_oEdge.Alpha;
+ return S_OK;
+ }
+ HRESULT CDocument::put_EdgeAlpha(LONG val)
+ {
+ m_oEdge.Alpha = val;
+ return S_OK;
+ }
+ HRESULT CDocument::get_EdgeDist(double* val)
+ {
+ *val = m_oEdge.Dist;
+ return S_OK;
+ }
+ HRESULT CDocument::put_EdgeDist(double val)
+ {
+ m_oEdge.Dist = val;
+ return S_OK;
+ }
+
+ //-------- Функции для вывода текста --------------------------------------------------------
+ HRESULT CDocument::CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount,
+ const double& dX, const double& dY, const double& dW,
+ const double& dH, const double& dBaseLineOffset)
+ {
+ double dAngleMatrix = m_oTransform.z_Rotation();
+ if (abs(dAngleMatrix) > 1 || m_oTransform.sx() < 0 || m_oTransform.sy() < 0)
+ {
+ _SetFont();
+ PathCommandEnd();
+ BeginCommand(c_nPathType);
+ m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pFontManager, dX, dY, dW, dH);
+ DrawPath(c_nWindingFillMode);
+ EndCommand(c_nPathType);
+ PathCommandEnd();
+ return S_OK;
+ }
+
+ m_oCurrentPage.WriteText((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer);
+ return S_OK;
+ }
+
+ HRESULT CDocument::CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ return CommandDrawTextPrivate(&lUnicode, NULL, 1, dX, dY, dW, dH);
+ }
+ HRESULT CDocument::CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH);
+ }
+ HRESULT CDocument::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ unsigned int nLen = 0;
+ unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen);
+ if (nLen == 0)
+ return S_OK;
+ CommandDrawTextPrivate((int*)pUnicodes, NULL, nLen, dX, dY, dW, dH);
+ delete [] pUnicodes;
+ return S_OK;
+ }
+ HRESULT CDocument::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ unsigned int nLen = 0;
+ unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen);
+ if (nLen == 0)
+ return S_OK;
+ if (nLen != nGidsCount)
+ {
+ delete [] pUnicodes;
+ return S_OK;
+ }
+
+ CommandDrawTextPrivate((int*)pUnicodes, (int*)pGids, (int)nLen, dX, dY, dW, dH);
+ delete [] pUnicodes;
+ return S_OK;
+ }
+ //-------- Маркеры для команд ---------------------------------------------------------------
+ HRESULT CDocument::BeginCommand(DWORD lType)
+ {
+ if (c_nPageType == lType && m_bIsDisablePageCommand)
+ return S_OK;
+
+ m_lCurrentCommandType = (LONG)lType;
+ m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType;
+
+ if (c_nTextType == lType)
+ m_oCurrentPage.m_dLastTextX_block = -1;
+
+ return S_OK;
+ }
+ HRESULT CDocument::EndCommand(DWORD lType)
+ {
+ if (c_nPageType == lType && m_bIsDisablePageCommand)
+ return S_OK;
+
+ m_lCurrentCommandType = -1;
+ m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType;
+
+ if (c_nPageType == lType)
+ {
+ // нужно записать страницу в файл
+ m_oCurrentPage.Build();
+ m_oCurrentPage.Write(m_oWriter);
+ }
+ else if (c_nPathType == lType)
+ {
+ m_oCurrentPage.End();
+ }
+
+ if (c_nTextType == lType)
+ m_oCurrentPage.m_dLastTextX_block = -1;
+
+ return S_OK;
+ }
+ //-------- Функции для работы с Graphics Path -----------------------------------------------
+ HRESULT CDocument::PathCommandMoveTo(double fX, double fY)
+ {
+ if (c_nSimpleGraphicType == m_lCurrentCommandType)
+ {
+ m_oCurrentPage.MoveTo(fX, fY);
+ }
+ else
+ {
+ m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY);
+ }
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandLineTo(double fX, double fY)
+ {
+ if (c_nSimpleGraphicType == m_lCurrentCommandType)
+ {
+ m_oCurrentPage.LineTo(fX, fY);
+ }
+ else
+ {
+ m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY);
+ }
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandLinesTo(double* pPoints, LONG lCount)
+ {
+ m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
+ {
+ if (c_nSimpleGraphicType == m_lCurrentCommandType)
+ {
+ m_oCurrentPage.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
+ }
+ else
+ {
+ m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
+ }
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandCurvesTo(double* pPoints, LONG lCount)
+ {
+ m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
+ {
+ m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandClose()
+ {
+ if (c_nSimpleGraphicType == m_lCurrentCommandType)
+ {
+ m_oCurrentPage.Close();
+ }
+ else
+ {
+ m_oSimpleGraphicsConverter.PathCommandClose();
+ }
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandEnd()
+ {
+ if (c_nSimpleGraphicType == m_lCurrentCommandType)
+ {
+ m_oCurrentPage.End();
+ }
+ else
+ {
+ m_oSimpleGraphicsConverter.PathCommandEnd();
+ }
+ return S_OK;
+ }
+ HRESULT CDocument::DrawPath(long nType)
+ {
+ LONG lTxId = -1;
+ if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type))
+ {
+ double x = 0;
+ double y = 0;
+ double w = 0;
+ double h = 0;
+ CImageInfo oInfo = m_oManager.WriteImage(m_oBrush.TexturePath, x, y, w, h);
+ lTxId = oInfo.m_nId;
+ }
+
+ m_oCurrentPage.DrawPath(nType, lTxId);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandStart()
+ {
+ if (c_nSimpleGraphicType == m_lCurrentCommandType)
+ {
+ m_oCurrentPage.Start();
+ }
+ else
+ {
+ m_oSimpleGraphicsConverter.PathCommandStart();
+ }
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandGetCurrentPoint(double* fX, double* fY)
+ {
+ m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY);
+ return S_OK;
+ }
+
+ HRESULT CDocument::PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ _SetFont();
+ m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, NULL, 1, m_pFontManager, dX, dY, dW, dH);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ _SetFont();
+ m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pFontManager, dX, dY, dW, dH);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ _SetFont();
+ m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pFontManager, dX, dY, dW, dH, 0);
+ return S_OK;
+ }
+ HRESULT CDocument::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH)
+ {
+ _SetFont();
+ m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pFontManager, dX, dY, dW, dH);
+ return S_OK;
+ }
+
+ HRESULT CDocument::GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
+ {
+ return S_OK;
+ }
+ HRESULT CDocument::SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
+ {
+ ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
+ return S_OK;
+ }
+ //-------- Функции для вывода изображений --------------------------------------------------
+ HRESULT CDocument::DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight)
+ {
+ CImageInfo oInfo = m_oManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight);
+ m_oCurrentPage.WriteImage(oInfo, fX, fY, fWidth, fHeight);
+ return S_OK;
+ }
+ HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight)
+ {
+ CImageInfo oInfo = m_oManager.WriteImage(sVal, fX, fY, fWidth, fHeight);
+ m_oCurrentPage.WriteImage(oInfo, fX, fY, fWidth, fHeight);
+ return S_OK;
+ }
+ //------------------------------------------------------------------------------------------
+ HRESULT CDocument::SetTransform(double dA, double dB, double dC, double dD, double dE, double dF)
+ {
+ ApplyTransform(dA, dB, dC, dD, dE, dF);
+ return S_OK;
+ }
+ HRESULT CDocument::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
+ {
+ return S_OK;
+ }
+ HRESULT CDocument::ResetTransform(void)
+ {
+ m_oTransform.Reset();
+ return S_OK;
+ }
+ HRESULT CDocument::get_ClipMode(LONG* plMode)
+ {
+ *plMode = m_lClipMode;
+ return S_OK;
+ }
+ HRESULT CDocument::put_ClipMode(LONG lMode)
+ {
+ m_lClipMode = lMode;
+ return S_OK;
+ }
+
+ void CDocument::ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6)
+ {
+ m_oTransform.SetElements(d1, d2, d3, d4, d5, d6);
+ }
+
+ void CDocument::ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
+ {
+ if ((dWidth <= 1) || (dHeight <= 1))
+ lFlags = 0;
+
+ bool bFlipX = (0 != (c_nParamFlipX & lFlags));
+ bool bFlipY = (0 != (c_nParamFlipY & lFlags));
+
+ double m11 = bFlipX ? -1.0 : 1.0;
+ double m22 = bFlipY ? -1.0 : 1.0;
+
+ Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0);
+
+ if ((0 != dAngle) || (0 != lFlags))
+ {
+ double dCentreX = (dLeft + dWidth / 2.0);
+ double dCentreY = (dTop + dHeight / 2.0);
+
+ oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend);
+
+ oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend);
+ oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend);
+
+ oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend);
+ }
+
+ m_oTransform = oMatrix;
+ }
+
+ void CDocument::_SetFont()
+ {
+ if (NULL == m_pFontManager)
+ {
+ m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts);
+ }
+
+ double dPix = m_oFont.CharSpace * m_dDpiX / 25.4;
+
+ if (m_oInstalledFont.IsEqual(&m_oFont))
+ {
+ if (1 < m_dWidth)
+ {
+ m_pFontManager->SetCharSpacing(dPix);
+ }
+ return;
+ }
+
+ m_pFontManager->SetStringGID(m_oFont.StringGID);
+ if (1 < m_dWidth)
+ {
+ m_pFontManager->SetCharSpacing(dPix);
+ }
+
+ if (m_oFont.Path.empty())
+ {
+ m_pFontManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY);
+ }
+ else
+ {
+ m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, (float)m_oFont.Size, m_dDpiX, m_dDpiY);
+ }
+
+ m_oInstalledFont = m_oFont;
+ }
+
+ bool CDocument::CreateDocument()
+ {
+ CreateTemplate(m_strTempDirectory);
+
+ // Init
+ Clear();
+
+ m_lCurrentCommandType = 0;
+ m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter);
+
+ m_oManager.NewDocument();
+ // media
+ m_oManager.m_strDstMedia = m_strTempDirectory + L"/word/media";
+ NSDirectory::CreateDirectory(m_oManager.m_strDstMedia);
+
+ m_oCurrentPage.m_oManager.m_oFontTable.m_mapTable.clear();
+
+ m_oDocumentStream.CloseFile();
+ m_oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml");
+ m_oDocumentStream.WriteStringUTF8(L"\
+\
+");
+
+ m_lPagesCount = 0;
+ m_oWriter.Clear();
+ m_oWriter.AddSize(10000);
+
+ return true;
+ }
+
+ void CDocument::Close()
+ {
+ // сохраним rels (images & docs)
+ NSStringUtils::CStringBuilder oWriter;
+
+ oWriter.WriteString(L"\
+\
+\
+\
+\
+\
+");
+
+ for (std::map::iterator iterImage = m_oManager.m_mapImageData.begin(); iterImage != m_oManager.m_mapImageData.end(); iterImage++)
+ {
+ CImageInfo& oInfo = iterImage->second;
+
+ oWriter.WriteString(L"") : oWriter.WriteString(L".jpg\"/>");
+ }
+
+ for (std::map::iterator iterImage = m_oManager.m_mapImagesFile.begin(); iterImage != m_oManager.m_mapImagesFile.end(); iterImage++)
+ {
+ CImageInfo& oInfo = iterImage->second;
+
+ oWriter.WriteString(L"") : oWriter.WriteString(L".jpg\"/>");
+ }
+
+ oWriter.WriteString(L"");
+
+ NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData());
+ oWriter.ClearNoAttack();
+
+ // сохраним fontTable
+ oWriter.WriteString(L"\
+");
+
+ CFontTable* pFontTable = &m_oCurrentPage.m_oManager.m_oFontTable;
+ for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); iterFont++)
+ {
+ CFontTableEntry& oEntry = iterFont->second;
+
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ if (oEntry.m_bIsFixedWidth)
+ oWriter.WriteString(L"");
+ else
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+ }
+
+ oWriter.WriteString(L"");
+ NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData());
+
+ // document
+ m_oCurrentPage.WriteSectionToFile(true, m_oWriter);
+ m_oWriter.WriteString(L"");
+ m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData());
+ m_oWriter.ClearNoAttack();
+
+ m_oDocumentStream.CloseFile();
+ }
+}
diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h
index bf9081de24..a8b849efd9 100644
--- a/DocxRenderer/src/logic/Document.h
+++ b/DocxRenderer/src/logic/Document.h
@@ -47,954 +47,153 @@ namespace NSDocxRenderer
bool m_bIsDisablePageCommand; // disable commands inside draw function
public:
- CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : m_oWriter(), m_oCurrentPage(pFonts)
- {
- m_pAppFonts = pFonts;
- m_oSimpleGraphicsConverter.SetRenderer(pRenderer);
- m_lCurrentCommandType = 0;
+ CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts);
+ void Clear();
- m_dWidth = 0;
- m_dHeight = 0;
-
- m_dDpiX = 72;
- m_dDpiY = 72;
-
- m_strTempDirectory = L"";
- m_lPagesCount = 0;
-
- m_bIsNeedPDFTextAnalyzer = false;
- m_pFontManager = NULL;
-
- m_bIsDisablePageCommand = false;
- }
- void Clear()
- {
- m_lClipMode = 0;
- }
-
- ~CDocument()
- {
- m_lClipMode = 0;
- RELEASEINTERFACE(m_pFontManager);
- }
+ ~CDocument();
public:
- HRESULT NewPage()
- {
- if (0 != m_lPagesCount)
- {
- m_oCurrentPage.WriteSectionToFile(false, m_oWriter);
- m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData());
- m_oWriter.ClearNoAttack();
- }
-
- m_oPen.SetDefaultParams();
- m_oBrush.SetDefaultParams();
- m_oFont.SetDefaultParams();
- m_oShadow.SetDefaultParams();
- m_oEdge.SetDefaultParams();
-
- m_oTransform.Reset();
-
- ++m_lPagesCount;
- m_oCurrentPage.Clear();
-
- return S_OK;
- }
- HRESULT get_Height(double* dHeight)
- {
- *dHeight = m_dHeight;
- return S_OK;
- }
- HRESULT put_Height(double dHeight)
- {
- m_dHeight = dHeight;
- m_oCurrentPage.m_dHeight = dHeight;
- return S_OK;
- }
- HRESULT get_Width(double* dWidth)
- {
- *dWidth = m_dWidth;
- return S_OK;
- }
- HRESULT put_Width(double dWidth)
- {
- m_dWidth = dWidth;
- m_oCurrentPage.m_dWidth = dWidth;
- return S_OK;
- }
- HRESULT get_DpiX(double* dDpiX)
- {
- *dDpiX = m_dDpiX;
- return S_OK;
- }
- HRESULT get_DpiY(double* dDpiY)
- {
- *dDpiY = m_dDpiY;
- return S_OK;
- }
+ HRESULT NewPage();
+ HRESULT get_Height(double* dHeight);
+ HRESULT put_Height(double dHeight);
+ HRESULT get_Width(double* dWidth);
+ HRESULT put_Width(double dWidth);
+ HRESULT get_DpiX(double* dDpiX);
+ HRESULT get_DpiY(double* dDpiY);
//-------- Функции для задания настроек текста ----------------------------------------------
// pen --------------------------------------------------------------------------------------
- HRESULT get_PenColor(LONG* lColor)
- {
- *lColor = m_oPen.Color;
- return S_OK;
- }
- HRESULT put_PenColor(LONG lColor)
- {
- m_oPen.Color = lColor;
- return S_OK;
- }
- HRESULT get_PenAlpha(LONG* lAlpha)
- {
- *lAlpha = m_oPen.Alpha;
- return S_OK;
- }
- HRESULT put_PenAlpha(LONG lAlpha)
- {
- m_oPen.Alpha = lAlpha;
- return S_OK;
- }
- HRESULT get_PenSize(double* dSize)
- {
- *dSize = m_oPen.Size;
- return S_OK;
- }
- HRESULT put_PenSize(double dSize)
- {
- m_oPen.Size = dSize;
- return S_OK;
- }
- HRESULT get_PenDashStyle(BYTE* val)
- {
- *val = m_oPen.DashStyle;
- return S_OK;
- }
- HRESULT put_PenDashStyle(BYTE val)
- {
- m_oPen.DashStyle = val;
- return S_OK;
- }
- HRESULT get_PenLineStartCap(BYTE* val)
- {
- *val = m_oPen.LineStartCap;
- return S_OK;
- }
- HRESULT put_PenLineStartCap(BYTE val)
- {
- m_oPen.LineStartCap = val;
- return S_OK;
- }
- HRESULT get_PenLineEndCap(BYTE* val)
- {
- *val = m_oPen.LineEndCap;
- return S_OK;
- }
- HRESULT put_PenLineEndCap(BYTE val)
- {
- m_oPen.LineEndCap = val;
- return S_OK;
- }
- HRESULT get_PenLineJoin(BYTE* val)
- {
- *val = m_oPen.LineJoin;
- return S_OK;
- }
- HRESULT put_PenLineJoin(BYTE val)
- {
- m_oPen.LineJoin = val;
- return S_OK;
- }
- HRESULT get_PenDashOffset(double* val)
- {
- *val = m_oPen.DashOffset;
- return S_OK;
- }
- HRESULT put_PenDashOffset(double val)
- {
- m_oPen.DashOffset = val;
- return S_OK;
- }
- HRESULT get_PenAlign(LONG* val)
- {
- *val = m_oPen.Align;
- return S_OK;
- }
- HRESULT put_PenAlign(LONG val)
- {
- m_oPen.Align = val;
- return S_OK;
- }
- HRESULT get_PenMiterLimit(double* val)
- {
- *val = m_oPen.MiterLimit;
- return S_OK;
- }
- HRESULT put_PenMiterLimit(double val)
- {
- m_oPen.MiterLimit = val;
- return S_OK;
- }
- HRESULT PenDashPattern(double* pPattern, LONG lCount)
- {
- if (NULL != pPattern)
- {
- m_oPen.SetDashPattern(pPattern, lCount);
- }
-
- return S_OK;
- }
+ HRESULT get_PenColor(LONG* lColor);
+ HRESULT put_PenColor(LONG lColor);
+ HRESULT get_PenAlpha(LONG* lAlpha);
+ HRESULT put_PenAlpha(LONG lAlpha);
+ HRESULT get_PenSize(double* dSize);
+ HRESULT put_PenSize(double dSize);
+ HRESULT get_PenDashStyle(BYTE* val);
+ HRESULT put_PenDashStyle(BYTE val);
+ HRESULT get_PenLineStartCap(BYTE* val);
+ HRESULT put_PenLineStartCap(BYTE val);
+ HRESULT get_PenLineEndCap(BYTE* val);
+ HRESULT put_PenLineEndCap(BYTE val);
+ HRESULT get_PenLineJoin(BYTE* val);
+ HRESULT put_PenLineJoin(BYTE val);
+ HRESULT get_PenDashOffset(double* val);
+ HRESULT put_PenDashOffset(double val);
+ HRESULT get_PenAlign(LONG* val);
+ HRESULT put_PenAlign(LONG val);
+ HRESULT get_PenMiterLimit(double* val);
+ HRESULT put_PenMiterLimit(double val);
+ HRESULT PenDashPattern(double* pPattern, LONG lCount);
// brush ------------------------------------------------------------------------------------
- HRESULT get_BrushType(LONG* lType)
- {
- *lType = m_oBrush.Type;
- return S_OK;
- }
- HRESULT put_BrushType(LONG lType)
- {
- m_oBrush.Type = lType;
- return S_OK;
- }
- HRESULT get_BrushColor1(LONG* lColor)
- {
- *lColor = m_oBrush.Color1;
- return S_OK;
- }
- HRESULT put_BrushColor1(LONG lColor)
- {
- m_oBrush.Color1 = lColor;
- return S_OK;
- }
- HRESULT get_BrushAlpha1(LONG* lAlpha)
- {
- *lAlpha = m_oBrush.Alpha1;
- return S_OK;
- }
- HRESULT put_BrushAlpha1(LONG lAlpha)
- {
- m_oBrush.Alpha1 = lAlpha;
- return S_OK;
- }
- HRESULT get_BrushColor2(LONG* lColor)
- {
- *lColor = m_oBrush.Color2;
- return S_OK;
- }
- HRESULT put_BrushColor2(LONG lColor)
- {
- m_oBrush.Color2 = lColor;
- return S_OK;
- }
- HRESULT get_BrushAlpha2(LONG* lAlpha)
- {
- *lAlpha = m_oBrush.Alpha2;
- return S_OK;
- }
- HRESULT put_BrushAlpha2(LONG lAlpha)
- {
- m_oBrush.Alpha2 = lAlpha;
- return S_OK;
- }
- HRESULT get_BrushTexturePath(std::wstring* sPath)
- {
- *sPath = m_oBrush.TexturePath;
- return S_OK;
- }
- HRESULT put_BrushTexturePath(const std::wstring& sPath)
- {
- m_oBrush.TexturePath = sPath;
- return S_OK;
- }
- HRESULT get_BrushTextureMode(LONG* lMode)
- {
- *lMode = m_oBrush.TextureMode;
- return S_OK;
- }
- HRESULT put_BrushTextureMode(LONG lMode)
- {
- m_oBrush.TextureMode = lMode;
- return S_OK;
- }
- HRESULT get_BrushTextureAlpha(LONG* lTxAlpha)
- {
- *lTxAlpha = m_oBrush.TextureAlpha;
- return S_OK;
- }
- HRESULT put_BrushTextureAlpha(LONG lTxAlpha)
- {
- m_oBrush.TextureAlpha = lTxAlpha;
- return S_OK;
- }
- HRESULT get_BrushLinearAngle(double* dAngle)
- {
- *dAngle = m_oBrush.LinearAngle;
- return S_OK;
- }
- HRESULT put_BrushLinearAngle(double dAngle)
- {
- m_oBrush.LinearAngle = dAngle;
- return S_OK;
- }
- HRESULT BrushRect(bool val, double left, double top, double width, double height)
- {
- m_oBrush.Rectable = val ? 1 : 0;
- m_oBrush.Rect.X = (float)left;
- m_oBrush.Rect.Y = (float)top;
- m_oBrush.Rect.Width = (float)width;
- m_oBrush.Rect.Height = (float)height;
-
- return S_OK;
- }
+ HRESULT get_BrushType(LONG* lType);
+ HRESULT put_BrushType(LONG lType);
+ HRESULT get_BrushColor1(LONG* lColor);
+ HRESULT put_BrushColor1(LONG lColor);
+ HRESULT get_BrushAlpha1(LONG* lAlpha);
+ HRESULT put_BrushAlpha1(LONG lAlpha);
+ HRESULT get_BrushColor2(LONG* lColor);
+ HRESULT put_BrushColor2(LONG lColor);
+ HRESULT get_BrushAlpha2(LONG* lAlpha);
+ HRESULT put_BrushAlpha2(LONG lAlpha);
+ HRESULT get_BrushTexturePath(std::wstring* sPath);
+ HRESULT put_BrushTexturePath(const std::wstring& sPath);
+ HRESULT get_BrushTextureMode(LONG* lMode);
+ HRESULT put_BrushTextureMode(LONG lMode);
+ HRESULT get_BrushTextureAlpha(LONG* lTxAlpha);
+ HRESULT put_BrushTextureAlpha(LONG lTxAlpha);
+ HRESULT get_BrushLinearAngle(double* dAngle);
+ HRESULT put_BrushLinearAngle(double dAngle);
+ HRESULT BrushRect(bool val, double left, double top, double width, double height);
// font -------------------------------------------------------------------------------------
- HRESULT get_FontName(std::wstring* sName)
- {
- *sName = m_oFont.Name;
- return S_OK;
- }
- HRESULT put_FontName(std::wstring sName)
- {
- m_oFont.Name = sName;
- return S_OK;
- }
- HRESULT get_FontPath(std::wstring* sPath)
- {
- *sPath = m_oFont.Path;
- return S_OK;
- }
- HRESULT put_FontPath(std::wstring sPath)
- {
- m_oFont.Path = sPath;
- return S_OK;
- }
- HRESULT get_FontSize(double* dSize)
- {
- *dSize = m_oFont.Size;
- return S_OK;
- }
- HRESULT put_FontSize(double dSize)
- {
- m_oFont.Size = dSize;
- return S_OK;
- }
- HRESULT get_FontStyle(LONG* lStyle)
- {
- *lStyle = m_oFont.GetStyle();
- return S_OK;
- }
- HRESULT put_FontStyle(LONG lStyle)
- {
- m_oFont.SetStyle(lStyle);
- return S_OK;
- }
- HRESULT get_FontStringGID(INT* bGID)
- {
- *bGID = m_oFont.StringGID;
- return S_OK;
- }
- HRESULT put_FontStringGID(INT bGID)
- {
- m_oFont.StringGID = bGID;
- return S_OK;
- }
- HRESULT get_FontCharSpace(double* dSpace)
- {
- *dSpace = m_oFont.CharSpace;
- return S_OK;
- }
- HRESULT put_FontCharSpace(double dSpace)
- {
- m_oFont.CharSpace = dSpace;
- return S_OK;
- }
- HRESULT get_FontFaceIndex(int* lFaceIndex)
- {
- *lFaceIndex = m_oFont.FaceIndex;
- return S_OK;
- }
- HRESULT put_FontFaceIndex(const int& lFaceIndex)
- {
- m_oFont.FaceIndex = lFaceIndex;
- return S_OK;
- }
+ HRESULT get_FontName(std::wstring* sName);
+ HRESULT put_FontName(std::wstring sName);
+ HRESULT get_FontPath(std::wstring* sPath);
+ HRESULT put_FontPath(std::wstring sPath);
+ HRESULT get_FontSize(double* dSize);
+ HRESULT put_FontSize(double dSize);
+ HRESULT get_FontStyle(LONG* lStyle);
+ HRESULT put_FontStyle(LONG lStyle);
+ HRESULT get_FontStringGID(INT* bGID);
+ HRESULT put_FontStringGID(INT bGID);
+ HRESULT get_FontCharSpace(double* dSpace);
+ HRESULT put_FontCharSpace(double dSpace);
+ HRESULT get_FontFaceIndex(int* lFaceIndex);
+ HRESULT put_FontFaceIndex(const int& lFaceIndex);
// shadow -----------------------------------------------------------------------------------
- HRESULT get_ShadowDistanceX(double* val)
- {
- *val = m_oShadow.DistanceX;
- return S_OK;
- }
- HRESULT put_ShadowDistanceX(double val)
- {
- m_oShadow.DistanceX = val;
- return S_OK;
- }
- HRESULT get_ShadowDistanceY(double* val)
- {
- *val = m_oShadow.DistanceY;
- return S_OK;
- }
- HRESULT put_ShadowDistanceY(double val)
- {
- m_oShadow.DistanceY = val;
- return S_OK;
- }
- HRESULT get_ShadowBlurSize(double* val)
- {
- *val = m_oShadow.BlurSize;
- return S_OK;
- }
- HRESULT put_ShadowBlurSize(double val)
- {
- m_oShadow.BlurSize = val;
- return S_OK;
- }
- HRESULT get_ShadowColor(LONG* val)
- {
- *val = m_oShadow.Color;
- return S_OK;
- }
- HRESULT put_ShadowColor(LONG val)
- {
- m_oShadow.Color = val;
- return S_OK;
- }
- HRESULT get_ShadowAlpha(LONG* val)
- {
- *val = m_oShadow.Alpha;
- return S_OK;
- }
- HRESULT put_ShadowAlpha(LONG val)
- {
- m_oShadow.Alpha = val;
- return S_OK;
- }
- HRESULT get_ShadowVisible(INT* val)
- {
- *val = m_oShadow.Visible;
- return S_OK;
- }
- HRESULT put_ShadowVisible(INT val)
- {
- m_oShadow.Visible = val;
- return S_OK;
- }
+ HRESULT get_ShadowDistanceX(double* val);
+ HRESULT put_ShadowDistanceX(double val);
+ HRESULT get_ShadowDistanceY(double* val);
+ HRESULT put_ShadowDistanceY(double val);
+ HRESULT get_ShadowBlurSize(double* val);
+ HRESULT put_ShadowBlurSize(double val);
+ HRESULT get_ShadowColor(LONG* val);
+ HRESULT put_ShadowColor(LONG val);
+ HRESULT get_ShadowAlpha(LONG* val);
+ HRESULT put_ShadowAlpha(LONG val);
+ HRESULT get_ShadowVisible(INT* val);
+ HRESULT put_ShadowVisible(INT val);
// edge -------------------------------------------------------------------------------------
- HRESULT get_EdgeVisible(LONG* val)
- {
- *val = m_oEdge.Visible;
- return S_OK;
- }
- HRESULT put_EdgeVisible(LONG val)
- {
- m_oEdge.Visible = val;
- return S_OK;
- }
- HRESULT get_EdgeColor(LONG* val)
- {
- *val = m_oEdge.Color;
- return S_OK;
- }
- HRESULT put_EdgeColor(LONG val)
- {
- m_oEdge.Color = val;
- return S_OK;
- }
- HRESULT get_EdgeAlpha(LONG* val)
- {
- *val = m_oEdge.Alpha;
- return S_OK;
- }
- HRESULT put_EdgeAlpha(LONG val)
- {
- m_oEdge.Alpha = val;
- return S_OK;
- }
- HRESULT get_EdgeDist(double* val)
- {
- *val = m_oEdge.Dist;
- return S_OK;
- }
- HRESULT put_EdgeDist(double val)
- {
- m_oEdge.Dist = val;
- return S_OK;
- }
-
+ HRESULT get_EdgeVisible(LONG* val);
+ HRESULT put_EdgeVisible(LONG val);
+ HRESULT get_EdgeColor(LONG* val);
+ HRESULT put_EdgeColor(LONG val);
+ HRESULT get_EdgeAlpha(LONG* val);
+ HRESULT put_EdgeAlpha(LONG val);
+ HRESULT get_EdgeDist(double* val);
+ HRESULT put_EdgeDist(double val);
//-------- Функции для вывода текста --------------------------------------------------------
- HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaseLineOffset = 0)
- {
- double dAngleMatrix = m_oTransform.z_Rotation();
- if (abs(dAngleMatrix) > 1 || m_oTransform.sx() < 0 || m_oTransform.sy() < 0)
- {
- _SetFont();
- PathCommandEnd();
- BeginCommand(c_nPathType);
- m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pFontManager, dX, dY, dW, dH);
- DrawPath(c_nWindingFillMode);
- EndCommand(c_nPathType);
- PathCommandEnd();
- return S_OK;
- }
-
- m_oCurrentPage.WriteText((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer);
- return S_OK;
- }
-
- HRESULT CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- return CommandDrawTextPrivate(&lUnicode, NULL, 1, dX, dY, dW, dH);
- }
- HRESULT CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH);
- }
- virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- unsigned int nLen = 0;
- unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen);
- if (nLen == 0)
- return S_OK;
- CommandDrawTextPrivate((int*)pUnicodes, NULL, nLen, dX, dY, dW, dH);
- delete [] pUnicodes;
- return S_OK;
- }
- virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- unsigned int nLen = 0;
- unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen);
- if (nLen == 0)
- return S_OK;
- if (nLen != nGidsCount)
- {
- delete [] pUnicodes;
- return S_OK;
- }
-
- CommandDrawTextPrivate((int*)pUnicodes, (int*)pGids, (int)nLen, dX, dY, dW, dH);
- delete [] pUnicodes;
- return S_OK;
- }
+ HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount,
+ const double& dX, const double& dY, const double& dW,
+ const double& dH, const double& dBaseLineOffset = 0);
+ HRESULT CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH);
+ HRESULT CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH);
+ virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH);
+ virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids,
+ const unsigned int nGidsCount, const double& dX, const double& dY,
+ const double& dW, const double& dH);
//-------- Маркеры для команд ---------------------------------------------------------------
- HRESULT BeginCommand(DWORD lType)
- {
- if (c_nPageType == lType && m_bIsDisablePageCommand)
- return S_OK;
-
- m_lCurrentCommandType = (LONG)lType;
- m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType;
-
- if (c_nTextType == lType)
- m_oCurrentPage.m_dLastTextX_block = -1;
-
- return S_OK;
- }
- HRESULT EndCommand(DWORD lType)
- {
- if (c_nPageType == lType && m_bIsDisablePageCommand)
- return S_OK;
-
- m_lCurrentCommandType = -1;
- m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType;
-
- if (c_nPageType == lType)
- {
- // нужно записать страницу в файл
- m_oCurrentPage.Build();
- m_oCurrentPage.Write(m_oWriter);
- }
- else if (c_nPathType == lType)
- {
- m_oCurrentPage.End();
- }
-
- if (c_nTextType == lType)
- m_oCurrentPage.m_dLastTextX_block = -1;
-
- return S_OK;
- }
+ HRESULT BeginCommand(DWORD lType);
+ HRESULT EndCommand(DWORD lType);
//-------- Функции для работы с Graphics Path -----------------------------------------------
- HRESULT PathCommandMoveTo(double fX, double fY)
- {
- if (c_nSimpleGraphicType == m_lCurrentCommandType)
- {
- m_oCurrentPage.MoveTo(fX, fY);
- }
- else
- {
- m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY);
- }
- return S_OK;
- }
- HRESULT PathCommandLineTo(double fX, double fY)
- {
- if (c_nSimpleGraphicType == m_lCurrentCommandType)
- {
- m_oCurrentPage.LineTo(fX, fY);
- }
- else
- {
- m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY);
- }
- return S_OK;
- }
- HRESULT PathCommandLinesTo(double* pPoints, LONG lCount)
- {
- m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount);
- return S_OK;
- }
- HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
- {
- if (c_nSimpleGraphicType == m_lCurrentCommandType)
- {
- m_oCurrentPage.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
- }
- else
- {
- m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3);
- }
- return S_OK;
- }
- HRESULT PathCommandCurvesTo(double* pPoints, LONG lCount)
- {
- m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount);
- return S_OK;
- }
- HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
- {
- m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle);
- return S_OK;
- }
- HRESULT PathCommandClose()
- {
- if (c_nSimpleGraphicType == m_lCurrentCommandType)
- {
- m_oCurrentPage.Close();
- }
- else
- {
- m_oSimpleGraphicsConverter.PathCommandClose();
- }
- return S_OK;
- }
- HRESULT PathCommandEnd()
- {
- if (c_nSimpleGraphicType == m_lCurrentCommandType)
- {
- m_oCurrentPage.End();
- }
- else
- {
- m_oSimpleGraphicsConverter.PathCommandEnd();
- }
- return S_OK;
- }
- HRESULT DrawPath(long nType)
- {
- LONG lTxId = -1;
- if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type))
- {
- double x = 0;
- double y = 0;
- double w = 0;
- double h = 0;
- CImageInfo oInfo = m_oManager.WriteImage(m_oBrush.TexturePath, x, y, w, h);
- lTxId = oInfo.m_nId;
- }
+ HRESULT PathCommandMoveTo(double fX, double fY);
+ HRESULT PathCommandLineTo(double fX, double fY);
+ HRESULT PathCommandLinesTo(double* pPoints, LONG lCount);
+ HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3);
+ HRESULT PathCommandCurvesTo(double* pPoints, LONG lCount);
+ HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
+ HRESULT PathCommandClose();
+ HRESULT PathCommandEnd();
+ HRESULT DrawPath(long nType);
+ HRESULT PathCommandStart();
+ HRESULT PathCommandGetCurrentPoint(double* fX, double* fY);
- m_oCurrentPage.DrawPath(nType, lTxId);
- return S_OK;
- }
- HRESULT PathCommandStart()
- {
- if (c_nSimpleGraphicType == m_lCurrentCommandType)
- {
- m_oCurrentPage.Start();
- }
- else
- {
- m_oSimpleGraphicsConverter.PathCommandStart();
- }
- return S_OK;
- }
- HRESULT PathCommandGetCurrentPoint(double* fX, double* fY)
- {
- m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY);
- return S_OK;
- }
+ HRESULT PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH);
+ HRESULT PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH);
+ HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH);
+ HRESULT PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH);
- HRESULT PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- _SetFont();
- m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, NULL, 1, m_pFontManager, dX, dY, dW, dH);
- return S_OK;
- }
- HRESULT PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- _SetFont();
- m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pFontManager, dX, dY, dW, dH);
- return S_OK;
- }
- HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- _SetFont();
- m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pFontManager, dX, dY, dW, dH, 0);
- return S_OK;
- }
- HRESULT PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH)
- {
- _SetFont();
- m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pFontManager, dX, dY, dW, dH);
- return S_OK;
- }
-
- HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
- {
- return S_OK;
- }
- HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
- {
- ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
- return S_OK;
- }
+ HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags);
+ HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags);
//-------- Функции для вывода изображений --------------------------------------------------
- HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight)
- {
- CImageInfo oInfo = m_oManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight);
- m_oCurrentPage.WriteImage(oInfo, fX, fY, fWidth, fHeight);
- return S_OK;
- }
- HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight)
- {
- CImageInfo oInfo = m_oManager.WriteImage(sVal, fX, fY, fWidth, fHeight);
- m_oCurrentPage.WriteImage(oInfo, fX, fY, fWidth, fHeight);
- return S_OK;
- }
+ HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight);
+ HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight);
//------------------------------------------------------------------------------------------
- HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF)
- {
- ApplyTransform(dA, dB, dC, dD, dE, dF);
- return S_OK;
- }
- HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
- {
- return S_OK;
- }
- HRESULT ResetTransform(void)
- {
- m_oTransform.Reset();
- return S_OK;
- }
- HRESULT get_ClipMode(LONG* plMode)
- {
- *plMode = m_lClipMode;
- return S_OK;
- }
- HRESULT put_ClipMode(LONG lMode)
- {
- m_lClipMode = lMode;
- return S_OK;
- }
+ HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF);
+ HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF);
+ HRESULT ResetTransform(void);
+ HRESULT get_ClipMode(LONG* plMode);
+ HRESULT put_ClipMode(LONG lMode);
protected:
- void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6)
- {
- m_oTransform.SetElements(d1, d2, d3, d4, d5, d6);
- }
+ void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6);
- void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
- {
- if ((dWidth <= 1) || (dHeight <= 1))
- lFlags = 0;
-
- bool bFlipX = (0 != (c_nParamFlipX & lFlags));
- bool bFlipY = (0 != (c_nParamFlipY & lFlags));
-
- double m11 = bFlipX ? -1.0 : 1.0;
- double m22 = bFlipY ? -1.0 : 1.0;
-
- Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0);
-
- if ((0 != dAngle) || (0 != lFlags))
- {
- double dCentreX = (dLeft + dWidth / 2.0);
- double dCentreY = (dTop + dHeight / 2.0);
-
- oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend);
-
- oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend);
- oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend);
-
- oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend);
- }
-
- m_oTransform = oMatrix;
- }
-
- void _SetFont()
- {
- if (NULL == m_pFontManager)
- {
- m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts);
- }
-
- double dPix = m_oFont.CharSpace * m_dDpiX / 25.4;
-
- if (m_oInstalledFont.IsEqual(&m_oFont))
- {
- if (1 < m_dWidth)
- {
- m_pFontManager->SetCharSpacing(dPix);
- }
- return;
- }
-
- m_pFontManager->SetStringGID(m_oFont.StringGID);
- if (1 < m_dWidth)
- {
- m_pFontManager->SetCharSpacing(dPix);
- }
-
- if (m_oFont.Path.empty())
- {
- m_pFontManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY);
- }
- else
- {
- m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, (float)m_oFont.Size, m_dDpiX, m_dDpiY);
- }
-
- m_oInstalledFont = m_oFont;
- }
+ void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags);
+ void _SetFont();
public:
- bool CreateDocument()
- {
- CreateTemplate(m_strTempDirectory);
+ bool CreateDocument();
- // Init
- Clear();
-
- m_lCurrentCommandType = 0;
- m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter);
-
- m_oManager.NewDocument();
- // media
- m_oManager.m_strDstMedia = m_strTempDirectory + L"/word/media";
- NSDirectory::CreateDirectory(m_oManager.m_strDstMedia);
-
- m_oCurrentPage.m_oManager.m_oFontTable.m_mapTable.clear();
-
- m_oDocumentStream.CloseFile();
- m_oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml");
- m_oDocumentStream.WriteStringUTF8(L"\
-\
-");
-
- m_lPagesCount = 0;
- m_oWriter.Clear();
- m_oWriter.AddSize(10000);
-
- return true;
- }
-
- void Close()
- {
- // сохраним rels (images & docs)
- NSStringUtils::CStringBuilder oWriter;
-
- oWriter.WriteString(L"\
-\
-\
-\
-\
-\
-");
-
- for (std::map::iterator iterImage = m_oManager.m_mapImageData.begin(); iterImage != m_oManager.m_mapImageData.end(); iterImage++)
- {
- CImageInfo& oInfo = iterImage->second;
-
- oWriter.WriteString(L"") : oWriter.WriteString(L".jpg\"/>");
- }
-
- for (std::map::iterator iterImage = m_oManager.m_mapImagesFile.begin(); iterImage != m_oManager.m_mapImagesFile.end(); iterImage++)
- {
- CImageInfo& oInfo = iterImage->second;
-
- oWriter.WriteString(L"") : oWriter.WriteString(L".jpg\"/>");
- }
-
- oWriter.WriteString(L"");
-
- NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData());
- oWriter.ClearNoAttack();
-
- // сохраним fontTable
- oWriter.WriteString(L"\
-");
-
- CFontTable* pFontTable = &m_oCurrentPage.m_oManager.m_oFontTable;
- for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); iterFont++)
- {
- CFontTableEntry& oEntry = iterFont->second;
-
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- if (oEntry.m_bIsFixedWidth)
- oWriter.WriteString(L"");
- else
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
- }
-
- oWriter.WriteString(L"");
- NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData());
-
- // document
- m_oCurrentPage.WriteSectionToFile(true, m_oWriter);
- m_oWriter.WriteString(L"");
- m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData());
- m_oWriter.ClearNoAttack();
-
- m_oDocumentStream.CloseFile();
- }
+ void Close();
};
}
diff --git a/DocxRenderer/src/logic/ElementParagraph.cpp b/DocxRenderer/src/logic/ElementParagraph.cpp
new file mode 100644
index 0000000000..c4f8f8747b
--- /dev/null
+++ b/DocxRenderer/src/logic/ElementParagraph.cpp
@@ -0,0 +1,683 @@
+#include "ElementParagraph.h"
+
+namespace NSDocxRenderer
+{
+ void DeleteSpaces(NSStringUtils::CStringUTF32& oText)
+ {
+ size_t nLen = oText.length();
+ size_t nStart = 0;
+
+ while ((nStart < nLen) && (' ' == oText[nStart]))
+ ++nStart;
+
+ if (nStart == nLen)
+ {
+ oText = L"";
+ return;
+ }
+
+ size_t nEnd = nLen - 1;
+ while ((nEnd > nStart) && (' ' == oText[nEnd]))
+ --nEnd;
+
+ oText = oText.substr(nStart, nEnd - nStart + 1);
+ }
+
+ CContText::CContText()
+ {
+ m_strPickFontName = L"";
+ m_lPickFontStyle = 0;
+
+ m_dX = 0;
+ m_dY = 0;
+ m_dWidth = 0;
+ m_dHeight = 0;
+ m_dLastX = 0;
+
+ m_dWidthWithoutSpaces = 0;
+ m_dLeftWithoutSpaces = 0;
+
+ m_dPosition = 0;
+ m_dSpaceWidthMM = 0;
+
+ m_dCalculateWidth = 0;
+
+ m_dSpaceByText = 0;
+ }
+
+ void CContText::Clear()
+ {
+ }
+
+ CContText::CContText(const CContText& oSrc)
+ {
+ *this = oSrc;
+ }
+ CContText& CContText::operator=(const CContText& oSrc)
+ {
+ if (this == &oSrc)
+ {
+ return *this;
+ }
+
+ m_oFont = oSrc.m_oFont;
+ m_oBrush = oSrc.m_oBrush;
+
+ m_oText = oSrc.m_oText;
+ m_oGidText = oSrc.m_oGidText;
+
+ m_strPickFontName = oSrc.m_strPickFontName;
+ m_lPickFontStyle = oSrc.m_lPickFontStyle;
+
+ m_dX = oSrc.m_dX;
+ m_dY = oSrc.m_dY;
+ m_dWidth = oSrc.m_dWidth;
+ m_dHeight = oSrc.m_dHeight;
+
+ m_dLastX = oSrc.m_dLastX;
+
+ m_dWidthWithoutSpaces = oSrc.m_dWidthWithoutSpaces;
+ m_dLeftWithoutSpaces = oSrc.m_dLeftWithoutSpaces;
+
+ m_dPosition = oSrc.m_dPosition;
+ m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
+
+ m_dCalculateWidth = oSrc.m_dCalculateWidth;
+ m_dSpaceByText = oSrc.m_dSpaceByText;
+
+ return *this;
+ }
+
+ bool CContText::IsBigger(const CContText* oSrc)
+ {
+ return (m_dX > oSrc->m_dX) ? true : false;
+ }
+ bool CContText::IsBiggerOrEqual(const CContText* oSrc)
+ {
+ return (m_dX >= oSrc->m_dX) ? true : false;
+ }
+
+ double CContText::GetIntersect(const CContText* oSrc) const
+ {
+ double d1 = std::max(m_dX, oSrc->m_dX);
+ double d2 = std::min(m_dX + m_dWidth, oSrc->m_dX + oSrc->m_dWidth);
+
+ if (d2 > d1)
+ return d2 - d1;
+ return 0;
+ }
+
+ void CContText::Write(NSStringUtils::CStringBuilder& oWriter,
+ CFontManagerLight* pManagerLight,
+ bool bIsAddSpace)
+ {
+ oWriter.WriteString(L"");
+
+ if (m_dWidth != m_dWidthWithoutSpaces)
+ {
+ DeleteSpaces(m_oText);
+ m_dWidth = m_dWidthWithoutSpaces;
+ }
+
+ if (m_strPickFontName.empty())
+ {
+ if (m_oFont.Bold)
+ oWriter.WriteString(L"");
+ if (m_oFont.Italic)
+ oWriter.WriteString(L"");
+
+ if (bIsAddSpace)
+ {
+ m_dWidth += m_dSpaceWidthMM;
+ m_oText += L" ";
+ }
+ }
+ else
+ {
+ if (0x01 == (0x01 & m_lPickFontStyle))
+ oWriter.WriteString(L"");
+ if (0x02 == (0x02 & m_lPickFontStyle))
+ oWriter.WriteString(L"");
+
+ if (bIsAddSpace)
+ {
+ m_dWidth += pManagerLight->GetSpaceWidth();
+ m_oText += L" ";
+ }
+
+ // нужно перемерять...
+ double ___dSize = (double)((LONG)(m_oFont.Size * 2)) / 2;
+ pManagerLight->LoadFont(m_strPickFontName, m_lPickFontStyle, ___dSize, false);
+ double dWidth = pManagerLight->MeasureStringWidth(m_oText.ToStdWString());
+
+ if (fabs(dWidth - m_dWidth) > 2)
+ {
+ double dSpacing = (m_dWidth - dWidth) / (m_oText.length() + 1);
+ dSpacing *= c_dMMToDx;
+
+ oWriter.WriteString(L"");
+ }
+ }
+
+ int lSize = (int)(2 * m_oFont.Size);
+ oWriter.WriteString(L"");
+
+ std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+ oWriter.WriteEncodeXmlString(m_oText.ToStdWString());
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+ }
+
+ void CContText::WriteTo(double dSpacingMM,
+ NSStringUtils::CStringBuilder& oWriter,
+ CFontManagerLight* pManagerLight)
+ {
+ oWriter.WriteString(L"");
+
+ double dSpaceMMSize = m_dSpaceWidthMM;
+ if (m_strPickFontName.empty())
+ {
+ if (m_oFont.Bold)
+ oWriter.WriteString(L"");
+ if (m_oFont.Italic)
+ oWriter.WriteString(L"");
+ }
+ else
+ {
+ if (0x01 == (0x01 & m_lPickFontStyle))
+ oWriter.WriteString(L"");
+ if (0x02 == (0x02 & m_lPickFontStyle))
+ oWriter.WriteString(L"");
+
+ dSpaceMMSize = pManagerLight->GetSpaceWidth();
+ }
+
+ int lSize = (int)(2 * m_oFont.Size);
+ oWriter.WriteString(L"");
+
+ std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ LONG lSpacing = (LONG)((dSpacingMM - dSpaceMMSize) * c_dMMToDx);
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+ oWriter.WriteString(L" ");
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"");
+ }
+
+ CTextLine::CTextLine() : m_arConts()
+ {
+ m_dBaselinePos = 0;
+ m_dBaselineOffset = 0;
+
+ m_dX = 0;
+ m_dY = 0;
+ m_dWidth = 0;
+ m_dHeight = 0;
+ }
+ void CTextLine::Clear()
+ {
+ for (std::vector::iterator iter = m_arConts.begin();
+ iter != m_arConts.end(); iter++)
+ {
+ CContText* pText = *iter;
+ RELEASEOBJECT(pText);
+ }
+ m_arConts.clear();
+ }
+
+ CTextLine::~CTextLine()
+ {
+ Clear();
+ }
+
+ CTextLine::CTextLine(const CTextLine& oSrc)
+ {
+ *this = oSrc;
+ }
+ CTextLine& CTextLine::operator=(const CTextLine& oSrc)
+ {
+ if (this == &oSrc)
+ {
+ return *this;
+ }
+
+ Clear();
+ for (std::vector::const_iterator iter = oSrc.m_arConts.begin(); iter != oSrc.m_arConts.end(); iter++)
+ {
+ m_arConts.push_back(new CContText(*(*iter)));
+ }
+
+ m_dBaselinePos = oSrc.m_dBaselinePos;
+ m_dBaselineOffset = oSrc.m_dBaselineOffset;
+
+ m_dX = oSrc.m_dX;
+ m_dY = oSrc.m_dY;
+ m_dWidth = oSrc.m_dWidth;
+ m_dHeight = oSrc.m_dHeight;
+
+ return *this;
+ }
+
+ void CTextLine::AddCont(CContText* pCont, double dBaselineOffset)
+ {
+ if (0 == m_arConts.size())
+ m_dBaselineOffset = dBaselineOffset;
+
+ if ( ( pCont->m_dX > 0 ) && ( ( m_dX == 0 ) || ( pCont->m_dX < m_dX ) ) )
+ m_dX = pCont->m_dX;
+
+ if (m_dHeight < pCont->m_dHeight)
+ m_dHeight = pCont->m_dHeight;
+
+ m_arConts.push_back(pCont);
+ }
+
+ bool CTextLine::IsBigger(const CTextLine* oSrc)
+ {
+ return (m_dBaselinePos > oSrc->m_dBaselinePos) ? true : false;
+ }
+
+ bool CTextLine::IsBiggerOrEqual(const CTextLine* oSrc)
+ {
+ return (m_dBaselinePos >= oSrc->m_dBaselinePos) ? true : false;
+ }
+
+ void CTextLine::SortConts()
+ {
+ // сортировка непрерывных слов по m_dX
+ SortElements(m_arConts);
+ }
+
+ void CTextLine::Merge(CTextLine* pTextLine)
+ {
+ size_t nCount = pTextLine->m_arConts.size();
+ if (0 != nCount)
+ {
+ if (pTextLine->m_dX < m_dX)
+ {
+ m_dX = pTextLine->m_dX;
+ }
+ if (pTextLine->m_dBaselinePos < m_dBaselinePos)
+ {
+ m_dHeight = (m_dBaselinePos - pTextLine->m_dBaselinePos + pTextLine->m_dHeight);
+ }
+ else
+ {
+ m_dHeight = (pTextLine->m_dBaselinePos - m_dBaselinePos + m_dHeight);
+ }
+
+ double dSubPosition = m_dBaselinePos - pTextLine->m_dBaselinePos;
+
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ pTextLine->m_arConts[i]->m_dPosition = dSubPosition;
+ m_arConts.push_back(pTextLine->m_arConts[i]);
+ }
+ }
+ }
+
+ void CTextLine::Analyze()
+ {
+ size_t nCountConts = m_arConts.size();
+
+ if (0 == nCountConts)
+ return;
+
+ CContText* pFirst = m_arConts[0];
+
+ for (size_t i = 1; i < nCountConts; ++i)
+ {
+ CContText* pCurrent = m_arConts[i];
+
+ if (pFirst->m_strPickFontName != pCurrent->m_strPickFontName ||
+ pFirst->m_oFont.Bold != pCurrent->m_oFont.Bold ||
+ pFirst->m_oFont.Italic != pCurrent->m_oFont.Italic)
+ {
+ // вообще надо бы все объединить. но пока этот метод на соединение "первых"
+ break;
+ }
+
+ double dRight = pFirst->m_dX + pFirst->m_dWidth;
+ double dLeft = pCurrent->m_dX;
+
+ if (fabs(dRight - dLeft) > 0.1)
+ {
+ // вообще надо бы все объединить. но пока этот метод на соединение "первых"
+ break;
+ }
+
+ // продолжаем слово
+ pFirst->m_oText += pCurrent->m_oText;
+ pFirst->m_dWidth = (dLeft + pCurrent->m_dWidth - pFirst->m_dX);
+
+ pFirst->m_dWidthWithoutSpaces < 0.0001 ?
+ pFirst->m_dLeftWithoutSpaces = pCurrent->m_dLeftWithoutSpaces :
+ pFirst->m_dWidthWithoutSpaces = pCurrent->m_dLeftWithoutSpaces +
+ pCurrent->m_dWidthWithoutSpaces - pFirst->m_dLeftWithoutSpaces;
+
+ m_arConts.erase(m_arConts.begin() + i);
+ --i;
+ --nCountConts;
+ }
+ }
+
+ void CTextLine::CalculateWidth()
+ {
+ m_dWidth = 2; //это хак - по идее должно == 0.
+ for (size_t i = 0; i < m_arConts.size(); ++i)
+ {
+ m_dWidth += m_arConts[i]->m_dWidthWithoutSpaces;
+ m_dWidth += m_arConts[i]->m_dSpaceWidthMM;
+ }
+ }
+
+ void CTextLine::AddSpaceToEnd()
+ {
+ /*double dX = 0;
+ size_t isNeedIndex = 0;
+
+ for (size_t i = 0; i < m_arConts.size(); i++)
+ {
+ if (dX < m_arConts[i]->m_dX)
+ {
+ dX = m_arConts[i]->m_dX;
+ isNeedIndex = i;
+ }
+ }
+
+ CContText* pCurrent = m_arConts[isNeedIndex];
+
+ if (pCurrent->m_oText[pCurrent->m_oText.length()-1] != uint32_t(' '))
+ {
+ NSStringUtils::CStringUTF32 oText(pCurrent->m_oText);
+ oText += uint32_t(' ');
+ pCurrent->m_oText = oText;
+ pCurrent->m_dWidth += pCurrent->m_dSpaceWidthMM;
+ m_dWidth += pCurrent->m_dSpaceWidthMM;
+ }*/
+
+ /*CContText* pCurrent = m_arConts.back();
+
+ if (pCurrent->m_oText[pCurrent->m_oText.length()-1] != uint32_t(' '))
+ {
+ pCurrent->m_oText += uint32_t(' ');
+ //pCurrent->m_dWidth += pCurrent->m_dSpaceWidthMM;
+ //m_dWidth += pCurrent->m_dSpaceWidthMM;
+ }*/
+
+ m_arConts.back()->m_oText += uint32_t(' ');
+ }
+
+ bool CTextLine::IsForceBlock()
+ {
+ // линия отсортирована, так что сравниваем только соседние conts
+ size_t nCount = m_arConts.size();
+ if (nCount <= 1)
+ return false;
+
+ for (size_t i = 0; i < nCount; i++)
+ {
+ for (size_t j = i + 1; j < nCount; j++)
+ {
+ if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight)
+ {
+ size_t nCountConts = m_arConts.size();
+
+ if (0 == nCountConts)
+ return;
+
+ CContText* pPrev = m_arConts[0];
+ double dDelta = 0;
+
+ for (size_t i = 1; i < nCountConts; ++i)
+ {
+ CContText* pCurrent = m_arConts[i];
+
+ if (0 == pCurrent->m_dWidthWithoutSpaces)
+ continue;
+
+ dDelta = pCurrent->m_dLeftWithoutSpaces - (pPrev->m_dLeftWithoutSpaces + pPrev->m_dWidthWithoutSpaces);
+
+ if (dDelta < 0.5)
+ {
+ // просто текст на тексте или сменились настройки (font/brush)
+ pPrev->Write(oWriter, pManagerLight);
+ pPrev = pCurrent;
+ }
+ //else if (dDelta < 2 * pPrev->m_dSpaceWidthMM)
+ //{
+ // // сменились настройки, но пробел все-таки вставить нужно
+ // pPrev->Write(oWriter, pManagerLight, true);
+ // pPrev = pCurrent;
+ //}
+ else
+ {
+ // расстояние слишком большое. нужно сделать большой пробел
+ pPrev->Write(oWriter, pManagerLight);
+ pPrev->WriteTo(dDelta, oWriter, pManagerLight);
+ pPrev = pCurrent;
+ }
+ }
+
+ pPrev->Write(oWriter, pManagerLight);
+ }
+
+ CParagraph::CParagraph(const TextAssociationType& eType) : m_arLines()
+ {
+ m_eType = etParagraph;
+
+ m_bIsTextFrameProperties = false;
+ m_bIsNeedFirstLineIndent = false;
+ m_eTextAlignmentType = TextAlignmentType_ByWidth;
+
+ m_dLeft = 0.0;
+ m_dRight = 0.0;
+ m_dTop = 0.0;
+ m_dWidth = 0.0;
+ m_dHeight = 0.0;
+ m_dFirstLine= 0.0;
+
+ m_dSpaceBefore = 0.0;
+ m_dBaselinePos = 0.0;
+
+ m_pManagerLight = NULL;
+ m_eTextAssociationType = eType;
+
+ m_numLines = 0;
+ }
+ CParagraph::CParagraph(const CParagraph& oSrc)
+ {
+ *this = oSrc;
+ }
+ CParagraph::~CParagraph()
+ {
+ Clear();
+ }
+
+ void CParagraph::Clear()
+ {
+ size_t nCount = m_arLines.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CTextLine* pText = m_arLines[i];
+ RELEASEOBJECT(pText);
+ }
+ m_arLines.clear();
+
+ m_pManagerLight = NULL;
+ }
+
+ CParagraph& CParagraph::operator=(const CParagraph& oSrc)
+ {
+ if (this == &oSrc)
+ {
+ return *this;
+ }
+
+ m_eType = etParagraph;
+
+ m_bIsTextFrameProperties = oSrc.m_bIsTextFrameProperties;
+ m_bIsNeedFirstLineIndent = oSrc.m_bIsNeedFirstLineIndent;
+ m_eTextAlignmentType = oSrc.m_eTextAlignmentType;
+
+ m_dLeft = oSrc.m_dLeft;
+ m_dRight = oSrc.m_dRight;
+ m_dTop = oSrc.m_dTop;
+ m_dWidth = oSrc.m_dWidth;
+ m_dHeight = oSrc.m_dHeight;
+ m_dFirstLine= oSrc.m_dFirstLine;
+
+ m_dSpaceBefore = oSrc.m_dSpaceBefore;
+ m_dBaselinePos = oSrc.m_dBaselinePos;
+
+ m_eTextAssociationType = oSrc.m_eTextAssociationType;
+
+ Clear();
+ size_t nCount = oSrc.m_arLines.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ m_arLines.push_back(new CTextLine(*oSrc.m_arLines[i]));
+ }
+
+ m_pManagerLight = oSrc.m_pManagerLight;
+
+ m_numLines = oSrc.m_numLines;
+ return *this;
+ }
+
+ void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter)
+ {
+ oWriter.WriteString(L"");
+
+ switch (m_eTextAssociationType)
+ {
+ case TextAssociationTypeBlockChar:
+ case TextAssociationTypeBlockLine:
+ {
+ oWriter.WriteString(L"");
+ break;
+ }
+ case TextAssociationTypePlainLine:
+ case TextAssociationTypePlainParagraph:
+ {
+ if (m_bIsTextFrameProperties)
+ {
+ oWriter.WriteString(L"");
+ break;
+ }
+ oWriter.WriteString(L" 0.0)
+ {
+ oWriter.WriteString(L"\" w:right=\"");
+ oWriter.AddInt((int)(m_dRight * c_dMMToDx));
+ }
+ if (m_bIsNeedFirstLineIndent)
+ {
+ oWriter.WriteString(L"\" w:firstLine=\"");
+ oWriter.AddInt((int)(m_dFirstLine * c_dMMToDx));
+ }
+
+ if (m_eTextAssociationType == TextAssociationTypePlainParagraph)
+ {
+ switch (m_eTextAlignmentType)
+ {
+ case TextAlignmentType_ByCenter:
+ oWriter.WriteString(L"\"/>");
+ break;
+ }
+ default:
+ break;
+ }
+
+ size_t nCount = m_arLines.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CTextLine* pTextLine = m_arLines[i];
+ if (m_eTextAssociationType != TextAssociationTypePlainParagraph)
+ {
+ pTextLine->SortConts();
+ }
+ pTextLine->ToXml(oWriter, m_pManagerLight);
+ }
+
+ oWriter.WriteString(L"");
+ }
+}
diff --git a/DocxRenderer/src/logic/ElementParagraph.h b/DocxRenderer/src/logic/ElementParagraph.h
index 6c554f22b8..bcab48fb54 100644
--- a/DocxRenderer/src/logic/ElementParagraph.h
+++ b/DocxRenderer/src/logic/ElementParagraph.h
@@ -85,26 +85,7 @@ namespace NSDocxRenderer
}
}
- inline void DeleteSpaces(NSStringUtils::CStringUTF32& oText)
- {
- size_t nLen = oText.length();
- size_t nStart = 0;
-
- while ((nStart < nLen) && (' ' == oText[nStart]))
- ++nStart;
-
- if (nStart == nLen)
- {
- oText = L"";
- return;
- }
-
- size_t nEnd = nLen - 1;
- while ((nEnd > nStart) && (' ' == oText[nEnd]))
- --nEnd;
-
- oText = oText.substr(nStart, nEnd - nStart + 1);
- }
+ void DeleteSpaces(NSStringUtils::CStringUTF32& oText);
class CContText
{
@@ -134,224 +115,28 @@ namespace NSDocxRenderer
double m_dSpaceByText;
public:
- CContText()
- {
- m_strPickFontName = L"";
- m_lPickFontStyle = 0;
+ CContText();
+ ~CContText(){}
- m_dX = 0;
- m_dY = 0;
- m_dWidth = 0;
- m_dHeight = 0;
- m_dLastX = 0;
+ inline void Clear();
- m_dWidthWithoutSpaces = 0;
- m_dLeftWithoutSpaces = 0;
+ CContText(const CContText& oSrc);
- m_dPosition = 0;
- m_dSpaceWidthMM = 0;
+ CContText& operator=(const CContText& oSrc);
+ void CopyFormat(const CContText& oSrc);
- m_dCalculateWidth = 0;
+ bool IsBigger(const CContText* oSrc);
+ bool IsBiggerOrEqual(const CContText* oSrc);
- m_dSpaceByText = 0;
- }
- ~CContText()
- {
- }
+ double GetIntersect(const CContText* oSrc) const;
- inline void Clear()
- {
- }
+ void Write(NSStringUtils::CStringBuilder& oWriter,
+ CFontManagerLight* pManagerLight,
+ bool bIsAddSpace = false);
- CContText(const CContText& oSrc)
- {
- *this = oSrc;
- }
- CContText& operator=(const CContText& oSrc)
- {
- m_oFont = oSrc.m_oFont;
- m_oBrush = oSrc.m_oBrush;
-
- m_oText = oSrc.m_oText;
- m_oGidText = oSrc.m_oGidText;
-
- m_strPickFontName = oSrc.m_strPickFontName;
- m_lPickFontStyle = oSrc.m_lPickFontStyle;
-
- m_dX = oSrc.m_dX;
- m_dY = oSrc.m_dY;
- m_dWidth = oSrc.m_dWidth;
- m_dHeight = oSrc.m_dHeight;
-
- m_dLastX = oSrc.m_dLastX;
-
- m_dWidthWithoutSpaces = oSrc.m_dWidthWithoutSpaces;
- m_dLeftWithoutSpaces = oSrc.m_dLeftWithoutSpaces;
-
- m_dPosition = oSrc.m_dPosition;
- m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM;
-
- m_dCalculateWidth = oSrc.m_dCalculateWidth;
- m_dSpaceByText = oSrc.m_dSpaceByText;
-
- return *this;
- }
-
- inline bool IsBigger(const CContText* oSrc)
- {
- return (m_dX > oSrc->m_dX) ? true : false;
- }
- inline bool IsBiggerOrEqual(const CContText* oSrc)
- {
- return (m_dX >= oSrc->m_dX) ? true : false;
- }
-
- inline double GetIntersect(const CContText* oSrc) const
- {
- double d1 = std::max(m_dX, oSrc->m_dX);
- double d2 = std::min(m_dX + m_dWidth, oSrc->m_dX + oSrc->m_dWidth);
-
- if (d2 > d1)
- return d2 - d1;
- return 0;
- }
-
- inline void Write(NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight, bool bIsAddSpace = false)
- {
- oWriter.WriteString(L"");
-
- if (m_dWidth != m_dWidthWithoutSpaces)
- {
- DeleteSpaces(m_oText);
- m_dWidth = m_dWidthWithoutSpaces;
- }
-
- if (m_strPickFontName.empty())
- {
- if (m_oFont.Bold)
- oWriter.WriteString(L"");
- if (m_oFont.Italic)
- oWriter.WriteString(L"");
-
- if (bIsAddSpace)
- {
- m_dWidth += m_dSpaceWidthMM;
- m_oText += L" ";
- }
- }
- else
- {
- if (0x01 == (0x01 & m_lPickFontStyle))
- oWriter.WriteString(L"");
- if (0x02 == (0x02 & m_lPickFontStyle))
- oWriter.WriteString(L"");
-
- if (bIsAddSpace)
- {
- m_dWidth += pManagerLight->GetSpaceWidth();
- m_oText += L" ";
- }
-
- // нужно перемерять...
- double ___dSize = (double)((LONG)(m_oFont.Size * 2)) / 2;
- pManagerLight->LoadFont(m_strPickFontName, m_lPickFontStyle, ___dSize, false);
- double dWidth = pManagerLight->MeasureStringWidth(m_oText.ToStdWString());
-
- if (fabs(dWidth - m_dWidth) > 2)
- {
- double dSpacing = (m_dWidth - dWidth) / (m_oText.length() + 1);
- dSpacing *= c_dMMToDx;
-
- oWriter.WriteString(L"");
- }
- }
-
- int lSize = (int)(2 * m_oFont.Size);
- oWriter.WriteString(L"");
-
- std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
- oWriter.WriteEncodeXmlString(m_oText.ToStdWString());
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
- }
-
- void WriteTo(double dSpacingMM, NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight)
- {
- oWriter.WriteString(L"");
-
- double dSpaceMMSize = m_dSpaceWidthMM;
- if (m_strPickFontName.empty())
- {
- if (m_oFont.Bold)
- oWriter.WriteString(L"");
- if (m_oFont.Italic)
- oWriter.WriteString(L"");
- }
- else
- {
- if (0x01 == (0x01 & m_lPickFontStyle))
- oWriter.WriteString(L"");
- if (0x02 == (0x02 & m_lPickFontStyle))
- oWriter.WriteString(L"");
-
- dSpaceMMSize = pManagerLight->GetSpaceWidth();
- }
-
- int lSize = (int)(2 * m_oFont.Size);
- oWriter.WriteString(L"");
-
- std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName;
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- LONG lSpacing = (LONG)((dSpacingMM - dSpaceMMSize) * c_dMMToDx);
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
- oWriter.WriteString(L" ");
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"");
- }
+ void WriteTo(double dSpacingMM,
+ NSStringUtils::CStringBuilder& oWriter,
+ CFontManagerLight* pManagerLight);
};
class CTextLine
@@ -368,359 +153,74 @@ namespace NSDocxRenderer
double m_dHeight;
public:
- CTextLine() : m_arConts()
- {
- m_dBaselinePos = 0;
+ CTextLine();
+ void Clear();
- m_dX = 0;
- m_dY = 0;
- m_dWidth = 0;
- m_dHeight = 0;
- }
- void Clear()
- {
- for (std::vector::iterator iter = m_arConts.begin(); iter != m_arConts.end(); iter++)
- {
- CContText* pText = *iter;
- RELEASEOBJECT(pText);
- }
- m_arConts.clear();
- }
+ ~CTextLine();
- ~CTextLine()
- {
- Clear();
- }
+ CTextLine(const CTextLine& oSrc);
+ CTextLine& operator=(const CTextLine& oSrc);
- CTextLine(const CTextLine& oSrc)
- {
- *this = oSrc;
- }
- CTextLine& operator=(const CTextLine& oSrc)
- {
- Clear();
- for (std::vector::const_iterator iter = oSrc.m_arConts.begin(); iter != oSrc.m_arConts.end(); iter++)
- {
- m_arConts.push_back(new CContText(*(*iter)));
- }
+ void AddCont(CContText* pCont, double dBaselineOffset);
+ bool IsBigger(const CTextLine* oSrc);
+ bool IsBiggerOrEqual(const CTextLine* oSrc);
+ void SortConts();
- m_dBaselinePos = oSrc.m_dBaselinePos;
- m_dX = oSrc.m_dX;
- m_dY = oSrc.m_dY;
- m_dWidth = oSrc.m_dWidth;
- m_dHeight = oSrc.m_dHeight;
- }
-
- inline void AddCont(CContText* pCont, double dBaselineOffset)
- {
- if (0 == m_arConts.size())
- m_dBaselineOffset = dBaselineOffset;
-
- if ( ( pCont->m_dX > 0 ) && ( ( m_dX == 0 ) || ( pCont->m_dX < m_dX ) ) )
- m_dX = pCont->m_dX;
-
- if (m_dHeight < pCont->m_dHeight)
- m_dHeight = pCont->m_dHeight;
-
- m_arConts.push_back(pCont);
- }
-
- inline bool IsBigger(const CTextLine* oSrc)
- {
- return (m_dBaselinePos > oSrc->m_dBaselinePos) ? true : false;
- }
- inline bool IsBiggerOrEqual(const CTextLine* oSrc)
- {
- return (m_dBaselinePos >= oSrc->m_dBaselinePos) ? true : false;
- }
-
- inline void SortConts()
- {
- // сортировка непрерывных слов по m_dX
- SortElements(m_arConts);
- }
-
- void Merge(CTextLine* pTextLine)
- {
- size_t nCount = pTextLine->m_arConts.size();
- if (0 != nCount)
- {
- if (pTextLine->m_dX < m_dX)
- {
- m_dX = pTextLine->m_dX;
- }
- if (pTextLine->m_dBaselinePos < m_dBaselinePos)
- {
- m_dHeight = (m_dBaselinePos - pTextLine->m_dBaselinePos + pTextLine->m_dHeight);
- }
- else
- {
- m_dHeight = (pTextLine->m_dBaselinePos - m_dBaselinePos + m_dHeight);
- }
-
- double dSubPosition = m_dBaselinePos - pTextLine->m_dBaselinePos;
-
- for (size_t i = 0; i < nCount; ++i)
- {
- pTextLine->m_arConts[i]->m_dPosition = dSubPosition;
- m_arConts.push_back(pTextLine->m_arConts[i]);
- }
- }
- }
-
- void Analyze()
- {
- size_t nCountConts = m_arConts.size();
-
- if (0 == nCountConts)
- return;
-
- CContText* pFirst = m_arConts[0];
-
- for (size_t i = 1; i < nCountConts; ++i)
- {
- CContText* pCurrent = m_arConts[i];
-
- if (pFirst->m_strPickFontName != pCurrent->m_strPickFontName ||
- pFirst->m_oFont.Bold != pCurrent->m_oFont.Bold ||
- pFirst->m_oFont.Italic != pCurrent->m_oFont.Italic)
- {
- // вообще надо бы все объединить. но пока этот метод на соединение "первых"
- break;
- }
-
- double dRight = pFirst->m_dX + pFirst->m_dWidth;
- double dLeft = pCurrent->m_dX;
-
- if (fabs(dRight - dLeft) > 0.5)
- {
- // вообще надо бы все объединить. но пока этот метод на соединение "первых"
- break;
- }
-
- // продолжаем слово
- pFirst->m_oText += pCurrent->m_oText;
- pFirst->m_dWidth = (dLeft + pCurrent->m_dWidth - pFirst->m_dX);
-
- if (pFirst->m_dWidthWithoutSpaces < 0.0001)
- {
- pFirst->m_dLeftWithoutSpaces = pCurrent->m_dLeftWithoutSpaces;
- }
-
- if (pCurrent->m_dWidthWithoutSpaces > 0.0001)
- {
- pFirst->m_dWidthWithoutSpaces = pCurrent->m_dLeftWithoutSpaces + pCurrent->m_dWidthWithoutSpaces - pFirst->m_dLeftWithoutSpaces;
- }
-
- m_arConts.erase(m_arConts.begin() + i);
- --i;
- --nCountConts;
- }
- }
-
- bool IsForceBlock()
- {
- // линия отсортирована, так что сравниваем только соседние conts
- size_t nCount = m_arConts.size();
- if (nCount <= 1)
- return false;
-
- for (size_t i = 0; i < nCount; i++)
- {
- for (size_t j = i + 1; j < nCount; j++)
- {
- if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10)
- return true;
- }
- }
- return false;
- }
-
- void ToXml(NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight)
- {
- size_t nCountConts = m_arConts.size();
-
- if (0 == nCountConts)
- return;
-
- CContText* pPrev = m_arConts[0];
- double dDelta = 0;
-
- for (size_t i = 1; i < nCountConts; ++i)
- {
- CContText* pCurrent = m_arConts[i];
-
- if (0 == pCurrent->m_dWidthWithoutSpaces)
- continue;
-
- dDelta = pCurrent->m_dLeftWithoutSpaces - (pPrev->m_dLeftWithoutSpaces + pPrev->m_dWidthWithoutSpaces);
-
- if (dDelta < 0.5)
- {
- // просто текст на тексте или сменились настройки (font/brush)
- pPrev->Write(oWriter, pManagerLight);
- pPrev = pCurrent;
- }
- //else if (dDelta < 2 * pPrev->m_dSpaceWidthMM)
- //{
- // // сменились настройки, но пробел все-таки вставить нужно
- // pPrev->Write(oWriter, pManagerLight, true);
- // pPrev = pCurrent;
- //}
- else
- {
- // расстояние слишком большое. нужно сделать большой пробел
- pPrev->Write(oWriter, pManagerLight);
- pPrev->WriteTo(dDelta, oWriter, pManagerLight);
- pPrev = pCurrent;
- }
- }
-
- pPrev->Write(oWriter, pManagerLight);
- }
+ //Объединяем слова из двух строк
+ void Merge(CTextLine* pTextLine);
+ //Объединяем подходящие слова в одну строку, если возможно
+ void Analyze();
+ bool IsForceBlock();
+ void ToXml(NSStringUtils::CStringBuilder& oWriter, CFontManagerLight* pManagerLight);
+ void CalculateWidth();
+ void AddSpaceToEnd();
};
class CParagraph : public CBaseItem
{
public:
+ enum TextAlignmentType
+ {
+ TextAlignmentType_ByLeftEdge = 0,
+ TextAlignmentType_ByCenter = 1,
+ TextAlignmentType_ByRightEdge = 2,
+ TextAlignmentType_ByWidth = 3
+ };
+
// text frame properties
bool m_bIsTextFrameProperties;
+ bool m_bIsNeedFirstLineIndent;
+ TextAlignmentType m_eTextAlignmentType;
// geometry paragraph
- double m_dLeft;
+ double m_dLeft; //сдвиг относительно левого края страницы
+ double m_dRight; //сдвиг относительно правого края страницы
double m_dTop;
double m_dWidth;
- double m_dHeight;
+ double m_dHeight; //высота каждой строки
+ double m_dFirstLine; //сдвиг относительно m_dLeft
CFontManagerLight* m_pManagerLight;
double m_dSpaceBefore;
+ double m_dBaselinePos;
TextAssociationType m_eTextAssociationType;
std::vector m_arLines;
+ // statistic
+ size_t m_numLines; //число изначально входящих линий
+
public:
- CParagraph(const TextAssociationType& eType) : m_arLines()
- {
- m_eType = etParagraph;
+ CParagraph(const TextAssociationType& eType);
+ CParagraph(const CParagraph& oSrc);
+ ~CParagraph();
- m_bIsTextFrameProperties = false;
+ void Clear();
+ CParagraph& operator=(const CParagraph& oSrc);
- m_dLeft = 0.0;
- m_dTop = 0.0;
- m_dWidth = 0.0;
- m_dHeight = 0.0;
+ virtual void ToXml(NSStringUtils::CStringBuilder& oWriter);
- m_dSpaceBefore = 0.0;
-
- m_pManagerLight = NULL;
- m_eTextAssociationType = eType;
- }
- CParagraph(const CParagraph& oSrc)
- {
- *this = oSrc;
- }
- ~CParagraph()
- {
- Clear();
- }
-
- void Clear()
- {
- size_t nCount = m_arLines.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CTextLine* pText = m_arLines[i];
- RELEASEOBJECT(pText);
- }
- m_arLines.clear();
-
- m_pManagerLight = NULL;
- }
-
- CParagraph& operator=(const CParagraph& oSrc)
- {
- m_eType = etParagraph;
-
- m_bIsTextFrameProperties = oSrc.m_bIsTextFrameProperties;
-
- m_dLeft = oSrc.m_dLeft;
- m_dTop = oSrc.m_dTop;
- m_dWidth = oSrc.m_dWidth;
- m_dHeight = oSrc.m_dHeight;
-
- m_dSpaceBefore = oSrc.m_dSpaceBefore;
-
- m_eTextAssociationType = oSrc.m_eTextAssociationType;
-
- Clear();
- size_t nCount = oSrc.m_arLines.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- m_arLines.push_back(new CTextLine(*oSrc.m_arLines[i]));
- }
-
- m_pManagerLight = oSrc.m_pManagerLight;
- return *this;
- }
-
- virtual void ToXml(NSStringUtils::CStringBuilder& oWriter)
- {
- oWriter.WriteString(L"");
-
- switch (m_eTextAssociationType)
- {
- case TextAssociationTypeBlockChar:
- {
- oWriter.WriteString(L"");
- break;
- }
- case TextAssociationTypeBlockLine:
- {
- oWriter.WriteString(L"");
- break;
- }
- case TextAssociationTypePlainLine:
- {
- if (m_bIsTextFrameProperties)
- {
- oWriter.WriteString(L"");
- break;
- }
- oWriter.WriteString(L"");
- break;
- }
- default:
- break;
- }
-
- size_t nCount = m_arLines.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CTextLine* pTextLine = m_arLines[i];
- pTextLine->SortConts();
- pTextLine->ToXml(oWriter, m_pManagerLight);
- }
-
- oWriter.WriteString(L"");
- }
+ void CalculateTextAlignmentType();
};
}
diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp
new file mode 100644
index 0000000000..551e7db116
--- /dev/null
+++ b/DocxRenderer/src/logic/Page.cpp
@@ -0,0 +1,1028 @@
+#include "Page.h"
+
+namespace NSDocxRenderer
+{
+ CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oManager(pFonts), m_oManagerLight(pFonts)
+ {
+ m_pFont = NULL;
+ m_pBrush = NULL;
+ m_pPen = NULL;
+ m_pShadow = NULL;
+ m_pEdgeText = NULL;
+
+ m_pTransform = NULL;
+ m_pSimpleGraphicsConverter = NULL;
+
+ m_dWidth = 0;
+ m_dHeight = 0;
+
+ m_pCurrentLine = NULL;
+ m_eTextAssociationType = TextAssociationTypePlainLine;
+
+ m_bIsDeleteTextClipPage = true;
+
+ m_dLastTextX = -1;
+ m_dLastTextY = -1;
+ m_dLastTextX_block = m_dLastTextX;
+ }
+
+void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush,
+ NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple)
+ {
+ m_pFont = pFont;
+ m_pPen = pPen;
+ m_pBrush = pBrush;
+ m_pShadow = pShadow;
+ m_pEdgeText = pEdge;
+
+ m_pTransform = pMatrix;
+ m_pSimpleGraphicsConverter = pSimple;
+
+ m_oManager.m_pFont = m_pFont;
+ m_oManager.m_pTransform = m_pTransform;
+
+ m_pCurrentLine = NULL;
+
+ m_oWriterVML.AddSize(1000);
+
+ m_dLastTextX = -1;
+ m_dLastTextY = -1;
+ m_dLastTextX_block = m_dLastTextX;
+ }
+
+void CPage::Clear()
+ {
+ ClearTextLines();
+ ClearGraphicItems();
+ ClearParagraphs();
+ ClearParagraphsBlocks();
+
+ m_pCurrentLine = NULL;
+
+ m_oWriterVML.ClearNoAttack();
+
+ m_dLastTextX = -1;
+ m_dLastTextY = -1;
+ m_dLastTextX_block = m_dLastTextX;
+ }
+
+ void CPage::ClearTextLines()
+ {
+ size_t nCount = m_arTextLine.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CTextLine* pTemp = m_arTextLine[i];
+ RELEASEOBJECT(pTemp);
+ }
+ m_arTextLine.clear();
+ }
+
+ void CPage::ClearGraphicItems()
+ {
+ size_t nCount = m_arGraphicItems.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CBaseItem* pTemp = m_arGraphicItems[i];
+ RELEASEOBJECT(pTemp);
+ }
+ m_arGraphicItems.clear();
+ }
+
+ void CPage::ClearParagraphs()
+ {
+ size_t nCount = m_arParagraphs.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CParagraph* pTemp = m_arParagraphs[i];
+ RELEASEOBJECT(pTemp);
+ }
+ m_arParagraphs.clear();
+ }
+
+ void CPage::ClearParagraphsBlocks()
+ {
+ size_t nCount = m_arParagraphsBlocks.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CParagraph* pTemp = m_arParagraphsBlocks[i];
+ RELEASEOBJECT(pTemp);
+ }
+ m_arParagraphsBlocks.clear();
+ }
+
+ CPage::~CPage()
+ {
+ Clear();
+ }
+
+ void CPage::SetCurrentLineByBaseline(const double& dBaseLinePos)
+ {
+ if ((NULL == m_pCurrentLine) || (TextAssociationTypeBlockChar == m_eTextAssociationType))
+ {
+ // пустая (в плане текста) страница
+ m_pCurrentLine = new CTextLine();
+
+ m_pCurrentLine->m_dBaselinePos = dBaseLinePos;
+ m_arTextLine.push_back(m_pCurrentLine);
+ return;
+ }
+ if (fabs(m_pCurrentLine->m_dBaselinePos - dBaseLinePos) <= THE_SAME_STRING_Y_PRECISION_MM)
+ {
+ return;
+ }
+ size_t nCount = m_arTextLine.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ if (fabs(m_arTextLine[i]->m_dBaselinePos - dBaseLinePos) <= THE_SAME_STRING_Y_PRECISION_MM)
+ {
+ m_pCurrentLine = m_arTextLine[i];
+ return;
+ }
+ }
+
+ // линия не нашлась - не беда - создадим новую
+ m_pCurrentLine = new CTextLine();
+ m_pCurrentLine->m_dBaselinePos = dBaseLinePos;
+ m_arTextLine.push_back(m_pCurrentLine);
+ return;
+ }
+
+ void CPage::DeleteTextClipPage()
+ {
+ if (m_bIsDeleteTextClipPage)
+ {
+ // удалим все линии, которые выходят за границы страницы
+ size_t nCount = m_arTextLine.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CTextLine* pTextLine = m_arTextLine[i];
+
+ double _top = pTextLine->m_dBaselinePos - pTextLine->m_dHeight;
+ double _bottom = pTextLine->m_dBaselinePos;
+
+ if (_top >= m_dHeight || _bottom <= 0)
+ {
+ m_arTextLine.erase(m_arTextLine.begin() + i);
+ --i;
+ --nCount;
+ }
+ }
+ }
+ }
+
+ // image commands
+ void CPage::WriteImage(CImageInfo& oInfo, double& fX, double& fY, double& fWidth, double& fHeight)
+ {
+ CImage* pImage = new CImage(oInfo, L"");
+
+ double dRotation = m_pTransform->z_Rotation();
+
+ if (fabs(dRotation) < 5.0)
+ {
+ double x1 = fX;
+ double y1 = fY;
+ double x2 = fX + fWidth;
+ double y2 = fY + fHeight;
+
+ m_pTransform->TransformPoint(x1, y1);
+ m_pTransform->TransformPoint(x2, y2);
+
+ if (x1 <= x2)
+ {
+ pImage->m_dLeft = x1;
+ pImage->m_dWidth = x2 - x1;
+ }
+ else
+ {
+ pImage->m_dLeft = x2;
+ pImage->m_dWidth = x1 - x2;
+ }
+
+ if (y1 <= y2)
+ {
+ pImage->m_dTop = y1;
+ pImage->m_dHeight = y2 - y1;
+ }
+ else
+ {
+ pImage->m_dTop = y2;
+ pImage->m_dHeight = y1 - y2;
+ }
+
+ pImage->m_dRotate = 0.0;
+ }
+ else
+ {
+ double x1 = fX;
+ double y1 = fY;
+ double x2 = fX + fWidth;
+ double y2 = fY + fHeight;
+
+ Aggplus::CMatrix oTemp = *m_pTransform;
+
+ double dCx = (x1 + x2) / 2;
+ double dCy = (y1 + y2) / 2;
+ m_pTransform->TransformPoint(dCx, dCy);
+ oTemp.RotateAt(-dRotation, dCx, dCy, Aggplus::MatrixOrderAppend);
+
+ oTemp.TransformPoint(x1, y1);
+ oTemp.TransformPoint(x2, y2);
+
+ if (x1 <= x2)
+ {
+ pImage->m_dLeft = x1;
+ pImage->m_dWidth = x2 - x1;
+ }
+ else
+ {
+ pImage->m_dLeft = x2;
+ pImage->m_dWidth = x1 - x2;
+ }
+
+ if (y1 <= y2)
+ {
+ pImage->m_dTop = y1;
+ pImage->m_dHeight = y2 - y1;
+ }
+ else
+ {
+ pImage->m_dTop = y2;
+ pImage->m_dHeight = y1 - y2;
+ }
+
+ pImage->m_dRotate = dRotation;
+ }
+
+ m_arGraphicItems.push_back(pImage);
+ }
+
+ // path commands
+ void CPage::MoveTo(double& dX, double& dY)
+ {
+ m_pTransform->TransformPoint(dX, dY);
+ m_oVector.MoveTo(dX, dY);
+
+ }
+ void CPage::LineTo(double& dX, double& dY)
+ {
+ m_pTransform->TransformPoint(dX, dY);
+ m_oVector.LineTo(dX, dY);
+ }
+ void CPage::CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
+ {
+ m_pTransform->TransformPoint(x1, y1);
+ m_pTransform->TransformPoint(x2, y2);
+ m_pTransform->TransformPoint(x3, y3);
+
+ m_oVector.CurveTo(x1, y1, x2, y2, x3, y3);
+ }
+ void CPage::Start()
+ {
+ }
+ void CPage::End()
+ {
+ m_oVector.End();
+ m_oWriterVML.ClearNoAttack();
+ }
+ void CPage::Close()
+ {
+ m_oVector.Close();
+ }
+ void CPage::DrawPath(LONG lType, LONG lTxId)
+ {
+ if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom))
+ {
+ CShape* pShape = new CShape();
+
+ pShape->m_lTxId = lTxId;
+
+ pShape->m_oPen = *m_pPen;
+ pShape->m_oBrush = *m_pBrush;
+
+ // нормализуем толщину линии
+ double dScaleTransform = (m_pTransform->sx() + m_pTransform->sy()) / 2.0;
+ pShape->m_oPen.Size *= dScaleTransform;
+
+ if ((lType & 0x01) == 0x00)
+ {
+ if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3))
+ {
+ lType = 0x01;
+ pShape->m_oPen.Color = m_pBrush->Color1;
+ pShape->m_oPen.Alpha = m_pBrush->Alpha1;
+ //pShape->m_oPen.Size = max(pShape->m_oPen.Size, 1);
+ }
+ }
+
+ pShape->CreateFromVectorData(&m_oVector, m_oWriterVML, 100000, lType);
+ m_arGraphicItems.push_back(pShape);
+ }
+ }
+
+ void CPage::WriteText(unsigned int* pUnicodes, unsigned int* pGids, unsigned int nCount, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, bool bIsPDFAnalyzer)
+ {
+ double dTextX = fX;
+ double dTextY = fY;
+ double dTextR = fX + fWidth;
+ double dTextB = fY + fHeight;
+
+ m_pTransform->TransformPoint(dTextX, dTextY);
+ m_pTransform->TransformPoint(dTextR, dTextB);
+
+ double dTextW = dTextR - dTextX;
+ double dTextH = dTextB - dTextY;
+
+ NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount);
+
+ if ((pUnicodes != NULL) && (pGids != NULL))
+ {
+ for (unsigned int i = 0; i < nCount; ++i)
+ {
+ if ( !IsUnicodeSymbol( pUnicodes[i] ) )
+ {
+ oText[i] = ' ';
+ }
+ }
+ }
+
+ bool bIsPath = ((NULL == pGids) && !bIsPDFAnalyzer) ? false : true;
+
+ m_oManager.LoadFont(0, !bIsPath);
+
+ if (bIsPath)
+ m_oManager.GenerateFontName2(oText);
+
+ if (fabs(dTextW) < 0.01 || (dTextW > 10))
+ {
+ double _x = 0;
+ double _y = 0;
+ double _w = 0;
+ double _h = 0;
+
+ if (NULL != pGids)
+ {
+ m_oManager.SetStringGid(1);
+ m_oManager.MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
+ }
+ else
+ {
+ // такого быть не должно (только из xps)
+ m_oManager.SetStringGid(0);
+ m_oManager.MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
+ }
+
+ dTextW = _w;
+ //dTextW *= c_dPixToMM;
+ }
+
+ double dBaseLinePos = dTextY + fBaseLineOffset;
+ dTextH = m_oManager.GetFontHeight();
+
+ SetCurrentLineByBaseline(dBaseLinePos);
+
+ CContText* pLastCont = NULL;
+ size_t nCountConts = m_pCurrentLine->m_arConts.size();
+ if (nCountConts != 0)
+ pLastCont = m_pCurrentLine->m_arConts[nCountConts - 1];
+
+ if (NULL == pLastCont)
+ {
+ // первое слово в линии
+ CContText* pCont = new CContText();
+
+ pCont->m_dX = dTextX;
+ pCont->m_dLastX = dTextX;
+ pCont->m_dY = dBaseLinePos;
+
+ pCont->m_dWidth = dTextW;
+ pCont->m_dHeight = dTextH;
+
+ if (IsSpaceUtf32(oText))
+ {
+ pCont->m_dWidthWithoutSpaces = 0;
+ pCont->m_dLeftWithoutSpaces = dTextX + dTextW;
+ }
+ else
+ {
+ pCont->m_dWidthWithoutSpaces = dTextW;
+ pCont->m_dLeftWithoutSpaces = dTextX;
+ }
+
+ pCont->m_oText = oText;
+
+ pCont->m_oFont = m_oManager.m_oFont.m_oFont;
+ pCont->m_oBrush = *m_pBrush;
+
+ if (bIsPath)
+ {
+ pCont->m_strPickFontName = m_oManager.m_strCurrentPickFont;
+ pCont->m_lPickFontStyle = m_oManager.m_lCurrentPictFontStyle;
+ }
+
+ pCont->m_dSpaceWidthMM = m_oManager.m_dSpaceWidthMM;
+
+ m_pCurrentLine->AddCont(pCont, m_oManager.m_oFont.m_dBaselineOffset);
+
+ m_dLastTextX = dTextX;
+ m_dLastTextY = dBaseLinePos;
+ m_dLastTextX_block = m_dLastTextX;
+ return;
+ }
+
+ // продолжение линии
+ //if (m_lCurrentCommand == c_nTextType && pLastCont->m_oFont.IsEqual(&m_oManager.m_oFontOld) && pLastCont->m_oBrush.IsEqual(m_pBrush))
+ //{
+ // // быстрое отметание вс¤ких проверок
+ // pLastCont->m_strText += strText;
+ // pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
+ // return;
+ //}
+
+ double dRight = pLastCont->m_dX + pLastCont->m_dWidth;
+
+ if (pLastCont->m_oFont.IsEqual(&m_oManager.m_oFont.m_oFont) && pLastCont->m_oBrush.IsEqual(m_pBrush))
+ {
+ // настройки одинаковые. теперь смотрим, на расположение
+ if (fabs(dRight - dTextX) < 0.5)
+ {
+ // продолжаем слово
+ pLastCont->m_oText += oText;
+ pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
+
+ if (!IsSpaceUtf32(oText))
+ {
+ if (0 == pLastCont->m_dWidthWithoutSpaces)
+ pLastCont->m_dLeftWithoutSpaces = dTextX;
+
+ pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
+ }
+ else if (0 == pLastCont->m_dWidthWithoutSpaces)
+ {
+ pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
+ }
+
+ m_dLastTextX = dTextX;
+ m_dLastTextY = dBaseLinePos;
+ m_dLastTextX_block = m_dLastTextX;
+ pLastCont->m_dLastX = dTextX;
+ return;
+ }
+ else if ((dRight < dTextX) && ((dTextX - dRight) < m_oManager.m_dSpaceWidthMM))
+ {
+ // продолжаем слово с пробелом
+ if (m_eTextAssociationType != TextAssociationTypePlainLine &&
+ m_eTextAssociationType != TextAssociationTypePlainParagraph)
+ {
+ pLastCont->m_oText += uint32_t(' ');
+ }
+ pLastCont->m_oText += oText;
+ pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
+
+ if (!IsSpaceUtf32(oText))
+ {
+ if (0 == pLastCont->m_dWidthWithoutSpaces)
+ pLastCont->m_dLeftWithoutSpaces = dTextX;
+
+ pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
+ }
+ else if (0 == pLastCont->m_dWidthWithoutSpaces)
+ {
+ pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
+ }
+
+ m_dLastTextX = dTextX;
+ m_dLastTextY = dBaseLinePos;
+ m_dLastTextX_block = m_dLastTextX;
+ pLastCont->m_dLastX = dTextX;
+ return;
+ }
+ else if (fabs(dBaseLinePos - pLastCont->m_dY) < 0.01 &&
+ fabs(m_dLastTextY - pLastCont->m_dY) < 0.01 &&
+ fabs(m_dLastTextX - pLastCont->m_dLastX) < 0.01)
+ {
+ // идет текст подряд, но с расстояниями что-то не так. смотрим - если новый текст идет после предыдущего, но
+ // просто левее чем предыдущий x + w - то считаем это нормальным. и дописываем слово. корректируя длину
+ if (dTextX < dRight && dTextX > pLastCont->m_dLastX)
+ {
+ // продолжаем слово
+ pLastCont->m_oText += oText;
+ double dNewW = (dTextX + dTextW - pLastCont->m_dX);
+ if (pLastCont->m_dWidth < dNewW)
+ pLastCont->m_dWidth = dNewW;
+
+ if (!IsSpaceUtf32(oText))
+ {
+ if (0 == pLastCont->m_dWidthWithoutSpaces)
+ pLastCont->m_dLeftWithoutSpaces = dTextX;
+
+ pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
+ }
+ else if (0 == pLastCont->m_dWidthWithoutSpaces)
+ {
+ pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
+ }
+
+ m_dLastTextX = dTextX;
+ m_dLastTextY = dBaseLinePos;
+ m_dLastTextX_block = m_dLastTextX;
+ pLastCont->m_dLastX = dTextX;
+ return;
+
+ }
+
+ // еще одна заглушка на большой пробел - добавляем пробел, потом в линии все разрулится через spacing
+ if (dTextX > dRight && (dTextX - dRight) < 5 && fabs(m_dLastTextX_block - m_dLastTextX) < 0.01)
+ {
+ // продолжаем слово с пробелом
+ if (m_eTextAssociationType != TextAssociationTypePlainLine &&
+ m_eTextAssociationType != TextAssociationTypePlainParagraph)
+ {
+ pLastCont->m_oText += uint32_t(' ');
+ }
+ pLastCont->m_oText += oText;
+ pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
+
+ if (!IsSpaceUtf32(oText))
+ {
+ if (0 == pLastCont->m_dWidthWithoutSpaces)
+ pLastCont->m_dLeftWithoutSpaces = dTextX;
+
+ pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
+ }
+ else if (0 == pLastCont->m_dWidthWithoutSpaces)
+ {
+ pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
+ }
+
+ m_dLastTextX = dTextX;
+ m_dLastTextY = dBaseLinePos;
+ m_dLastTextX_block = m_dLastTextX;
+ pLastCont->m_dLastX = dTextX;
+ return;
+ }
+ }
+ }
+
+ // либо пробел большой между словами, либо новый текст левее, либо настройки не те (шрифт, кисть)
+ // либо все вместе... просто добавл¤ем новое слово
+ CContText* pCont = new CContText();
+
+ pCont->m_dX = dTextX;
+ pCont->m_dY = dBaseLinePos;
+ pCont->m_dLastX = dTextX;
+
+ pCont->m_dWidth = dTextW;
+ pCont->m_dHeight = dTextH;
+
+ if (IsSpaceUtf32(oText))
+ {
+ pCont->m_dWidthWithoutSpaces = 0;
+ pCont->m_dLeftWithoutSpaces = dTextX + dTextW;
+ }
+ else
+ {
+ pCont->m_dWidthWithoutSpaces = dTextW;
+ pCont->m_dLeftWithoutSpaces = dTextX;
+ }
+
+ pCont->m_oText = oText;
+
+ pCont->m_oFont = m_oManager.m_oFont.m_oFont;
+ pCont->m_oBrush = *m_pBrush;
+
+ if (bIsPath)
+ {
+ pCont->m_strPickFontName = m_oManager.m_strCurrentPickFont;
+ pCont->m_lPickFontStyle = m_oManager.m_lCurrentPictFontStyle;
+ }
+
+ pCont->m_dSpaceWidthMM = m_oManager.m_dSpaceWidthMM;
+
+ m_pCurrentLine->AddCont(pCont, m_oManager.m_oFont.m_dBaselineOffset);
+
+ m_dLastTextX = dTextX;
+ m_dLastTextY = dBaseLinePos;
+ m_dLastTextX_block = m_dLastTextX;
+ }
+
+ void CPage::Build()
+ {
+ DeleteTextClipPage();
+
+ if (0 == m_arTextLine.size())
+ return;
+
+ switch (m_eTextAssociationType)
+ {
+ case TextAssociationTypeBlockChar:
+ BuildByTypeBlockChar();
+ break;
+ case TextAssociationTypeBlockLine:
+ BuildByTypeBlockLine();
+ break;
+ case TextAssociationTypePlainLine:
+ BuildByTypePlainLine();
+ break;
+ case TextAssociationTypePlainParagraph:
+ BuildByTypePlainParagraph();
+ break;
+ default:
+ break;
+ }
+
+ m_arTextLine.clear(); //todo удалить нельзя и ClearTextLines(); тоже нельзя - наверное переделать
+ //использовать не указатели, а новые объекты
+ }
+
+ void CPage::BuildByTypeBlockChar()
+ {
+ size_t nCount = m_arTextLine.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CTextLine* pTextLine = m_arTextLine[i];
+
+ CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
+ pParagraph->m_pManagerLight = &m_oManagerLight;
+ pParagraph->m_bIsTextFrameProperties = true;
+
+ pParagraph->m_dLeft = pTextLine->m_dX;
+ pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
+
+ pParagraph->m_arLines.push_back(pTextLine);
+
+ m_arParagraphs.push_back(pParagraph);
+ }
+ }
+
+ void CPage::BuildByTypeBlockLine()
+ {
+ CTextLine* pFirstLine = m_arTextLine[0];
+
+ CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
+ pParagraph->m_pManagerLight = &m_oManagerLight;
+ pParagraph->m_bIsTextFrameProperties = true;
+
+ pParagraph->m_dLeft = pFirstLine->m_dX;
+ pParagraph->m_dTop = pFirstLine->m_dBaselinePos - pFirstLine->m_dHeight - pFirstLine->m_dBaselineOffset;
+ double dCurrentTop = pParagraph->m_dTop;
+
+ pParagraph->m_arLines.push_back(pFirstLine);
+
+ m_arParagraphs.push_back(pParagraph);
+ size_t nCount = m_arTextLine.size();
+ for (size_t i = 1; i < nCount; ++i)
+ {
+ CTextLine* pTextLine = m_arTextLine[i];
+
+ CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
+ pParagraph->m_pManagerLight = &m_oManagerLight;
+ pParagraph->m_bIsTextFrameProperties = true;
+
+ if (((fabs(pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pFirstLine->m_dBaselinePos) > STANDART_STRING_HEIGHT_MM) && (pTextLine->m_dX == pFirstLine->m_dX)) ||
+ ((pTextLine->m_dX != pFirstLine->m_dX) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos)))
+ {
+ pParagraph->m_dLeft = pTextLine->m_dX;
+ pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
+ dCurrentTop = pParagraph->m_dTop;
+ }
+ else
+ {
+ pParagraph->m_dLeft = pFirstLine->m_dX;
+ pParagraph->m_dTop = dCurrentTop;
+ }
+
+ pFirstLine = pTextLine;
+
+ pParagraph->m_arLines.push_back(pTextLine);
+ m_arParagraphs.push_back(pParagraph);
+ }
+ }
+
+ void CPage::BuildByTypePlainLine()
+ {
+ SortElements(m_arTextLine);
+
+ if (m_eTextAssociationType == TextAssociationTypePlainLine)
+ {
+ if (true) // merge line
+ {
+ for (std::vector::iterator iter = m_arTextLine.begin(); iter != m_arTextLine.end(); ++iter)
+ {
+ (*iter)->Analyze();
+ }
+ }
+ Merge(STANDART_STRING_HEIGHT_MM / 3);
+ }
+
+ double previousStringOffset = 0;
+ size_t nCount = m_arTextLine.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ CTextLine* pTextLine = m_arTextLine[i];
+
+ CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
+ pParagraph->m_pManagerLight = &m_oManagerLight;
+ pParagraph->m_bIsTextFrameProperties = false;
+#if 0
+ // у рамок нельзя выключить обтекание. поэтому в этом случае нужно конверировать в шейп
+ if (pTextLine->IsForceBlock())
+ {
+ pParagraph->m_bIsTextFrameProperties = true;
+ pParagraph->m_dLeft = pTextLine->m_dX;
+ pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
+
+ pParagraph->m_arLines.push_back(pTextLine);
+ m_arParagraphs.push_back(pParagraph);
+ continue;
+ }
+#endif
+
+ pTextLine->CalculateWidth();
+
+ pParagraph->m_dLeft = pTextLine->m_dX;
+ pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
+ pParagraph->m_dRight = m_dWidth - (pTextLine->m_dX + pTextLine->m_dWidth);
+ pParagraph->m_dWidth = pTextLine->m_dWidth;
+
+ double dBeforeSpacing = (pTextLine->m_dBaselinePos - previousStringOffset - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset);
+
+ pParagraph->m_dSpaceBefore = std::max(dBeforeSpacing, 0.0);
+ pParagraph->m_dBaselinePos = pTextLine->m_dBaselinePos;
+
+ double dHeight = 1;
+ if (pTextLine->m_dHeight != 0)
+ {
+ dHeight = pTextLine->m_dHeight;
+
+ if (dBeforeSpacing < 0)
+ dHeight += dBeforeSpacing;
+ }
+
+ pParagraph->m_dHeight = dHeight;
+
+ previousStringOffset = pTextLine->m_dBaselinePos - pTextLine->m_dBaselineOffset;
+
+ pParagraph->m_arLines.push_back(pTextLine);
+ pParagraph->m_numLines++;
+
+ CalculateTextAlignmentType(*pParagraph);
+
+ m_arParagraphs.push_back(pParagraph);
+ }
+ }
+
+ void CPage::CalculateTextAlignmentType(CParagraph& a_rParagraph)
+ {
+ if (a_rParagraph.m_dFirstLine == 0) //еще не был определен или для параграфа с одной строкой внутри
+ {
+ static double maxSringWidth = m_dWidth / 4 * 3; //нужна какая-нибудь константа...
+ static const double ERROR_X_MM = 3;
+ double delta = 2 * ERROR_X_MM; //координата m_dWidth/2 +- THE_STRING_X_PRECISION_MM
+
+ if (fabs(m_dWidth/2 - a_rParagraph.m_dLeft - a_rParagraph.m_dWidth/2) <= delta && //если середины линий по x одинаковы
+ a_rParagraph.m_dWidth < maxSringWidth)
+ {
+ a_rParagraph.m_eTextAlignmentType = CParagraph::TextAlignmentType_ByCenter;
+ }
+ else if ((a_rParagraph.m_dLeft + a_rParagraph.m_dWidth/2) > (m_dWidth/2 + ERROR_X_MM) && //середина строки правее центра страницы
+ a_rParagraph.m_dWidth < maxSringWidth)
+ {
+ a_rParagraph.m_eTextAlignmentType = CParagraph::TextAlignmentType_ByRightEdge;
+ }
+ else if ((a_rParagraph.m_dLeft + a_rParagraph.m_dWidth/2) < (m_dWidth/2 - ERROR_X_MM) && //середина строки левее центра страницы
+ a_rParagraph.m_dWidth < maxSringWidth)
+ {
+ a_rParagraph.m_eTextAlignmentType = CParagraph::TextAlignmentType_ByLeftEdge;
+ }
+ else
+ {
+ a_rParagraph.m_eTextAlignmentType = CParagraph::TextAlignmentType_ByWidth;
+ }
+ }
+ else
+ {
+ //todo
+ a_rParagraph.m_eTextAlignmentType = CParagraph::TextAlignmentType_ByWidth;
+ }
+
+ }
+
+
+ void CPage::BuildByTypePlainParagraph()
+ {
+ //todo возможно лучше разделить все сразу на фреймы и параграфы, до разбиения по линиям,
+ //т.к. если разномастный текст находится на примерно одной линии его корректно будет сложно отобразить
+ BuildByTypePlainLine();
+
+ CParagraph *currP, *nextP;
+
+ //todo выравнивание m_arParagraphsBlocks с TextAlignmentType_ByWidth по всей странице для нескольких стилей
+ //пока работает только если присутствует один стиль сплошного текста
+ double corrRight = 0, corrHeight = 0; //
+
+ //todo добавить междустрочные интервалы если их нет
+
+ //коррекция BeforeSpacing
+ double corrBeforeSpacing = 0;
+
+ for (size_t index = 0; index < m_arParagraphs.size(); index++)
+ {
+ size_t nextIndex = index+1;
+ CParagraph* pParagraph = nullptr;
+
+ currP = m_arParagraphs[index];
+ nextIndex == m_arParagraphs.size() ?
+ nextP = nullptr :
+ nextP = m_arParagraphs[nextIndex];
+
+ corrBeforeSpacing = 0;
+
+ //todo пока только для левостроннего письма! - tmp!
+ if (nextP && //это должна быть не последняя строка
+ fabs(currP->m_dHeight - nextP->m_dHeight) <= THE_SAME_STRING_Y_PRECISION_MM && //высота строк должна быть примерно одинаковой
+ (currP->m_eTextAlignmentType == CParagraph::TextAlignmentType_ByLeftEdge || //todo - есть проблема если весь текст выровнен по центру
+ currP->m_eTextAlignmentType == CParagraph::TextAlignmentType_ByWidth) &&
+ ((currP->m_dLeft > nextP->m_dLeft && fabs(currP->m_dRight - nextP->m_dRight) > THE_STRING_X_PRECISION_MM) ||
+ (fabs(currP->m_dRight - nextP->m_dRight) <= THE_STRING_X_PRECISION_MM)))
+ {
+ index++;
+
+ //наверное это сплошной текст
+ pParagraph = new CParagraph(*currP);
+
+ //делаем абзац в сплошном тексте
+ pParagraph->m_bIsNeedFirstLineIndent = true;
+
+ //Объединим 2 параграфа-строчки
+ pParagraph->m_arLines.back()->AddSpaceToEnd(); //todo - невсегда добавляется пробел, если текущая строка сложная (разные m_arConts)
+ for (size_t i = 0; i < nextP->m_arLines.size(); ++i)
+ {
+ pParagraph->m_arLines.push_back(new CTextLine(*nextP->m_arLines[i]));
+ pParagraph->m_numLines++;
+ }
+ pParagraph->m_dFirstLine = currP->m_dLeft - nextP->m_dLeft;
+ pParagraph->m_dRight = std::min(currP->m_dRight, nextP->m_dRight);
+ pParagraph->m_dLeft = std::min(currP->m_dLeft, nextP->m_dLeft);
+ pParagraph->m_dWidth = std::max(currP->m_dWidth, nextP->m_dWidth);
+ pParagraph->m_dHeight = (pParagraph->m_dHeight + nextP->m_dHeight) / 2; //берем среднее
+
+ //для последующей коррекции
+ corrRight > 0 ?
+ corrRight = (corrRight + currP->m_dRight)/2:
+ corrRight = currP->m_dRight;
+ corrHeight > 0 ?
+ corrHeight = (corrHeight + currP->m_dHeight)/2:
+ corrHeight = currP->m_dHeight;
+ corrBeforeSpacing = nextP->m_dSpaceBefore;
+
+ //проверим, подходят ли следующие параграфы-строчки для текущего pParagraph
+ if (nextIndex < m_arParagraphs.size()-1)
+ {
+ currP = nextP;
+ nextP = m_arParagraphs[++nextIndex];
+
+ while(nextIndex < m_arParagraphs.size() &&
+ fabs(currP->m_dHeight - nextP->m_dHeight) < THE_SAME_STRING_Y_PRECISION_MM &&
+ fabs(currP->m_dSpaceBefore - nextP->m_dSpaceBefore) <= THE_SAME_STRING_Y_PRECISION_MM && //расстрояние между строк тоже одинаково
+ (currP->m_eTextAlignmentType == nextP->m_eTextAlignmentType ||
+ nextP->m_eTextAlignmentType == CParagraph::TextAlignmentType_ByLeftEdge) &&
+ fabs(currP->m_dLeft - nextP->m_dLeft) < THE_STRING_X_PRECISION_MM //у последующих строк одинаковый отступ
+ )
+ {
+ index++;
+
+ //Объединим 2 параграфа-строчки
+ pParagraph->m_arLines.back()->AddSpaceToEnd(); //todo - невсегда добавляется пробел, если текущая строка сложная (разные m_arConts)
+ for (size_t i = 0; i < nextP->m_arLines.size(); ++i)
+ {
+ pParagraph->m_arLines.push_back(new CTextLine(*nextP->m_arLines[i]));
+ pParagraph->m_numLines++;
+ }
+ pParagraph->m_dRight = std::min(pParagraph->m_dRight, nextP->m_dRight);
+ pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, nextP->m_dLeft);
+ pParagraph->m_dWidth = std::max(currP->m_dWidth, nextP->m_dWidth);
+ pParagraph->m_dHeight = (pParagraph->m_dHeight + nextP->m_dHeight) / 2;
+
+ corrRight = (corrRight + currP->m_dRight)/2;
+ corrHeight = (corrHeight + currP->m_dHeight)/2;
+ corrBeforeSpacing += nextP->m_dSpaceBefore;
+
+ if (nextIndex < m_arParagraphs.size()) {
+ currP = nextP;
+ nextP = m_arParagraphs[++nextIndex];
+ } else {
+ break;
+ }
+ }
+ }
+ } else {
+ //todo может нужно некоторые параграфы сделать фреймами? условия?
+ /*if (currP->m_eTextAlignmentType == CParagraph::TextAlignmentType_ByRightEdge)
+ {
+ currP->m_bIsTextFrameProperties = true;
+ }*/
+ pParagraph = new CParagraph(*currP);
+ }
+
+ if (pParagraph)
+ {
+ if (corrBeforeSpacing > 0)
+ {
+ pParagraph->m_dSpaceBefore += corrBeforeSpacing;
+ }
+ m_arParagraphsBlocks.push_back(pParagraph);
+ }
+ }
+
+ //коррекция всей страницы
+ for (std::vector::iterator iter = m_arParagraphsBlocks.begin();
+ iter != m_arParagraphsBlocks.end(); ++iter)
+ {
+ if ((*iter)->m_eTextAlignmentType == CParagraph::TextAlignmentType_ByWidth)
+ {
+ (*iter)->m_dRight = corrRight;
+ (*iter)->m_dHeight = corrHeight;
+ }
+ }
+
+ ClearParagraphs();
+ }
+
+ void CPage::Merge(double dAffinity)
+ {
+ size_t nCount = m_arTextLine.size();
+ if (1 < nCount)
+ {
+ CTextLine* pPrev = m_arTextLine[0];
+ for (size_t i = 1; i < nCount; ++i)
+ {
+ CTextLine* pNext = m_arTextLine[i];
+
+ if (fabs(pNext->m_dBaselinePos - pPrev->m_dBaselinePos) < dAffinity)
+ {
+ pPrev->Merge(pNext);
+
+ pNext->m_arConts.clear();
+ RELEASEOBJECT(pNext);
+
+ m_arTextLine.erase(m_arTextLine.begin() + i);
+ --i;
+ --nCount;
+ continue;
+ }
+ pPrev = pNext;
+ }
+ }
+ }
+
+ void CPage::Write(NSStringUtils::CStringBuilder& oWriter)
+ {
+ // drawings
+ size_t nCountDrawings = m_arGraphicItems.size();
+ if (0 != nCountDrawings)
+ {
+ oWriter.WriteString(L"");
+
+ for (size_t i = 0; i < nCountDrawings; ++i)
+ {
+ m_arGraphicItems[i]->ToXml(oWriter);
+ }
+
+ oWriter.WriteString(L"");
+ }
+
+ size_t nCountParagraphs = m_eTextAssociationType != TextAssociationTypePlainParagraph ?
+ m_arParagraphs.size(): m_arParagraphsBlocks.size();
+ for (size_t i = 0; i < nCountParagraphs; ++i)
+ {
+ m_eTextAssociationType != TextAssociationTypePlainParagraph ?
+ m_arParagraphs[i]->ToXml(oWriter):
+ m_arParagraphsBlocks[i]->ToXml(oWriter);
+ }
+ }
+
+ void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter)
+ {
+ // section
+ int lWidthDx = (int)(m_dWidth * c_dMMToDx);
+ int lHeightDx = (int)(m_dHeight * c_dMMToDx);
+
+ if (!bLastPage)
+ oWriter.WriteString(L"");
+ else
+ oWriter.WriteString(L"");
+
+ oWriter.WriteString(L"= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait");
+ oWriter.WriteString(L"\"/>");
+
+ if (!bLastPage)
+ oWriter.WriteString(L"");
+ else
+ oWriter.WriteString(L"");
+ }
+}
diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h
index 232bc40d5e..d8abb54a36 100644
--- a/DocxRenderer/src/logic/Page.h
+++ b/DocxRenderer/src/logic/Page.h
@@ -5,8 +5,13 @@
namespace NSDocxRenderer
{
- const double STANDART_STRING_HEIGHT_MM = 4.2333333333333334;
- const double THE_SAME_STRING_Y_PRECISION_MM = 0.01;
+ const double STANDART_STRING_HEIGHT_MM = 4.2333333333333334;
+ const double THE_SAME_STRING_Y_PRECISION_MM = 0.01;
+ const double THE_STRING_X_PRECISION_MM = 0.1;
+
+ const double STANDART_LEFT_INDENT_MM = 30;
+ const double STANDART_RIGHT_INDENT_MM = 15;
+ const double STANDART_FIRSTLINE_INDENT_MM = 12.5;
inline bool IsSpaceUtf32(const uint32_t& c)
{
@@ -20,37 +25,37 @@ namespace NSDocxRenderer
}
inline bool IsUnicodeSymbol( int symbol )
- {
- bool result = false;
+ {
+ bool result = false;
- if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) ||
- ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) ||
- ( ( 0x10000 <= symbol ) && symbol ) )
- {
- result = true;
- }
+ if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) ||
+ ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) ||
+ ( ( 0x10000 <= symbol ) && symbol ) )
+ {
+ result = true;
+ }
- return result;
- }
+ return result;
+ }
- class CPage
- {
- public:
- NSStructures::CFont* m_pFont;
- NSStructures::CPen* m_pPen;
- NSStructures::CBrush* m_pBrush;
- NSStructures::CShadow* m_pShadow;
- NSStructures::CEdgeText* m_pEdgeText;
+ class CPage
+ {
+ public:
+ NSStructures::CFont* m_pFont;
+ NSStructures::CPen* m_pPen;
+ NSStructures::CBrush* m_pBrush;
+ NSStructures::CShadow* m_pShadow;
+ NSStructures::CEdgeText* m_pEdgeText;
Aggplus::CMatrix* m_pTransform;
Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter;
- CVectorGraphics m_oVector;
+ CVectorGraphics m_oVector;
- double m_dWidth;
- double m_dHeight;
+ double m_dWidth;
+ double m_dHeight;
- LONG m_lCurrentCommand;
+ LONG m_lCurrentCommand;
std::vector m_arGraphicItems;
std::vector m_arParagraphs;
@@ -58,811 +63,65 @@ namespace NSDocxRenderer
std::vector m_arParagraphsBlocks;
std::vector m_arTextLine;
- CTextLine* m_pCurrentLine;
+ CTextLine* m_pCurrentLine;
- CFontManager m_oManager;
- CFontManagerLight m_oManagerLight;
+ CFontManager m_oManager;
+ CFontManagerLight m_oManagerLight;
- TextAssociationType m_eTextAssociationType;
+ TextAssociationType m_eTextAssociationType;
NSStringUtils::CStringBuilder m_oWriterVML;
- bool m_bIsDeleteTextClipPage;
+ bool m_bIsDeleteTextClipPage;
double m_dLastTextX;
double m_dLastTextY;
double m_dLastTextX_block;
- public:
- CPage(NSFonts::IApplicationFonts* pFonts) : m_oManager(pFonts), m_oManagerLight(pFonts)
- {
- m_pFont = NULL;
- m_pBrush = NULL;
- m_pPen = NULL;
- m_pShadow = NULL;
- m_pEdgeText = NULL;
-
- m_pTransform = NULL;
- m_pSimpleGraphicsConverter = NULL;
-
- m_dWidth = 0;
- m_dHeight = 0;
-
- m_pCurrentLine = NULL;
- m_eTextAssociationType = TextAssociationTypePlainLine;
-
- m_bIsDeleteTextClipPage = true;
-
- m_dLastTextX = -1;
- m_dLastTextY = -1;
- m_dLastTextX_block = m_dLastTextX;
- }
-
- public:
+ public:
+ CPage(NSFonts::IApplicationFonts* pFonts);
+ ~CPage();
void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush,
- NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple)
- {
- m_pFont = pFont;
- m_pPen = pPen;
- m_pBrush = pBrush;
- m_pShadow = pShadow;
- m_pEdgeText = pEdge;
+ NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple);
- m_pTransform = pMatrix;
- m_pSimpleGraphicsConverter = pSimple;
+ void Clear();
+ void ClearTextLines();
+ void ClearGraphicItems();
+ void ClearParagraphs();
+ void ClearParagraphsBlocks();
- m_oManager.m_pFont = m_pFont;
- m_oManager.m_pTransform = m_pTransform;
+ void SetCurrentLineByBaseline(const double& dBaseLinePos);
+ void DeleteTextClipPage();
- m_pCurrentLine = NULL;
+ // image commands
+ void WriteImage(CImageInfo& oInfo, double& fX, double& fY, double& fWidth, double& fHeight);
- m_oWriterVML.AddSize(1000);
+ // path commands
+ void MoveTo(double& dX, double& dY);
+ void LineTo(double& dX, double& dY);
+ void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3);
+ void Start();
+ void End();
+ void Close();
+ void DrawPath(LONG lType, LONG lTxId);
- m_dLastTextX = -1;
- m_dLastTextY = -1;
- m_dLastTextX_block = m_dLastTextX;
- }
+ void WriteText(unsigned int* pUnicodes, unsigned int* pGids, unsigned int nCount,
+ double fX, double fY, double fWidth, double fHeight,
+ double fBaseLineOffset, bool bIsPDFAnalyzer);
- void Clear()
- {
- size_t nCount = 0;
+ void Build();
+ void BuildByTypeBlockChar();
+ void BuildByTypeBlockLine();
+ void BuildByTypePlainLine();
+ void BuildByTypePlainParagraph();
- nCount = m_arTextLine.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CTextLine* pTemp = m_arTextLine[i];
- RELEASEOBJECT(pTemp);
- }
- m_arTextLine.clear();
+ void CalculateTextAlignmentType(CParagraph& a_rParagraph);
- nCount = m_arGraphicItems.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CBaseItem* pTemp = m_arGraphicItems[i];
- RELEASEOBJECT(pTemp);
- }
- m_arGraphicItems.clear();
+ //Объединяем строки, которые находятся на расстроянии не большем dAffinity
+ void Merge(double dAffinity);
- nCount = m_arParagraphs.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CParagraph* pTemp = m_arParagraphs[i];
- RELEASEOBJECT(pTemp);
- }
- m_arParagraphs.clear();
+ void Write(NSStringUtils::CStringBuilder& oWriter);
- m_pCurrentLine = NULL;
-
- m_oWriterVML.ClearNoAttack();
-
- m_dLastTextX = -1;
- m_dLastTextY = -1;
- m_dLastTextX_block = m_dLastTextX;
- }
-
- ~CPage()
- {
- Clear();
- }
-
- void SetCurrentLineByBaseline(const double& dBaseLinePos)
- {
- if ((NULL == m_pCurrentLine) || (TextAssociationTypeBlockChar == m_eTextAssociationType))
- {
- // пустая (в плане текста) страница
- m_pCurrentLine = new CTextLine();
-
- m_pCurrentLine->m_dBaselinePos = dBaseLinePos;
- m_arTextLine.push_back(m_pCurrentLine);
- return;
- }
- if (fabs(m_pCurrentLine->m_dBaselinePos - dBaseLinePos) <= THE_SAME_STRING_Y_PRECISION_MM)
- {
- return;
- }
- size_t nCount = m_arTextLine.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- if (fabs(m_arTextLine[i]->m_dBaselinePos - dBaseLinePos) <= THE_SAME_STRING_Y_PRECISION_MM)
- {
- m_pCurrentLine = m_arTextLine[i];
- return;
- }
- }
-
- // линия не нашлась - не беда - создадим новую
- m_pCurrentLine = new CTextLine();
- m_pCurrentLine->m_dBaselinePos = dBaseLinePos;
- m_arTextLine.push_back(m_pCurrentLine);
- return;
- }
-
- // image commands
- void WriteImage(CImageInfo& oInfo, double& fX, double& fY, double& fWidth, double& fHeight)
- {
- CImage* pImage = new CImage(oInfo, L"");
-
- double dRotation = m_pTransform->z_Rotation();
-
- if (fabs(dRotation) < 5.0)
- {
- double x1 = fX;
- double y1 = fY;
- double x2 = fX + fWidth;
- double y2 = fY + fHeight;
-
- m_pTransform->TransformPoint(x1, y1);
- m_pTransform->TransformPoint(x2, y2);
-
- if (x1 <= x2)
- {
- pImage->m_dLeft = x1;
- pImage->m_dWidth = x2 - x1;
- }
- else
- {
- pImage->m_dLeft = x2;
- pImage->m_dWidth = x1 - x2;
- }
-
- if (y1 <= y2)
- {
- pImage->m_dTop = y1;
- pImage->m_dHeight = y2 - y1;
- }
- else
- {
- pImage->m_dTop = y2;
- pImage->m_dHeight = y1 - y2;
- }
-
- pImage->m_dRotate = 0.0;
- }
- else
- {
- double x1 = fX;
- double y1 = fY;
- double x2 = fX + fWidth;
- double y2 = fY + fHeight;
-
- Aggplus::CMatrix oTemp = *m_pTransform;
-
- double dCx = (x1 + x2) / 2;
- double dCy = (y1 + y2) / 2;
- m_pTransform->TransformPoint(dCx, dCy);
- oTemp.RotateAt(-dRotation, dCx, dCy, Aggplus::MatrixOrderAppend);
-
- oTemp.TransformPoint(x1, y1);
- oTemp.TransformPoint(x2, y2);
-
- if (x1 <= x2)
- {
- pImage->m_dLeft = x1;
- pImage->m_dWidth = x2 - x1;
- }
- else
- {
- pImage->m_dLeft = x2;
- pImage->m_dWidth = x1 - x2;
- }
-
- if (y1 <= y2)
- {
- pImage->m_dTop = y1;
- pImage->m_dHeight = y2 - y1;
- }
- else
- {
- pImage->m_dTop = y2;
- pImage->m_dHeight = y1 - y2;
- }
-
- pImage->m_dRotate = dRotation;
- }
-
- m_arGraphicItems.push_back(pImage);
- }
-
- // path commands
- void MoveTo(double& dX, double& dY)
- {
- m_pTransform->TransformPoint(dX, dY);
- m_oVector.MoveTo(dX, dY);
-
- }
- void LineTo(double& dX, double& dY)
- {
- m_pTransform->TransformPoint(dX, dY);
- m_oVector.LineTo(dX, dY);
- }
- void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3)
- {
- m_pTransform->TransformPoint(x1, y1);
- m_pTransform->TransformPoint(x2, y2);
- m_pTransform->TransformPoint(x3, y3);
-
- m_oVector.CurveTo(x1, y1, x2, y2, x3, y3);
- }
- void Start()
- {
- }
- void End()
- {
- m_oVector.End();
- m_oWriterVML.ClearNoAttack();
- }
- void Close()
- {
- m_oVector.Close();
- }
- void DrawPath(LONG lType, LONG lTxId)
- {
- if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom))
- {
- CShape* pShape = new CShape();
-
- pShape->m_lTxId = lTxId;
-
- pShape->m_oPen = *m_pPen;
- pShape->m_oBrush = *m_pBrush;
-
- // нормализуем толщину линии
- double dScaleTransform = (m_pTransform->sx() + m_pTransform->sy()) / 2.0;
- pShape->m_oPen.Size *= dScaleTransform;
-
- if ((lType & 0x01) == 0x00)
- {
- if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3))
- {
- lType = 0x01;
- pShape->m_oPen.Color = m_pBrush->Color1;
- pShape->m_oPen.Alpha = m_pBrush->Alpha1;
- //pShape->m_oPen.Size = max(pShape->m_oPen.Size, 1);
- }
- }
-
- pShape->CreateFromVectorData(&m_oVector, m_oWriterVML, 100000, lType);
- m_arGraphicItems.push_back(pShape);
- }
- }
-
- void WriteText(unsigned int* pUnicodes, unsigned int* pGids, unsigned int nCount, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, bool bIsPDFAnalyzer)
- {
- double dTextX = fX;
- double dTextY = fY;
- double dTextR = fX + fWidth;
- double dTextB = fY + fHeight;
-
- m_pTransform->TransformPoint(dTextX, dTextY);
- m_pTransform->TransformPoint(dTextR, dTextB);
-
- double dTextW = dTextR - dTextX;
- double dTextH = dTextB - dTextY;
-
- NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount);
-
- if ((pUnicodes != NULL) && (pGids != NULL))
- {
- for (unsigned int i = 0; i < nCount; ++i)
- {
- if ( !IsUnicodeSymbol( pUnicodes[i] ) )
- {
- oText[i] = ' ';
- }
- }
- }
-
- bool bIsPath = ((NULL == pGids) && !bIsPDFAnalyzer) ? false : true;
-
- m_oManager.LoadFont(0, !bIsPath);
-
- if (bIsPath)
- m_oManager.GenerateFontName2(oText);
-
- if (fabs(dTextW) < 0.01 || (dTextW > 10))
- {
- double _x = 0;
- double _y = 0;
- double _w = 0;
- double _h = 0;
-
- if (NULL != pGids)
- {
- m_oManager.SetStringGid(1);
- m_oManager.MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
- }
- else
- {
- // такого быть не должно (только из xps)
- m_oManager.SetStringGid(0);
- m_oManager.MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::MeasureTypePosition);
- }
-
- dTextW = _w;
- //dTextW *= c_dPixToMM;
- }
-
- double dBaseLinePos = dTextY + fBaseLineOffset;
- dTextH = m_oManager.GetFontHeight();
-
- SetCurrentLineByBaseline(dBaseLinePos);
-
- CContText* pLastCont = NULL;
- size_t nCountConts = m_pCurrentLine->m_arConts.size();
- if (nCountConts != 0)
- pLastCont = m_pCurrentLine->m_arConts[nCountConts - 1];
-
- if (NULL == pLastCont)
- {
- // первое слово в линии
- CContText* pCont = new CContText();
-
- pCont->m_dX = dTextX;
- pCont->m_dLastX = dTextX;
- pCont->m_dY = dBaseLinePos;
-
- pCont->m_dWidth = dTextW;
- pCont->m_dHeight = dTextH;
-
- if (IsSpaceUtf32(oText))
- {
- pCont->m_dWidthWithoutSpaces = 0;
- pCont->m_dLeftWithoutSpaces = dTextX + dTextW;
- }
- else
- {
- pCont->m_dWidthWithoutSpaces = dTextW;
- pCont->m_dLeftWithoutSpaces = dTextX;
- }
-
- pCont->m_oText = oText;
-
- pCont->m_oFont = m_oManager.m_oFont.m_oFont;
- pCont->m_oBrush = *m_pBrush;
-
- if (bIsPath)
- {
- pCont->m_strPickFontName = m_oManager.m_strCurrentPickFont;
- pCont->m_lPickFontStyle = m_oManager.m_lCurrentPictFontStyle;
- }
-
- pCont->m_dSpaceWidthMM = m_oManager.m_dSpaceWidthMM;
-
- m_pCurrentLine->AddCont(pCont, m_oManager.m_oFont.m_dBaselineOffset);
-
- m_dLastTextX = dTextX;
- m_dLastTextY = dBaseLinePos;
- m_dLastTextX_block = m_dLastTextX;
- return;
- }
-
- // продолжение линии
- //if (m_lCurrentCommand == c_nTextType && pLastCont->m_oFont.IsEqual(&m_oManager.m_oFontOld) && pLastCont->m_oBrush.IsEqual(m_pBrush))
- //{
- // // быстрое отметание вс¤ких проверок
- // pLastCont->m_strText += strText;
- // pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
- // return;
- //}
-
- double dRight = pLastCont->m_dX + pLastCont->m_dWidth;
-
- if (pLastCont->m_oFont.IsEqual(&m_oManager.m_oFont.m_oFont) && pLastCont->m_oBrush.IsEqual(m_pBrush))
- {
- // настройки одинаковые. теперь смотрим, на расположение
- if (fabs(dRight - dTextX) < 0.5)
- {
- // продолжаем слово
- pLastCont->m_oText += oText;
- pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
-
- if (!IsSpaceUtf32(oText))
- {
- if (0 == pLastCont->m_dWidthWithoutSpaces)
- pLastCont->m_dLeftWithoutSpaces = dTextX;
-
- pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
- }
- else if (0 == pLastCont->m_dWidthWithoutSpaces)
- {
- pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
- }
-
- m_dLastTextX = dTextX;
- m_dLastTextY = dBaseLinePos;
- m_dLastTextX_block = m_dLastTextX;
- pLastCont->m_dLastX = dTextX;
- return;
- }
- else if ((dRight < dTextX) && ((dTextX - dRight) < m_oManager.m_dSpaceWidthMM))
- {
- // продолжаем слово с пробелом
- pLastCont->m_oText += uint32_t(' ');
- pLastCont->m_oText += oText;
- pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
-
- if (!IsSpaceUtf32(oText))
- {
- if (0 == pLastCont->m_dWidthWithoutSpaces)
- pLastCont->m_dLeftWithoutSpaces = dTextX;
-
- pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
- }
- else if (0 == pLastCont->m_dWidthWithoutSpaces)
- {
- pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
- }
-
- m_dLastTextX = dTextX;
- m_dLastTextY = dBaseLinePos;
- m_dLastTextX_block = m_dLastTextX;
- pLastCont->m_dLastX = dTextX;
- return;
- }
- else if (fabs(dBaseLinePos - pLastCont->m_dY) < 0.01 &&
- fabs(m_dLastTextY - pLastCont->m_dY) < 0.01 &&
- fabs(m_dLastTextX - pLastCont->m_dLastX) < 0.01)
- {
- // идет текст подряд, но с расстояниями что-то не так. смотрим - если новый текст идет после предыдущего, но
- // просто левее чем предыдущий x + w - то считаем это нормальным. и дописываем слово. корректируя длину
- if (dTextX < dRight && dTextX > pLastCont->m_dLastX)
- {
- // продолжаем слово
- pLastCont->m_oText += oText;
- double dNewW = (dTextX + dTextW - pLastCont->m_dX);
- if (pLastCont->m_dWidth < dNewW)
- pLastCont->m_dWidth = dNewW;
-
- if (!IsSpaceUtf32(oText))
- {
- if (0 == pLastCont->m_dWidthWithoutSpaces)
- pLastCont->m_dLeftWithoutSpaces = dTextX;
-
- pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
- }
- else if (0 == pLastCont->m_dWidthWithoutSpaces)
- {
- pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
- }
-
- m_dLastTextX = dTextX;
- m_dLastTextY = dBaseLinePos;
- m_dLastTextX_block = m_dLastTextX;
- pLastCont->m_dLastX = dTextX;
- return;
-
- }
-
- // еще одна заглушка на большой пробел - добавляем пробел, потом в линии все разрулится через spacing
- if (dTextX > dRight && (dTextX - dRight) < 5 && fabs(m_dLastTextX_block - m_dLastTextX) < 0.01)
- {
- // продолжаем слово с пробелом
- pLastCont->m_oText += uint32_t(' ');
- pLastCont->m_oText += oText;
- pLastCont->m_dWidth = (dTextX + dTextW - pLastCont->m_dX);
-
- if (!IsSpaceUtf32(oText))
- {
- if (0 == pLastCont->m_dWidthWithoutSpaces)
- pLastCont->m_dLeftWithoutSpaces = dTextX;
-
- pLastCont->m_dWidthWithoutSpaces = dTextX + dTextW - pLastCont->m_dLeftWithoutSpaces;
- }
- else if (0 == pLastCont->m_dWidthWithoutSpaces)
- {
- pLastCont->m_dLeftWithoutSpaces = dTextX + dTextW;
- }
-
- m_dLastTextX = dTextX;
- m_dLastTextY = dBaseLinePos;
- m_dLastTextX_block = m_dLastTextX;
- pLastCont->m_dLastX = dTextX;
- return;
- }
- }
- }
-
- // либо пробел большой между словами, либо новый текст левее, либо настройки не те (шрифт, кисть)
- // либо все вместе... просто добавл¤ем новое слово
- CContText* pCont = new CContText();
-
- pCont->m_dX = dTextX;
- pCont->m_dY = dBaseLinePos;
- pCont->m_dLastX = dTextX;
-
- pCont->m_dWidth = dTextW;
- pCont->m_dHeight = dTextH;
-
- if (IsSpaceUtf32(oText))
- {
- pCont->m_dWidthWithoutSpaces = 0;
- pCont->m_dLeftWithoutSpaces = dTextX + dTextW;
- }
- else
- {
- pCont->m_dWidthWithoutSpaces = dTextW;
- pCont->m_dLeftWithoutSpaces = dTextX;
- }
-
- pCont->m_oText = oText;
-
- pCont->m_oFont = m_oManager.m_oFont.m_oFont;
- pCont->m_oBrush = *m_pBrush;
-
- if (bIsPath)
- {
- pCont->m_strPickFontName = m_oManager.m_strCurrentPickFont;
- pCont->m_lPickFontStyle = m_oManager.m_lCurrentPictFontStyle;
- }
-
- pCont->m_dSpaceWidthMM = m_oManager.m_dSpaceWidthMM;
-
- m_pCurrentLine->AddCont(pCont, m_oManager.m_oFont.m_dBaselineOffset);
-
- m_dLastTextX = dTextX;
- m_dLastTextY = dBaseLinePos;
- m_dLastTextX_block = m_dLastTextX;
- }
-
- void Build()
- {
- if (m_bIsDeleteTextClipPage)
- {
- // удалим все линии, которые выходят за границы страницы
- size_t nCount = m_arTextLine.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CTextLine* pTextLine = m_arTextLine[i];
-
- double _top = pTextLine->m_dBaselinePos - pTextLine->m_dHeight;
- double _bottom = pTextLine->m_dBaselinePos;
-
- if (_top >= m_dHeight || _bottom <= 0)
- {
- m_arTextLine.erase(m_arTextLine.begin() + i);
- --i;
- --nCount;
- }
- }
- }
-
- switch (m_eTextAssociationType)
- {
- case TextAssociationTypeBlockChar:
- {
- size_t nCount = m_arTextLine.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CTextLine* pTextLine = m_arTextLine[i];
-
- CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
- pParagraph->m_pManagerLight = &m_oManagerLight;
- pParagraph->m_bIsTextFrameProperties = true;
-
- pParagraph->m_dLeft = pTextLine->m_dX;
- pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
-
- pParagraph->m_arLines.push_back(pTextLine);
-
- m_arParagraphs.push_back(pParagraph);
- }
-
- // удалим все линии
- m_arTextLine.clear();
- break;
- }
- case TextAssociationTypeBlockLine:
- {
- size_t nCount = m_arTextLine.size();
-
- if (0 == nCount)
- break;
-
- CTextLine* pFirstLine = m_arTextLine[0];
-
- CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
- pParagraph->m_pManagerLight = &m_oManagerLight;
- pParagraph->m_bIsTextFrameProperties = true;
-
- pParagraph->m_dLeft = pFirstLine->m_dX;
- pParagraph->m_dTop = pFirstLine->m_dBaselinePos - pFirstLine->m_dHeight - pFirstLine->m_dBaselineOffset;
- double dCurrentTop = pParagraph->m_dTop;
-
- pParagraph->m_arLines.push_back(pFirstLine);
-
- m_arParagraphs.push_back(pParagraph);
-
- for (size_t i = 1; i < nCount; ++i)
- {
- CTextLine* pTextLine = m_arTextLine[i];
-
- CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
- pParagraph->m_pManagerLight = &m_oManagerLight;
- pParagraph->m_bIsTextFrameProperties = true;
-
- if (((fabs(pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pFirstLine->m_dBaselinePos) > STANDART_STRING_HEIGHT_MM) && (pTextLine->m_dX == pFirstLine->m_dX)) ||
- ((pTextLine->m_dX != pFirstLine->m_dX) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos)))
- {
- pParagraph->m_dLeft = pTextLine->m_dX;
- pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
- dCurrentTop = pParagraph->m_dTop;
- }
- else
- {
- pParagraph->m_dLeft = pFirstLine->m_dX;
- pParagraph->m_dTop = dCurrentTop;
- }
-
- pFirstLine = pTextLine;
-
- pParagraph->m_arLines.push_back(pTextLine);
- m_arParagraphs.push_back(pParagraph);
- }
-
- // удалим все линии
- m_arTextLine.clear();
- break;
- }
- case TextAssociationTypePlainLine:
- {
- SortElements(m_arTextLine);
-
- if (true) // merge line
- {
- for (std::vector::iterator iter = m_arTextLine.begin(); iter != m_arTextLine.end(); ++iter)
- {
- (*iter)->Analyze();
- }
- }
-
- Merge(STANDART_STRING_HEIGHT_MM / 3);
-
- double previousStringOffset = 0;
- size_t nCount = m_arTextLine.size();
- for (size_t i = 0; i < nCount; ++i)
- {
- CTextLine* pTextLine = m_arTextLine[i];
-
- CParagraph* pParagraph = new CParagraph(m_eTextAssociationType);
- pParagraph->m_pManagerLight = &m_oManagerLight;
- pParagraph->m_bIsTextFrameProperties = false;
-
-#if 0
- // у рамок нельзя выключить обтекание. поэтому в этом случае нужно конверировать в шейп
- if (pTextLine->IsForceBlock())
- {
- pParagraph->m_bIsTextFrameProperties = true;
- pParagraph->m_dLeft = pTextLine->m_dX;
- pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset;
-
- pParagraph->m_arLines.push_back(pTextLine);
- m_arParagraphs.push_back(pParagraph);
- continue;
- }
-#endif
-
- pParagraph->m_dLeft = pTextLine->m_dX;
-
- double dBeforeSpacing = (pTextLine->m_dBaselinePos - previousStringOffset - pTextLine->m_dHeight - pTextLine->m_dBaselineOffset);
-
- pParagraph->m_dSpaceBefore = std::max(dBeforeSpacing, 0.0);
-
- double dHeight = 1;
- if (pTextLine->m_dHeight != 0)
- {
- dHeight = pTextLine->m_dHeight;
-
- if (dBeforeSpacing < 0)
- dHeight += dBeforeSpacing;
- }
-
- pParagraph->m_dHeight = dHeight;
-
- previousStringOffset = pTextLine->m_dBaselinePos - pTextLine->m_dBaselineOffset;
-
- pParagraph->m_arLines.push_back(pTextLine);
- m_arParagraphs.push_back(pParagraph);
- }
-
- m_arTextLine.clear();
- break;
- }
- }
- }
-
- void Merge(double dAffinity)
- {
- size_t nCount = m_arTextLine.size();
- if (1 < nCount)
- {
- CTextLine* pPrev = m_arTextLine[0];
- for (size_t i = 1; i < nCount; ++i)
- {
- CTextLine* pNext = m_arTextLine[i];
-
- if (fabs(pNext->m_dBaselinePos - pPrev->m_dBaselinePos) < dAffinity)
- {
- pPrev->Merge(pNext);
-
- pNext->m_arConts.clear();
- RELEASEOBJECT(pNext);
-
- m_arTextLine.erase(m_arTextLine.begin() + i);
- --i;
- --nCount;
- continue;
- }
- pPrev = pNext;
- }
- }
- }
-
- void Write(NSStringUtils::CStringBuilder& oWriter)
- {
- // drawings
- size_t nCountDrawings = m_arGraphicItems.size();
- if (0 != nCountDrawings)
- {
- oWriter.WriteString(L"");
-
- for (size_t i = 0; i < nCountDrawings; ++i)
- {
- m_arGraphicItems[i]->ToXml(oWriter);
- }
-
- oWriter.WriteString(L"");
- }
-
- size_t nCountParagraphs = m_arParagraphs.size();
- for (size_t i = 0; i < nCountParagraphs; ++i)
- {
- m_arParagraphs[i]->ToXml(oWriter);
- }
- }
-
- void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter)
- {
- // section
- int lWidthDx = (int)(m_dWidth * c_dMMToDx);
- int lHeightDx = (int)(m_dHeight * c_dMMToDx);
-
- if (!bLastPage)
- oWriter.WriteString(L"");
- else
- oWriter.WriteString(L"");
-
- oWriter.WriteString(L"= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait");
- oWriter.WriteString(L"\"/>");
-
- if (!bLastPage)
- oWriter.WriteString(L"");
- else
- oWriter.WriteString(L"");
- }
- };
+ void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter);
+ };
}