diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index ee46db33ee..059140bc77 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -18,12 +18,12 @@ namespace NSCSS { typedef std::map::const_iterator styles_iterator; - CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point) + CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point), m_dCoreFontSize(DEFAULT_FONT_SIZE) {} CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) : m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), - m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), + m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), m_dCoreFontSize(oStyle.m_dCoreFontSize), m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground), m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){} @@ -116,7 +116,10 @@ namespace NSCSS void CCompiledStyle::AddStyle(const std::map& mStyle, const unsigned int unLevel, const bool& bHardMode) { const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true; - const double dFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE; + const double dParentFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE; + + if (0 == unLevel) + m_dCoreFontSize = dParentFontSize; for (std::pair pPropertie : mStyle) { @@ -128,15 +131,15 @@ namespace NSCSS CASE(L"font"): { m_oFont.SetValue(pPropertie.second, unLevel, bHardMode); - m_oFont.UpdateSize(dFontSize); - m_oFont.UpdateLineHeight(dFontSize); + m_oFont.UpdateSize(dParentFontSize, m_dCoreFontSize); + m_oFont.UpdateLineHeight(dParentFontSize, m_dCoreFontSize); break; } CASE(L"font-size"): CASE(L"font-size-adjust"): { m_oFont.SetSize(pPropertie.second, unLevel, bHardMode); - m_oFont.UpdateSize(dFontSize); + m_oFont.UpdateSize(dParentFontSize, m_dCoreFontSize); break; } CASE(L"font-stretch"): @@ -176,7 +179,7 @@ namespace NSCSS break; m_oMargin.SetValues(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateAll(dFontSize); + m_oMargin.UpdateAll(dParentFontSize, m_dCoreFontSize); break; } CASE(L"margin-top"): @@ -196,7 +199,7 @@ namespace NSCSS break; m_oMargin.SetRight(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateRight(dFontSize); + m_oMargin.UpdateRight(dParentFontSize, m_dCoreFontSize); break; } CASE(L"margin-bottom"): @@ -206,7 +209,7 @@ namespace NSCSS break; m_oMargin.SetBottom(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateBottom(dFontSize); + m_oMargin.UpdateBottom(dParentFontSize, m_dCoreFontSize); break; } CASE(L"margin-left"): @@ -217,7 +220,7 @@ namespace NSCSS break; m_oMargin.SetLeft(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateLeft(dFontSize); + m_oMargin.UpdateLeft(dParentFontSize, m_dCoreFontSize); break; } //PADDING @@ -225,35 +228,35 @@ namespace NSCSS CASE(L"mso-padding-alt"): { m_oPadding.SetValues(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateAll(dFontSize); + m_oPadding.UpdateAll(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-top"): CASE(L"mso-padding-top-alt"): { m_oPadding.SetTop(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateTop(dFontSize); + m_oPadding.UpdateTop(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-right"): CASE(L"mso-padding-right-alt"): { m_oPadding.SetRight(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateRight(dFontSize); + m_oPadding.UpdateRight(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-bottom"): CASE(L"mso-padding-bottom-alt"): { m_oPadding.SetBottom(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateBottom(dFontSize); + m_oPadding.UpdateBottom(dParentFontSize, m_dCoreFontSize); break; } CASE(L"padding-left"): CASE(L"mso-padding-left-alt"): { m_oPadding.SetLeft(pPropertie.second, unLevel, bHardMode); - m_oPadding.UpdateLeft(dFontSize); + m_oPadding.UpdateLeft(dParentFontSize, m_dCoreFontSize); break; } // TEXT diff --git a/Common/3dParty/html/css/src/CCompiledStyle.h b/Common/3dParty/html/css/src/CCompiledStyle.h index 7877945a6b..530e41b4a3 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -22,6 +22,7 @@ namespace NSCSS unsigned short int m_nDpi; UnitMeasure m_UnitMeasure; + double m_dCoreFontSize; public: NSProperties::CFont m_oFont; NSProperties::CIndent m_oMargin; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index fcfc62b0e3..eff2556758 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -2301,32 +2301,32 @@ namespace NSCSS return m_oLeft.SetValue(dValue, unLevel, bHardMode); } - void CIndent::UpdateAll(double dFontSize) + void CIndent::UpdateAll(const double& dParentFontSize, const double& dCoreFontSize) { - UpdateTop (dFontSize); - UpdateRight (dFontSize); - UpdateBottom(dFontSize); - UpdateLeft (dFontSize); + UpdateTop (dParentFontSize, dCoreFontSize); + UpdateRight (dParentFontSize, dCoreFontSize); + UpdateBottom(dParentFontSize, dCoreFontSize); + UpdateLeft (dParentFontSize, dCoreFontSize); } - void CIndent::UpdateTop(double dFontSize) + void CIndent::UpdateTop(const double& dParentFontSize, const double& dCoreFontSize) { - UpdateSide(m_oTop, dFontSize); + UpdateSide(m_oTop, dParentFontSize, dCoreFontSize); } - void CIndent::UpdateRight(double dFontSize) + void CIndent::UpdateRight(const double& dParentFontSize, const double& dCoreFontSize) { - UpdateSide(m_oRight, dFontSize); + UpdateSide(m_oRight, dParentFontSize, dCoreFontSize); } - void CIndent::UpdateBottom(double dFontSize) + void CIndent::UpdateBottom(const double& dParentFontSize, const double& dCoreFontSize) { - UpdateSide(m_oBottom, dFontSize); + UpdateSide(m_oBottom, dParentFontSize, dCoreFontSize); } - void CIndent::UpdateLeft(double dFontSize) + void CIndent::UpdateLeft(const double& dParentFontSize, const double& dCoreFontSize) { - UpdateSide(m_oLeft, dFontSize); + UpdateSide(m_oLeft, dParentFontSize, dCoreFontSize); } const CDigit &CIndent::GetTop() const @@ -2395,13 +2395,15 @@ namespace NSCSS return bTopResult || bRightResult || bBottomResult || bLeftResult; } - void CIndent::UpdateSide(CDigit &oSide, double dFontSize) + void CIndent::UpdateSide(CDigit &oSide, const double& dParentFontSize, const double& dCoreFontSize) { if (oSide.Empty()) return; - if (NSCSS::Em == oSide.GetUnitMeasure() || NSCSS::Rem == oSide.GetUnitMeasure()) - oSide.ConvertTo(NSCSS::Twips, dFontSize); + if (NSCSS::Em == oSide.GetUnitMeasure()) + oSide.ConvertTo(NSCSS::Twips, dParentFontSize); + else if (NSCSS::Rem == oSide.GetUnitMeasure()) + oSide.ConvertTo(NSCSS::Twips, dCoreFontSize); } // FONT @@ -2644,16 +2646,20 @@ namespace NSCSS std::make_pair(L"700", L"bold"), std::make_pair(L"800", L"bold"), std::make_pair(L"900", L"bold")}, unLevel, bHardMode); } - void CFont::UpdateSize(double dFontSize) + void CFont::UpdateSize(const double& dParentFontSize, const double& dCoreFontSize) { - if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure()) - m_oSize.ConvertTo(NSCSS::Point, dFontSize); + if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure()) + m_oSize.ConvertTo(NSCSS::Point, dParentFontSize); + else if (NSCSS::Rem == m_oSize.GetUnitMeasure()) + m_oSize.ConvertTo(NSCSS::Point, dCoreFontSize); } - void CFont::UpdateLineHeight(double dFontSize) + void CFont::UpdateLineHeight(const double& dParentFontSize, const double& dCoreFontSize) { - if (NSCSS::Em == m_oLineHeight.GetUnitMeasure() || NSCSS::Rem == m_oLineHeight.GetUnitMeasure()) - m_oLineHeight.ConvertTo(NSCSS::Twips, dFontSize); + if (NSCSS::Em == m_oLineHeight.GetUnitMeasure()) + m_oLineHeight.ConvertTo(NSCSS::Twips, dParentFontSize); + else if (NSCSS::Rem == m_oLineHeight.GetUnitMeasure()) + m_oLineHeight.ConvertTo(NSCSS::Twips, dCoreFontSize); } bool CFont::Bold() const diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 91a9afb2f9..92713238c2 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -656,11 +656,11 @@ namespace NSCSS bool SetLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetLeft (const double& dValue, unsigned int unLevel, bool bHardMode = false); - void UpdateAll (double dFontSize); - void UpdateTop (double dFontSize); - void UpdateRight (double dFontSize); - void UpdateBottom(double dFontSize); - void UpdateLeft (double dFontSize); + void UpdateAll (const double& dParentFontSize, const double& dCoreFontSize); + void UpdateTop (const double& dParentFontSize, const double& dCoreFontSize); + void UpdateRight (const double& dParentFontSize, const double& dCoreFontSize); + void UpdateBottom(const double& dParentFontSize, const double& dCoreFontSize); + void UpdateLeft (const double& dParentFontSize, const double& dCoreFontSize); const CDigit& GetTop () const; const CDigit& GetRight () const; @@ -675,7 +675,7 @@ namespace NSCSS bool operator!=(const CIndent& oIndent) const; private: bool SetValues(const std::wstring& wsTopValue, const std::wstring& wsRightValue, const std::wstring& wsBottomValue, const std::wstring& wsLeftValue, unsigned int unLevel, bool bHardMode = false); - void UpdateSide(CDigit& oSide, double dFontSize); + void UpdateSide(CDigit& oSide, const double& dParentFontSize, const double& dCoreFontSize); CDigit m_oLeft; CDigit m_oTop; @@ -702,8 +702,8 @@ namespace NSCSS bool SetVariant (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetWeight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - void UpdateSize(double dFontSize); - void UpdateLineHeight(double dFontSize); + void UpdateSize(const double& dParentFontSize, const double& dCoreFontSize); + void UpdateLineHeight(const double& dParentFontSize, const double& dCoreFontSize); void Clear(); diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 2e5ba1eaef..3fdf63a5d1 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -55,6 +55,11 @@ static void replace_all(std::string& s, const std::string& s1, const std::string } } +static bool NodeIsUnprocessed(const std::string& wsTagName) +{ + return "xml" == wsTagName; +} + static bool IsUnckeckedNodes(const std::string& sValue) { return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue); @@ -592,6 +597,9 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde std::string tagname = get_tag_name(node); + if (NodeIsUnprocessed(tagname)) + return; + if (bCheckValidNode) bCheckValidNode = !IsUnckeckedNodes(tagname); diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp index 8303dc2165..e836df1343 100644 --- a/DesktopEditor/common/File.cpp +++ b/DesktopEditor/common/File.cpp @@ -1535,6 +1535,11 @@ namespace NSFile return bIsSuccess; } + bool CFileBinary::IsGlobalTempPathUse() + { + return g_overrideTmpPath.empty() ? false : true; + } + std::wstring CFileBinary::GetTempPath() { if (!g_overrideTmpPath.empty()) diff --git a/DesktopEditor/common/File.h b/DesktopEditor/common/File.h index b8ce97b3f8..b232ef680d 100644 --- a/DesktopEditor/common/File.h +++ b/DesktopEditor/common/File.h @@ -189,6 +189,7 @@ namespace NSFile static void SetTempPath(const std::wstring& strTempPath); static std::wstring GetTempPath(); + static bool IsGlobalTempPathUse(); static std::wstring CreateTempFileWithUniqueName(const std::wstring& strFolderPathRoot, const std::wstring& Prefix); static bool OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName = NULL); diff --git a/DesktopEditor/doctrenderer/docbuilder_p.cpp b/DesktopEditor/doctrenderer/docbuilder_p.cpp index 68add68351..ecc71991a0 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.cpp +++ b/DesktopEditor/doctrenderer/docbuilder_p.cpp @@ -56,7 +56,6 @@ CV8RealTimeWorker::CV8RealTimeWorker(NSDoctRenderer::CDocBuilder* pBuilder, cons CJSContextScope scope(m_context); CJSContext::Embed(false); - CJSContext::Embed(); NSJSBase::CreateDefaults(); JSSmart try_catch = m_context->GetExceptions(); diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h index e82fd1ffdc..a6cca0d4d4 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.h +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -728,22 +728,13 @@ namespace NSDoctRenderer oBuilder.WriteEncodeXmlString(sFolder); oBuilder.WriteString(L"/Editor.bin8192"); - if (!m_bIsNotUseConfigAllFontsDir) - { - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common"); - oBuilder.WriteString(L""); - } - else - { - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); - oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); + oBuilder.WriteString(L""); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(m_strAllFonts); - oBuilder.WriteString(L""); - } + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_strAllFonts); + oBuilder.WriteString(L""); oBuilder.WriteString(L"true"); oBuilder.WriteString(L"./sdkjs/slide/themestrue"); @@ -1054,22 +1045,13 @@ namespace NSDoctRenderer oBuilder.WriteString(L"truetrue"); oBuilder.WriteString(L"464"); - if (!m_bIsNotUseConfigAllFontsDir) - { - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common"); - oBuilder.WriteString(L""); - } - else - { - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); - oBuilder.WriteString(L""); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts)); + oBuilder.WriteString(L""); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(m_strAllFonts); - oBuilder.WriteString(L""); - } + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_strAllFonts); + oBuilder.WriteString(L""); if (!sConvertionParams.empty()) { diff --git a/DesktopEditor/doctrenderer/doctrenderer.cpp b/DesktopEditor/doctrenderer/doctrenderer.cpp index a57464e8cb..ea35778b10 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.cpp +++ b/DesktopEditor/doctrenderer/doctrenderer.cpp @@ -575,7 +575,6 @@ namespace NSDoctRenderer { CJSContextScope scope(context); CJSContext::Embed(false); - CJSContext::Embed(); NSJSBase::CreateDefaults(); JSSmart try_catch = context->GetExceptions(); @@ -1067,7 +1066,6 @@ namespace NSDoctRenderer { CJSContextScope scope(context); CJSContext::Embed(); - CJSContext::Embed(); NSJSBase::CreateDefaults(); JSSmart global = context->GetGlobal(); diff --git a/DesktopEditor/doctrenderer/embed/Default.cpp b/DesktopEditor/doctrenderer/embed/Default.cpp index 52d814ce58..7c5db97160 100644 --- a/DesktopEditor/doctrenderer/embed/Default.cpp +++ b/DesktopEditor/doctrenderer/embed/Default.cpp @@ -4,6 +4,7 @@ #include "./MemoryStreamEmbed.h" #include "./TextMeasurerEmbed.h" #include "./HashEmbed.h" +#include "./GraphicsEmbed.h" namespace NSJSBase { @@ -13,5 +14,6 @@ namespace NSJSBase CJSContext::Embed(); CJSContext::Embed(); CJSContext::Embed(); + CJSContext::Embed(); } } diff --git a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp index 9ef11b3673..918277445f 100644 --- a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp @@ -1,8 +1,128 @@ -#include "GraphicsEmbed.h" +#include "../graphics.h" + +// APPLICATION INFO +class CGraphicsAppImage_private +{ +public: + NSFonts::IApplicationFonts* m_pFonts; + std::wstring m_sFontsDirectory; + std::wstring m_sImagesDirectory; + std::wstring m_sThemesDirectory; + bool m_bIsRgba; + + CGraphicsAppImage_private() + { + m_pFonts = NULL; + m_sFontsDirectory = L""; + m_sImagesDirectory = L""; + m_sThemesDirectory = L""; + m_bIsRgba = false; + } + ~CGraphicsAppImage_private() + { + RELEASEINTERFACE(m_pFonts); + } +}; + +CGraphicsAppImage::CGraphicsAppImage() +{ + m_internal = new CGraphicsAppImage_private(); +} +CGraphicsAppImage::~CGraphicsAppImage() +{ + delete m_internal; +} + +void CGraphicsAppImage::SetFontsDirectory(const std::wstring& dir) +{ + m_internal->m_sFontsDirectory = dir; +} +std::wstring CGraphicsAppImage::GetFontsDirectory() +{ + return m_internal->m_sFontsDirectory; +} + +void CGraphicsAppImage::SetImagesDirectory(const std::wstring& dir) +{ + m_internal->m_sImagesDirectory = dir; +} +std::wstring CGraphicsAppImage::GetImagesDirectory() +{ + return m_internal->m_sImagesDirectory; +} + +void CGraphicsAppImage::SetThemesDirectory(const std::wstring& dir) +{ + m_internal->m_sThemesDirectory = dir; +} +std::wstring CGraphicsAppImage::GetThemesDirectory() +{ + return m_internal->m_sThemesDirectory; +} + +void CGraphicsAppImage::SetFonts(NSFonts::IApplicationFonts* fonts) +{ + m_internal->m_pFonts = fonts; + ADDREFINTERFACE(fonts); +} +NSFonts::IApplicationFonts* CGraphicsAppImage::GetFonts() +{ + return m_internal->m_pFonts; +} + +void CGraphicsAppImage::SetRgba(const bool& isRgba) +{ + m_internal->m_bIsRgba = isRgba; +} +bool CGraphicsAppImage::GetRgba() +{ + return m_internal->m_bIsRgba; +} + +unsigned char* CGraphicsAppImage::GetBits(int& w, int& h) +{ + return NULL; +} +unsigned char* CGraphicsAppImage::AllocBits(const int& w, const int& h) +{ + return new unsigned char[4 * w * h]; +} + +// APPLICATION INFO END + +CGraphicsEmbed::CGraphicsEmbed() : m_pInternal(new NSGraphics::CGraphics()) +{ +} +CGraphicsEmbed::~CGraphicsEmbed() +{ + RELEASEOBJECT(m_pInternal); +} + +CGraphicsAppImage* CGraphicsEmbed::GetAppImage() +{ + return m_pInternal->m_pAppImage; +} + +void CGraphicsEmbed::SetAppImage(CGraphicsAppImage* appImage) +{ + m_pInternal->m_pAppImage = appImage; +} JSSmart CGraphicsEmbed::create(JSSmart Native, JSSmart width_px, JSSmart height_px, JSSmart width_mm, JSSmart height_mm) { - m_pInternal->init((NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject(), width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble()); + NSNativeControl::CNativeControl* pControl = NULL; + if (!Native->isNull()) + { + pControl = (NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject(); + + if (m_pInternal->m_pAppImage) + delete m_pInternal->m_pAppImage; + m_pInternal->m_pAppImage = new CGraphicsAppImage(); + m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory); + m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory); + } + + m_pInternal->init(width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble()); return NULL; } JSSmart CGraphicsEmbed::Destroy() diff --git a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h index 1d386f4d25..68d50c5814 100644 --- a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h +++ b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.h @@ -1,21 +1,55 @@ #ifndef _BUILD_NATIVE_GRAPHICS_EMBED_H_ #define _BUILD_NATIVE_GRAPHICS_EMBED_H_ -#include "../graphics.h" +#include "../../graphics/pro/Fonts.h" #include "../js_internal/js_base.h" +class CGraphicsAppImage_private; +class JS_DECL CGraphicsAppImage +{ +public: + CGraphicsAppImage(); + virtual ~CGraphicsAppImage(); +public: + void SetFontsDirectory(const std::wstring& dir); + std::wstring GetFontsDirectory(); + + void SetImagesDirectory(const std::wstring& dir); + std::wstring GetImagesDirectory(); + + void SetThemesDirectory(const std::wstring& dir); + std::wstring GetThemesDirectory(); + + void SetFonts(NSFonts::IApplicationFonts* fonts); + NSFonts::IApplicationFonts* GetFonts(); + + void SetRgba(const bool& isRgba); + bool GetRgba(); + + virtual unsigned char* GetBits(int& w, int& h); + virtual unsigned char* AllocBits(const int& w, const int& h); + +private: + CGraphicsAppImage_private* m_internal; +}; + +namespace NSGraphics { class CGraphics; } + using namespace NSJSBase; -class CGraphicsEmbed : public CJSEmbedObject +class JS_DECL CGraphicsEmbed : public CJSEmbedObject { public: NSGraphics::CGraphics* m_pInternal; public: - CGraphicsEmbed() : m_pInternal(new NSGraphics::CGraphics()) {} - ~CGraphicsEmbed() { RELEASEOBJECT(m_pInternal); } + CGraphicsEmbed(); + ~CGraphicsEmbed(); virtual void* getObject() override { return (void*)m_pInternal; } + CGraphicsAppImage* GetAppImage(); + void SetAppImage(CGraphicsAppImage* appImage); + public: JSSmart create(JSSmart Native, JSSmart width_px, JSSmart height_px, JSSmart width_mm, JSSmart height_mm); JSSmart Destroy(); diff --git a/DesktopEditor/doctrenderer/graphics.cpp b/DesktopEditor/doctrenderer/graphics.cpp index 005d6738e4..667cc2b68e 100644 --- a/DesktopEditor/doctrenderer/graphics.cpp +++ b/DesktopEditor/doctrenderer/graphics.cpp @@ -10,18 +10,35 @@ #define M_PI 3.14159265358979323846 #endif +#ifdef _DEBUG +//#define ENABLE_GR_LOGS +#endif + namespace NSGraphics { - void CGraphics::init(NSNativeControl::CNativeControl* oNative, double width_px, double height_px, double width_mm, double height_mm) + void CGraphics::init(double width_px, double height_px, double width_mm, double height_mm) { - m_sApplicationImagesDirectory = oNative->m_strImagesDirectory; - m_sApplicationFontsDirectory = oNative->m_strFontsDirectory; -#ifdef _DEBUG - std::wcout << L"init "<< m_sApplicationImagesDirectory << L" " << m_sApplicationFontsDirectory << L" " << width_px << L" " << height_px << L" " << width_mm << L" " << height_mm << std::endl; + if (!m_pAppImage) + return; + + if (NULL == m_pAppImage->GetFonts()) + { + NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); + std::wstring sFontsDir = m_pAppImage->GetFontsDirectory(); + pFonts->InitializeFromFolder(sFontsDir.empty() ? NSFile::GetProcessDirectory() : sFontsDir); + m_pAppImage->SetFonts(pFonts); + RELEASEINTERFACE(pFonts); + } + + NSFonts::IFontManager* pManager = m_pAppImage->GetFonts()->GenerateFontManager(); + +#ifdef ENABLE_GR_LOGS + std::wcout << L"init "<< + m_pAppImage->GetImagesDirectory() << L" " << + m_pAppImage->GetFontsDirectory() << L" " << + width_px << L" " << height_px << L" " << + width_mm << L" " << height_mm << std::endl; #endif - m_pApplicationFonts = NSFonts::NSApplication::Create(); - m_pApplicationFonts->InitializeFromFolder(m_sApplicationFontsDirectory.empty() ? NSFile::GetProcessDirectory() : m_sApplicationFontsDirectory); - NSFonts::IFontManager* pManager = m_pApplicationFonts->GenerateFontManager(); m_pRenderer = NSGraphics::Create(); m_pRenderer->SetFontManager(pManager); @@ -42,7 +59,19 @@ namespace NSGraphics if (nRasterH < 1) nRasterH = 0; } - BYTE* pData = new BYTE[4 * nRasterW * nRasterH]; + int nExistW = 0; + int nExistH = 0; + BYTE* pData = m_pAppImage->GetBits(nExistW, nExistH); + if (pData != NULL) + { + nRasterW = nExistW; + nRasterH = nExistH; + } + else + { + pData = m_pAppImage->AllocBits(nRasterW, nRasterH); + } + unsigned int back = 0xffffff; unsigned int* pData32 = (unsigned int*)pData; unsigned int* pData32End = pData32 + nRasterW * nRasterH; @@ -55,21 +84,21 @@ namespace NSGraphics m_oFrame.put_Stride(4 * nRasterW); m_pRenderer->CreateFromBgraFrame(&m_oFrame); - m_pRenderer->SetSwapRGB(false); + m_pRenderer->SetSwapRGB(m_pAppImage->GetRgba()); m_pRenderer->put_Width(width_mm); m_pRenderer->put_Height(height_mm); } void CGraphics::put_GlobalAlpha(bool enable, double alpha) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_GlobalAlpha " << enable << " " << alpha << std::endl; #endif m_pRenderer->put_GlobalAlphaEnabled(enable, alpha); } void CGraphics::End_GlobalAlpha() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "End_GlobalAlpha " << std::endl; #endif bool bIsInteger = m_pRenderer->get_IntegerGrid(); @@ -86,7 +115,7 @@ namespace NSGraphics } void CGraphics::p_color(int r, int g, int b, int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "p_color " << r << " " << g << " " << b << " " << a << std::endl; #endif m_pRenderer->put_PenColor(r | (g << 8) | (b << 16)); @@ -94,14 +123,14 @@ namespace NSGraphics } void CGraphics::p_width(double w) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "p_width " << w << std::endl; #endif m_pRenderer->put_PenSize(w / 1000.0); } void CGraphics::p_dash(size_t length, double* dash) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "p_dash " << length << std::endl; #endif if(length > 0) @@ -119,7 +148,7 @@ namespace NSGraphics } void CGraphics::b_color1(int r, int g, int b, int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "b_color1 " << r << " " << g << " " << b << " " << a << std::endl; #endif m_pRenderer->put_BrushType(c_BrushTypeSolid); @@ -128,7 +157,7 @@ namespace NSGraphics } void CGraphics::b_color2(int r, int g, int b, int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "b_color2 " << r << " " << g << " " << b << " " << a << std::endl; #endif m_pRenderer->put_BrushColor2(r | (g << 8) | (b << 16)); @@ -136,42 +165,42 @@ namespace NSGraphics } void CGraphics::transform(double sx, double shy, double shx, double sy, double tx, double ty) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "transform " << sx << " " << shy << " " << shx << " " << sy << " " << tx << " " << ty << std::endl; #endif m_pRenderer->SetTransform(sx, shy, shx, sy, tx, ty); } void CGraphics::CalculateFullTransform() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "CalculateFullTransform " << std::endl; #endif m_pRenderer->CalculateFullTransform(); } void CGraphics::_s() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_s " << std::endl; #endif m_pRenderer->PathCommandEnd(); } void CGraphics::_e() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_e " << std::endl; #endif m_pRenderer->PathCommandEnd(); } void CGraphics::_z() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_z " << std::endl; #endif m_pRenderer->PathCommandClose(); } void CGraphics::_m(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_m " << x << " " << y << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -184,7 +213,7 @@ namespace NSGraphics } void CGraphics::_l(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_l " << x << " " << y << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -197,7 +226,7 @@ namespace NSGraphics } void CGraphics::_c (double x1, double y1, double x2, double y2, double x3, double y3) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_c " << x1 << " " << y1 << " " << x2 << " " << y2 << " " << x3 << " " << y3 << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -212,7 +241,7 @@ namespace NSGraphics } void CGraphics::_c2(double x1, double y1, double x2, double y2) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "_c2 " << x1 << " " << y1 << " " << x2 << " " << y2 << std::endl; #endif if (!m_pRenderer->get_IntegerGrid()) @@ -226,28 +255,28 @@ namespace NSGraphics } void CGraphics::ds() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "ds " << std::endl; #endif m_pRenderer->Stroke(); } void CGraphics::df() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "df " << std::endl; #endif m_pRenderer->Fill(); } void CGraphics::save() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "save " << std::endl; #endif - m_oFrame.SaveFile(m_sApplicationImagesDirectory + L"/img.png", _CXIMAGE_FORMAT_PNG); + m_oFrame.SaveFile(m_pAppImage->GetImagesDirectory() + L"/img.png", _CXIMAGE_FORMAT_PNG); } void CGraphics::restore() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "restore " << std::endl; #endif m_pRenderer->BeginCommand(c_nResetClipType); @@ -255,7 +284,7 @@ namespace NSGraphics } void CGraphics::clip() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "clip " << std::endl; #endif m_pRenderer->BeginCommand(c_nClipType); @@ -263,43 +292,43 @@ namespace NSGraphics } void CGraphics::reset() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "reset " << std::endl; #endif m_pRenderer->ResetTransform(); } void CGraphics::FreeFont() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "FreeFont " << std::endl; #endif m_pRenderer->CloseFont(); } void CGraphics::ClearLastFont() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "ClearLastFont " << std::endl; #endif m_pRenderer->ClearInstallFont(); } void CGraphics::drawImage(const std::wstring& img, double x, double y, double w, double h, BYTE alpha) { - std::wstring strImage = (0 == img.find(L"theme") ? m_sApplicationThemesDirectory : m_sApplicationImagesDirectory) + L'/' + img; -#ifdef _DEBUG + std::wstring strImage = (0 == img.find(L"theme") ? m_pAppImage->GetThemesDirectory() : m_pAppImage->GetImagesDirectory()) + L'/' + img; +#ifdef ENABLE_GR_LOGS std::wcout << L"drawImage " << strImage << L" " << x << " " << y << L" " << w << L" " << h << L" " << alpha << std::endl; #endif m_pRenderer->DrawImageFromFile(strImage, x, y, w, h, alpha); } std::wstring CGraphics::GetFont() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetFont " << std::endl; #endif return m_pRenderer->GetFontManager()->GetName(); } void CGraphics::SetFont(const std::wstring& name, int face, double size, int style) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"SetFont " << name << L" " << face << L" " << size << L" " << style << std::endl; #endif double DpiX, DpiY; @@ -314,21 +343,21 @@ namespace NSGraphics } void CGraphics::FillText(double x, double y, int text) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"FillText " << (wchar_t)text << L" " << x << L" " << y << std::endl; #endif m_pRenderer->CommandDrawTextCHAR(text, x, y, 0, 0); } void CGraphics::t(double x, double y, const std::wstring& text) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"t " << text << L" " << x << L" " << y << std::endl; #endif m_pRenderer->CommandDrawText(text, x, y, 0, 0); } void CGraphics::tg(int text, double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"tg " << text << L" " << x << L" " << y << std::endl; #endif m_pRenderer->put_FontStringGID(TRUE); @@ -337,21 +366,21 @@ namespace NSGraphics } void CGraphics::SetIntegerGrid(bool param) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "SetIntegerGrid " << param << std::endl; #endif m_pRenderer->put_IntegerGrid(param); } bool CGraphics::GetIntegerGrid() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetIntegerGrid " << std::endl; #endif return m_pRenderer->get_IntegerGrid(); } void CGraphics::DrawStringASCII (const std::wstring& text, double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"DrawStringASCII " << text << L" " << x << L" " << y << std::endl; #endif double DpiY; @@ -373,7 +402,7 @@ namespace NSGraphics } void CGraphics::DrawHeaderEdit(double yPos) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawHeaderEdit " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -416,7 +445,7 @@ namespace NSGraphics } void CGraphics::DrawFooterEdit(double yPos) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawFooterEdit " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -459,7 +488,7 @@ namespace NSGraphics } void CGraphics::DrawLockParagraph (double x, double y1, double y2) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawLockParagraph " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -531,7 +560,7 @@ namespace NSGraphics } void CGraphics::DrawLockObjectRect(double x, double y, double w, double h) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawLockObjectRect " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -557,7 +586,7 @@ namespace NSGraphics } void CGraphics::DrawEmptyTableLine(double x1, double y1, double x2, double y2) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawEmptyTableLine " << std::endl; #endif m_pRenderer->PathCommandEnd(); @@ -642,7 +671,7 @@ namespace NSGraphics } void CGraphics::DrawSpellingLine (double y0, double x0, double x1, double w) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawSpellingLine " << std::endl; #endif Aggplus::CMatrix* pMatrix = m_pRenderer->GetTransformMatrix(); @@ -988,7 +1017,7 @@ namespace NSGraphics } void CGraphics::SaveGrState() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "SaveGrState " << std::endl; #endif CGrStateState* pState = new CGrStateState(); @@ -1004,7 +1033,7 @@ namespace NSGraphics } void CGraphics::RestoreGrState() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "RestoreGrState " << std::endl; #endif if (m_oGrState.States.empty()) @@ -1068,14 +1097,14 @@ namespace NSGraphics } void CGraphics::StartClipPath() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "StartClipPath " << std::endl; #endif m_pRenderer->BeginCommand(c_nClipType); } void CGraphics::EndClipPath() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "EndClipPath " << std::endl; #endif m_pRenderer->EndCommand(c_nClipType); @@ -1133,7 +1162,7 @@ namespace NSGraphics } std::string CGraphics::toDataURL(std::wstring type) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << "toDataURL " << type << std::endl; #endif std::wstring sFormat = (type.length() > 6) ? type.substr(6) : type; @@ -1178,11 +1207,11 @@ namespace NSGraphics { if (src.find(L"data:") == 0) { - std::wstring strImage = m_sApplicationImagesDirectory + L"/texture.png"; + std::wstring strImage = m_pAppImage->GetImagesDirectory() + L"/texture.png"; bool bIsOnlyOfficeHatch = false; if(src.find(L"onlyoffice_hatch") != std::wstring::npos) bIsOnlyOfficeHatch = true; -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"put_brushTexture " << src << L" " << type << std::endl; #endif src.erase(0, src.find(L',') + 1); @@ -1221,7 +1250,7 @@ namespace NSGraphics } else { - std::wstring strImage = (0 == src.find(L"theme") ? m_sApplicationThemesDirectory : m_sApplicationImagesDirectory) + L'/' + src; + std::wstring strImage = (0 == src.find(L"theme") ? m_pAppImage->GetThemesDirectory() : m_pAppImage->GetImagesDirectory()) + L'/' + src; std::wstring sName = strImage.substr(0, strImage.rfind(L'.') + 1); std::wstring sExt = src.substr(src.rfind(L'.') + 1); if (sExt == L"svg") @@ -1244,7 +1273,7 @@ namespace NSGraphics } else sName += sExt; -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::wcout << L"put_brushTexture " << sName << L" " << type << std::endl; #endif m_pRenderer->put_BrushType(c_BrushTypeTexture); @@ -1254,21 +1283,21 @@ namespace NSGraphics } void CGraphics::put_brushTextureMode(int mode) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_brushTextureMode " << mode << std::endl; #endif m_pRenderer->put_BrushTextureMode(mode); } void CGraphics::put_BrushTextureAlpha(int a) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_BrushTextureAlpha " << a << std::endl; #endif m_pRenderer->put_BrushTextureAlpha(a == 0 ? 255 : a); } void CGraphics::put_BrushGradient(LONG* pColors, double* pPositions, size_t nCount, double x0, double y0, double x1, double y1, double r0, double r1) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_BrushGradient " << nCount << " " << x0 << " " << y0 << " " << x1 << " " << y1 << " " << r0 << " " << r1 << std::endl; for (size_t i = 0; i < nCount; i++) std::cout << pPositions[i] << " " << pColors[i] << " "; @@ -1293,7 +1322,7 @@ namespace NSGraphics } double CGraphics::TransformPointX(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "TransformPointX " << std::endl; #endif m_pRenderer->GetFullTransform()->TransformPoint(x, y); @@ -1301,7 +1330,7 @@ namespace NSGraphics } double CGraphics::TransformPointY(double x, double y) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "TransformPointY " << std::endl; #endif m_pRenderer->GetFullTransform()->TransformPoint(x, y); @@ -1309,14 +1338,14 @@ namespace NSGraphics } void CGraphics::put_LineJoin(int nJoin) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_LineJoin " << std::endl; #endif m_pRenderer->put_PenLineJoin(nJoin); } int CGraphics::GetLineJoin() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetLineJoin " << std::endl; #endif BYTE nRes; @@ -1325,7 +1354,7 @@ namespace NSGraphics } void CGraphics::put_TextureBounds(double x, double y, double w, double h) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "put_TextureBounds " << x << " " << y << " " << w << " " << h << std::endl; #endif if(m_pRenderer->get_IntegerGrid()) @@ -1341,7 +1370,7 @@ namespace NSGraphics } double CGraphics::GetlineWidth() { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "GetlineWidth " << std::endl; #endif double nRes; @@ -1350,7 +1379,7 @@ namespace NSGraphics } void CGraphics::DrawPath(int path) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "DrawPath " << path << std::endl; #endif if(path == 257) @@ -1363,7 +1392,7 @@ namespace NSGraphics } void CGraphics::CoordTransformOffset(double tx, double ty) { -#ifdef _DEBUG +#ifdef ENABLE_GR_LOGS std::cout << "CoordTransformOffset " << tx << " " << ty << std::endl; #endif m_pRenderer->SetCoordTransformOffset(tx, ty); diff --git a/DesktopEditor/doctrenderer/graphics.h b/DesktopEditor/doctrenderer/graphics.h index 68683c3329..c0939e9483 100644 --- a/DesktopEditor/doctrenderer/graphics.h +++ b/DesktopEditor/doctrenderer/graphics.h @@ -7,6 +7,7 @@ #include "../common/File.h" #include "nativecontrol.h" #include "../graphics/pro/Graphics.h" +#include "embed/GraphicsEmbed.h" namespace NSGraphics { @@ -114,28 +115,35 @@ namespace NSGraphics class CGraphics { public: - std::wstring m_sApplicationFontsDirectory; - std::wstring m_sApplicationImagesDirectory; - std::wstring m_sApplicationThemesDirectory; + CGraphicsAppImage* m_pAppImage; + CBgraFrame m_oFrame; private: NSFonts ::IApplicationFonts* m_pApplicationFonts; NSGraphics::IGraphicsRenderer* m_pRenderer; - CBgraFrame m_oFrame; CGrState m_oGrState; public: - CGraphics() {} + CGraphics() + { + m_pAppImage = NULL; + } ~CGraphics() { Destroy(); } - void init(NSNativeControl::CNativeControl* oNative, double width_px, double height_px, double width_mm, double height_mm); + void init(double width_px, double height_px, double width_mm, double height_mm); void Destroy() { + int w, h; + if (m_pAppImage->GetBits(w, h)) + m_oFrame.put_Data(NULL); + RELEASEINTERFACE(m_pRenderer); RELEASEINTERFACE(m_pApplicationFonts); + + RELEASEOBJECT(m_pAppImage); } void EndDraw() {} void put_GlobalAlpha(bool enable, double globalAlpha); diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index a30f58ce8d..003ed3a1eb 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -488,7 +488,11 @@ namespace NSJSBase virtual CJSEmbedObject* getNative() { + if (0 == value->InternalFieldCount()) + return NULL; v8::Handle field = v8::Handle::Cast(value->GetInternalField(0)); + if (field.IsEmpty()) + return NULL; return (CJSEmbedObject*)field->Value(); } diff --git a/DesktopEditor/doctrenderer/json/json.cpp b/DesktopEditor/doctrenderer/json/json.cpp index 9126c91e9e..7435043072 100644 --- a/DesktopEditor/doctrenderer/json/json.cpp +++ b/DesktopEditor/doctrenderer/json/json.cpp @@ -99,6 +99,11 @@ namespace NSJSON return m_internal->m_type == CTypedValue::vtObject; } + bool IValue::IsImage() const + { + return m_internal->m_type == CTypedValue::vtImage; + } + bool IValue::ToBool() const { if (m_internal->m_type != CTypedValue::vtPrimitive) @@ -350,6 +355,11 @@ namespace NSJSON strRes += "}"; break; } + case CTypedValue::vtImage: + { + // TODO: implement like typed array? + break; + } } return strRes; @@ -497,6 +507,82 @@ namespace NSJSON return static_cast(m_internal->m_value.get())->getPropertyNames(); } + const BYTE* IValue::GetImageBits() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return nullptr; + } + return static_cast(m_internal->m_value.get())->getBits(); + } + + BYTE* IValue::GetImageBits() + { + return const_cast(static_cast(*this).GetImageBits()); + } + + int IValue::GetImageWidth() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + return static_cast(m_internal->m_value.get())->getWidth(); + } + + int IValue::GetImageHeight() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return 0; + } + return static_cast(m_internal->m_value.get())->getHeight(); + } + + ImageFormat IValue::GetImageFormat() const + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return ImageFormat::ifInvalid; + } + return static_cast(m_internal->m_value.get())->getFormat(); + } + + void IValue::ImageExternalize() + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return; + } + static_cast(m_internal->m_value.get())->externalize(); + } + + void IValue::ImageAlloc(const int& width, const int& height, const ImageFormat& format) + { + if (m_internal->m_type != CTypedValue::vtImage) + { +#ifdef JSON_DEBUG + throw std::bad_cast(); +#endif + return; + } + static_cast(m_internal->m_value.get())->alloc(width, height, format); + } CValue::CValue() : IValue() { @@ -590,6 +676,35 @@ namespace NSJSON NSJSBase::NSAllocator::Free(data, size); } + CValue CValue::CreateImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize) + { + CValue ret; + if (width <= 0 || height <= 0) + return ret; + + ret.m_internal->m_value = std::make_shared(bits, width, height, format, isExternalize); + ret.m_internal->m_type = CTypedValue::vtImage; + return ret; + } + + CValue CValue::CreateEmptyImage(ImageFormat format) + { + CValue ret; + ret.m_internal->m_value = std::make_shared((BYTE*)NULL, 0, 0, format, false); + ret.m_internal->m_type = CTypedValue::vtImage; + return ret; + } + + BYTE* CValue::AllocImageBits(int width, int height) + { + return new BYTE[4 * width * height]; + } + + void CValue::FreeImageBits(BYTE* bits) + { + delete[] bits; + } + CValue CValue::CreateObject() { CValue ret; diff --git a/DesktopEditor/doctrenderer/json/json.h b/DesktopEditor/doctrenderer/json/json.h index ada6baaf03..429a3db020 100644 --- a/DesktopEditor/doctrenderer/json/json.h +++ b/DesktopEditor/doctrenderer/json/json.h @@ -20,7 +20,7 @@ #endif // uncomment to enable exceptions throwing -//#define JSON_DEBUG +// #define JSON_DEBUG #ifdef JSON_DEBUG #include @@ -29,6 +29,14 @@ namespace NSJSON { typedef unsigned char BYTE; + + enum class ImageFormat + { + ifRGBA, + ifBGRA, + ifARGB, + ifInvalid + }; class CValue; class CValueRef; @@ -88,6 +96,10 @@ namespace NSJSON * Returns true if the value is an object. */ bool IsObject() const; + /** + * Returns true if the value is an image. + */ + bool IsImage() const; // FUNCTIONS FOR WORKING WITH PRIMITIVE VALUES /** @@ -193,6 +205,39 @@ namespace NSJSON */ std::vector GetPropertyNames() const; + // FUNCTIONS FOR WORKING WITH IMAGES + /** + * Gets bits of image. + * @return the pointer to memory, allocated for the image. If current value is not an image, returns nullptr. + */ + const BYTE* GetImageBits() const; + BYTE* GetImageBits(); + /** + * Gets width of the image. + * @returns Returns the width of the image. If current value is not an image, returns 0. + */ + int GetImageWidth() const; + /** + * Gets height of the image. + * @returns Returns the height of the image. If current value is not an image, returns 0. + */ + int GetImageHeight() const; + /** + * Gets format of the image. + * @returns Returns the image format. If current value is not an image, returns ImageFormat::ifInvalid. + */ + ImageFormat GetImageFormat() const; + + /** + * Make image bits external. + */ + void ImageExternalize(); + + /** + * Alloc image bits as internal. + */ + void ImageAlloc(const int& width, const int& height, const ImageFormat& format); + protected: std::shared_ptr m_internal; }; @@ -251,6 +296,30 @@ namespace NSJSON */ static void FreeTypedArray(BYTE* data, size_t size); + // IMAGE + /** + * Creates and returns new image object. + * @param bits The pointer to image data. The pointer should be acquired with AllocImageBits(). + * @param width The width of the image. + * @param height The height of the image. + * @param format The format of the image. + * @param isExternalize If true the memory will not be reclaimed when the created image is destroyed. + * If this parameter is false then the memory will be released using FreeImageBits() during the image object destruction. + */ + static CValue CreateImage(BYTE* bits, int width, int height, ImageFormat format = ImageFormat::ifBGRA, bool isExternalize = true); + static CValue CreateEmptyImage(ImageFormat format = ImageFormat::ifBGRA); + /** + * Allocates the memory for an image. + * @param width The width of the image. + * @param height The height of the image. + */ + static BYTE* AllocImageBits(int width, int height); + /** + * Frees the memory for a image bits. + * @param data The allocated memory to be released. + */ + static void FreeImageBits(BYTE* bits); + // OBJECT CONSTRUCTOR /** * Creates and returns empty object. diff --git a/DesktopEditor/doctrenderer/json/json_p.h b/DesktopEditor/doctrenderer/json/json_p.h index 0198a402d0..903dac7845 100644 --- a/DesktopEditor/doctrenderer/json/json_p.h +++ b/DesktopEditor/doctrenderer/json/json_p.h @@ -17,7 +17,8 @@ namespace NSJSON vtPrimitive, vtArray, vtTypedArray, - vtObject + vtObject, + vtImage }; public: diff --git a/DesktopEditor/doctrenderer/json/json_values.cpp b/DesktopEditor/doctrenderer/json/json_values.cpp index 3b745cbbb8..bddf10a660 100644 --- a/DesktopEditor/doctrenderer/json/json_values.cpp +++ b/DesktopEditor/doctrenderer/json/json_values.cpp @@ -211,4 +211,56 @@ namespace NSJSON } return ret; } + + CImage::CImage(BYTE* bits, const int& width, const int& height, const ImageFormat& format, const bool& isExternalize) : + m_bits(bits), m_width(width), m_height(height), m_format(format), m_isExternalize(isExternalize) + { + } + + CImage::~CImage() + { + if (!m_isExternalize) + { + CValue::FreeImageBits(m_bits); + } + } + + void CImage::alloc(const int& width, const int& height, const ImageFormat& format) + { + if (!m_isExternalize && m_bits) + { + CValue::FreeImageBits(m_bits); + } + + m_bits = CValue::AllocImageBits(width, height); + m_width = width; + m_height = height; + m_format = format; + m_isExternalize = false; + } + + BYTE* CImage::getBits() + { + return m_bits; + } + + int CImage::getWidth() + { + return m_width; + } + + int CImage::getHeight() + { + return m_height; + } + + ImageFormat CImage::getFormat() + { + return m_format; + } + + void CImage::externalize() + { + m_isExternalize = true; + } } diff --git a/DesktopEditor/doctrenderer/json/json_values.h b/DesktopEditor/doctrenderer/json/json_values.h index e3c01ecaf4..af5693d57d 100644 --- a/DesktopEditor/doctrenderer/json/json_values.h +++ b/DesktopEditor/doctrenderer/json/json_values.h @@ -113,6 +113,28 @@ namespace NSJSON private: storage_t m_values; }; -} + + class CImage : public IBaseValue + { + public: + CImage(BYTE* bits, const int& width, const int& height, const ImageFormat& format, const bool& isExternalize = true); + ~CImage(); + + public: + BYTE* getBits(); + int getWidth(); + int getHeight(); + ImageFormat getFormat(); + void externalize(); + void alloc(const int& width, const int& height, const ImageFormat& format); + + private: + BYTE* m_bits; + int m_width; + int m_height; + ImageFormat m_format; + bool m_isExternalize; + }; +} // namespace #endif // JSON_VALUES_H_ diff --git a/DesktopEditor/doctrenderer/json/serialization.h b/DesktopEditor/doctrenderer/json/serialization.h index 07a75a3868..4f681c3503 100644 --- a/DesktopEditor/doctrenderer/json/serialization.h +++ b/DesktopEditor/doctrenderer/json/serialization.h @@ -3,9 +3,75 @@ #include "json.h" #include "../js_internal/js_base.h" +#include "../embed/GraphicsEmbed.h" #include +class CAppImageTo : public CGraphicsAppImage +{ +private: + NSJSON::CValueRef* m_image; + +public: + CAppImageTo(const NSJSON::CValue& image) : CGraphicsAppImage() + { + m_image = new NSJSON::CValueRef(image); + } + virtual ~CAppImageTo() + { + if (m_image) + delete m_image; + } + +public: + virtual unsigned char* GetBits(int& w, int& h) + { + unsigned char* bits = m_image->GetImageBits(); + if (NULL != bits) + { + w = m_image->GetImageWidth(); + h = m_image->GetImageHeight(); + } + return bits; + } + virtual unsigned char* AllocBits(const int& w, const int& h) + { + m_image->ImageAlloc(w, h, GetRgba() ? NSJSON::ImageFormat::ifRGBA : NSJSON::ImageFormat::ifBGRA); + return m_image->GetImageBits(); + } +}; + +class CAppImageFrom : public CGraphicsAppImage +{ +public: + unsigned char* m_pData; + int m_nW; + int m_nH; +public: + CAppImageFrom() : CGraphicsAppImage() + { + m_pData = NULL; + m_nW = 0; + m_nH = 0; + } + virtual ~CAppImageFrom() + { + } + +public: + virtual unsigned char* GetBits(int& w, int& h) + { + return m_pData; + } + virtual unsigned char* AllocBits(const int& w, const int& h) + { + m_nW = w; + m_nH = h; + m_pData = NSJSON::CValue::AllocImageBits(w, h); + return m_pData; + } +}; + namespace NSJSON { static JSSmart toJS(const CValue& value) @@ -50,6 +116,12 @@ namespace NSJSON JSSmart jsTypedArr = NSJSBase::CJSContext::createUint8Array(const_cast(value.GetData()), value.GetCount()); ret = jsTypedArr->toValue(); } + else if (value.IsImage()) + { + JSSmart wrap = CJSContext::createEmbedObject("CGraphicsEmbed"); + ((CGraphicsEmbed*)wrap->getNative())->SetAppImage(new CAppImageTo(value)); + ret = wrap->toValue(); + } // objects (there is no need for IsObject()) else { @@ -130,6 +202,25 @@ namespace NSJSON else if (jsValue->isObject()) { JSSmart jsObj = jsValue->toObject(); + + CJSEmbedObject* pNative = jsObj->getNative(); + if (pNative != NULL) + { + CGraphicsEmbed* pGrEmbed = dynamic_cast(pNative); + if (pGrEmbed) + { + CAppImageFrom* pAppImage = dynamic_cast(pGrEmbed->GetAppImage()); + if (pAppImage) + { + return NSJSON::CValue::CreateImage(pAppImage->m_pData, + pAppImage->m_nW, + pAppImage->m_nH, + pAppImage->GetRgba() ? ImageFormat::ifRGBA : ImageFormat::ifBGRA, + false); + } + } + } + std::vector properties = jsObj->getPropertyNames(); ret = CValue::CreateObject(); for (const std::string& name : properties) diff --git a/DesktopEditor/doctrenderer/test/json/main.cpp b/DesktopEditor/doctrenderer/test/json/main.cpp index 61e945e8ef..e5c6a0e52d 100644 --- a/DesktopEditor/doctrenderer/test/json/main.cpp +++ b/DesktopEditor/doctrenderer/test/json/main.cpp @@ -467,6 +467,62 @@ TEST_F(CJSONTest, object) EXPECT_FALSE(compare(obj, jsObj->toValue(), false)); } +TEST_F(CJSONTest, image_externalize) +{ + int width = 1080; + int height = 480; + BYTE* bits = CValue::AllocImageBits(width, height); + CValue img = CValue::CreateImage(bits, width, height, ifBGRA); + + EXPECT_TRUE(img.IsImage()); + EXPECT_EQ(img.GetImageBits(), bits); + EXPECT_EQ(img.GetImageWidth(), width); + EXPECT_EQ(img.GetImageHeight(), height); + EXPECT_EQ(img.GetImageFormat(), ifBGRA); + + CValue::FreeImageBits(bits); + + width = 50; + height = 100; + bits = CValue::AllocImageBits(width, height); + img = CValue::CreateImage(bits, width, height, ifRGBA); + + EXPECT_TRUE(img.IsImage()); + EXPECT_EQ(img.GetImageBits(), bits); + EXPECT_EQ(img.GetImageWidth(), width); + EXPECT_EQ(img.GetImageHeight(), height); + EXPECT_EQ(img.GetImageFormat(), ifRGBA); + + CValue::FreeImageBits(bits); +} + +TEST_F(CJSONTest, image_not_externalize) +{ + int width = 320; + int height = 480; + BYTE* bits = CValue::AllocImageBits(width, height); + CValue img = CValue::CreateImage(bits, width, height, ifARGB, false); + + EXPECT_TRUE(img.IsImage()); + EXPECT_EQ(img.GetImageBits(), bits); + EXPECT_EQ(img.GetImageWidth(), width); + EXPECT_EQ(img.GetImageHeight(), height); + EXPECT_EQ(img.GetImageFormat(), ifARGB); +} + +TEST_F(CJSONTest, image_wrong_size) +{ + BYTE* bits = CValue::AllocImageBits(100, 100); + CValue img = CValue::CreateImage(bits, 0, 100, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); + img = CValue::CreateImage(bits, -1, 100, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); + img = CValue::CreateImage(bits, 0, 0, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); + img = CValue::CreateImage(bits, -100, -100, ifARGB, false); + EXPECT_TRUE(img.IsUndefined()); +} + TEST_F(CJSONTest, references) { CValue val = 42; @@ -526,12 +582,20 @@ TEST_F(CJSONTest, wrong_usage) EXPECT_THROW(val.GetPropertyNames(), std::bad_cast); EXPECT_THROW(val.GetCount(), std::bad_cast); EXPECT_THROW(val.GetData(), std::bad_cast); + EXPECT_THROW(val.GetImageBits(), std::bad_cast); + EXPECT_THROW(val.GetImageFormat(), std::bad_cast); + EXPECT_THROW(val.GetImageHeight(), std::bad_cast); + EXPECT_THROW(val.GetImageWidth(), std::bad_cast); #else EXPECT_TRUE(val["name"].IsUndefined()); EXPECT_TRUE(val[0].IsUndefined()); EXPECT_TRUE(val.GetPropertyNames().empty()); EXPECT_EQ(val.GetCount(), 0); EXPECT_EQ(val.GetData(), nullptr); + EXPECT_EQ(val.GetImageBits(), nullptr); + EXPECT_EQ(val.GetImageFormat(), ifInvalid); + EXPECT_EQ(val.GetImageHeight(), 0); + EXPECT_EQ(val.GetImageWidth(), 0); #endif EXPECT_DOUBLE_EQ(val.ToDouble(), 42.0); #ifdef JSON_DEBUG @@ -1601,7 +1665,11 @@ TEST_F(CJSONTest, FromJSON_arrays) CValue val = CValue::FromJSON(strJson); EXPECT_TRUE(val.IsArray()); EXPECT_EQ(val.GetCount(), 0); +#ifndef JSON_DEBUG EXPECT_TRUE(val[0].IsUndefined()); +#else + EXPECT_THROW(val[0], std::out_of_range); +#endif strJson = "[1, 2, 3]"; val = CValue::FromJSON(strJson); diff --git a/DesktopEditor/graphics/BooleanOperations.cpp b/DesktopEditor/graphics/BooleanOperations.cpp index d2d50a6a94..557d5981b7 100644 --- a/DesktopEditor/graphics/BooleanOperations.cpp +++ b/DesktopEditor/graphics/BooleanOperations.cpp @@ -312,8 +312,8 @@ PointD Curve::Get(const double& t, const int& type) const noexcept } else if (t > tMax) { - x0 = 3 * (x[3] - y[2]); - y0 = 3 * (y[3] - x[2]); + x0 = 3 * (x[3] - x[2]); + y0 = 3 * (y[3] - y[2]); } else { @@ -369,7 +369,7 @@ Curve Curve::GetPart(double from, double to) const noexcept result.Segment2.HO.X -= result.Segment2.P.X; result.Segment2.HO.Y -= result.Segment2.P.Y; } - else if (to < 1) + if (to < 1) { result = result.Subdivide((to - from) / (1 - from))[0]; result.Segment2.HI.X -= result.Segment2.P.X; @@ -653,8 +653,11 @@ int Curve::SolveCubic(double a, double b, double c, double d, void Curve::Flip() noexcept { + PointD tmpHI = Segment2.P + Segment2.HI; + PointD tmpHO = Segment2.P + Segment2.HO; std::swap(Segment1.P, Segment2.P); - std::swap(Segment1.HI, Segment1.HO); + Segment2.HI = tmpHI - Segment2.P; + Segment2.HO = tmpHO - Segment2.P; } bool Curve::IsStraight() const noexcept @@ -707,12 +710,14 @@ bool Location::IsTouching() noexcept CBooleanOperations::CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, - BooleanOpType op) : + BooleanOpType op, + long fillType) : Op(op), Close1(path1.Is_poly_closed()), Close2(path2.Is_poly_closed()), Path1(path1), - Path2(path2) + Path2(path2), + FillType(fillType) { TraceBoolean(); } @@ -1705,6 +1710,10 @@ void CBooleanOperations::SetWinding() } while (!s.IsEmpty() && !s.Inters && s != start); } } + + if (FillType & c_nStroke) + for (auto& s : Segments2) + s.Winding = 0; } void CBooleanOperations::DivideLocations() @@ -1896,7 +1905,8 @@ void CBooleanOperations::AddOffsets(std::vector& offsets, CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, const CGraphicsPath& path2, - BooleanOpType op) + BooleanOpType op, + long fillType) { std::vector paths1 = path1.GetSubPaths(), paths2 = path2.GetSubPaths(), @@ -1906,7 +1916,7 @@ CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, { for (const auto& p2 : paths2) { - CBooleanOperations operation(p1, p2, op); + CBooleanOperations operation(p1, p2, op, fillType); paths.push_back(operation.GetResult()); } } diff --git a/DesktopEditor/graphics/BooleanOperations.h b/DesktopEditor/graphics/BooleanOperations.h index e35ffb99bc..addb65da6b 100644 --- a/DesktopEditor/graphics/BooleanOperations.h +++ b/DesktopEditor/graphics/BooleanOperations.h @@ -107,7 +107,7 @@ namespace Aggplus class CBooleanOperations { public: - CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op); + CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op, long fillType = c_nWindingFillMode); ~CBooleanOperations(); CGraphicsPath&& GetResult(); @@ -159,6 +159,9 @@ namespace Aggplus bool Close1 = true; bool Close2 = true; + // c_nStroke, c_nWindingFillMode, c_nEvenOddFillMode + long FillType = c_nWindingFillMode; + CGraphicsPath Path1; CGraphicsPath Path2; CGraphicsPath Result; diff --git a/DesktopEditor/graphics/GraphicsPath.h b/DesktopEditor/graphics/GraphicsPath.h index 2ed5d83b6e..1e44a29e75 100644 --- a/DesktopEditor/graphics/GraphicsPath.h +++ b/DesktopEditor/graphics/GraphicsPath.h @@ -189,7 +189,7 @@ namespace Aggplus Exclusion = 3 }; - GRAPHICS_DECL CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op); + GRAPHICS_DECL CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op, long fillType = c_nWindingFillMode); } // namespace Aggplus diff --git a/DesktopEditor/graphics/boolean_operations_math.h b/DesktopEditor/graphics/boolean_operations_math.h index 0eaef891a2..cb0c747fab 100644 --- a/DesktopEditor/graphics/boolean_operations_math.h +++ b/DesktopEditor/graphics/boolean_operations_math.h @@ -242,64 +242,59 @@ void getConvexHull(const double& dq0, const double& dq1, double dist1 = dq1 - (2.0 * dq0 + dq3) / 3.0, dist2 = dq2 - (dq0 + 2.0 * dq3) / 3.0; - std::vector& realTop = top; - std::vector& realBottom = bottom; - if (dist1 < 0.0 || dist2 < 0.0) - { - realTop = bottom; - realBottom = top; - } - if (dist1 * dist2 < 0.0) { - realTop.reserve(3); - realTop.push_back(p0); - realTop.push_back(p1); - realTop.push_back(p3); + top.reserve(3); + top.push_back(p0); + top.push_back(p1); + top.push_back(p3); - realBottom.reserve(3); - realBottom.push_back(p0); - realBottom.push_back(p2); - realBottom.push_back(p3); + bottom.reserve(3); + bottom.push_back(p0); + bottom.push_back(p2); + bottom.push_back(p3); } else { double distRatio = dist1 / dist2; if (distRatio >= 2.0) { - realTop.reserve(3); - realTop.push_back(p0); - realTop.push_back(p1); - realTop.push_back(p3); + top.reserve(3); + top.push_back(p0); + top.push_back(p1); + top.push_back(p3); - realBottom.reserve(2); - realBottom.push_back(p0); - realBottom.push_back(p3); + bottom.reserve(2); + bottom.push_back(p0); + bottom.push_back(p3); } else if (distRatio <= 0.5) { - realTop.reserve(3); - realTop.push_back(p0); - realTop.push_back(p2); - realTop.push_back(p3); + top.reserve(3); + top.push_back(p0); + top.push_back(p2); + top.push_back(p3); - realBottom.reserve(2); - realBottom.push_back(p0); - realBottom.push_back(p3); + bottom.reserve(2); + bottom.push_back(p0); + bottom.push_back(p3); } else { - realTop.reserve(4); - realTop.push_back(p0); - realTop.push_back(p1); - realTop.push_back(p2); - realTop.push_back(p3); + top.reserve(4); + top.push_back(p0); + top.push_back(p1); + top.push_back(p2); + top.push_back(p3); - realBottom.reserve(2); - realBottom.push_back(p0); - realBottom.push_back(p3); + bottom.reserve(2); + bottom.push_back(p0); + bottom.push_back(p3); } } + + if (dist1 < 0.0 || dist2 < 0.0) + std::swap(top, bottom); } double clipConvexHullPart(const std::vector& part, const bool& top, diff --git a/DesktopEditor/raster/Metafile/Common/MetaFile.h b/DesktopEditor/raster/Metafile/Common/MetaFile.h index 0bd2dbc146..4e0d19f671 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFile.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFile.h @@ -45,7 +45,7 @@ namespace MetaFile { public: IMetaFileBase() - : m_pOutput(NULL), m_pBufferData(NULL), m_bIsExternalBuffer(false), m_bError(false), m_pParent(NULL) + : m_pOutput(NULL), m_pParent(NULL), m_pBufferData(NULL), m_bIsExternalBuffer(false), m_bError(false) { m_oStream.SetStream(NULL, 0); } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp index 2f4611c6d1..1a2691ff62 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.cpp @@ -1113,4 +1113,58 @@ namespace MetaFile return wsValue; } + + std::wstring ConvertToUnicode(const unsigned char* pText, unsigned long unLength, unsigned short uchCharSet) + { + NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;; + + // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 + // http://msdn.microsoft.com/en-us/library/cc194829.aspx + // Charset Name Charset Value(hex) Codepage number + // ------------------------------------------------------ + // + // DEFAULT_CHARSET 1 (x01) + // SYMBOL_CHARSET 2 (x02) + // OEM_CHARSET 255 (xFF) + // ANSI_CHARSET 0 (x00) 1252 + // RUSSIAN_CHARSET 204 (xCC) 1251 + // EASTEUROPE_CHARSET 238 (xEE) 1250 + // GREEK_CHARSET 161 (xA1) 1253 + // TURKISH_CHARSET 162 (xA2) 1254 + // BALTIC_CHARSET 186 (xBA) 1257 + // HEBREW_CHARSET 177 (xB1) 1255 + // ARABIC _CHARSET 178 (xB2) 1256 + // SHIFTJIS_CHARSET 128 (x80) 932 + // HANGEUL_CHARSET 129 (x81) 949 + // GB2313_CHARSET 134 (x86) 936 + // CHINESEBIG5_CHARSET 136 (x88) 950 + // THAI_CHARSET 222 (xDE) 874 + // JOHAB_CHARSET 130 (x82) 1361 + // VIETNAMESE_CHARSET 163 (xA3) 1258 + + switch (uchCharSet) + { + default: + case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; + case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; + case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; + case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; + case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; + case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; + case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; + case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; + case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; + case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; + case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; + case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; + case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; + case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; + case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; + case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; + case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; + } + + return NSStringExt::CConverter::GetUnicodeFromSingleByteString(pText, unLength, eCharSet); + } + } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h index 0001315f0b..9b792aca08 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h @@ -47,6 +47,7 @@ namespace MetaFile { bool Equals(double dFirst, double dSecond, double dEpsilon = DBL_EPSILON); + std::wstring ConvertToUnicode(const unsigned char* pText, unsigned long unLength, unsigned short uchCharSet); struct TRgbQuad { diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp index 8ea0af97cd..8565cbe918 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp @@ -1167,23 +1167,29 @@ namespace MetaFile arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)}); - std::wstring wsFontName = pFont->GetFaceName(); + NSStringUtils::CStringBuilder oFontName; + oFontName.WriteEncodeXmlString(pFont->GetFaceName()); -#ifndef BUILDING_WASM_MODULE - if (!wsFontName.empty()) + if (0 != oFontName.GetSize()) { + #ifndef BUILDING_WASM_MODULE NSFonts::CFontSelectFormat oFormat; oFormat.wsName = new std::wstring(pFont->GetFaceName()); NSFonts::CFontInfo *pFontInfo = m_pParser->GetFontManager()->GetFontInfoByParams(oFormat); - if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) - wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; + if (NULL != pFontInfo && !StringEquals(*oFormat.wsName, pFontInfo->m_wsFontName)) + { + oFontName.Clear(); + oFontName.WriteEncodeXmlString(L"\'"); + oFontName.WriteEncodeXmlString(*oFormat.wsName); + oFontName.WriteEncodeXmlString(L"\',\'"); + oFontName.WriteEncodeXmlString(pFontInfo->m_wsFontName); + oFontName.WriteEncodeXmlString(L"\'"); + } + #endif + arNodeAttributes.push_back({L"font-family", oFontName.GetData()}); } -#endif - - if (!wsFontName.empty()) - arNodeAttributes.push_back({L"font-family", wsFontName}); if (pFont->GetWeight() > 550) arNodeAttributes.push_back({L"font-weight", L"bold"}); diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp index 18423b0fc0..5582b42aa6 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp @@ -454,60 +454,10 @@ namespace MetaFile return SetError(); const IFont* pFont = GetFont(); - NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; - if (pFont) - { - // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 - // http://msdn.microsoft.com/en-us/library/cc194829.aspx - // Charset Name Charset Value(hex) Codepage number - // ------------------------------------------------------ - // - // DEFAULT_CHARSET 1 (x01) - // SYMBOL_CHARSET 2 (x02) - // OEM_CHARSET 255 (xFF) - // ANSI_CHARSET 0 (x00) 1252 - // RUSSIAN_CHARSET 204 (xCC) 1251 - // EASTEUROPE_CHARSET 238 (xEE) 1250 - // GREEK_CHARSET 161 (xA1) 1253 - // TURKISH_CHARSET 162 (xA2) 1254 - // BALTIC_CHARSET 186 (xBA) 1257 - // HEBREW_CHARSET 177 (xB1) 1255 - // ARABIC _CHARSET 178 (xB2) 1256 - // SHIFTJIS_CHARSET 128 (x80) 932 - // HANGEUL_CHARSET 129 (x81) 949 - // GB2313_CHARSET 134 (x86) 936 - // CHINESEBIG5_CHARSET 136 (x88) 950 - // THAI_CHARSET 222 (xDE) 874 - // JOHAB_CHARSET 130 (x82) 1361 - // VIETNAMESE_CHARSET 163 (xA3) 1258 - - switch (pFont->GetCharSet()) - { - default: - case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; - case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; - case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; - case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; - case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; - case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; - case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; - case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; - case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; - case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; - case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; - case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; - case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; - case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; - case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; - } - } - - std::wstring wsText = NSStringExt::CConverter::GetUnicodeFromSingleByteString((unsigned char*)oText.pOutputString, oText.unChars, eCharSet); + std::wstring wsText = ConvertToUnicode(oText.pOutputString, oText.unChars, (NULL != pFont) ? pFont->GetCharSet() : DEFAULT_CHARSET); int* pDx = NULL; - if (oText.pOutputDx) + if (oText.pOutputDx && oText.unChars == wsText.length()) { pDx = new int[oText.unChars]; if (pDx) @@ -538,7 +488,7 @@ namespace MetaFile unsigned int unLen = 0; int* pDx = NULL; - if (oText.pOutputDx && oText.unChars) + if (oText.pOutputDx && oText.unChars && oText.unChars == wsText.length()) { // Здесь мы эмулируем конвертацию Utf16 в Utf32, чтобы правильно получить массив pDx pDx = new int[oText.unChars]; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index 2935fabc23..040d75f594 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -1416,7 +1416,7 @@ namespace MetaFile return true; } - BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, TRectL& oNewRect, unsigned int& nWidth, unsigned int& nHeight) + BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, const TRectL& oNewRect, unsigned int& nWidth, unsigned int& nHeight) { if (NULL == pBuffer) return NULL; @@ -1432,6 +1432,10 @@ namespace MetaFile if (nBeginY >= lHeight || nEndY <= 0) return NULL; + if (nBeginX <= 0 && nEndX >= lWidth && + nBeginY <= 0 && nEndY >= lHeight) + return NULL; + if (nBeginX < 0) nBeginX = 0; if (nBeginY < 0) @@ -1625,18 +1629,15 @@ namespace MetaFile TRectL oClipRect; - oClipRect.Left = std::floor(oSrcRect.dX * dScale); - oClipRect.Top = std::floor(oSrcRect.dY * dScale); - oClipRect.Right = std::floor((oSrcRect.dX + oSrcRect.dWidth) * dScale); - oClipRect.Bottom = std::floor((oSrcRect.dY + oSrcRect.dHeight) * dScale); + oClipRect.Left = std::floor((oSrcRect.dX - oFileBounds.Left) * dScale); + oClipRect.Top = std::floor((oSrcRect.dY - oFileBounds.Top) * dScale); + oClipRect.Right = std::floor((oSrcRect.dX + oSrcRect.dWidth - oFileBounds.Left) * dScale); + oClipRect.Bottom = std::floor((oSrcRect.dY + oSrcRect.dHeight - oFileBounds.Top) * dScale); unsigned int nW = (unsigned int)nWidth; unsigned int nH = (unsigned int)nHeight; BYTE* pNewBuffer = GetClipedImage(pPixels, nWidth, nHeight, oClipRect, nW, nH); - const unsigned int unWidth = std::min(((unsigned int)abs(oClipRect.Right - oClipRect.Left)), ((unsigned int)nWidth )); - const unsigned int unHeight = std::min(((unsigned int)abs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)nHeight)); - m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(), (NULL != pNewBuffer) ? pNewBuffer : pPixels, nW, nH); diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp b/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp index c022422160..529ae2dfd4 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlayer.cpp @@ -716,21 +716,21 @@ namespace MetaFile const TEmfWindow& oWindow{GetWindow()}; const TEmfWindow& oViewPort{GetViewport()}; - double dM11 = (oViewPort.ulW >= 0) ? 1 : -1; - double dM22 = (oViewPort.ulH >= 0) ? 1 : -1; + double dM11 = ((oViewPort.ulW >= 0) ? 1. : -1.) * GetPixelWidth(); + double dM22 = ((oViewPort.ulH >= 0) ? 1. : -1.) * GetPixelHeight(); - TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.lX * GetPixelWidth() * dM11), -(oWindow.lY * GetPixelHeight() * dM22)); - TEmfXForm oViewportXForm(GetPixelWidth() * dM11, 0, 0, GetPixelHeight() * dM22, oViewPort.lX, oViewPort.lY); + TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.lX * dM11), -(oWindow.lY * dM22)); + TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.lX, oViewPort.lY); m_oFinalTransform.Init(); - m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); + m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Init(); - m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); + m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); } void CEmfDC::FixIsotropic() diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp index 960b9b1b05..ac55b515b0 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CWmfInterpretatorSvg.cpp @@ -149,63 +149,13 @@ namespace MetaFile if (NULL != m_pParser) pFont = m_pParser->GetFont(); - NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;; - if (pFont) - { - // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 - // http://msdn.microsoft.com/en-us/library/cc194829.aspx - // Charset Name Charset Value(hex) Codepage number - // ------------------------------------------------------ - // - // DEFAULT_CHARSET 1 (x01) - // SYMBOL_CHARSET 2 (x02) - // OEM_CHARSET 255 (xFF) - // ANSI_CHARSET 0 (x00) 1252 - // RUSSIAN_CHARSET 204 (xCC) 1251 - // EASTEUROPE_CHARSET 238 (xEE) 1250 - // GREEK_CHARSET 161 (xA1) 1253 - // TURKISH_CHARSET 162 (xA2) 1254 - // BALTIC_CHARSET 186 (xBA) 1257 - // HEBREW_CHARSET 177 (xB1) 1255 - // ARABIC _CHARSET 178 (xB2) 1256 - // SHIFTJIS_CHARSET 128 (x80) 932 - // HANGEUL_CHARSET 129 (x81) 949 - // GB2313_CHARSET 134 (x86) 936 - // CHINESEBIG5_CHARSET 136 (x88) 950 - // THAI_CHARSET 222 (xDE) 874 - // JOHAB_CHARSET 130 (x82) 1361 - // VIETNAMESE_CHARSET 163 (xA3) 1258 - - switch (pFont->GetCharSet()) - { - default: - case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; - case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; - case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; - case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; - case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; - case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; - case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; - case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; - case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; - case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; - case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; - case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; - case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; - case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; - case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; - } - } - - std::wstring wsText = NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)pString, (long)shStringLength, eCharSet); + const std::wstring wsText{ConvertToUnicode(pString, (long)shStringLength, (NULL != pFont) ? pFont->GetCharSet() : DEFAULT_CHARSET)}; TPointD oScale((m_pParser->IsWindowFlippedX()) ? -1 : 1, (m_pParser->IsWindowFlippedY()) ? -1 : 1); std::vector arDx(0); - if (NULL != pDx) + if (NULL != pDx && shStringLength == wsText.length()) arDx = std::vector(pDx, pDx + wsText.length()); WriteText(wsText, TPointD(shX, shY), oRectangle, oScale, arDx); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp index a21e0aa0a1..75bf97de77 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp @@ -182,7 +182,8 @@ namespace MetaFile std::wstring CWmfFont::GetFaceName() const { - return std::wstring(NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)uchFacename, 32).c_str()); + const std::wstring wsFontName(ConvertToUnicode((const unsigned char*)uchFacename, 32, uchCharSet)); + return wsFontName.substr(0, wsFontName.find(L'\0')); } int CWmfFont::GetWeight() const diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp index 80c253233b..214b314d83 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp @@ -52,7 +52,7 @@ namespace MetaFile m_oStream.SetCurrentBlockSize(m_unRecordSize); if (NULL != m_pInterpretator) - PRINT_WMF_RECORD(ushType) + PRINT_WMF_RECORD(ushType); switch (ushType) { diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp index f5afe05998..c0d9adec1f 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp @@ -353,57 +353,7 @@ namespace MetaFile } const IFont* pFont = GetFont(); - NSStringExt::CConverter::ESingleByteEncoding eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;; - if (pFont) - { - // Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478 - // http://msdn.microsoft.com/en-us/library/cc194829.aspx - // Charset Name Charset Value(hex) Codepage number - // ------------------------------------------------------ - // - // DEFAULT_CHARSET 1 (x01) - // SYMBOL_CHARSET 2 (x02) - // OEM_CHARSET 255 (xFF) - // ANSI_CHARSET 0 (x00) 1252 - // RUSSIAN_CHARSET 204 (xCC) 1251 - // EASTEUROPE_CHARSET 238 (xEE) 1250 - // GREEK_CHARSET 161 (xA1) 1253 - // TURKISH_CHARSET 162 (xA2) 1254 - // BALTIC_CHARSET 186 (xBA) 1257 - // HEBREW_CHARSET 177 (xB1) 1255 - // ARABIC _CHARSET 178 (xB2) 1256 - // SHIFTJIS_CHARSET 128 (x80) 932 - // HANGEUL_CHARSET 129 (x81) 949 - // GB2313_CHARSET 134 (x86) 936 - // CHINESEBIG5_CHARSET 136 (x88) 950 - // THAI_CHARSET 222 (xDE) 874 - // JOHAB_CHARSET 130 (x82) 1361 - // VIETNAMESE_CHARSET 163 (xA3) 1258 - - switch (pFont->GetCharSet()) - { - default: - case DEFAULT_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case SYMBOL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break; - case ANSI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break; - case RUSSIAN_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break; - case EASTEUROPE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break; - case GREEK_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break; - case TURKISH_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break; - case BALTIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break; - case HEBREW_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break; - case ARABIC_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break; - case SHIFTJIS_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break; - case HANGEUL_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break; - case 134/*GB2313_CHARSET*/: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break; - case CHINESEBIG5_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break; - case THAI_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break; - case JOHAB_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break; - case VIETNAMESE_CHARSET: eCharSet = NSStringExt::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break; - } - } - - std::wstring wsText = NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)pString, (long)unCharsCount, eCharSet); + std::wstring wsText = ConvertToUnicode(pString, (long)unCharsCount, (NULL != pFont) ? pFont->GetCharSet() : DEFAULT_CHARSET); if (NULL != m_pInterpretator) { @@ -411,7 +361,7 @@ namespace MetaFile TranslatePoint(nX, nY, dX, dY); double* pdDx = NULL; - if (NULL != pDx) + if (NULL != pDx && unCharsCount == wsText.length()) { pdDx = new double[unCharsCount]; if (pdDx) diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h index d989b40255..5716462b35 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.h @@ -11,8 +11,8 @@ #undef DrawText #endif -#define PRINT_WMF_RECORD(type) do {} while(false); -#define PRINT_WMF_LOG(text) do {} while(false); +#define PRINT_WMF_RECORD(type) do {} while(false) +#define PRINT_WMF_LOG(text) do {} while(false) #ifdef _DEBUG #define LOG_WMF_RECORDS 1 @@ -105,13 +105,13 @@ }; #define PRINT_WMF_RECORD(type) \ - {\ + do {\ std::map::const_iterator itFound = mWmfRecords.find(type); \ if (mWmfRecords.cend() != itFound) \ std::cout << itFound->second << std::endl; \ else \ std::cout << "Unknown record: " << type << std::endl; \ - } + } while(false) #endif #endif #endif diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp index 2e59367315..af784237ed 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfPlayer.cpp @@ -571,20 +571,20 @@ namespace MetaFile const TWmfWindow& oWindow{GetWindow()}; const TWmfWindow& oViewPort{GetViewport()}; - double dM11 = (oViewPort.w >= 0) ? 1 : -1; - double dM22 = (oViewPort.h >= 0) ? 1 : -1; + double dM11 = ((oViewPort.w >= 0) ? 1. : -1.) * GetPixelWidth(); + double dM22 = ((oViewPort.h >= 0) ? 1. : -1.) * GetPixelHeight(); - TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.x * GetPixelWidth() * dM11), -(oWindow.y * GetPixelHeight() * dM22)); - TEmfXForm oViewportXForm(GetPixelWidth() * dM11, 0, 0, GetPixelHeight() * dM22, oViewPort.x, oViewPort.y); + TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.x * dM11), -(oWindow.y * dM22)); + TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.x, oViewPort.y); m_oFinalTransform.Init(); - m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); + m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Init(); + m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY); -// m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY); m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY); } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp index c504960712..aa3a67b8fb 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp @@ -17,6 +17,7 @@ namespace SVG { + #define DEFAULT_TSPAN_FONT_SIZE 16 #define DefaultFontFamily L"Times New Roman" #define MIN_FONT_SIZE 5 #define MAX_FONT_SIZE 100 @@ -26,7 +27,7 @@ namespace SVG CTSpan::CTSpan(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, bool bCheckText) : CRenderedObject(oNode, pParent), m_pFontManager(pFontManager) { - m_oFont.UpdateSize(16); + m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE,DEFAULT_TSPAN_FONT_SIZE); if (bCheckText) m_wsText = StrUtils::TrimExtraEnding(oNode.GetText()); @@ -63,7 +64,7 @@ namespace SVG CTSpan::CTSpan(const std::wstring &wsText, const Point &oPosition, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, bool bCheckText) : CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager), m_wsText(wsText) { - m_oFont.UpdateSize(16); + m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE); if (bCheckText) m_wsText = StrUtils::TrimExtraEnding(m_wsText); @@ -304,7 +305,7 @@ namespace SVG pRenderer->put_BrushColor1(m_oStyles.m_oFill.ToInt()); pRenderer->put_BrushAlpha1(255); } - + bool CTSpan::UseExternalFont(const CSvgFile *pFile, double dX, double dY, IRenderer *pRenderer, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const { std::wstring wsFontFamily = DefaultFontFamily; diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 590867806c..2b74040192 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -303,6 +303,7 @@ namespace NSDocxRenderer color.position = (long)(pPositions[i] * 65536); m_oBrush.m_arrSubColors.push_back(color); } + m_oCurrentPage.m_bIsGradient = true; return S_OK; } HRESULT CDocument::put_BrushGradInfo(void* pGradInfo) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 3e38d7d4df..42858e022e 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -57,7 +57,6 @@ namespace NSDocxRenderer if (lType == c_nResetClipType) { - m_oCurrVectorGraphics.Clear(); m_oClipVectorGraphics.Clear(); } else if (lType == c_nClipType) @@ -162,11 +161,12 @@ namespace NSDocxRenderer void CPage::PathStart() { + m_oCurrVectorGraphics.Clear(); } void CPage::PathEnd() { - m_oCurrVectorGraphics.End(); + m_oCurrVectorGraphics.Clear(); } void CPage::PathClose() @@ -174,7 +174,6 @@ namespace NSDocxRenderer m_oCurrVectorGraphics.Close(); } - // c_nStroke = 0x0001; // c_nWindingFillMode = 0x0100; // c_nEvenOddFillMode = 0x0200; @@ -182,10 +181,7 @@ namespace NSDocxRenderer { // in case if text comes as a path with unicode 32 (space) if (m_oCurrVectorGraphics.IsEmpty()) - { - m_oClipVectorGraphics.Clear(); return; - } double rotation = m_pTransform->z_Rotation(); double left = m_oCurrVectorGraphics.GetLeft(); @@ -239,23 +235,25 @@ namespace NSDocxRenderer CVectorGraphics new_vector_graphics = CVectorGraphics::CalcBoolean( m_oCurrVectorGraphics, m_oClipVectorGraphics, - m_lClipMode); + m_lClipMode, + lType); if (new_vector_graphics.IsEmpty()) { m_oCurrVectorGraphics.Clear(); - m_oClipVectorGraphics.Clear(); return; } m_oCurrVectorGraphics = std::move(new_vector_graphics); } shape->SetVector(std::move(m_oCurrVectorGraphics)); - if (!shape->IsOoxmlValid()) - return; auto info = pInfo; if (!info && m_bIsGradient) { + // image with gradient must be closed + if (!shape->m_oVector.IsEmpty() && shape->m_oVector.GetData().back().type != CVectorGraphics::ePathCommandType::pctClose) + shape->m_oVector.Add({CVectorGraphics::ePathCommandType::pctClose, {}}); + long width_pix = static_cast(shape->m_dWidth * c_dMMToPix); long height_pix = static_cast(shape->m_dHeight * c_dMMToPix); @@ -296,6 +294,7 @@ namespace NSDocxRenderer g_renderer->put_Width(shape->m_dWidth); g_renderer->put_Height(shape->m_dHeight); g_renderer->RestoreBrush(shifted_brush); + g_renderer->RestorePen(*m_pPen); g_renderer->BeginCommand(c_nPathType); shifted_vector.DrawOnRenderer(g_renderer); g_renderer->DrawPath(c_nWindingFillMode); @@ -326,6 +325,9 @@ namespace NSDocxRenderer else shape->m_eType = CShape::eShapeType::stVectorGraphics; + if (!shape->IsOoxmlValid()) + return; + // big white shape with page width & height skip if (fabs(shape->m_dHeight - m_dHeight) <= c_dSHAPE_X_OFFSET * 2 && fabs(shape->m_dWidth - m_dWidth) <= c_dSHAPE_X_OFFSET * 2 && @@ -334,7 +336,6 @@ namespace NSDocxRenderer shape->m_nOrder = ++m_nShapeOrder; m_arShapes.push_back(shape); - m_oClipVectorGraphics.Clear(); } void CPage::CollectTextData( @@ -817,18 +818,18 @@ namespace NSDocxRenderer continue; // если совпадает строка по высоте - берем ее и выходим - if (fabs(line->m_dBaselinePos - drop_cap_cont->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(line->m_dBotWithMaxDescent - drop_cap_cont->m_dBotWithDescent) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { num_of_lines++; break; } - if (line->m_dBaselinePos > drop_cap_cont->m_dBaselinePos) - break; - - if (fabs(line->m_dTop - drop_cap_cont->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < drop_cap_cont->m_dTop) + if (line->m_dBotWithMaxDescent < drop_cap_cont->m_dTopWithAscent) continue; + if (line->m_dTopWithMaxAscent > drop_cap_cont->m_dBotWithDescent) + break; + num_of_lines++; } if (num_of_lines > 1) diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 7022378567..4efd97251a 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -885,8 +885,8 @@ namespace NSDocxRenderer if (0xFF != m_oBrush.Alpha1) { oWriter.WriteString(L"\">(m_oBrush.Alpha1 / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/>"); + oWriter.AddInt(static_cast(m_oBrush.Alpha1 / 255.0 * 100.0 * 1000)); + oWriter.WriteString(L"\"/>"); } else { diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index c46e4524f6..48c2a2b5d6 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -154,12 +154,12 @@ namespace NSDocxRenderer std::shared_ptr CImageManager::GenerateImageID(Aggplus::CImage* pImage) { - if (m_pExternalStorage) - return m_pExternalStorage->GenerateImageID(pImage); - if (pImage->GetStride() > 0) FlipY(pImage); + if (m_pExternalStorage) + return m_pExternalStorage->GenerateImageID(pImage); + int size = pImage->GetStride() * pImage->GetHeight(); if (size < 0) size = -size; diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 12ef5d3630..8460db6078 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -220,10 +220,6 @@ namespace NSDocxRenderer ResetBorders(); } - void CVectorGraphics::End() - { - Clear(); - } void CVectorGraphics::Add(const PathCommand& command) { m_arData.push_back(command); @@ -321,10 +317,14 @@ namespace NSDocxRenderer // ClipRegionUnion = 0x0100; // ClipRegionXor = 0x0200; // ClipRegionDiff = 0x0400; - CVectorGraphics CVectorGraphics::CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType) + + // c_nStroke = 0x0001; + // c_nWindingFillMode = 0x0100; + // c_nEvenOddFillMode = 0x0200; + CVectorGraphics CVectorGraphics::CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType) { auto op = GetOpType(clipType); - Aggplus::CGraphicsPath result = Aggplus::CalcBooleanOperation(vg1.GetGraphicsPath(), vg2.GetGraphicsPath(), op); + Aggplus::CGraphicsPath result = Aggplus::CalcBooleanOperation(vg1.GetGraphicsPath(), vg2.GetGraphicsPath(), op, fillType); return CVectorGraphics(result); } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index 9399a7ccd7..ea29b12546 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -68,7 +68,6 @@ namespace NSDocxRenderer const double& x2, const double& y2, const double& x3, const double& y3); void Close(); - void End(); void Add(const PathCommand& command); void Join(CVectorGraphics&& other); @@ -81,7 +80,7 @@ namespace NSDocxRenderer void Transform(const Aggplus::CMatrix& matrix); void DrawOnRenderer(IRenderer* renderer) const noexcept; - static CVectorGraphics CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType); + static CVectorGraphics CalcBoolean(const CVectorGraphics& vg1, const CVectorGraphics& vg2, long clipType, long fillType = c_nWindingFillMode); private: std::list m_arData; diff --git a/EpubFile/src/CEpubFile.cpp b/EpubFile/src/CEpubFile.cpp index 587fa3fda5..0ee795bb15 100644 --- a/EpubFile/src/CEpubFile.cpp +++ b/EpubFile/src/CEpubFile.cpp @@ -155,6 +155,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s std::wstring sDocxFileTempDir = m_sTempDir + L"/tmp"; NSDirectory::CreateDirectory(sDocxFileTempDir); oFile.SetTmpDirectory(sDocxFileTempDir); + oFile.SetCoreDirectory(NSFile::GetDirectoryName(sContent)); std::vector arFiles; for (const CBookContentItem& oContent : m_arContents) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 9c3bfda306..d0eeb0f31c 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1400,11 +1400,17 @@ bool GetStatusUsingExternalLocalFiles() return true; } -bool CanUseThisPath(const std::wstring& wsPath, bool bIsAllowExternalLocalFiles) +bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, const std::wstring& wsCorePath, bool bIsAllowExternalLocalFiles) { if (bIsAllowExternalLocalFiles) return true; + if (!wsCorePath.empty()) + { + const std::wstring wsFullPath = NSSystemPath::ShortenPath(NSSystemPath::Combine(wsSrcPath, wsPath)); + return boost::starts_with(wsFullPath, wsCorePath); + } + if (wsPath.length() >= 3 && L"../" == wsPath.substr(0, 3)) return false; @@ -1424,6 +1430,7 @@ public: std::wstring m_sSrc; // Директория источника std::wstring m_sDst; // Директория назначения std::wstring m_sBase; // Полный базовый адрес + std::wstring m_sCore; // Путь до корневого файла (используется для работы с Epub) NSCSS::CTree m_oTree; // Дерево body html-файла @@ -4205,7 +4212,7 @@ private: { sSrcM = NSSystemPath::ShortenPath(sSrcM); - if (!CanUseThisPath(sSrcM, bIsAllowExternalLocalFiles)) + if (!CanUseThisPath(sSrcM, m_sSrc, m_sCore, bIsAllowExternalLocalFiles)) return true; } @@ -4683,7 +4690,12 @@ bool CHtmlFile2::IsMhtFile(const std::wstring& sFile) void CHtmlFile2::SetTmpDirectory(const std::wstring& sFolder) { - m_internal->m_sTmp = sFolder; + m_internal->m_sTmp = NSSystemPath::NormalizePath(sFolder); +} + +void CHtmlFile2::SetCoreDirectory(const std::wstring& wsFolder) +{ + m_internal->m_sCore = NSSystemPath::NormalizePath(wsFolder); } HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams) diff --git a/HtmlFile2/htmlfile2.h b/HtmlFile2/htmlfile2.h index 80ed8f1214..a7c70f9ae8 100644 --- a/HtmlFile2/htmlfile2.h +++ b/HtmlFile2/htmlfile2.h @@ -84,6 +84,7 @@ public: bool IsHtmlFile(const std::wstring& sFile); bool IsMhtFile (const std::wstring& sFile); void SetTmpDirectory(const std::wstring& sFolder); + void SetCoreDirectory(const std::wstring& wsFolder); HRESULT OpenHtml(const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL); HRESULT OpenMht (const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL); HRESULT OpenBatchHtml(const std::vector& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL); diff --git a/MsBinaryFile/DocFile/MemoryStream.cpp b/MsBinaryFile/DocFile/MemoryStream.cpp index c048f6960b..44eae54ad8 100644 --- a/MsBinaryFile/DocFile/MemoryStream.cpp +++ b/MsBinaryFile/DocFile/MemoryStream.cpp @@ -31,6 +31,7 @@ */ #include "MemoryStream.h" +#include "../XlsFile/Format/Logging/Log.h" MemoryStream::MemoryStream (unsigned char* data, unsigned long size, bool bMemCopy) : m_Data(NULL), m_Size(0), m_Position(0), bMemoryCopy(bMemCopy) { @@ -66,6 +67,10 @@ _UINT64 MemoryStream::ReadUInt64() rdU64 = DocFileFormat::FormatUtils::BytesToUInt64(m_Data, m_Position, m_Size); m_Position += 8; } + else + { + Log::warning(L"MemoryStream: UInt64 read"); + } return rdU64; } @@ -78,7 +83,10 @@ unsigned short MemoryStream::ReadUInt16() rdUShort = DocFileFormat::FormatUtils::BytesToUInt16 (m_Data, m_Position, m_Size); m_Position += 2; } - + else + { + Log::warning(L"MemoryStream: UInt16 read"); + } return rdUShort; } void MemoryStream::WriteUInt16(unsigned short val) @@ -88,6 +96,10 @@ void MemoryStream::WriteUInt16(unsigned short val) ((unsigned short *)(m_Data + m_Position))[0] = val; m_Position += 2; } + else + { + Log::warning(L"MemoryStream: UInt16 write"); + } } short MemoryStream::ReadInt16() { @@ -98,7 +110,10 @@ short MemoryStream::ReadInt16() rdShort = DocFileFormat::FormatUtils::BytesToInt16 (m_Data, m_Position, m_Size); m_Position += 2; } - + else + { + Log::warning(L"MemoryStream: Int16 read"); + } return rdShort; } @@ -111,7 +126,10 @@ int MemoryStream::ReadInt32() rdInt = DocFileFormat::FormatUtils::BytesToInt32 (m_Data, m_Position, m_Size); m_Position += 4; } - + else + { + Log::warning(L"MemoryStream: Int32 read"); + } return rdInt; } void MemoryStream::WriteInt32(_INT32 val) @@ -121,6 +139,10 @@ void MemoryStream::WriteInt32(_INT32 val) ((_INT32 *)(m_Data + m_Position))[0] = val; m_Position += 4; } + else + { + Log::warning(L"MemoryStream: Int32 read"); + } } void MemoryStream::Align(_UINT32 val) { @@ -139,7 +161,10 @@ unsigned int MemoryStream::ReadUInt32() rdUInt = DocFileFormat::FormatUtils::BytesToUInt32 (m_Data, m_Position, m_Size); m_Position += 4; } - + else + { + Log::warning(L"MemoryStream: UInt32 read"); + } return rdUInt; } void MemoryStream::WriteByte(unsigned char val) @@ -157,6 +182,10 @@ void MemoryStream::WriteUInt32(_UINT32 val) ((_UINT32 *)(m_Data + m_Position))[0] = val; m_Position += sizeof(_UINT32); } + else + { + Log::warning(L"MemoryStream: UInt32 write"); + } } unsigned char MemoryStream::ReadByte() { @@ -167,7 +196,10 @@ unsigned char MemoryStream::ReadByte() rdByte = (m_Position < m_Size) ? m_Data[m_Position] : 0; m_Position += sizeof(rdByte); } - + else + { + Log::warning(L"MemoryStream: UInt8 read"); + } return rdByte; } @@ -194,6 +226,10 @@ void MemoryStream::WriteBytes(unsigned char* pData, int size) memcpy(m_Data + m_Position, pData, size); m_Position += size; } + else + { + Log::warning(L"MemoryStream: bytes write"); + } } unsigned long MemoryStream::GetPosition() const diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp index 914b1612d0..5a06a1d350 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/MOper.cpp @@ -45,15 +45,21 @@ void MOper::load(CFRecord& record) { record >> colLast >> rowLast; - for(int i = 0; i < (colLast + 1) * (rowLast + 1); ++i) + for (int i = 0; i < (colLast + 1) * (rowLast + 1); ++i) { unsigned char rec_type; record >> rec_type; SerArPtr ser(SerAr::createSerAr(rec_type)); - record >> *ser; - - extOper.push_back(ser); + if (ser) + { + record >> *ser; + extOper.push_back(ser); + } + else + { + break; + } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp index 5ccc5ff6e9..64994ee8e1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.cpp @@ -1507,6 +1507,9 @@ XLS::BiffStructurePtr ADJH::clone() void ADJH::load(IBinaryReader* reader) { + unsigned long pos = reader->GetPosition(); + unsigned long pos_end = reader->GetPosition() + cbElement; + _UINT32 flag = reader->ReadUInt32(); fahInverseX = GETBIT(flag, 31); @@ -1552,6 +1555,8 @@ void ADJH::load(IBinaryReader* reader) if (fahxMax) xMax = reader->ReadInt16(); if (fahyMin) yMin = reader->ReadInt16(); if (fahyMax) yMax = reader->ReadInt16(); + + reader->Seek(pos_end, 0); } void ADJH::load(XLS::CFRecord& record) diff --git a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h index d1851f5066..98cc503e98 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -609,7 +609,8 @@ extern int g_nCurFormatVersion; delInstrText = 31, linebreakClearAll = 32, linebreakClearLeft = 33, - linebreakClearRight = 34 + linebreakClearRight = 34, + pptxDrawingAlternative = 0x99 };} namespace c_oSerVbaProjectTypes{enum c_oSerVbaProjectType { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index f8fd747da5..dc4e4dc45a 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -6705,7 +6705,7 @@ bool BinaryDocumentTableWriter::WriteDrawingPptx(OOX::WritingElement* item) } res = WriteDrawingPptx(we); - if (res == false || we == NULL) + if (res == false || we == NULL || m_oParamsWriter.bWriteAlternative) { if (false == pAlternateContent->m_arrFallbackItems.empty()) { @@ -6750,7 +6750,8 @@ bool BinaryDocumentTableWriter::WriteDrawingPptx(OOX::WritingElement* item) } else { - int nCurPos = m_oBcw.WriteItemStart(c_oSerRunType::pptxDrawing); + int nCurPos = m_oBcw.WriteItemStart(m_oParamsWriter.bWriteAlternative ? c_oSerRunType::pptxDrawingAlternative : c_oSerRunType::pptxDrawing); + m_oParamsWriter.bWriteAlternative = false; WriteDrawing(NULL, pGraphicDrawing, pGraphic); m_oBcw.WriteItemEnd(nCurPos); } @@ -6833,6 +6834,11 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr pGraphic->chartRec->toPPTY(&m_oBcw.m_oStream); m_oBcw.WriteItemWithLengthEnd(nCurPos); + + if (pGraphic->chartRec->m_bChartEx) + { + m_oParamsWriter.bWriteAlternative = true; + } } else { @@ -6848,11 +6854,6 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr { pGraphic->olePic->toPPTY(&m_oBcw.m_oStream); } - //else if (pGraphic->smartArt.is_init()) - //{ - // pGraphic->smartArt->LoadDrawing(&m_oBcw.m_oStream); - // pGraphic->smartArt->toPPTY(&m_oBcw.m_oStream); - //} else if (pGraphic->element.is_init()) { pGraphic->element.toPPTY(&m_oBcw.m_oStream); diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.h b/OOXML/Binary/Document/BinWriter/BinWriters.h index 4ae2b2b6fe..ae5128ea20 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.h +++ b/OOXML/Binary/Document/BinWriter/BinWriters.h @@ -98,6 +98,8 @@ namespace BinDocxRW NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager); std::wstring AddEmbeddedStyle(const std::wstring & styleId); + + bool bWriteAlternative = false; }; class ParamsDocumentWriter { diff --git a/OOXML/Binary/Presentation/BinReaderWriterDefines.h b/OOXML/Binary/Presentation/BinReaderWriterDefines.h index cf1687bce8..28af712555 100644 --- a/OOXML/Binary/Presentation/BinReaderWriterDefines.h +++ b/OOXML/Binary/Presentation/BinReaderWriterDefines.h @@ -197,22 +197,24 @@ namespace NSBinPptxRW #define SPTREE_TYPE_OLE 6 #define SPTREE_TYPE_VIDEO 7 #define SPTREE_TYPE_AUDIO 8 -#define SPTREE_TYPE_LOCKED_CANVAS 9 +#define SPTREE_TYPE_LOCKED_CANVAS 9 + +#define SPTREE_TYPE_ALTERNATIVE 0x99 #define DIAGRAM_LAYOUT_TYPE_NONE 0xB0 #define DIAGRAM_LAYOUT_TYPE_ALG 0xB1 #define DIAGRAM_LAYOUT_TYPE_CHOOSE 0xB2 -#define DIAGRAM_LAYOUT_TYPE_CONSTRLST 0xB3 +#define DIAGRAM_LAYOUT_TYPE_CONSTRLST 0xB3 #define DIAGRAM_LAYOUT_TYPE_FOREACH 0xB4 -#define DIAGRAM_LAYOUT_TYPE_LAYOUTNODE 0xB5 +#define DIAGRAM_LAYOUT_TYPE_LAYOUTNODE 0xB5 #define DIAGRAM_LAYOUT_TYPE_PRESOF 0xB6 #define DIAGRAM_LAYOUT_TYPE_RULELST 0xB7 #define DIAGRAM_LAYOUT_TYPE_SHAPE 0xB8 -#define DIAGRAM_LAYOUT_TYPE_VARIABLELIST 0xB9 +#define DIAGRAM_LAYOUT_TYPE_VARIABLELIST 0xB9 -#define SPTREE_TYPE_MACRO 0xA1 +#define SPTREE_TYPE_MACRO 0xA1 static BYTE SchemeClr_GetBYTECode(const std::wstring& sValue) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 311c7c7d1b..01c81bf617 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -6547,9 +6547,18 @@ void BinaryWorksheetTableWriter::WriteDrawing(const OOX::Spreadsheet::CWorksheet m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingType::pptxDrawing); int nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_oBcw.m_oStream.StartRecord(0); m_oBcw.m_oStream.WriteRecord2(1, pCellAnchor->m_oElement->GetElem()); m_oBcw.m_oStream.EndRecord(); + + if (pCellAnchor->m_oElement->GetElemAlternative().IsInit()) + { + m_oBcw.m_oStream.StartRecord(0x99); + m_oBcw.m_oStream.WriteRecord2(1, pCellAnchor->m_oElement->GetElemAlternative()); + m_oBcw.m_oStream.EndRecord(); + } + m_oBcw.WriteItemWithLengthEnd(nCurPos); m_oBcw.m_oStream.SetRels(oldRels); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 0e94b1be81..8a0019b2a4 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4156,19 +4156,19 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadSheetPr, &oSheetPr); SEEK_TO_POS_END(oSheetPr); //------------------------------------------------------------------------------------------------------------- - OOX::Spreadsheet::CSheetViews oSheetViews; + m_pCurWorksheet->m_oSheetViews.Init(); SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetViews); - READ1_DEF(length, res, this->ReadSheetViews, &oSheetViews); + READ1_DEF(length, res, this->ReadSheetViews, m_pCurWorksheet->m_oSheetViews.GetPointer()); SEEK_TO_POS_END2(); - if (oSheetViews.m_arrItems.empty()) - oSheetViews.m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); - OOX::Spreadsheet::CSheetView* pSheetView = oSheetViews.m_arrItems.front(); + if (m_pCurWorksheet->m_oSheetViews->m_arrItems.empty()) + m_pCurWorksheet->m_oSheetViews->m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); + OOX::Spreadsheet::CSheetView* pSheetView = m_pCurWorksheet->m_oSheetViews->m_arrItems.front(); if (false == pSheetView->m_oWorkbookViewId.IsInit()) { pSheetView->m_oWorkbookViewId.Init(); pSheetView->m_oWorkbookViewId->SetValue(0); } - oSheetViews.toXML(oStreamWriter); + m_pCurWorksheet->m_oSheetViews->toXML(oStreamWriter); //------------------------------------------------------------------------------------------------------------- OOX::Spreadsheet::CSheetFormatPr oSheetFormatPr; SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetFormatPr); diff --git a/OOXML/Binary/Sheets/Writer/CSVWriter.cpp b/OOXML/Binary/Sheets/Writer/CSVWriter.cpp index 4a5452dd66..d520667013 100644 --- a/OOXML/Binary/Sheets/Writer/CSVWriter.cpp +++ b/OOXML/Binary/Sheets/Writer/CSVWriter.cpp @@ -74,7 +74,8 @@ private: OOX::Spreadsheet::CXlsx& m_oXlsx; unsigned int m_nCodePage; const std::wstring& m_sDelimiter; - bool m_bJSON; + bool m_bJSON = false; + bool m_bShowFormulas = false; MS_LCID_converter m_lcidConverter; @@ -628,6 +629,8 @@ CSVWriter::Impl::Impl(OOX::Spreadsheet::CXlsx &m_oXlsx, unsigned int m_nCodePage m_bStartRow = true; m_bStartCell = true; + m_bShowFormulas = false; + m_nColDimension = 1; } CSVWriter::Impl::~Impl() @@ -665,6 +668,15 @@ void CSVWriter::Impl::WriteSheetStart(OOX::Spreadsheet::CWorksheet* pWorksheet) { WriteFile(&m_oFile, &m_pWriteBuffer, m_nCurrentIndex, g_sBkt, m_nCodePage); } + + if (pWorksheet && pWorksheet->m_oSheetViews.IsInit() && false == pWorksheet->m_oSheetViews->m_arrItems.empty()) + { + if (pWorksheet->m_oSheetViews->m_arrItems[0]->m_oShowFormulas.IsInit() && + pWorksheet->m_oSheetViews->m_arrItems[0]->m_oShowFormulas->ToBool()) + { + m_bShowFormulas = true; + } + } } void CSVWriter::Impl::WriteRowStart(OOX::Spreadsheet::CRow *pRow) { @@ -732,7 +744,11 @@ void CSVWriter::Impl::WriteCell(OOX::Spreadsheet::CCell *pCell) //else bool bString = false; - if (pCell->m_oValue.IsInit()) + if (m_bShowFormulas && pCell->m_oFormula.IsInit()) + { + sCellValue = L"=" + pCell->m_oFormula->m_sText; + } + else if (pCell->m_oValue.IsInit()) { sCellValue = pCell->m_oValue->ToString(); @@ -798,7 +814,7 @@ void CSVWriter::Impl::WriteCell(OOX::Spreadsheet::CCell *pCell) } if (pCell->m_oFormula.IsInit() && sCellValue.empty()) { - sCellValue = pCell->m_oFormula->m_sText; + sCellValue = L"=" + pCell->m_oFormula->m_sText; } // Escape cell value diff --git a/OOXML/DocxFormat/Diagram/DiagramColors.cpp b/OOXML/DocxFormat/Diagram/DiagramColors.cpp index 6880951fda..a4e9d90136 100644 --- a/OOXML/DocxFormat/Diagram/DiagramColors.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramColors.cpp @@ -34,11 +34,56 @@ #include "DiagramColors.h" #include "../../Common/SimpleTypes_Drawing.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../Drawing/DrawingExt.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX { + CDiagramColors::CDiagramColors(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + } + CDiagramColors::CDiagramColors(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + + read(uri.GetDirectory(), uri); + } + CDiagramColors::CDiagramColors(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + + read(oRootPath, oPath); + } + CDiagramColors::~CDiagramColors() + { + } + const OOX::FileType CDiagramColors::type() const + { + return FileTypes::DiagramColors; + } + const CPath CDiagramColors::DefaultDirectory() const + { + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); + } + const CPath CDiagramColors::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CDiagramColors::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } void CDiagramColors::read(const CPath& oRootPath, const CPath& oFilePath) { IFileContainer::Read(oRootPath, oFilePath); @@ -204,6 +249,8 @@ namespace OOX } void Diagram::CClrLst::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + ReadAttributes(oReader); if (oReader.IsEmptyNode()) diff --git a/OOXML/DocxFormat/Diagram/DiagramColors.h b/OOXML/DocxFormat/Diagram/DiagramColors.h index a5400568c5..83ab66995e 100644 --- a/OOXML/DocxFormat/Diagram/DiagramColors.h +++ b/OOXML/DocxFormat/Diagram/DiagramColors.h @@ -114,40 +114,19 @@ namespace OOX class CDiagramColors : public OOX::FileGlobalEnumerated, public OOX::IFileContainer { public: - CDiagramColors(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) - { - } - CDiagramColors(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) - { - read(uri.GetDirectory(), uri); - } - CDiagramColors(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) - { - read(oRootPath, oPath); - } - virtual ~CDiagramColors() - { - } - virtual void read(const CPath& oFilePath) - { - CPath oRootPath; - read(oRootPath, oFilePath); - } + CDiagramColors(OOX::Document* pMain, bool bDocument = true); + CDiagramColors(OOX::Document* pMain, const CPath& uri); + CDiagramColors(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CDiagramColors(); + + virtual void read(const CPath& oFilePath); virtual void read(const CPath& oRootPath, const CPath& oFilePath); virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return FileTypes::DiagramColors; - } - virtual const CPath DefaultDirectory() const - { - return type().DefaultDirectory(); - } - virtual const CPath DefaultFileName() const - { - return type().DefaultFileName(); - } + virtual const OOX::FileType type() const; + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; @@ -163,5 +142,6 @@ namespace OOX nullable m_oExtLst; private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramData.cpp b/OOXML/DocxFormat/Diagram/DiagramData.cpp index 330b2647f3..018e09761e 100644 --- a/OOXML/DocxFormat/Diagram/DiagramData.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramData.cpp @@ -37,8 +37,11 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../Drawing/DrawingExt.h" -#include "../../../OOXML/PPTXFormat/Logic/SpTree.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + +#include "../../PPTXFormat/Logic/SpTree.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX @@ -443,6 +446,8 @@ namespace OOX void Diagram::CVariableList::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + if (oReader.IsEmptyNode()) return; @@ -1701,6 +1706,8 @@ namespace OOX void Diagram::CText::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + ReadAttributes(oReader); if (oReader.IsEmptyNode()) @@ -1751,17 +1758,25 @@ namespace OOX //------------------------------------------------------------------------------------------- - CDiagramData::CDiagramData(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + CDiagramData::CDiagramData(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramData::CDiagramData(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramData::CDiagramData(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read( oRootPath, oPath ); } @@ -1828,7 +1843,10 @@ namespace OOX const CPath CDiagramData::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramData::DefaultFileName() const diff --git a/OOXML/DocxFormat/Diagram/DiagramData.h b/OOXML/DocxFormat/Diagram/DiagramData.h index 7613f782ff..7f33e3e076 100644 --- a/OOXML/DocxFormat/Diagram/DiagramData.h +++ b/OOXML/DocxFormat/Diagram/DiagramData.h @@ -609,7 +609,7 @@ namespace OOX class CDiagramData : public OOX::IFileContainer, public OOX::FileGlobalEnumerated { public: - CDiagramData(OOX::Document* pMain); + CDiagramData(OOX::Document* pMain, bool bDocument = true); CDiagramData(OOX::Document* pMain, const CPath& uri); CDiagramData(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); virtual ~CDiagramData(); @@ -632,6 +632,8 @@ namespace OOX nullable m_oDataModel; nullable id_drawing; + private: + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp b/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp index eb1fbe76d4..dce0503fac 100644 --- a/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramDrawing.cpp @@ -33,23 +33,34 @@ #include "DiagramDrawing.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../../PPTXFormat/Logic/SpTree.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" #include "../Logic/Pict.h" namespace OOX { - CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) + CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain, bool bDocument) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain, const CPath& uri) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramDrawing::CDiagramDrawing(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read( oRootPath, oPath ); } @@ -95,7 +106,10 @@ namespace OOX } const CPath CDiagramDrawing::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramDrawing::DefaultFileName() const { diff --git a/OOXML/DocxFormat/Diagram/DiagramDrawing.h b/OOXML/DocxFormat/Diagram/DiagramDrawing.h index 6effd5568b..d362076634 100644 --- a/OOXML/DocxFormat/Diagram/DiagramDrawing.h +++ b/OOXML/DocxFormat/Diagram/DiagramDrawing.h @@ -48,7 +48,7 @@ namespace OOX class CDiagramDrawing : public OOX::IFileContainer, public OOX::FileGlobalEnumerated { public: - CDiagramDrawing(OOX::Document* pMain); + CDiagramDrawing(OOX::Document* pMain, bool bDocument = true); CDiagramDrawing(OOX::Document* pMain, const CPath& uri); CDiagramDrawing(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); @@ -73,6 +73,7 @@ namespace OOX CPath m_oReadPath; nullable m_oShapeTree; - + private: + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramLayout.cpp b/OOXML/DocxFormat/Diagram/DiagramLayout.cpp index f8205c07a2..6277d0b437 100644 --- a/OOXML/DocxFormat/Diagram/DiagramLayout.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramLayout.cpp @@ -34,6 +34,9 @@ #include "DiagramLayout.h" #include "../Drawing/DrawingExt.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Drawing.h" @@ -124,15 +127,23 @@ for (size_t i = 0; i < m_arrItems.size(); ++i)\ //------------------------------------------------------------------------------------------------------------------ namespace OOX { - CDiagramLayout::CDiagramLayout(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + CDiagramLayout::CDiagramLayout(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramLayout::CDiagramLayout(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramLayout::CDiagramLayout(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(oRootPath, oPath); } CDiagramLayout::~CDiagramLayout() @@ -232,7 +243,10 @@ namespace OOX } const CPath CDiagramLayout::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramLayout::DefaultFileName() const { @@ -361,10 +375,13 @@ namespace OOX } void Diagram::CDiferentData::fromXML(XmlUtils::CXmlLiteReader& oReader) { + node_name = oReader.GetName(); + ReadAttributes(oReader); if (oReader.IsEmptyNode()) return; + int nParentDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nParentDepth)) { diff --git a/OOXML/DocxFormat/Diagram/DiagramLayout.h b/OOXML/DocxFormat/Diagram/DiagramLayout.h index 047aec8212..24d147a726 100644 --- a/OOXML/DocxFormat/Diagram/DiagramLayout.h +++ b/OOXML/DocxFormat/Diagram/DiagramLayout.h @@ -504,7 +504,7 @@ namespace OOX class CDiagramLayout : public OOX::FileGlobalEnumerated, public OOX::IFileContainer { public: - CDiagramLayout(OOX::Document* pMain); + CDiagramLayout(OOX::Document* pMain, bool bDocument = true); CDiagramLayout(OOX::Document* pMain, const CPath& uri); CDiagramLayout(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); virtual ~CDiagramLayout(); @@ -538,6 +538,7 @@ namespace OOX nullable m_oExtLst; private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp index 94cc1e7c99..26daa2eb8b 100644 --- a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.cpp @@ -34,21 +34,32 @@ #include "DiagramQuickStyle.h" #include "../Drawing/DrawingExt.h" +#include "../Document.h" +#include "../../XlsxFormat/Xlsx.h" + #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX { - CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) + CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain, bool bDocument) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = bDocument; + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); } CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(uri.GetDirectory(), uri); } CDiagramQuickStyle::CDiagramQuickStyle(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::FileGlobalEnumerated(pMain) { + m_bDocument = (NULL != dynamic_cast(pMain)); + m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + read(oRootPath, oPath); } @@ -148,7 +159,10 @@ namespace OOX const CPath CDiagramQuickStyle::DefaultDirectory() const { - return type().DefaultDirectory(); + if (m_bDocument) + return type().DefaultDirectory(); + else + return L"../" + type().DefaultDirectory(); } const CPath CDiagramQuickStyle::DefaultFileName() const diff --git a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h index 0ded760a56..c6fcc894f2 100644 --- a/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h +++ b/OOXML/DocxFormat/Diagram/DiagramQuickStyle.h @@ -74,7 +74,7 @@ namespace OOX class CDiagramQuickStyle : public OOX::FileGlobalEnumerated, public OOX::IFileContainer { public: - CDiagramQuickStyle(OOX::Document* pMain); + CDiagramQuickStyle(OOX::Document* pMain, bool bDocument = true); CDiagramQuickStyle(OOX::Document* pMain, const CPath& uri); CDiagramQuickStyle(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); @@ -107,6 +107,7 @@ namespace OOX private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + bool m_bDocument = true; //for upper/lower level rels (defaultDirectory) }; } // namespace OOX diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp index c93ba4a809..da2054524b 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp @@ -2678,9 +2678,13 @@ void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CX if (pPPTShape->m_eType == PPTShapes::sptCTextBox || pPPTShape->m_eType == PPTShapes::sptCRect || pPPTShape->m_eType == PPTShapes::sptCRoundRect || + pPPTShape->m_eType == PPTShapes::sptCEllipse || pPPTShape->m_eType == PPTShapes::sptCWedgeRectCallout || - pPPTShape->m_eType == PPTShapes::sptCWedgeRoundRectCallout) - // sptCRound1Rect ? + pPPTShape->m_eType == PPTShapes::sptCWedgeRoundRectCallout || + pPPTShape->m_eType == PPTShapes::sptCWedgeEllipseCallout || + pPPTShape->m_eType == PPTShapes::sptCCloudCallout || + pPPTShape->m_eType == PPTShapes::sptCFlowChartConnector || + pPPTShape->m_eType == PPTShapes::sptCFlowChartProcess) { pShape->oTextBoxBodyPr->lIns = 91440; pShape->oTextBoxBodyPr->tIns = 45720; diff --git a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp index 315dc2cb8e..d10c74b6b1 100644 --- a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp +++ b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp @@ -543,63 +543,6 @@ namespace PPTX xml_object_vml = GetVmlXmlBySpid(xml_object_rels); } - //if (smartArt.is_init() && !table.is_init() && !chartRec.is_init() && !slicer.is_init() && !slicerExt.is_init() && !vmlSpid.is_init()) - //{ - // smartArt->LoadDrawing(pWriter); - // - // if (smartArt->m_diag.is_init()) - // { - // if (nvGraphicFramePr.IsInit()) - // { - // smartArt->m_diag->nvGrpSpPr.cNvPr = nvGraphicFramePr->cNvPr; - // smartArt->m_diag->nvGrpSpPr.nvPr = nvGraphicFramePr->nvPr; - // } - - // bool bIsInitCoords = false; - // if (smartArt->m_diag->grpSpPr.xfrm.IsInit()) - // { - // bIsInitCoords = true; - // } - // else if (xfrm.IsInit()) - // { - // smartArt->m_diag->grpSpPr.xfrm = new PPTX::Logic::Xfrm(); - // } - - // PPTX::Logic::Xfrm* dst = smartArt->m_diag->grpSpPr.xfrm.GetPointer(); - // PPTX::Logic::Xfrm* src = xfrm.GetPointer(); - - // if (dst && src) - // { - // dst->offX = src->offX; - // dst->offY = src->offY; - // dst->extX = src->extX; - // dst->extY = src->extY; - // - // if (!bIsInitCoords || !dst->chOffX.is_init() || !dst->chOffY.is_init() || !dst->chExtX.is_init() || !dst->chExtY.is_init()) - // { - // dst->chOffX = 0; - // dst->chOffY = 0; - // dst->chExtX = src->extX; - // dst->chExtY = src->extY; - // } - // - // dst->flipH = src->flipH; - // dst->flipV = src->flipV; - // dst->rot = src->rot; - // } - // //удалим индекс плейсхолдера если он есть(p:nvPr) - он будет лишний так как будет имплементация объекта - // if (smartArt->m_diag->nvGrpSpPr.nvPr.ph.IsInit()) - // { - // if(smartArt->m_diag->nvGrpSpPr.nvPr.ph->idx.IsInit()) - // { - // smartArt->m_diag->nvGrpSpPr.nvPr.ph.reset(); - // } - // } - // smartArt->toPPTY(pWriter); - // } - // return; - //} - if (false == xml_object_vml.empty() && !table.IsInit() && !chartRec.IsInit() && !slicer.IsInit() && !slicerExt.IsInit() && !smartArt.IsInit()) { std::wstring temp = L""; diff --git a/OOXML/PPTXFormat/Logic/SpTree.cpp b/OOXML/PPTXFormat/Logic/SpTree.cpp index 16178058be..176a105ef6 100644 --- a/OOXML/PPTXFormat/Logic/SpTree.cpp +++ b/OOXML/PPTXFormat/Logic/SpTree.cpp @@ -67,13 +67,15 @@ namespace PPTX return OOX::et_p_ShapeTree; } void SpTree::FillParentPointersForChilds() - { - nvGrpSpPr.SetParentPointer(this); - grpSpPr.SetParentPointer(this); + { + nvGrpSpPr.SetParentPointer(this); + grpSpPr.SetParentPointer(this); - for (size_t i = 0; i < SpTreeElems.size(); ++i) - SpTreeElems[i].SetParentPointer(this); - } + for (size_t i = 0; i < SpTreeElems.size(); ++i) + { + SpTreeElems[i].SetParentPointer(this); + } + } void SpTree::fromXML(XmlUtils::CXmlLiteReader& oReader) { m_namespace = XmlUtils::GetNamespace(oReader.GetName()); @@ -432,47 +434,45 @@ namespace PPTX BYTE _at = pReader->GetUChar(); switch (_at) { - case 0: - { - nvGrpSpPr.fromPPTY(pReader); - break; - } - case 1: - { - grpSpPr.fromPPTY(pReader); - break; - } - case 2: - { - pReader->Skip(4); // len - ULONG _c = pReader->GetULong(); - - for (ULONG i = 0; i < _c; ++i) + case 0: { - pReader->Skip(1); // type (0) - LONG nElemLength = pReader->GetLong(); // len - //SpTreeElem::fromPPTY сразу делает GetChar, а toPPTY ничего не пишет если не инициализирован - if (nElemLength > 0) - { - SpTreeElem elm; - elm.fromPPTY(pReader); + nvGrpSpPr.fromPPTY(pReader); + }break; + case 1: + { + grpSpPr.fromPPTY(pReader); + }break; + case 2: + { + pReader->Skip(4); // len + ULONG _c = pReader->GetULong(); - if (elm.is_init()) + for (ULONG i = 0; i < _c; ++i) + { + pReader->Skip(1); // type (0) + LONG nElemLength = pReader->GetLong(); // len + //SpTreeElem::fromPPTY сразу делает GetChar, а toPPTY ничего не пишет если не инициализирован + if (nElemLength > 0) { - if (elm.getType() == OOX::et_p_ShapeTree) + SpTreeElem elm; + elm.fromPPTY(pReader); + + if (elm.is_init()) { - smart_ptr e = elm.GetElem().smart_dynamic_cast(); - e->m_lGroupIndex = m_lGroupIndex + 1; + if (elm.getType() == OOX::et_p_ShapeTree) + { + smart_ptr e = elm.GetElem().smart_dynamic_cast(); + e->m_lGroupIndex = m_lGroupIndex + 1; + } + SpTreeElems.push_back(elm); } - SpTreeElems.push_back(elm); } } - } - } - default: - { - break; - } + }break; + default: + { + pReader->SkipRecord(); + }break; } } pReader->Seek(_end_rec); diff --git a/OOXML/PPTXFormat/Logic/SpTreeElem.cpp b/OOXML/PPTXFormat/Logic/SpTreeElem.cpp index 7f2cf76bfe..875eaa859e 100644 --- a/OOXML/PPTXFormat/Logic/SpTreeElem.cpp +++ b/OOXML/PPTXFormat/Logic/SpTreeElem.cpp @@ -391,15 +391,30 @@ namespace PPTX std::wstring name = XmlUtils::GetNameNoNS(oReader.GetName()); if (name == L"sp" || name == L"wsp") - m_elem.reset(new Logic::Shape(oReader)); + { + if (m_bAlternative) + m_elem_alternative.reset(new Logic::Shape(oReader)); + else + m_elem.reset(new Logic::Shape(oReader)); + } else if (name == L"pic") - m_elem.reset(new Logic::Pic(oReader)); + { + if (m_bAlternative) + m_elem_alternative.reset(new Logic::Pic(oReader)); + else + m_elem.reset(new Logic::Pic(oReader)); + } else if (name == L"cxnSp") m_elem.reset(new Logic::CxnSp(oReader)); else if (name == L"lockedCanvas") m_elem.reset(CreatePtrXmlContent(oReader)); else if (name == L"grpSp" || name == L"wgp" || name == L"spTree" || name == L"wpc") - m_elem.reset(CreatePtrXmlContent(oReader)); + { + if (m_bAlternative) + m_elem_alternative.reset(CreatePtrXmlContent(oReader)); + else + m_elem.reset(CreatePtrXmlContent(oReader)); + } else if (name == L"graphicFrame") { Logic::GraphicFrame *pGraphic = new Logic::GraphicFrame(); @@ -407,7 +422,12 @@ namespace PPTX pGraphic->fromXML(oReader); if (pGraphic && pGraphic->IsEmpty() == false) - m_elem.reset(pGraphic); + { + if (m_bAlternative) + m_elem_alternative.reset(pGraphic); + else + m_elem.reset(pGraphic); + } else RELEASEOBJECT(pGraphic); } @@ -426,12 +446,15 @@ namespace PPTX if (strName == L"mc:Choice") { ReadAttributesRequires(oReader); + oReader.ReadNextSiblingNode(nCurDepth + 1); - fromXML(oReader); + fromXML(oReader); + m_bAlternative = (L"cx1" == m_sRequires || L"cx2" == m_sRequires); m_sRequires = L""; - if (m_elem.is_init()) + + if (m_elem.is_init() && !m_bAlternative) break; } else if (strName == L"mc:Fallback") @@ -441,24 +464,44 @@ namespace PPTX } } } + + m_bAlternative = false; } void SpTreeElem::fromXML(XmlUtils::CXmlNode& node) { std::wstring name = XmlUtils::GetNameNoNS(node.GetName()); if (name == L"sp" || name == L"wsp") - m_elem.reset(new Logic::Shape(node)); + { + if (m_bAlternative) + m_elem_alternative.reset(new Logic::Shape(node)); + else + m_elem.reset(new Logic::Shape(node)); + } else if (name == L"pic") - m_elem.reset(new Logic::Pic(node)); + { + if (m_bAlternative) + m_elem_alternative.reset(new Logic::Pic(node)); + else + m_elem.reset(new Logic::Pic(node)); + } else if (name == L"cxnSp") m_elem.reset(new Logic::CxnSp(node)); else if (name == L"lockedCanvas") m_elem.reset(CreatePtrXmlContent(node)); else if (name == L"grpSp" || name == L"wgp" || name == L"spTree" || name == L"wpc") - m_elem.reset(CreatePtrXmlContent(node)); + { + if (m_bAlternative) + m_elem_alternative.reset(CreatePtrXmlContent(node)); + else + m_elem.reset(CreatePtrXmlContent(node)); + } else if (name == L"graphicFrame") { - m_elem.reset(new Logic::GraphicFrame(node)); + if (m_bAlternative) + m_elem_alternative.reset(new Logic::GraphicFrame(node)); + else + m_elem.reset(new Logic::GraphicFrame(node)); Logic::GraphicFrame *graphic_frame = dynamic_cast(m_elem.GetPointer()); if (graphic_frame) @@ -470,18 +513,21 @@ namespace PPTX else if (name == L"AlternateContent") { bool isEmpty = true; + XmlUtils::CXmlNode oNodeChoice; if (node.GetNode(L"mc:Choice", oNodeChoice)) { XmlUtils::CXmlNode oNodeFall; std::vector oNodesC; - std::wstring sRequires; + //todo better check (a14 can be math, slicer) - if(oNodeChoice.GetAttributeIfExist(L"Requires", sRequires) && (L"a14" == sRequires || L"cx1" == sRequires)) + oNodeChoice.GetAttributeIfExist(L"Requires", m_sRequires); + + if (L"a14" == m_sRequires || L"cx1" == m_sRequires || L"cx2" == m_sRequires) { oNodeChoice.GetNodes(L"*", oNodesC); - if (1 == oNodesC.size()) + if (oNodesC.size() > 0) { XmlUtils::CXmlNode & oNodeC = oNodesC[0]; @@ -490,11 +536,12 @@ namespace PPTX isEmpty = (false == m_elem.IsInit()); } } - if (isEmpty && node.GetNode(L"mc:Fallback", oNodeFall)) + m_bAlternative = (L"cx1" == m_sRequires || L"cx2" == m_sRequires); + if ((isEmpty || m_bAlternative) && node.GetNode(L"mc:Fallback", oNodeFall)) { oNodeFall.GetNodes(L"*", oNodesC); - if (1 == oNodesC.size()) + if (oNodesC.size() > 0) { XmlUtils::CXmlNode & oNodeC = oNodesC[0]; @@ -503,7 +550,7 @@ namespace PPTX } } } - if(isEmpty) + if (isEmpty) { m_elem.reset(); } @@ -514,6 +561,8 @@ namespace PPTX m_binaryData = node; } else m_elem.reset(); + + m_bAlternative = false; } void SpTreeElem::ReadAttributesRequires(XmlUtils::CXmlLiteReader& oReader) { @@ -627,6 +676,13 @@ namespace PPTX { if (m_elem.is_init()) m_elem->toPPTY(pWriter); + + if (m_elem_alternative.is_init()) + { + pWriter->StartRecord(SPTREE_TYPE_ALTERNATIVE); + m_elem_alternative->toPPTY(pWriter); + pWriter->EndRecord(); + } } void SpTreeElem::InitElem(WrapperWritingElement* pElem) { @@ -689,10 +745,17 @@ namespace PPTX { return m_elem; } + smart_ptr SpTreeElem::GetElemAlternative() + { + return m_elem_alternative; + } void SpTreeElem::SetParentPointer(const WrapperWritingElement* pParent) { - if (is_init()) + if (m_elem.is_init()) m_elem->SetParentPointer(pParent); + + if (m_elem_alternative.is_init()) + m_elem_alternative->SetParentPointer(pParent); } void SpTreeElem::FillParentPointersForChilds(){} } // namespace Logic diff --git a/OOXML/PPTXFormat/Logic/SpTreeElem.h b/OOXML/PPTXFormat/Logic/SpTreeElem.h index 3ad68f9ecc..670e5c8eea 100644 --- a/OOXML/PPTXFormat/Logic/SpTreeElem.h +++ b/OOXML/PPTXFormat/Logic/SpTreeElem.h @@ -93,15 +93,18 @@ namespace PPTX std::wstring GetUriElem(); smart_ptr GetElem(); + smart_ptr GetElemAlternative(); virtual void SetParentPointer(const WrapperWritingElement* pParent); std::wstring GetSlicerRequires(); nullable m_binaryData; std::wstring m_sRequires;//from mc:Choice + bool m_bAlternative = false; private: smart_ptr m_elem; + smart_ptr m_elem_alternative; protected: virtual void FillParentPointersForChilds(); diff --git a/OOXML/XlsbFormat/Biff12_unions/HLINKS.cpp b/OOXML/XlsbFormat/Biff12_unions/HLINKS.cpp index e466937fe3..65cd9d9fb5 100644 --- a/OOXML/XlsbFormat/Biff12_unions/HLINKS.cpp +++ b/OOXML/XlsbFormat/Biff12_unions/HLINKS.cpp @@ -93,7 +93,7 @@ namespace XLSB count--; } - return count > 0; + return m_arHlinks.size() > 0; } const bool HLINKS::saveContent(BinProcessor& proc) diff --git a/OdfFile/DataTypes/borderwidths.cpp b/OdfFile/DataTypes/borderwidths.cpp index 2f3a7d1cdb..c28403e6d1 100644 --- a/OdfFile/DataTypes/borderwidths.cpp +++ b/OdfFile/DataTypes/borderwidths.cpp @@ -39,7 +39,7 @@ namespace cpdoccore { namespace odf_types { std::wostream & operator << (std::wostream & _Wostream, const border_widths & _Val) { - _Wostream << _Val.get_len1() << " " << _Val.get_len2() << " " << _Val.get_len3(); + _Wostream << _Val.get_len1() << L" " << _Val.get_len2() << L" " << _Val.get_len3(); return _Wostream; } diff --git a/OdfFile/DataTypes/dropcaplength.cpp b/OdfFile/DataTypes/dropcaplength.cpp index 480143bee5..dd5873f735 100644 --- a/OdfFile/DataTypes/dropcaplength.cpp +++ b/OdfFile/DataTypes/dropcaplength.cpp @@ -42,7 +42,7 @@ std::wostream & operator << (std::wostream & _Wostream, const drop_cap_length & switch(_Val.get_type()) { case drop_cap_length::Word: - _Wostream << "word"; + _Wostream << L"word"; break; case drop_cap_length::Integer: _Wostream << _Val.get_value(); diff --git a/OdfFile/DataTypes/linemode.cpp b/OdfFile/DataTypes/linemode.cpp index 0086dc4817..9c34af9bd7 100644 --- a/OdfFile/DataTypes/linemode.cpp +++ b/OdfFile/DataTypes/linemode.cpp @@ -41,10 +41,10 @@ std::wostream & operator << (std::wostream & _Wostream, const line_mode & _Val) switch(_Val.get_type()) { case line_mode::Continuous: - _Wostream << "continuous"; + _Wostream << L"continuous"; break; case line_mode::SkipWhiteSpace: - _Wostream << "skip-white-space"; + _Wostream << L"skip-white-space"; break; default: break; diff --git a/OdfFile/DataTypes/linestyle.cpp b/OdfFile/DataTypes/linestyle.cpp index fb473b8b59..e428bd3a58 100644 --- a/OdfFile/DataTypes/linestyle.cpp +++ b/OdfFile/DataTypes/linestyle.cpp @@ -41,28 +41,28 @@ std::wostream & operator << (std::wostream & _Wostream, const line_style & _Val) switch(_Val.get_type()) { case line_style::None: - _Wostream << "none"; + _Wostream << L"none"; break; case line_style::Solid: - _Wostream << "solid"; + _Wostream << L"solid"; break; case line_style::Dotted: - _Wostream << "dotted"; + _Wostream << L"dotted"; break; case line_style::Dash: - _Wostream << "dash"; + _Wostream << L"dash"; break; case line_style::LongDash: - _Wostream << "long-dash"; + _Wostream << L"long-dash"; break; case line_style::DotDash: - _Wostream << "dot-dash"; + _Wostream << L"dot-dash"; break; case line_style::DotDotDash: - _Wostream << "dot-dot-dash"; + _Wostream << L"dot-dot-dash"; break; case line_style::Wave: - _Wostream << "wave"; + _Wostream << L"wave"; break; default: break; diff --git a/OdfFile/DataTypes/linetype.cpp b/OdfFile/DataTypes/linetype.cpp index 548cdbe43c..7383c43ea5 100644 --- a/OdfFile/DataTypes/linetype.cpp +++ b/OdfFile/DataTypes/linetype.cpp @@ -41,13 +41,13 @@ std::wostream & operator << (std::wostream & _Wostream, const line_type & _Val) switch(_Val.get_type()) { case line_type::None: - _Wostream << "none"; + _Wostream << L"none"; break; case line_type::Single: - _Wostream << "single"; + _Wostream << L"single"; break; case line_type::Double: - _Wostream << "double"; + _Wostream << L"double"; break; default: break; diff --git a/OdfFile/DataTypes/linewidth.cpp b/OdfFile/DataTypes/linewidth.cpp index c5f5242239..9c556e84b1 100644 --- a/OdfFile/DataTypes/linewidth.cpp +++ b/OdfFile/DataTypes/linewidth.cpp @@ -41,25 +41,25 @@ std::wostream & operator << (std::wostream & _Wostream, const line_width & _Val) switch(_Val.get_type()) { case line_width::Auto: - _Wostream << "auto"; + _Wostream << L"auto"; break; case line_width::Normal: - _Wostream << "normal"; + _Wostream << L"normal"; break; case line_width::Bold: - _Wostream << "bold"; + _Wostream << L"bold"; break; case line_width::Thin: - _Wostream << "thin"; + _Wostream << L"thin"; break; case line_width::Dash: - _Wostream << "dash"; + _Wostream << L"dash"; break; case line_width::Medium: - _Wostream << "medium"; + _Wostream << L"medium"; break; case line_width::Thick: - _Wostream << "thick"; + _Wostream << L"thick"; break; case line_width::PositiveInteger: _Wostream << _Val.get_positive_integer(); diff --git a/OdfFile/DataTypes/officevaluetype.cpp b/OdfFile/DataTypes/officevaluetype.cpp index ebfccd6966..a4d3b084a1 100644 --- a/OdfFile/DataTypes/officevaluetype.cpp +++ b/OdfFile/DataTypes/officevaluetype.cpp @@ -34,9 +34,12 @@ #include "officevaluetype.h" #include "../Common/errors.h" +#include +#include + namespace cpdoccore { namespace odf_types { -std::wostream & operator << (std::wostream & _Wostream, const office_value_type & _Val) +std::wostream& operator << (std::wostream& _Wostream, const office_value_type& _Val) { switch(_Val.get_type()) { @@ -46,27 +49,29 @@ std::wostream & operator << (std::wostream & _Wostream, const office_value_type case office_value_type::Float: case office_value_type::Scientific: case office_value_type::Fraction: - _Wostream << "float"; - break; + { + _Wostream << L"float"; + } break; case office_value_type::Currency: - _Wostream << "currency"; + _Wostream << L"currency"; break; case office_value_type::Percentage: - _Wostream << "percentage"; + _Wostream << L"percentage"; break; case office_value_type::Date: case office_value_type::DateTime: - _Wostream << "date"; + _Wostream << L"date"; break; case office_value_type::Time: - _Wostream << "time"; + _Wostream << L"time"; break; case office_value_type::Boolean: - _Wostream << "boolean"; + _Wostream << L"boolean"; break; case office_value_type::String: - _Wostream << "string"; - break; + { + _Wostream << L"string"; + }break; default: break; } diff --git a/OdfFile/DataTypes/targetframename.cpp b/OdfFile/DataTypes/targetframename.cpp index d35c3e031f..3743b9731a 100644 --- a/OdfFile/DataTypes/targetframename.cpp +++ b/OdfFile/DataTypes/targetframename.cpp @@ -45,16 +45,16 @@ std::wostream & operator << (std::wostream & _Wostream, const target_frame_name { default: case target_frame_name::Self: - _Wostream << "_self"; + _Wostream << L"_self"; break; case target_frame_name::Blank: - _Wostream << "_blank"; + _Wostream << L"_blank"; break; case target_frame_name::Parent: - _Wostream << "_parent"; + _Wostream << L"_parent"; break; case target_frame_name::Top: - _Wostream << "_top"; + _Wostream << L"_top"; break; case target_frame_name::String: _Wostream << _Val.get_name(); diff --git a/OdfFile/DataTypes/xlink.cpp b/OdfFile/DataTypes/xlink.cpp index 5fedfc8223..153af9aaef 100644 --- a/OdfFile/DataTypes/xlink.cpp +++ b/OdfFile/DataTypes/xlink.cpp @@ -55,11 +55,11 @@ std::wostream & operator << (std::wostream & _Wostream, const xlink_actuate & _A switch (_Actuate.get_type()) { case xlink_actuate::OnLoad: - _Wostream << "onLoad"; + _Wostream << L"onLoad"; break; default: case xlink_actuate::OnRequest: - _Wostream << "onRequest"; + _Wostream << L"onRequest"; break; } return _Wostream; diff --git a/OdfFile/Reader/Format/draw_shapes.cpp b/OdfFile/Reader/Format/draw_shapes.cpp index 58e9ac7adf..c1c841497d 100644 --- a/OdfFile/Reader/Format/draw_shapes.cpp +++ b/OdfFile/Reader/Format/draw_shapes.cpp @@ -530,34 +530,31 @@ void draw_enhanced_geometry::add_child_element( xml::sax * Reader, const std::ws } } -std::wstring convert_equation(const std::wstring& formula) +bool convert_equation(const std::wstring& formula, std::wstring &result) { - std::wstring result; std::wstring operators; + std::wstring function; std::vector values; size_t pos = 0; - bool operator_prev = false; while (pos < formula.size()) { - if ((formula[pos] == L'+' || formula[pos] == L'/' || formula[pos] == L'*' || formula[pos] == L'-') - && pos > 0 && !operator_prev) + if ((formula[pos] == L'+' || formula[pos] == L'/' || formula[pos] == L'*' || formula[pos] == L'-') && pos > 0) { - if (operators.size() > 1) - return L""; - operator_prev = true; + if (operators.size() > 1 && !function.empty()) + { + return false; // ? todooo + } operators += formula[pos++]; } else if (formula[pos] == L'i' && formula[pos + 1] == L'f') { if (false == operators.empty()) - return L""; - operator_prev = true; - operators += L"?:"; pos += 2; + return false; + function += L"?:"; pos += 2; } else if (formula[pos] == L'?') { - operator_prev = false; values.emplace_back(); values.back() = L"gd"; pos += 2; while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9') @@ -568,60 +565,67 @@ std::wstring convert_equation(const std::wstring& formula) else if (formula[pos] == L'c') { if (false == operators.empty()) - return L""; - operator_prev = true; - operators += L"cos"; pos += 3; + return false; + + if (pos + 2 < formula.size() && formula[pos + 1] == L'o') + { + function = L"cos"; pos += 3; + } + else if (pos + 3 < formula.size() && formula[pos + 1] == L'a' && formula[pos + 2] == L't') + { + function = L"cat2"; pos += 4; + } + else pos++; } else if (formula[pos] == L'b') {//bottom - operator_prev = false; values.emplace_back(); values.back() = L"h"; pos += 6; } else if (formula[pos] == L't') {//top - operator_prev = false; values.emplace_back(); values.back() = L"0"; pos += 3; } else if (formula[pos] == L'r') {//right - operator_prev = false; values.emplace_back(); values.back() = L"w"; pos += 5; } else if (formula[pos] == L's') { if (false == operators.empty()) - return L""; - operator_prev = true; + return false; if (pos + 2 < formula.size() && formula[pos + 1] == L'i') { - operators = L"sin"; pos += 3; + function = L"sin"; pos += 3; } else if (pos + 3 < formula.size() && formula[pos + 1] == L'q') { - operators = L"sqrt"; pos += 4; + function = L"sqrt"; pos += 4; } + else if (pos + 3 < formula.size() && formula[pos + 1] == L'a' && formula[pos + 2] == L't') + { + function = L"sat2"; pos += 4; + } + else pos++; } else if (formula[pos] == L'm') { if (false == operators.empty()) - return L""; - operator_prev = true; + return false; if (pos + 2 < formula.size() && formula[pos + 1] == L'a') { - operators = L"max"; pos += 3; + function = L"max"; pos += 3; } else if (pos + 2 < formula.size() && formula[pos + 1] == L'i') { - operators = L"min"; pos += 3; + function = L"min"; pos += 3; } else pos++; } else if (formula[pos] == L'l') { - operator_prev = false; if (pos + 8 < formula.size() && formula[pos + 1] == L'o' && formula[pos + 2] == L'g') { if (formula[pos + 3] == L'w') @@ -644,8 +648,6 @@ std::wstring convert_equation(const std::wstring& formula) } else if (formula[pos] == L'$') { - operator_prev = false; - if (pos + 1 < formula.size() && formula[pos + 1] >= L'0' && formula[pos + 1] <= L'9') { std::wstring strVal = formula.substr(pos + 1, 1); @@ -656,39 +658,37 @@ std::wstring convert_equation(const std::wstring& formula) } pos += 2; } - else if (formula[pos] >= L'0' && formula[pos] <= L'9' || formula[pos] == L'-') + else if (formula[pos] >= L'0' && formula[pos] <= L'9' || formula[pos] == L'-' || formula[pos] == L'w' || formula[pos] == L'h') { - operator_prev = false; - values.emplace_back(); size_t pos_start = pos; - while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9' || (formula[pos] == L'-' && pos_start == pos)) + while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9' || ((formula[pos] == L'-' || formula[pos] == L'w' || formula[pos] == L'h') && pos_start == pos)) { values.back() += formula[pos++]; } } + else if (formula[pos] == L',') + { + pos++; + } else pos++; } - if (operators.empty()) + if (operators.empty() && function.empty()) { result = L"val"; } - else if (operators.size() < 2) - { - return L""; - } else { - result = operators; + result = function.empty() ? operators : function; } for (int i = 0; i < values.size(); ++i) { result += L" " + values[i]; } - return result; + return true; } void draw_enhanced_geometry::find_draw_type_oox() { @@ -804,19 +804,23 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro std::wstring value = eq->attlist_.draw_formula_.get_value_or(L""); XmlUtils::replace_all(name, L"f", L"gd"); - value = convert_equation(value); + + XmlUtils::replace_all(value, L"(bottom-top)", L"h"); + XmlUtils::replace_all(value, L"(right-left)", L"w"); ; - if (value.empty()) + std::wstring value_conv; + if (convert_equation(value, value_conv)) { + equations.push_back(std::make_pair(name, value)); + equations.push_back(std::make_pair(name, value_conv.empty() ? value : value_conv)); + } + else + {// if (!draw_type_oox_index_) set_shape = false; equations.clear(); break; } - else - {// - equations.push_back(std::make_pair(name, value)); - } } } diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index 586c9da949..6545f16250 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -1345,7 +1345,7 @@ void odf_drawing_context::start_element(office_element_ptr elm, office_element_p //если фейковый предыдущий уровень (для сохранения порядка выше) - привязывааем к уровню выше - for (int i = impl_->current_level_.size() - 1; elm && i >= 0; i--) + for (int i = (int)impl_->current_level_.size() - 1; elm && i >= 0; i--) { if (impl_->current_level_[i].elm) { @@ -1653,7 +1653,7 @@ int odf_drawing_context::get_formulas_count() if (!impl_->current_drawing_state_.oox_shape_) return 0; - return impl_->current_drawing_state_.oox_shape_->equations.size(); + return (int)impl_->current_drawing_state_.oox_shape_->equations.size(); } void odf_drawing_context::set_path(std::wstring path_string) { @@ -1766,6 +1766,11 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) size_t nStart = 0; size_t nCurrent = 0; + XmlUtils::replace_all(fmla, L" * ", L"*"); + XmlUtils::replace_all(fmla, L" - ", L"-"); + XmlUtils::replace_all(fmla, L" + ", L"+"); + XmlUtils::replace_all(fmla, L" / ", L"/"); + const wchar_t* pData = fmla.c_str(); int nFound = 0, x = 0, y = 0; @@ -1791,7 +1796,10 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) } else { - val[nFound-1] = std::wstring( pData + nStart, (ULONG)(nCurrent - nStart)); + if (nFound > 4) + return; // ! + + val[nFound - 1] = std::wstring(pData + nStart, (ULONG)(nCurrent - nStart)); } nStart = nCurrent + 1; ++nFound; @@ -1836,7 +1844,7 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) { odf_fmla += val[i] + L","; } - odf_fmla += val[nFound-1] + L")"; break; + odf_fmla += val[nFound - 1] + L")"; break; case 4: odf_fmla = L"abs(" + val[0] + L")"; break; @@ -1861,7 +1869,6 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) XmlUtils::replace_all(odf_fmla, L"h", L"(bottom-top)"); XmlUtils::replace_all(odf_fmla, L"w", L"(right-left)"); XmlUtils::replace_all(odf_fmla, L"adj", L"$"); - //XmlUtils::replace_all(name, L"gd", L"f"); impl_->current_drawing_state_.oox_shape_->add(name, odf_fmla); } diff --git a/OdfFile/Writer/Format/office_meta.cpp b/OdfFile/Writer/Format/office_meta.cpp index 4574c33cbe..507992192f 100644 --- a/OdfFile/Writer/Format/office_meta.cpp +++ b/OdfFile/Writer/Format/office_meta.cpp @@ -229,7 +229,7 @@ void meta_user_defined::serialize(std::wostream & _Wostream) CP_XML_NODE_SIMPLE() { CP_XML_ATTR(L"meta:name", meta_name_); - CP_XML_ATTR(L"meta:value-type", meta_value_type_); + CP_XML_ATTR_OPT(L"meta:value-type", meta_value_type_); CP_XML_STREAM() << XmlUtils::EncodeXmlString(content_); } diff --git a/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro b/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro index 21c1d2d66a..df66d25d18 100644 --- a/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro +++ b/OfficeCryptReader/ooxml_crypt/ooxml_crypt.pro @@ -24,11 +24,15 @@ DESTDIR = $$CORE_BUILDS_BINARY_PATH HEADERS += \ $$PWD/../source/ECMACryptFile.h \ $$PWD/../source/CryptTransform.h \ - $$PWD/../source/simple_xml_writer.h + $$PWD/../source/simple_xml_writer.h \ + ../../MsBinaryFile/XlsFile/Format/Logging/Log.h \ + ../../MsBinaryFile/XlsFile/Format/Logging/Logger.h SOURCES += \ $$PWD/../source/ECMACryptFile.cpp \ - $$PWD/../source/CryptTransform.cpp + $$PWD/../source/CryptTransform.cpp \ + ../../MsBinaryFile/XlsFile/Format/Logging/Log.cpp \ + ../../MsBinaryFile/XlsFile/Format/Logging/Logger.cpp SOURCES += \ $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp \ diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index feb6568bab..5d01bdba03 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -113,7 +113,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) { obj->arrayGetNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pArray, bBinary, ""); + DictToCDictObject(&oTemp, pArray, bBinary, "", bUnicode); oTemp.free(); } break; @@ -126,7 +126,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, { char* chKey = obj->dictGetKey(nIndex); obj->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pDict, bBinary, chKey); + DictToCDictObject(&oTemp, pDict, bBinary, chKey, bUnicode); oTemp.free(); } break; @@ -1198,8 +1198,9 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) { + bool bUnicode = false; char* chKey = oAnnot.dictGetKey(nIndex); - if (strcmp("Popup", chKey) == 0) + if (!strcmp("Popup", chKey)) { Object oPopupRef; if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) @@ -1213,7 +1214,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } continue; } - if (strcmp("Parent", chKey) == 0 && bIsWidget) + else if (!strcmp("Parent", chKey) && bIsWidget) { Object oParentRef; oAnnot.dictGetValNF(nIndex, &oParentRef); @@ -1244,9 +1245,11 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } oParentRef.free(); } + else if (!strcmp("Opt", chKey)) + bUnicode = true; Object oTemp; oAnnot.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pAnnot, false, chKey); + DictToCDictObject(&oTemp, pAnnot, false, chKey, bUnicode); oTemp.free(); } diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 3eeac7e478..6a8ac9c115 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -303,16 +303,19 @@ namespace PdfWriter sRes.append(" ] 0 d\012"); return sRes; } + CAnnotAppearanceObject* CAnnotation::StartAP() + { + m_pAppearance = new CAnnotAppearance(m_pXref, this); + if (!m_pAppearance) + return NULL; + Add("AP", m_pAppearance); + return m_pAppearance->GetNormal(); + } void CAnnotation::APFromFakePage(CPage* pFakePage) { - // xref NULL - тогда у CAnnotAppearanceObject не будет создан stream - m_pAppearance = new CAnnotAppearance(NULL, this); if (!m_pAppearance) return; - Add("AP", m_pAppearance); - CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal((CResourcesDict*)pFakePage->Get("Resources")); - m_pXref->Add(pNormal); - m_pAppearance->Add("N", pNormal); + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); CArrayObject* pArray = new CArrayObject(); if (!pArray) @@ -335,15 +338,6 @@ namespace PdfWriter pArray->Add(1); pArray->Add(-GetRect().fLeft); pArray->Add(-GetRect().fBottom); - - CDictObject* pFPStream = pFakePage->GetContent(); - pNormal->SetStream(m_pXref, pFPStream->GetStream(), false); -#ifndef FILTER_FLATE_DECODE_DISABLED - if (m_pDocument->GetCompressionMode() & COMP_TEXT) - pNormal->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif - pFPStream->SetStream(NULL); - // RELEASEOBJECT(pFPStream); Нельзя удалять - это объект стрима, он уже в xref } //---------------------------------------------------------------------------------------- // CMarkupAnnotation @@ -2041,10 +2035,35 @@ namespace PdfWriter void CCheckBoxWidget::SwitchAP(const std::string& sV) { CObjectBase* pAP, *pAPN; - if ((pAP = Get("AP")) && pAP->GetType() == object_type_DICT && (pAPN = ((CDictObject*)pAP)->Get("N")) && pAPN->GetType() == object_type_DICT && ((CDictObject*)pAPN)->Get(sV)) + Add("AS", "Off"); + if (!m_sAP_N_Yes.empty()) + { + CObjectBase* pObj = GetObjValue("Opt"); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + CArrayObject* pArr = (CArrayObject*)pObj; + for (int i = 0; i < pArr->GetCount(); ++i) + { + pObj = pArr->Get(i); + if (pObj->GetType() == object_type_ARRAY && ((CArrayObject*)pObj)->GetCount() > 0) + pObj = ((CArrayObject*)pObj)->Get(0); + if (pObj->GetType() == object_type_STRING) + { + CStringObject* pStr = (CStringObject*)pObj; + const BYTE* pBinary = pStr->GetString(); + if (pStr->GetLength() == m_sAP_N_Yes.length() && !StrCmp((const char*)pBinary, m_sAP_N_Yes.c_str())) + { + m_sAP_N_Yes = std::to_string(i); + SetV(UTF8_TO_U(m_sAP_N_Yes)); + break; + } + } + } + } + Add("AS", m_sAP_N_Yes.c_str()); + } + else if ((pAP = Get("AP")) && pAP->GetType() == object_type_DICT && (pAPN = ((CDictObject*)pAP)->Get("N")) && pAPN->GetType() == object_type_DICT && ((CDictObject*)pAPN)->Get(sV)) Add("AS", sV.c_str()); - else - Add("AS", "Off"); } void CCheckBoxWidget::SetFlag(const int& nFlag) { @@ -2108,6 +2127,7 @@ namespace PdfWriter { m_dHeight = 0; m_nTI = -1; + m_bAPV = false; } void CChoiceWidget::SetFlag(const int& nFlag) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index d3a7d48903..5c8db04a39 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -184,6 +184,7 @@ namespace PdfWriter void SetC(const std::vector& arrC); void APFromFakePage(CPage* pFakePage); + CAnnotAppearanceObject* StartAP(); TRect& GetRect() { return m_oRect; } void SetXref(CXref* pXref) { m_pXref = pXref; } void SetDocument(CDocument* pDocument); @@ -549,6 +550,7 @@ namespace PdfWriter double m_dHeight; int m_nTI; std::vector m_arrIndex; + bool m_bAPV; public: CChoiceWidget(CXref* pXref); @@ -558,12 +560,14 @@ namespace PdfWriter void SetI(const std::vector& arrI); void SetV(const std::vector& arrV); void SetOpt(const std::vector< std::pair >& arrOpt); + void SetAPV() { m_bAPV = true; } std::wstring GetValue(const std::wstring& wsExportV); void SetListBoxHeight(double dHeight) { m_dHeight = dHeight; } double GetListBoxHeight() { return m_dHeight; } std::wstring SetListBoxIndex(const std::vector& arrV); std::vector GetListBoxIndex() { return m_arrIndex; } + bool HaveAPV() { return m_bAPV; } }; class CSignatureWidget : public CWidgetAnnotation { diff --git a/RtfFile/OOXml/Reader/OOXMathReader.cpp b/RtfFile/OOXml/Reader/OOXMathReader.cpp index a213d16409..a36ca28fa8 100644 --- a/RtfFile/OOXml/Reader/OOXMathReader.cpp +++ b/RtfFile/OOXml/Reader/OOXMathReader.cpp @@ -236,6 +236,20 @@ bool OOXMathReader::ParseElement(ReaderParameter oParam , OOX::WritingElement * rtfMath->AddItem(oSubMath); } }break; + case OOX::et_m_borderBox: + { + OOX::Logic::CBorderBox* ooxSubMath = dynamic_cast(ooxMath); + if (ooxSubMath) + { + RtfMathPtr oSubMath; + if (ParseElement(oParam, ooxSubMath->m_oBorderBoxPr.GetPointer(), oSubMath)) + rtfMath->AddItem(oSubMath); + + oSubMath.reset(); + if (ParseElement(oParam, ooxSubMath->m_oElement.GetPointer(), oSubMath)) + rtfMath->AddItem(oSubMath); + } + }break; case OOX::et_m_box: { OOX::Logic::CBox *ooxSubMath = dynamic_cast(ooxMath); @@ -250,6 +264,25 @@ bool OOXMathReader::ParseElement(ReaderParameter oParam , OOX::WritingElement * rtfMath->AddItem(oSubMath); } }break; + case OOX::et_m_borderBoxPr: + { + OOX::Logic::CBorderBoxPr* ooxSubMath = dynamic_cast(ooxMath); + if (ooxSubMath) + { + RtfMathPtr oSubMath; + if (ParseElement(oParam, ooxSubMath->m_oCtrlPr.GetPointer(), oSubMath)) + rtfMath->AddItem(oSubMath); + + //nullable m_oHideBot; + //nullable m_oHideLeft; + //nullable m_oHideRight; + //nullable m_oHideTop; + //nullable m_oStrikeBLTR; + //nullable m_oStrikeH; + //nullable m_oStrikeTLBR; + //nullable m_oStrikeV; + } + }break; case OOX::et_m_boxPr: { OOX::Logic::CBoxPr *ooxSubMath = dynamic_cast(ooxMath); diff --git a/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp b/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp index 8233c736cc..e8a5697fed 100644 --- a/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp +++ b/RtfFile/OOXml/Reader/OOXParagraphElementReaders.cpp @@ -468,7 +468,7 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP oMathReader.m_oCharProperty = m_oCharProperty; oMathReader.m_oCharProperty.Merge(oOutputParagraph.m_oProperty.m_oCharProperty); - if(true == oMathReader.Parse( oParam, (*oNewMath) ) ) + if (true == oMathReader.Parse( oParam, (*oNewMath) ) ) oOutputParagraph.AddItem( oNewMath ); }break; case OOX::et_m_oMathPara: @@ -482,17 +482,17 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP oMathReader.m_oCharProperty = m_oCharProperty; oMathReader.m_oCharProperty.Merge(oOutputParagraph.m_oProperty.m_oCharProperty); - if(true == oMathReader.Parse( oParam, (*oNewMath) ) ) + if (true == oMathReader.Parse( oParam, (*oNewMath) ) ) oOutputParagraph.AddItem( oNewMath ); }break; case OOX::et_w_sdt: { OOX::Logic::CSdt * pSdt = dynamic_cast(m_ooxElement); - if( pSdt->m_oSdtEndPr.IsInit() ) + if (pSdt->m_oSdtEndPr.IsInit() ) { //todo } - if(pSdt->m_oSdtContent.IsInit()) + if (pSdt->m_oSdtContent.IsInit()) { if (pSdt->m_oSdtContent->m_arrItems.size() > 0) { @@ -508,12 +508,12 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP { OOX::Logic::CCommentRangeStart * pCommentStart = dynamic_cast(m_ooxElement); - if(pCommentStart->m_oId.IsInit()) + if (pCommentStart->m_oId.IsInit()) { int nId = pCommentStart->m_oId->GetValue(); std::map::iterator pFind = oParam.oReader->m_mapComments.find( nId ); - if( pFind == oParam.oReader->m_mapComments.end()) + if (pFind == oParam.oReader->m_mapComments.end()) { RtfAnnotElemPtr oNewAnnotElem ( new RtfAnnotElem(1) ); oNewAnnotElem->m_sValue = std::to_wstring(0x7700000 + nId); @@ -535,7 +535,7 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP std::map::iterator pFindRef = oParam.oReader->m_mapComments.find( nId ); - if( pFindRef != oParam.oReader->m_mapComments.end()) + if (pFindRef != oParam.oReader->m_mapComments.end()) { RtfAnnotElemPtr oNewAnnotElem ( new RtfAnnotElem(2) ); oNewAnnotElem->m_sValue = pFindRef->second.ref; @@ -546,7 +546,7 @@ bool OOXParagraphReader::Parse3( ReaderParameter oParam , RtfParagraph& oOutputP if (pFindComment != oParam.oDocx->m_oMain.comments->m_mapComments.end()) { - if ( pFindComment->second < (int)oParam.oDocx->m_oMain.comments->m_arrComments.size() && pFindComment->second >= 0) + if (pFindComment->second < (int)oParam.oDocx->m_oMain.comments->m_arrComments.size() && pFindComment->second >= 0) { OOX::CComment* oox_comment = oParam.oDocx->m_oMain.comments->m_arrComments[pFindComment->second]; if (oox_comment) @@ -688,28 +688,28 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap { switch(ooxFldChar->m_oFldCharType->GetValue()) { - case SimpleTypes::fldchartypeBegin: + case SimpleTypes::fldchartypeBegin: { - OOXFieldBeginPtr oNewField ( new OOXFieldBegin() ); + OOXFieldBeginPtr oNewField(new OOXFieldBegin()); if (ooxFldChar->m_oFldLock.IsInit()) oNewField->m_bLock = ooxFldChar->m_oFldLock->ToBool(); if (ooxFldChar->m_oDirty.IsInit()) oNewField->m_bDirty = ooxFldChar->m_oDirty->ToBool(); - + oNewField->m_oCharProperty = oNewProperty; - oOutputParagraph.AddItem( oNewField ); + oOutputParagraph.AddItem(oNewField); }break; - case SimpleTypes::fldchartypeEnd: + case SimpleTypes::fldchartypeEnd: { - OOXFieldEndPtr oNewField ( new OOXFieldEnd() ); - oOutputParagraph.AddItem( oNewField ); + OOXFieldEndPtr oNewField(new OOXFieldEnd()); + oOutputParagraph.AddItem(oNewField); }break; - case SimpleTypes::fldchartypeSeparate: + case SimpleTypes::fldchartypeSeparate: { - OOXFieldSeparatePtr oNewField ( new OOXFieldSeparate() ); - oOutputParagraph.AddItem( oNewField ); + OOXFieldSeparatePtr oNewField(new OOXFieldSeparate()); + oOutputParagraph.AddItem(oNewField); }break; - default: break; + default: break; } } }break; @@ -735,7 +735,7 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap int nID = ooxFootnoteReference->m_oId->GetValue(); std::map::iterator oPair = oParam.oReader->m_mapFootnotes.find( nID ); - if( oParam.oReader->m_mapFootnotes.end() != oPair ) + if (oParam.oReader->m_mapFootnotes.end() != oPair ) { RtfFootnotePtr oNewFootnote ( new RtfFootnote() ); oNewFootnote->m_oCharProp = oNewProperty; @@ -753,7 +753,7 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap int nID = ooxEndnoteReference->m_oId->GetValue(); std::map::iterator oPair = oParam.oReader->m_mapEndnotes.find ( nID ); - if( oParam.oReader->m_mapEndnotes.end() != oPair ) + if (oParam.oReader->m_mapEndnotes.end() != oPair ) { RtfFootnotePtr oNewEndnote ( new RtfFootnote() ); oNewEndnote->m_oCharProp = oNewProperty; diff --git a/RtfFile/OOXml/Reader/OOXReader.h b/RtfFile/OOXml/Reader/OOXReader.h index 16d739866b..8dea8cadef 100644 --- a/RtfFile/OOXml/Reader/OOXReader.h +++ b/RtfFile/OOXml/Reader/OOXReader.h @@ -63,7 +63,8 @@ public: RtfConvertationManager* m_convertationManager; std::wstring m_sPath; - int m_nCurItap; //для определение вложенности таблицы + int m_nCurItap = 0; //для определение вложенности таблицы + bool m_bInTable = false; int m_nCurOleChartId; int m_nCurFittextId; diff --git a/RtfFile/OOXml/Reader/OOXTableReader.cpp b/RtfFile/OOXml/Reader/OOXTableReader.cpp index 611679d76c..f98f439982 100644 --- a/RtfFile/OOXml/Reader/OOXTableReader.cpp +++ b/RtfFile/OOXml/Reader/OOXTableReader.cpp @@ -33,6 +33,7 @@ #include "OOXTableRowReader.h" #include "OOXTableReader.h" #include "OOXParagraphReader.h" +#include "OOXTextItemReader.h" #include "../../../OOXML/DocxFormat/Logic/Table.h" #include "../../../OOXML/DocxFormat/Logic/Paragraph.h" @@ -305,26 +306,8 @@ bool OOXTableCellReader::Parse( ReaderParameter oParam ,RtfTableCell& oOutputCel { switch((*it)->getType()) { - case OOX::et_w_p: - { - OOX::Logic::CParagraph * pParagraph = dynamic_cast(*it); - - RtfParagraphPtr oNewParagraph( new RtfParagraph() ); - //применяем к новому параграфу default property - oNewParagraph->m_oProperty = oParam.oRtf->m_oDefaultParagraphProp; - oNewParagraph->m_oProperty.m_oCharProperty = oParam.oRtf->m_oDefaultCharProp; - - OOXParagraphReader oParagraphReader(pParagraph); - oParagraphReader.Parse( oParam, (*oNewParagraph), oConditionalTableStyle ); - - //ставим стиль таблицы - if( NULL != oParam.poTableStyle ) - oNewParagraph->m_oProperty.m_nTableStyle = oParam.poTableStyle->m_nID; - oNewParagraph->m_oProperty.m_nItap = oParam.oReader->m_nCurItap; - oNewParagraph->m_oProperty.m_bInTable = 1; - - oOutputCell.AddItem( oNewParagraph ); - }break; + case OOX::et_w_tcPr: + break; case OOX::et_w_tbl: { OOX::Logic::CTbl * pTbl = dynamic_cast(*it); @@ -336,13 +319,23 @@ bool OOXTableCellReader::Parse( ReaderParameter oParam ,RtfTableCell& oOutputCel oOutputCell.AddItem( oNewTabel ); oParam.oReader->m_nCurItap -- ; }break; - default: + default: { - //todooo - универсальный риадер - //OOXElementReader oElementReader((*it)); - //ITextItemPtr *rtfElement = oElementReader.Parse( oParam); - //oOutputCell.AddItem( rtfElement ); - }break; + oParam.oReader->m_bInTable = true; + + OOXTextItemReader oElementReader; + if (oElementReader.Parse(*it, oParam)) + { + if (oElementReader.m_oTextItems) + { + for (auto elm : oElementReader.m_oTextItems->m_aArray) + { + oOutputCell.AddItem(elm); + } + } + } + oParam.oReader->m_bInTable = false; + }break; } } return true; diff --git a/RtfFile/OOXml/Reader/OOXTextItemReader.cpp b/RtfFile/OOXml/Reader/OOXTextItemReader.cpp index 8a73a59f6c..371163468d 100644 --- a/RtfFile/OOXml/Reader/OOXTextItemReader.cpp +++ b/RtfFile/OOXml/Reader/OOXTextItemReader.cpp @@ -73,15 +73,28 @@ bool OOXTextItemReader::Parse(OOX::WritingElement* ooxElement, ReaderParameter o OOXParagraphReader oParagraphReader(pParagraph); RtfParagraphPtr oNewParagraph(new RtfParagraph()); - //применяем к новому параграфу default property + //применяем к новому параграфу default property oNewParagraph->m_oProperty = oParam.oRtf->m_oDefaultParagraphProp; oNewParagraph->m_oProperty.m_oCharProperty = oParam.oRtf->m_oDefaultCharProp; - oNewParagraph->m_oProperty.m_nItap = 0; + + if (oParam.oReader->m_bInTable) + { + if (NULL != oParam.poTableStyle) + oNewParagraph->m_oProperty.m_nTableStyle = oParam.poTableStyle->m_nID; + oNewParagraph->m_oProperty.m_bInTable = 1; + oNewParagraph->m_oProperty.m_nItap = oParam.oReader->m_nCurItap; + } + else + { + oNewParagraph->m_oProperty.m_nItap = 0; + } if (true == oParagraphReader.Parse(oParam, (*oNewParagraph), CcnfStyle())) { m_oTextItems->AddItem(oNewParagraph); } + + }break; case OOX::et_w_tbl: { diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index a51b6d630b..53f1872143 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1488,10 +1488,16 @@ namespace NExtractTools return AVS_FILEUTILS_ERROR_UNKNOWN; } + std::wstring sGlobalTempDir = L""; + if (NSFile::CFileBinary::IsGlobalTempPathUse()) + sGlobalTempDir = NSFile::CFileBinary::GetTempPath(); + NSFile::CFileBinary::SetTempPath(oConvertParams.m_sTempDir); if (!oInputParams.checkInputLimits()) { + if (!sGlobalTempDir.empty()) + NSFile::CFileBinary::SetTempPath(sGlobalTempDir); return AVS_FILEUTILS_ERROR_CONVERT_LIMITS; } @@ -2116,6 +2122,9 @@ namespace NExtractTools NSDirectory::DeleteDirectory(oConvertParams.m_sTempDir); } + if (!sGlobalTempDir.empty()) + NSFile::CFileBinary::SetTempPath(sGlobalTempDir); + // clean up v8 #ifndef BUILD_X2T_AS_LIBRARY_DYLIB NSDoctRenderer::CDocBuilder::Dispose();