diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 6dd82b5e1e..1deffe5bfb 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -514,6 +514,9 @@ namespace NSCSS return true; } + if (!arSelectors.back().m_pCompiledStyle->Empty()) + return true; + arSelectors.back().m_pCompiledStyle->SetDpi(m_nDpi); unsigned int unStart = 0; @@ -522,7 +525,7 @@ namespace NSCSS if (itFound != arSelectors.crend()) unStart = itFound.base() - arSelectors.cbegin(); - std::vector arNodes = CalculateAllNodes(arSelectors, unStart); + std::vector arNodes = CalculateAllNodes(arSelectors, unStart, arSelectors.size()); std::vector arPrevNodes = CalculateAllNodes(arSelectors, 0, unStart); bool bInTable = false; @@ -548,6 +551,7 @@ namespace NSCSS { arSelectors[i].m_pCompiledStyle->m_oBackground.Clear(); arSelectors[i].m_pCompiledStyle->m_oBorder.Clear(); + arSelectors[i].m_pCompiledStyle->m_oDisplay.Clear(); } arSelectors[i].m_pCompiledStyle->AddStyle(arSelectors[i].m_mAttributes, i + 1); @@ -594,7 +598,7 @@ namespace NSCSS std::vector CCssCalculator_Private::CalculateAllNodes(const std::vector &arSelectors, unsigned int unStart, unsigned int unEnd) { - if (0 != unEnd && (unEnd < unStart || unEnd > arSelectors.size())) + if ((0 != unEnd && (unEnd < unStart || unEnd > arSelectors.size())) || (unStart == unEnd)) return std::vector(); std::vector arNodes; @@ -630,7 +634,7 @@ namespace NSCSS if (arNextNodes.empty()) return; - const std::vector arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend()); + const std::vector arTempPrev = pElement->GetPrevElements(arNextNodes.cbegin(), arNextNodes.cend()); const std::vector arTempKins = pElement->GetNextOfKin(wsName, arClasses); if (!arTempPrev.empty()) @@ -647,20 +651,19 @@ namespace NSCSS std::vector arFindedElements; - std::wstring wsName, wsId; + std::wstring wsName, wsClasses, wsId; std::vector arClasses; if (!arNodes.empty() && arNodes.back()[0] == L'#') { wsId = arNodes.back(); arNodes.pop_back(); - arNextNodes.push_back(wsId); } if (!arNodes.empty() && arNodes.back()[0] == L'.') { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" "); - arNextNodes.push_back(arNodes.back()); + wsClasses = arNodes.back(); + arClasses = NS_STATIC_FUNCTIONS::GetWordsW(wsClasses, false, L" "); arNodes.pop_back(); } @@ -668,7 +671,6 @@ namespace NSCSS { wsName = arNodes.back(); arNodes.pop_back(); - arNextNodes.push_back(wsName); } if (!wsId.empty()) @@ -727,6 +729,14 @@ namespace NSCSS { return oFirstElement->GetWeight() > oSecondElement->GetWeight(); }); } + if (!wsId.empty()) + arNextNodes.push_back(wsId); + + if (!wsClasses.empty()) + arNextNodes.push_back(wsClasses); + + arNextNodes.push_back(wsName); + return arFindedElements; } @@ -741,7 +751,7 @@ namespace NSCSS if (arSelectors.empty()) return false; - std::vector arNodes = CalculateAllNodes(arSelectors); + std::vector arNodes = CalculateAllNodes(arSelectors, 0, arSelectors.size()); std::vector arNextNodes; for (size_t i = 0; i < arSelectors.size(); ++i) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 5d433a9b29..2f6543a4a4 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -110,7 +110,7 @@ namespace NSCSS void ClearPageData(); #endif - std::vector CalculateAllNodes(const std::vector& arSelectors, unsigned int unStart = 0, unsigned int unEnd = 0); + std::vector CalculateAllNodes(const std::vector& arSelectors, unsigned int unStart, unsigned int unEnd); std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes); void AddStyles(const std::string& sStyle); diff --git a/Common/3dParty/html/css/src/CElement.cpp b/Common/3dParty/html/css/src/CElement.cpp index 1ceda93ff4..22a06291f5 100644 --- a/Common/3dParty/html/css/src/CElement.cpp +++ b/Common/3dParty/html/css/src/CElement.cpp @@ -176,14 +176,14 @@ namespace NSCSS return arElements; } - std::vector CElement::GetPrevElements(const std::vector::const_reverse_iterator& oNodesRBegin, const std::vector::const_reverse_iterator& oNodesREnd) const + std::vector CElement::GetPrevElements(const std::vector::const_iterator& oNodesBegin, const std::vector::const_iterator& oNodesEnd) const { - if (oNodesRBegin >= oNodesREnd || m_arPrevElements.empty()) + if (oNodesBegin >= oNodesEnd || m_arPrevElements.empty()) return std::vector(); std::vector arElements; - for (std::vector::const_reverse_iterator iWord = oNodesRBegin; iWord != oNodesREnd; ++iWord) + for (std::vector::const_iterator iWord = oNodesBegin; iWord != oNodesEnd; ++iWord) { if ((*iWord)[0] == L'.' && ((*iWord).find(L" ") != std::wstring::npos)) { @@ -195,7 +195,7 @@ namespace NSCSS if (oPrevElement->m_sSelector == wsClass) { arElements.push_back(oPrevElement); - std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd); + std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesEnd); arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end()); } } @@ -208,9 +208,8 @@ namespace NSCSS if (oPrevElement->m_sSelector == *iWord) { arElements.push_back(oPrevElement); - std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd); + std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesEnd); arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end()); - // return arElements; } } } diff --git a/Common/3dParty/html/css/src/CElement.h b/Common/3dParty/html/css/src/CElement.h index 9844b27cc6..c606ac1983 100644 --- a/Common/3dParty/html/css/src/CElement.h +++ b/Common/3dParty/html/css/src/CElement.h @@ -39,7 +39,7 @@ namespace NSCSS std::map GetFullStyle(const std::vector& arSelectors) const; std::map GetFullStyle(const std::vector& arNodes) const; std::vector GetNextOfKin(const std::wstring& sName, const std::vector& arClasses = {}) const; - std::vector GetPrevElements(const std::vector::const_reverse_iterator& oNodesRBegin, const std::vector::const_reverse_iterator& oNodesREnd) const; + std::vector GetPrevElements(const std::vector::const_iterator& oNodesBegin, const std::vector::const_iterator& oNodesEnd) const; std::map GetConvertStyle(const std::vector& arNodes) const; CElement *FindPrevElement(const std::wstring& sSelector) const; diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index de5a434faa..9bd2a1eb66 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -69,7 +69,8 @@ namespace NSCSS R_Highlight, R_Shd, R_SmallCaps, - R_Kern + R_Kern, + R_Vanish } RunnerProperties; typedef enum diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index c1594b9ff0..94ac55edea 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1483,6 +1483,21 @@ namespace NSCSS (m_eWhiteSpace.Empty() || m_eWhiteSpace == EWhiteSpace::Normal); } + void CDisplay::Clear() + { + m_oX.Clear(); + m_oY.Clear(); + m_oWidth.Clear(); + m_oHeight.Clear(); + + m_oHAlign.Clear(); + m_oVAlign.Clear(); + + m_oDisplay.Clear(); + + m_eWhiteSpace.Clear(); + } + CDisplay &CDisplay::operator+=(const CDisplay &oDisplay) { m_oX += oDisplay.m_oX; diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 1af5b04755..7198ef4aa8 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -373,6 +373,7 @@ namespace NSCSS const CEnum& GetWhiteSpace() const; bool Empty() const; + void Clear(); CDisplay& operator+=(const CDisplay& oDisplay); bool operator==(const CDisplay& oDisplay) const; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 68622eec01..60084871a5 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -509,6 +509,9 @@ namespace NSCSS else if (L"serif" == wsFontFamily) wsFontFamily = L"Times New Roman"; + if (oStyle.m_oDisplay.GetDisplay() == L"none") + oXmlElement.AddPropertiesInR(RProperties::R_Vanish, L"true"); + oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString()); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 6eb112e02a..0fe9a1b273 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -473,6 +473,12 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const sRStyle += L""; break; } + case CSSProperties::RunnerProperties::R_Vanish: + { + if (oItem.second == L"true") + sRStyle += L""; + break; + } default: break; } diff --git a/Common/3dParty/md/md2html.cpp b/Common/3dParty/md/md2html.cpp index 2c23ae17aa..2257d13b61 100644 --- a/Common/3dParty/md/md2html.cpp +++ b/Common/3dParty/md/md2html.cpp @@ -5,6 +5,9 @@ namespace Md { +#define MD_PARSER_FLAGS MD_DIALECT_GITHUB | MD_FLAG_NOINDENTEDCODEBLOCKS | MD_HTML_FLAG_SKIP_UTF8_BOM | MD_FLAG_HARD_SOFT_BREAKS | MD_HTML_FLAG_XHTML +#define MD_RENDERER_FLAGS MD_HTML_FLAG_XHTML + void ToHtml(const MD_CHAR* pValue, MD_SIZE uSize, void* pData) { if (NULL != pData) @@ -14,7 +17,7 @@ void ToHtml(const MD_CHAR* pValue, MD_SIZE uSize, void* pData) std::string ConvertMdStringToHtml(const std::string& sMdString) { std::string sData; - md_html(sMdString.c_str(), sMdString.length(), ToHtml, &sData, 0, 0); + md_html(sMdString.c_str(), sMdString.length(), ToHtml, &sData, MD_PARSER_FLAGS, MD_RENDERER_FLAGS); return sData; } @@ -36,14 +39,13 @@ void WriteBaseHtmlStyles(NSFile::CFileBinary& oFile) oFile.WriteStringUTF8(L"img { vertical-align: middle; }"); // Styles for tables - oFile.WriteStringUTF8(L"table { margin-bottom: 20px; width: 100%; max-width: 100%; border-spacing:0; border-collapse: collapse; border-color: gray;}"); - oFile.WriteStringUTF8(L"thead { display: table-header-group; vertical-align: middle; }"); + oFile.WriteStringUTF8(L"table { margin-bottom: 20px; width: 100%; max-width: 100%; border-spacing:0; border-collapse: collapse; border-color: gray; vertical-align:middle;}"); + oFile.WriteStringUTF8(L"thead { display: table-header-group;}"); oFile.WriteStringUTF8(L"tr { display: table-row; }"); - oFile.WriteStringUTF8(L"th { text-align: left; display: table-cell; font-weight: bold; }"); + oFile.WriteStringUTF8(L"th { text-align: center; display: table-cell; font-weight: bold; }"); - oFile.WriteStringUTF8(L"table thead tr th { vertical-align: bottom; border-bottom: 2px solid #ddd; }"); - oFile.WriteStringUTF8(L"table thead tr th, table tbody tr th, table thead tr td, table tbody tr td { padding 8px; line-height: 1.4; vertical-align: top; border-top: 1px solid #ddd; }"); - oFile.WriteStringUTF8(L"table > caption + thead > tr > th, table > colgroup + thead > tr > th, table > thead > tr > th, table > caption + thead > tr > td, table > colgroup + thead > tr > td, table > thead > tr > td { border-top: 0; }"); + oFile.WriteStringUTF8(L"table thead tr th, table thead tr td { border-bottom: 2px solid #ddd; border-top: none; }"); + oFile.WriteStringUTF8(L"table tbody tr th, table tbody tr td { padding 8px; line-height: 1.4; border-top: 1px solid #ddd; }"); // Styles for blockquote oFile.WriteStringUTF8(L"blockquote { border-left: 3px solid #e9e9e9; margin: 1.5em 0; padding: 0.5em 10px 0.5em 24px; font-size: 1.25rem; display: block; margin-top: 8pt; font-style: italic; color: #404040; }"); @@ -87,9 +89,7 @@ bool ConvertMdFileToHtml(const std::wstring& wsPathToMdFile, const std::wstring& bool bResult = true; - if (0 != md_html(sMdData.c_str(), sMdData.length(), ToHtmlFile, &oFile, - MD_DIALECT_GITHUB | MD_FLAG_NOINDENTEDCODEBLOCKS | MD_HTML_FLAG_SKIP_UTF8_BOM, - 0)) + if (0 != md_html(sMdData.c_str(), sMdData.length(), ToHtmlFile, &oFile, MD_PARSER_FLAGS, MD_RENDERER_FLAGS)) bResult = false; oFile.WriteStringUTF8(L""); diff --git a/DesktopEditor/raster/Metafile/MetaFile.cpp b/DesktopEditor/raster/Metafile/MetaFile.cpp index 33b3d6aabe..e3acbe2691 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.cpp +++ b/DesktopEditor/raster/Metafile/MetaFile.cpp @@ -68,6 +68,10 @@ namespace MetaFile #ifdef METAFILE_SUPPORT_SVM m_oSvmFile.SetFontManager(m_pFontManager); #endif + + #ifdef METAFILE_SUPPORT_SVG + m_oSvgFile.SetFontManager(m_pFontManager); + #endif m_lType = 0; } @@ -84,7 +88,6 @@ namespace MetaFile std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight) { - #ifdef METAFILE_SUPPORT_WMF_EMF if (c_lMetaWmf == m_lType) { diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index 093a6c8632..244aff037a 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -68,7 +68,13 @@ bool CSvgFile::MarkObject(SVG::CObject *pObject) if (NULL == pObject || pObject->GetId().empty()) return false; - pObject->AddRef(); + pObject->Mark(); + + const MarkedMap::const_iterator itFound = m_mMarkedObjects.find(pObject->GetId()); + + if (m_mMarkedObjects.cend() != itFound) + RELEASEINTERFACE(m_mMarkedObjects[pObject->GetId()]) + m_mMarkedObjects[pObject->GetId()] = pObject; return true; @@ -153,8 +159,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d dTranslateY -= oViewBox.m_oY.ToDouble(NSCSS::Pixel) * dScaleY * dM22; } - const double dMinScale = std::min(dScaleX, dScaleY); - pRenderer->SetTransform(dM11 * dMinScale, 0, 0, dM22 * dMinScale, dTranslateX, dTranslateY); + pRenderer->SetTransform(dM11 * dScaleX, 0, 0, dM22 * dScaleY, dTranslateX, dTranslateY); bool bResult = m_pContainer->Draw(pRenderer, this); @@ -165,7 +170,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d void CSvgFile::Clear() { - RELEASEOBJECT(m_pContainer); + RELEASEINTERFACE(m_pContainer); m_oSvgCalculator.Clear(); for (MarkedMap::reference oIter : m_mMarkedObjects) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp b/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp index 5953aaf328..209bdada77 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp @@ -117,7 +117,7 @@ namespace SVG ScanStyles(oReader, pFile); oReader.MoveToStart(); - RELEASEOBJECT(pContainer); + RELEASEINTERFACE(pContainer); pContainer = CObject::Create(oReader, pFile); @@ -224,7 +224,7 @@ namespace SVG pObject = CObject::Create(oReader, pFile, pParent); if (!ReadChildrens(oReader, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject)) { - RELEASEOBJECT(pObject); + RELEASEINTERFACE(pObject); return false; } } @@ -290,21 +290,21 @@ namespace SVG if (ReadChildrens(oReader, (CSymbol*)pObject, pFile)) return true; else - RELEASEOBJECT(pObject); + RELEASEINTERFACE(pObject); } else if ("font" == sElementName) { - pObject = CObject::Create(oReader, pFile); + pObject = CObject::Create(oReader, pFile, pFile); } if (NULL == pObject) return false; - if ((RendererObject == pObject->GetType() && AddObject((ObjectType*)pObject, pContainer)) || + if ((RendererObject == pObject->GetType() && (AddObject((ObjectType*)pObject, pContainer) || pObject->Marked())) || AppliedObject == pObject->GetType()) return true; - RELEASEOBJECT(pObject); + RELEASEINTERFACE(pObject); return false; } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp index e7b465da49..2781dc40f8 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp @@ -2,22 +2,23 @@ namespace SVG { - CGlyph::CGlyph(CSvgReader& oReader) + CGlyph::CGlyph(CSvgReader& oReader, CSvgFile* pFile) : CPath(oReader) - { - START_READ_ATTRIBUTES(oReader) - { - if ("unicode" == sAttributeName) - { - const std::wstring wsUnicode{oReader.GetText()}; + {} - if (!wsUnicode.empty()) - m_wchUnicode = wsUnicode[0]; - } - else if ("horiz-adv-x" == sAttributeName) - m_oHorizAdvX.SetValue(oReader.GetText()); + void CGlyph::SetAttribute(const std::string& sName, CSvgReader& oReader) + { + if ("unicode" == sName) + { + const std::wstring wsUnicode{oReader.GetText()}; + + if (!wsUnicode.empty()) + m_wchUnicode = wsUnicode[0]; } - END_READ_ATTRIBUTES(oReader) + else if ("horiz-adv-x" == sName) + m_oHorizAdvX.SetValue(oReader.GetText()); + else + CPath::SetAttribute(sName, oReader); } wchar_t CGlyph::GetUnicode() const @@ -28,10 +29,10 @@ namespace SVG CFontFace::CFontFace(CSvgReader& oReader) {} - CFont::CFont(CSvgReader& oReader) + CFont::CFont(CSvgReader& oReader, CSvgFile* pFile) : CAppliedObject(oReader), m_pMissingGlyph(NULL) { - ParseGlyphs(oReader); + ParseGlyphs(oReader, pFile); } CFont::~CFont() @@ -95,7 +96,7 @@ namespace SVG { \ oMatrix.Scale(1. / dGlyphScale, -1. / dGlyphScale); \ pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \ - } \ + } for (wchar_t wchGlyph : wsText) { @@ -128,13 +129,13 @@ namespace SVG return true; } - void CFont::ParseGlyphs(CSvgReader& oReader) + void CFont::ParseGlyphs(CSvgReader& oReader, CSvgFile* pFile) { WHILE_READ_NEXT_NODE_WITH_NAME(oReader) { if ("glyph" == sNodeName) { - CGlyph *pGlyph = new CGlyph(oReader); + CGlyph *pGlyph = CObject::Create(oReader, pFile, pFile); if (NULL == pGlyph) continue; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h index eb13af2d19..a79330c9db 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h @@ -8,7 +8,9 @@ namespace SVG class CGlyph : public CPath { public: - CGlyph(CSvgReader& oReader); + CGlyph(CSvgReader& oReader, CSvgFile* pFile = nullptr); + + void SetAttribute(const std::string& sName, CSvgReader& oReader) override; wchar_t GetUnicode() const; private: @@ -37,7 +39,7 @@ namespace SVG class CFont : public CAppliedObject { friend class CObject; - CFont(CSvgReader& oReader); + CFont(CSvgReader& oReader, CSvgFile* pFile = nullptr); public: ~CFont(); @@ -48,7 +50,7 @@ namespace SVG bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override; bool Draw(const std::wstring& wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const; private: - void ParseGlyphs(CSvgReader& oReader); + void ParseGlyphs(CSvgReader& oReader, CSvgFile* pFile = nullptr); TFontArguments m_oArguments; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp index a82afb233c..afb8afb5e3 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp @@ -9,7 +9,7 @@ namespace SVG ObjectType CStopElement::GetType() const { - return AppliedObject; + return DataObject; } SvgDigit CStopElement::GetOffset() const @@ -62,16 +62,7 @@ namespace SVG return; WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, "stop") - { - CStopElement *pStopElement = new CStopElement(oReader); - - if (NULL == pStopElement) - continue; - - pSvgFile->GetSvgCalculator()->SetData(pStopElement); - - AddObject(pStopElement); - } + AddObject(CObject::Create(oReader, pSvgFile)); END_WHILE } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp index d7e673b6ef..d5ea746b17 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.cpp @@ -42,6 +42,18 @@ namespace SVG : m_oXmlNode(oObject.m_oXmlNode), m_oTransformation(oObject.m_oTransformation) {} + void CObject::Mark() + { + this->AddRef(); + } + + bool CObject::Marked() const + { + //Так как по логике кода объект может храниться только в одном контейнере и в списке маркированных элементов, + //то хватит и такой проверки + return 1 != m_lRef; + } + void CObject::SetAttribute(const std::string& sName, CSvgReader& oReader) { if ("class" == sName) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h index 1f495cf4eb..869e235b2e 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h @@ -34,7 +34,8 @@ namespace SVG enum ObjectType { RendererObject, - AppliedObject + AppliedObject, + DataObject }; class CObject : public IGrObject @@ -48,6 +49,9 @@ namespace SVG virtual ObjectType GetType() const = 0; + void Mark(); + bool Marked() const; + virtual void SetAttribute(const std::string& sName, CSvgReader& oReader); void SetData(const std::wstring wsStyles, unsigned short ushLevel, bool bHardMode = false); @@ -92,7 +96,8 @@ namespace SVG if (NULL == pSvgFile) return pObject; - if (!pSvgFile->MarkObject(pObject) && AppliedObject == pObject->GetType()) + if (DataObject != pObject->GetType() && + (!pSvgFile->MarkObject(pObject) && AppliedObject == pObject->GetType())) { delete pObject; return NULL; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp index 636ced97e5..00341e8bce 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp @@ -32,7 +32,7 @@ namespace SVG const std::vector arSelectors = pSvgObject->GetFullPath(); - std::vector arNodes = m_pInternal->CalculateAllNodes(arSelectors); + std::vector arNodes = m_pInternal->CalculateAllNodes(arSelectors, 0, arSelectors.size()); std::vector arPrevNodes; for (size_t i = 0; i < arSelectors.size(); ++i) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp index 95e566d2ba..7d84b5fae0 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp @@ -9,6 +9,8 @@ #include "../../../../Common/3dParty/html/css/src/StaticFunctions.h" +#include + #ifndef MININT8 #define MAXUINT8 ((unsigned char)~((unsigned char)0)) #define MAXINT8 ((char)(MAXUINT8 >> 1)) @@ -136,7 +138,7 @@ namespace SVG const char* pCheckValue = pValue; while ('\0' != *pCheckValue) { - if (0x32 >= *pCheckValue++) + if (std::isprint(static_cast(*pCheckValue++))) { bFoundedSymbol = true; break; @@ -161,9 +163,9 @@ namespace SVG else if (eNodeType == XmlUtils::XmlNodeType_Element && "tspan" == oReader.GetName()) { const TBounds oBounds{GetBounds()}; - const Point oPoint{oBounds.m_dRight, oBounds.m_dTop}; + const Point oPoint{oBounds.m_dRight, oBounds.m_dBottom}; - AddObject(CRenderedObject::Create(oReader, pSvgFile, this, m_pFontManager, oPoint)); + AddObject(CObject::Create(oReader, pSvgFile, this, m_pFontManager, oPoint)); } } } @@ -185,8 +187,14 @@ namespace SVG { if (!m_wsText.empty()) { - ApplyFont(pRenderer, dX, dY); + Aggplus::CMatrix oCurrentMatrix; + ApplyFont(pRenderer, dX, dY, oCurrentMatrix); + pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0); + + pRenderer->SetTransform(oCurrentMatrix.sx(), oCurrentMatrix.shy(), + oCurrentMatrix.shx(), oCurrentMatrix.sy(), + oCurrentMatrix.tx(), oCurrentMatrix.ty()); } } @@ -228,12 +236,12 @@ namespace SVG nTypePath += c_nWindingFillMode; } - void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const + void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY, Aggplus::CMatrix& oOldMatrix) const { std::wstring wsFontFamily = DefaultFontFamily; double dFontSize = ((!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE) * 72. / 25.4; - Normalize(pRenderer, dX, dY, dFontSize); + Normalize(pRenderer, dX, dY, dFontSize, oOldMatrix); if (!m_oFont.GetFamily().Empty()) { @@ -327,7 +335,7 @@ namespace SVG pRenderer->put_FontStyle(nStyle); pRenderer->put_BrushType(c_BrushTypeSolid); pRenderer->put_BrushColor1(m_oStyles.m_oFill.ToInt()); - pRenderer->put_BrushAlpha1(255); + pRenderer->put_BrushAlpha1(255 * m_oStyles.m_oFill.GetOpacity()); } void CTSpan::UpdateFontSize() @@ -338,7 +346,7 @@ namespace SVG if (NULL != pParentTSpan) { - m_oFont.UpdateSize((!pParentTSpan->m_oFont.GetSize().Empty()) ? pParentTSpan->m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); + m_oFont.UpdateSize((!pParentTSpan->m_oFont.GetSize().Empty()) ? pParentTSpan->m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); return; } } @@ -476,7 +484,7 @@ namespace SVG dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop); } - void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight) const + void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight, Aggplus::CMatrix& oOldMatrix) const { if (NULL == pRenderer) return; @@ -519,6 +527,8 @@ namespace SVG pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy); + oOldMatrix.SetElements(dM11, dM12, dM21, dM22, dDx, dDy); + Aggplus::CMatrix oMatrix(dM11, dM12, dM21, dM22, dDx, dDy); oMatrix.Scale(dXScale, dYScale); diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h index 7e686ebb2b..1c5e135d4d 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h @@ -32,7 +32,7 @@ namespace SVG void InheritStyles(const CTSpan* pTSpan); private: void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; - void ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const; + void ApplyFont(IRenderer* pRenderer, double& dX, double& dY, Aggplus::CMatrix& oOldMatrix) const; void UpdateFontSize(); bool UseExternalFont(const CSvgFile* pFile, double dX, double dY, IRenderer* pRenderer, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const; @@ -44,7 +44,7 @@ namespace SVG void CalculatePosition(double& dX, double& dY) const; - void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight) const; + void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight, Aggplus::CMatrix& oOldMatrix) const; void SetPosition(const Point& oPosition); void SetPositionFromParent(CRenderedObject* pParent); diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 4fd0f4af40..d2378a68ea 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -203,6 +203,11 @@ bool TagIsUnprocessed(const std::wstring& wsTagName) return L"xml" == wsTagName; } +bool IsSVG(const std::wstring& wsExtention) +{ + return L"svg" == wsExtention || L"svg+xml" == wsExtention; +} + static inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag) { std::map::const_iterator oFound = m_HTML_TAGS.find(wsStrTag); @@ -1248,7 +1253,7 @@ public: bool ConvertToOOXML(NSStringUtils::CStringBuilder& oStringBuilder) { - if (m_arRows.empty()) + if (m_arRows.empty() && m_arHeaders.empty() && m_arFoother.empty()) return false; oStringBuilder.WriteNodeBegin(L"w:tbl"); @@ -3054,12 +3059,6 @@ private: std::wstring sNote = GetSubClass(oXml, sSelectors); - if (NULL != sSelectors.back().m_pCompiledStyle && L"none" == sSelectors.back().m_pCompiledStyle->m_oDisplay.GetDisplay().ToWString()) - { - sSelectors.pop_back(); - return false; - } - bool bResult = true; const HtmlTag eHtmlTag{GetHtmlTag(sName)}; @@ -4271,7 +4270,7 @@ private: if (!pImageData || FALSE == NSBase64::Base64Decode(sSrcM.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen)) return bRes; - if (L"svg" == sExtention || L"svg+xml" == sExtention) + if (IsSVG(sExtention)) { std::wstring wsSvg(pImageData, pImageData + nDecodeLen); bRes = readSVG(wsSvg); @@ -4316,8 +4315,8 @@ private: { return sExtention != L"bmp" && sExtention != L"emf" && sExtention != L"emz" && sExtention != L"eps" && sExtention != L"fpx" && sExtention != L"gif" && sExtention != L"jpe" && sExtention != L"jpeg" && sExtention != L"jpg" && sExtention != L"jfif" && sExtention != L"pct" && sExtention != L"pict" && - sExtention != L"png" && sExtention != L"pntg" && sExtention != L"psd" && sExtention != L"qtif" && sExtention != L"sgi" && sExtention != L"svg" && - sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && sExtention != L"wmz"; + sExtention != L"png" && sExtention != L"pntg" && sExtention != L"psd" && sExtention != L"qtif" && sExtention != L"sgi" && sExtention != L"wmz" && + sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && !IsSVG(sExtention); } void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData) @@ -4416,16 +4415,57 @@ private: } int nImageId = -1; - std::wstring sImageSrc, sExtention; + std::wstring sExtention; // Предполагаем картинку в Base64 if (bIsBase64) bRes = readBase64(sSrcM, sExtention); + // Проверка расширения + sExtention = NSFile::GetFileExtention(sSrcM); + std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); + + std::wstring::const_iterator itFound = std::find_if(sExtention.cbegin(), sExtention.cend(), [](wchar_t wChar){ return !iswalpha(wChar) && L'+' != wChar; }); + + if (sExtention.cend() != itFound) + sExtention.erase(itFound, sExtention.cend()); + + // Предполагаем картинку в сети + if (!bRes && + ((!m_sBase.empty() && m_sBase.length() > 4 && m_sBase.substr(0, 4) == L"http") || + (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"http"))) + { + const std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + ((!sExtention.empty()) ? sExtention : L"png"); + + // Проверка gc_allowNetworkRequest предполагается в kernel_network + NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_sBase + sSrcM, false); + oDownloadImg.SetFilePath(wsDst); + bRes = oDownloadImg.DownloadSync(); + + if (!bRes) + { + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData); + return true; + } + + if (IsSVG(sExtention)) + { + std::wstring wsFileData; + + if (!NSFile::CFileBinary::ReadAllTextUtf8(wsDst, wsFileData) || !readSVG(wsFileData)) + bRes = false; + + NSFile::CFileBinary::Remove(wsDst); + sExtention = L"png"; + } + else if (sExtention.empty()) + { + //TODO:: лучше узнавать формат изображения из содержимого + sExtention = L"png"; + } + } + if (!bRes) { - // Проверка расширения - sExtention = NSFile::GetFileExtention(sSrcM); - std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); if (NotValidExtension(sExtention)) { ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData); @@ -4441,36 +4481,24 @@ private: } } + // Предполагаем картинку по локальному пути if (!bRes) { - sImageSrc = sSrcM; - std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + sExtention; + const std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + sExtention; - // Предполагаем картинку по локальному пути - if (!((!m_sBase.empty() && m_sBase.length() > 4 && m_sBase.substr(0, 4) == L"http") || (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"http"))) + if (!m_sBase.empty()) { - if (!m_sBase.empty()) - { - if (!bRes) - bRes = CopyImage(NSSystemPath::Combine(m_sBase, sSrcM), wsDst, bIsAllowExternalLocalFiles); - if (!bRes) - bRes = CopyImage(NSSystemPath::Combine(m_sSrc, m_sBase + sSrcM), wsDst, bIsAllowExternalLocalFiles); - } if (!bRes) - bRes = CopyImage(NSSystemPath::Combine(m_sSrc, sSrcM), wsDst, bIsAllowExternalLocalFiles); + bRes = CopyImage(NSSystemPath::Combine(m_sBase, sSrcM), wsDst, bIsAllowExternalLocalFiles); if (!bRes) - bRes = CopyImage(m_sSrc + L"/" + NSFile::GetFileName(sSrcM), wsDst, bIsAllowExternalLocalFiles); - if (!bRes) - bRes = CopyImage(sSrcM, wsDst, bIsAllowExternalLocalFiles); - } - // Предполагаем картинку в сети - else - { - // Проверка gc_allowNetworkRequest предполагается в kernel_network - NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_sBase + sSrcM, false); - oDownloadImg.SetFilePath(wsDst); - bRes = oDownloadImg.DownloadSync(); + bRes = CopyImage(NSSystemPath::Combine(m_sSrc, m_sBase + sSrcM), wsDst, bIsAllowExternalLocalFiles); } + if (!bRes) + bRes = CopyImage(NSSystemPath::Combine(m_sSrc, sSrcM), wsDst, bIsAllowExternalLocalFiles); + if (!bRes) + bRes = CopyImage(m_sSrc + L"/" + NSFile::GetFileName(sSrcM), wsDst, bIsAllowExternalLocalFiles); + if (!bRes) + bRes = CopyImage(sSrcM, wsDst, bIsAllowExternalLocalFiles); } if (!bRes) @@ -4478,7 +4506,7 @@ private: else { wrP(oXml, sSelectors, oTS); - ImageRels(oXml, nImageId, sImageSrc, sExtention, oImageData); + ImageRels(oXml, nImageId, sSrcM, sExtention, oImageData); } return true; @@ -4681,8 +4709,9 @@ private: if (bNew) nImageId = m_arrImages.size(); - std::wstring sImageId = std::to_wstring(nImageId); - std::wstring sImageName = sImageId + L'.' + sExtention; + const std::wstring sImageId = std::to_wstring(nImageId); + const std::wstring sImageName = sImageId + L'.' + sExtention; + CBgraFrame oBgraFrame; if (!oBgraFrame.OpenFile(m_sDst + L"/word/media/i" + sImageName)) { @@ -4757,7 +4786,7 @@ private: oXml->WriteString(L"\"/>"); m_oNoteXml.WriteString(L""); + m_oNoteXml.WriteString(L"\"> "); m_oNoteXml.WriteEncodeXmlString(sNote); m_oNoteXml.WriteString(L""); @@ -4770,8 +4799,13 @@ private: return false; if (NULL == m_pFonts) + { m_pFonts = NSFonts::NSApplication::Create(); + if (NULL != m_pFonts) + m_pFonts->Initialize(); + } + MetaFile::IMetaFile* pSvgReader = MetaFile::Create(m_pFonts); if (!pSvgReader->LoadFromString(wsSvg)) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp index 3e6c96cea6..093a0de536 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp @@ -81,7 +81,12 @@ void PtgExtraArray::load(CFRecord& record) for(int i = 0; i < (tempcols) * (temprows); ++i) { if (record.getRdPtr() >= record.getDataSize()) - break; + { + unsigned char rec_type = SerAr::SerType::typeSerNil; + SerArPtr ser(SerAr::createSerAr(rec_type)); + array_.push_back(ser); + continue; + } unsigned char rec_type; record >> rec_type; if (record.getGlobalWorkbookInfo()->Version >= 0x0800) @@ -138,24 +143,31 @@ void PtgExtraArray::save(CFRecord& record) const std::wstring PtgExtraArray::toString() const { std::wstring ret_val; - unsigned char col_cnt = cols + 1; + unsigned char col_cnt = cols; if (array_.empty()) return L""; for(std::vector::const_iterator it = array_.begin(), itEnd = --array_.end(); it != itEnd; ++it) { - ret_val += (*it)->toString(); - if(--col_cnt) + auto tempVal = (*it)->toString(); + if(tempVal.empty()) + tempVal = L"#N/A"; + ret_val += tempVal; + if (col_cnt > 1) { ret_val += L','; + --col_cnt; } else { ret_val += L';'; - col_cnt = cols + 1; + col_cnt = cols; } } - ret_val += array_.back()->toString(); + auto tempVal = array_.back()->toString(); + if(tempVal.empty()) + tempVal = L"#N/A"; + ret_val += tempVal; return ret_val; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp index f01548f273..6dc9455dcb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp @@ -62,6 +62,16 @@ BiffStructurePtr SerNum::clone() void SerNum::load(CFRecord& record) { record >> xnum; + // Excel limitations + constexpr double ExcelMinAbs = 2.229e-308; + constexpr double ExcelMax = 9.99999999999999e+307; + + if(std::abs(xnum) < ExcelMinAbs && xnum != 0.0) + xnum = (xnum > 0) ? ExcelMinAbs : -ExcelMinAbs; + else if(xnum > ExcelMax) + xnum = ExcelMax; + else if(xnum < -ExcelMax) + xnum = -ExcelMax; } void SerNum::save(CFRecord& record) @@ -77,7 +87,10 @@ void SerNum::save(CFRecord& record) const std::wstring SerNum::toString() const { - return STR::double2str(xnum); + auto tempNum = STR::double2str(xnum); + if(tempNum == L"-nan") + tempNum = L"#NUM!"; + return tempNum; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp index 491f06161a..7e71356ba4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp @@ -94,7 +94,11 @@ void SerStr::save(CFRecord& record) const std::wstring SerStr::toString() const { - return L"\"" + boost::algorithm::replace_all_copy(std::wstring(rgch), L"\"", L"\"\"") + L"\""; + std::wstring tempVal = rgch; + tempVal.erase(std::remove(tempVal.begin(), tempVal.end(), L'\0'), tempVal.end()); + if(tempVal.size() > 255) + tempVal.resize(255); + return L"\"" + boost::algorithm::replace_all_copy(tempVal, L"\"", L"\"\"") + L"\""; } diff --git a/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp index 436bf056c4..a1af0e0505 100644 --- a/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp +++ b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp @@ -5176,7 +5176,7 @@ int Binary_DocumentTableReader::ReadParagraph(BYTE type, long length, void* poRe else if (c_oSerParType::ParaID == type) { m_oParaId.Init(); - _INT64 res = m_oBufferedStream.GetLong64(); + _INT64 res = m_oBufferedStream.GetULong(); m_oParaId->SetValue(res); } else if (c_oSerParType::TextID == type) diff --git a/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp index f87ad8aefb..02d9cf51f7 100644 --- a/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp +++ b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp @@ -3929,7 +3929,7 @@ void BinaryDocumentTableWriter::WriteParapraph(OOX::Logic::CParagraph& par, OOX: { m_oBcw.m_oStream.WriteBYTE(c_oSerParType::ParaID); nCurPos = m_oBcw.WriteItemWithLengthStart(); - m_oBcw.m_oStream.WriteLONG64(par.m_oParaId->GetValue()); + m_oBcw.m_oStream.WriteULONG(par.m_oParaId->GetValue()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } if (par.m_oTextId.IsInit()) diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index 3416f86765..c34bdbaa16 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -362,7 +362,8 @@ namespace BinXlsxRW DateCompatibility = 1, HidePivotFieldList = 2, ShowPivotChartFilter = 3, - UpdateLinks = 4 + UpdateLinks = 4, + CodeName = 5 };} namespace c_oSerWorkbookViewTypes{enum c_oSerWorkbookViewTypes { diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp index b6b0ba000a..d489127d64 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp @@ -2461,6 +2461,12 @@ void BinaryWorkbookTableWriter::WriteWorkbookPr(const OOX::Spreadsheet::CWorkboo m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); m_oBcw.m_oStream.WriteBYTE(workbookPr.m_oUpdateLinks->GetValue()); } + if (workbookPr.m_oCodeName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::CodeName); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*workbookPr.m_oCodeName); + } } void BinaryWorkbookTableWriter::WriteConnectionTextFields(const OOX::Spreadsheet::CTextFields& textFields) { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp index 4bf325084d..42eabdf4f4 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp @@ -2957,6 +2957,10 @@ int BinaryWorkbookTableReader::ReadWorkbookPr(BYTE type, long length, void* poRe m_oWorkbook.m_oWorkbookPr->m_oUpdateLinks.Init(); m_oWorkbook.m_oWorkbookPr->m_oUpdateLinks->SetValueFromByte(m_oBufferedStream.GetUChar()); } + else if (c_oSerWorkbookPrTypes::CodeName == type) + { + m_oWorkbook.m_oWorkbookPr->m_oCodeName = m_oBufferedStream.GetString4(length); + } else res = c_oSerConstants::ReadUnknown; return res; diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 729b85fdad..1b4252b23b 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -66,7 +66,7 @@ namespace OOX WritingStringNullableAttrBool(L"autoCompressPictures", m_oAutoCompressPictures); WritingStringNullableAttrBool(L"backupFile", m_oBackupFile); WritingStringNullableAttrBool(L"checkCompatibility", m_oCheckCompatibility); - WritingStringNullableAttrBool(L"codeName", m_oCodeName); + WritingStringNullableAttrString(L"codeName", m_oCodeName, *m_oCodeName); WritingStringNullableAttrBool(L"date1904", m_oDate1904); WritingStringNullableAttrBool(L"dateCompatibility", m_oDateCompatibility); WritingStringNullableAttrInt(L"defaultThemeVersion", m_oDefaultThemeVersion, m_oDefaultThemeVersion->GetValue()); @@ -109,7 +109,7 @@ namespace OOX else ptr->fCheckCompat = false; if(m_oCodeName.IsInit()) - ptr->strName.value = m_oCodeName->GetValue(); + ptr->strName.value = *m_oCodeName; else ptr->strName.value = false; if(m_oDate1904.IsInit()) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 77de4016ec..5d8a2b7ff6 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -79,7 +79,6 @@ namespace OOX nullable m_oAutoCompressPictures; nullable m_oBackupFile; nullable m_oCheckCompatibility; - nullable m_oCodeName; nullable m_oDate1904; nullable m_oDateCompatibility; nullable m_oDefaultThemeVersion; @@ -93,6 +92,7 @@ namespace OOX nullable m_oShowObjects; nullable m_oShowPivotChartFilter; nullable m_oUpdateLinks; + nullable_string m_oCodeName; }; class CWorkbookProtection : public WritingElement { diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 2e27f269b1..66def02b8e 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -814,7 +814,10 @@ namespace OOX if(m_oRowBreaks.IsInit()) m_oRowBreaks->toXML(writer); if(m_oColBreaks.IsInit()) + { + m_oColBreaks->m_fRowBreak = false; m_oColBreaks->toXML(writer); + } if (m_oCellWatches.IsInit()) m_oCellWatches->toXML(writer); if(m_oDrawing.IsInit()) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index fdc4e9371c..c3f51e9a32 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -3193,7 +3193,10 @@ namespace OOX } void CRowColBreaks::toXML(NSStringUtils::CStringBuilder& writer) const { - toXML2(writer, L"rowBreaks"); + if(m_fRowBreak) + toXML2(writer, L"rowBreaks"); + else + toXML2(writer, L"colBreaks"); } void CRowColBreaks::toXML2(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const { diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index c3d7a8c24d..7725da6524 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -754,6 +754,8 @@ namespace OOX public: nullable m_oCount; nullable m_oManualBreakCount; + + bool m_fRowBreak = true; }; class CSheetProtection : public WritingElement diff --git a/OdfFile/DataTypes/chartaxistype.cpp b/OdfFile/DataTypes/chartaxistype.cpp new file mode 100644 index 0000000000..334f9bd63a --- /dev/null +++ b/OdfFile/DataTypes/chartaxistype.cpp @@ -0,0 +1,65 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "chartaxistype.h" +#include +#include + +namespace cpdoccore { namespace odf_types { + +std::wostream & operator << (std::wostream & _Wostream, const chart_axis_type& _Val) +{ + switch(_Val.get_type()) + { + case chart_axis_type::text: _Wostream << L"text"; break; + case chart_axis_type::date: _Wostream << L"date"; break; + case chart_axis_type::_auto: + default: + _Wostream << L"auto"; break; + } + return _Wostream; +} +chart_axis_type chart_axis_type::parse(const std::wstring & Str) +{ + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"date") + return chart_axis_type( date ); + else if (tmp == L"text") + return chart_axis_type( text); + else + { + return chart_axis_type( _auto ); + } +} +} } diff --git a/OdfFile/DataTypes/chartaxistype.h b/OdfFile/DataTypes/chartaxistype.h new file mode 100644 index 0000000000..8732364f0e --- /dev/null +++ b/OdfFile/DataTypes/chartaxistype.h @@ -0,0 +1,72 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include +#include "odfattributes.h" +// + +namespace cpdoccore { namespace odf_types { + +class chart_axis_type +{ +public: + enum type + { + _auto, + text, + date + }; + + chart_axis_type() {} + + chart_axis_type(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + + static chart_axis_type parse(const std::wstring & Str); + +private: + type type_; + +}; + std::wostream & operator << (std::wostream & _Wostream, const chart_axis_type& _Val); +} + +APPLY_PARSE_XML_ATTRIBUTES(odf_types::chart_axis_type); + +} diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index 9b9591e235..f65bc2e44d 100644 --- a/OdfFile/Projects/Linux/OdfFormatLib.pro +++ b/OdfFile/Projects/Linux/OdfFormatLib.pro @@ -53,7 +53,8 @@ SOURCES += \ ../../DataTypes/borderstyle.cpp \ ../../DataTypes/borderwidths.cpp \ ../../DataTypes/calcext_type.cpp \ - ../../DataTypes/chartdatalabelnumber.cpp \ + ../../DataTypes/chartaxistype.cpp \ + ../../DataTypes/chartdatalabelnumber.cpp \ ../../DataTypes/charterrorcategory.cpp \ ../../DataTypes/chartinterpolation.cpp \ ../../DataTypes/chartlabelarrangement.cpp \ diff --git a/OdfFile/Projects/Linux/odf_datatypes.cpp b/OdfFile/Projects/Linux/odf_datatypes.cpp index a5d3030bf9..186afb49f4 100644 --- a/OdfFile/Projects/Linux/odf_datatypes.cpp +++ b/OdfFile/Projects/Linux/odf_datatypes.cpp @@ -155,3 +155,4 @@ #include "../../DataTypes/tableoperator.cpp" #include "../../DataTypes/referenceformat.cpp" #include "../../DataTypes/color_mode.cpp" +#include "../../DataTypes/chartaxistype.cpp" diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj b/OdfFile/Projects/Windows/cpcommon.vcxproj index ac9ae3b6e2..73dd3caee2 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj @@ -189,6 +189,7 @@ + @@ -324,6 +325,7 @@ + diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters index ce03a7239c..79a5381a6b 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters @@ -131,6 +131,7 @@ + @@ -276,6 +277,7 @@ + diff --git a/OdfFile/Reader/Converter/oox_chart_axis.cpp b/OdfFile/Reader/Converter/oox_chart_axis.cpp index 2f3508fc35..a807f1e129 100644 --- a/OdfFile/Reader/Converter/oox_chart_axis.cpp +++ b/OdfFile/Reader/Converter/oox_chart_axis.cpp @@ -42,30 +42,22 @@ namespace cpdoccore { namespace oox { -_CP_PTR(oox_axis_content) oox_axis_content::create(int type, unsigned int id) +_CP_PTR(oox_axis_content) oox_axis_content::create(unsigned int id) { - return boost::make_shared(type, id); + return boost::make_shared(id); } -oox_axis_content::oox_axis_content(int type/*,std::wstring name*/, unsigned int id) +oox_axis_content::oox_axis_content(unsigned int id) { - if (type == 0) - { - id_ = 0; - } - else - { - id_ = id; - } - type_ = type; + id_ = id; } void oox_axis_content::oox_serialize(std::wostream & _Wostream) { if (id_ < 1 ) return; //not activate, blank axis - + CP_XML_WRITER(_Wostream) { - switch(type_) + switch(content_.type_) { case 1: CP_XML_NODE(L"c:catAx") diff --git a/OdfFile/Reader/Converter/oox_chart_axis.h b/OdfFile/Reader/Converter/oox_chart_axis.h index 24c48ca13b..a82d40ac0d 100644 --- a/OdfFile/Reader/Converter/oox_chart_axis.h +++ b/OdfFile/Reader/Converter/oox_chart_axis.h @@ -50,10 +50,10 @@ class oox_axis_content public: odf_reader::chart::oox_typeconvert oox_typeconvert_; - oox_axis_content(int type/*,std::wstring name*/, unsigned int id); + oox_axis_content(unsigned int id); ~oox_axis_content(){} - static oox_axis_content_ptr create(int type/*,std::wstring name*/, unsigned int id); + static oox_axis_content_ptr create(unsigned int id); void oox_serialize(std::wostream & _Wostream); void oox_serialize_content(std::wostream & _Wostream); @@ -61,11 +61,9 @@ public: int get_Id(){return id_;} void add_CrossedId (int id){cross_id_.push_back( id);} - unsigned int id_; + unsigned int id_; std::vector cross_id_; odf_reader::chart::axis content_; - - int type_; }; } diff --git a/OdfFile/Reader/Converter/oox_chart_context.h b/OdfFile/Reader/Converter/oox_chart_context.h index 5878d4725c..67fa4a7ce0 100644 --- a/OdfFile/Reader/Converter/oox_chart_context.h +++ b/OdfFile/Reader/Converter/oox_chart_context.h @@ -73,9 +73,9 @@ public: { plot_area_.set_data_table(v); } - void add_axis(int type, odf_reader::chart::axis & content) + void add_axis(odf_reader::chart::axis & content) { - plot_area_.add_axis(type, content); + plot_area_.add_axis(content); } void set_3D_chart(bool val) { diff --git a/OdfFile/Reader/Converter/oox_plot_area.cpp b/OdfFile/Reader/Converter/oox_plot_area.cpp index 26ec3957d6..9e3c7f7235 100644 --- a/OdfFile/Reader/Converter/oox_plot_area.cpp +++ b/OdfFile/Reader/Converter/oox_plot_area.cpp @@ -102,10 +102,10 @@ namespace cpdoccore { charts_.push_back(chart); } - void oox_plot_area::add_axis(int type, odf_reader::chart::axis& content) + void oox_plot_area::add_axis(odf_reader::chart::axis& content) { - unsigned int id = axis_id_++; - oox_axis_content_ptr ax = oox_axis_content::create(type, id); + unsigned int id = content.type_ != 0 ? axis_id_++ : 0; + oox_axis_content_ptr ax = oox_axis_content::create(id); ax->content_ = content; if (content.dimension_ == L"x") axis_.insert(axis_.begin(), ax); diff --git a/OdfFile/Reader/Converter/oox_plot_area.h b/OdfFile/Reader/Converter/oox_plot_area.h index aaa2c56d94..8d0bd3b9fa 100644 --- a/OdfFile/Reader/Converter/oox_plot_area.h +++ b/OdfFile/Reader/Converter/oox_plot_area.h @@ -60,7 +60,7 @@ public: void oox_serialize_view3D(std::wostream & _Wostream); void add_chart (int type); - void add_axis (int type, odf_reader::chart::axis & content); + void add_axis (odf_reader::chart::axis & content); void set_no_local_table (bool val); //whithout embedded tables //void set_content_series (odf_reader::chart::series & content); diff --git a/OdfFile/Reader/Format/chart_build_oox.cpp b/OdfFile/Reader/Format/chart_build_oox.cpp index e6c8cd5452..648eea6672 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -617,7 +617,7 @@ void object_odf_context::oox_convert(oox::oox_chart_context & chart_context) if (a.dimension_ == L"y" && y_enabled)continue; if (a.dimension_ == L"z" && z_enabled)continue; - if (a.dimension_ == L"x")//могут быть типы 1, 2, 3, 4 + if (a.dimension_ == L"x") { if (last_set_class == chart_class::scatter || last_set_class == chart_class::bubble) a.type_ = 2; @@ -637,9 +637,6 @@ void object_odf_context::oox_convert(oox::oox_chart_context & chart_context) a.type_ = 2; if (last_set_class == chart_class::bar) { - //вот нахрена свойства относящиеся к серии и самому чарту воткнули в оси ???? (ооо писали идиеты???) - //или это банальная ошибка которую так никогда и не исправили??? - //overlap & gap-width oox::oox_chart_ptr current = chart_context.get_current_chart(); current->set_graphic_properties(a.graphic_properties_); } @@ -653,7 +650,7 @@ void object_odf_context::oox_convert(oox::oox_chart_context & chart_context) z_enabled = true; } - chart_context.add_axis(a.bCategories_ ? 1 : a.type_, a); + chart_context.add_axis(a); } if (bIs3D.get_value_or(false)) @@ -663,7 +660,7 @@ void object_odf_context::oox_convert(oox::oox_chart_context & chart_context) chart::axis a; a.type_ = 0; // blank - chart_context.add_axis(a.type_, a); + chart_context.add_axis(a); } chart_context.set_3D_chart (true); } @@ -1021,6 +1018,15 @@ void process_build_object::visit(chart_axis& val) val.attlist_.chart_name_.get_value_or(L""), val.attlist_.common_attlist_.chart_style_name_.get_value_or(L"")); + if (val.attlist_.axis_type_) + { + if (val.attlist_.axis_type_->get_type() == odf_types::chart_axis_type::date) + object_odf_context_.axises_.back().type_ = 4; + else if (val.attlist_.axis_type_->get_type() == odf_types::chart_axis_type::text) + object_odf_context_.axises_.back().type_ = 1; + + } + ACCEPT_ALL_CONTENT(val.content_); std::wstring style_name = val.attlist_.common_attlist_.chart_style_name_.get_value_or(L""); @@ -1124,11 +1130,11 @@ void process_build_object::visit(chart_mean_value & val) } void process_build_object::visit(chart_date_scale & val) { - object_odf_context_.axises_.back().type_ = 4; + //... } void process_build_object::visit(chartooo_date_scale & val) { - object_odf_context_.axises_.back().type_ = 4; + //... } void process_build_object::visit(chart_error_indicator & val) { diff --git a/OdfFile/Reader/Format/chart_objects.h b/OdfFile/Reader/Format/chart_objects.h index 4c3cba7cea..50dc50edc6 100644 --- a/OdfFile/Reader/Format/chart_objects.h +++ b/OdfFile/Reader/Format/chart_objects.h @@ -102,7 +102,7 @@ namespace chart { graphic_format_properties_ptr graphic_properties_; }; bool bCategories_ = false; - + title title_; std::wstring dimension_; diff --git a/OdfFile/Reader/Format/office_chart.cpp b/OdfFile/Reader/Format/office_chart.cpp index ba1747b598..fb4be97413 100644 --- a/OdfFile/Reader/Format/office_chart.cpp +++ b/OdfFile/Reader/Format/office_chart.cpp @@ -256,6 +256,7 @@ void chart_axis_attlist::add_attributes( const xml::attributes_wc_ptr & Attribut { CP_APPLY_ATTR(L"chart:dimension", chart_dimension_); CP_APPLY_ATTR(L"chart:name", chart_name_); + CP_APPLY_ATTR(L"chartooo:axis-type", axis_type_); common_attlist_.add_attributes(Attributes); } diff --git a/OdfFile/Reader/Format/office_chart.h b/OdfFile/Reader/Format/office_chart.h index 854ee4b2bc..199a35df17 100644 --- a/OdfFile/Reader/Format/office_chart.h +++ b/OdfFile/Reader/Format/office_chart.h @@ -41,6 +41,7 @@ #include "../../DataTypes/common_attlists.h" #include "../../DataTypes/charttimeunit.h" #include "../../DataTypes/chartclass.h" +#include "../../DataTypes/chartaxistype.h" namespace cpdoccore { namespace odf_reader { @@ -275,8 +276,7 @@ public: public: _CP_OPT(odf_types::length) svg_width_; - common_chart_attlist common_attlist_; - + common_chart_attlist common_attlist_; }; class chart_wall : public office_element_impl @@ -314,10 +314,9 @@ private: virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); public: - common_chart_attlist common_attlist_; + common_chart_attlist common_attlist_; }; - CP_REGISTER_OFFICE_ELEMENT2(chart_floor); class chart_axis_attlist @@ -325,10 +324,11 @@ class chart_axis_attlist public: void add_attributes( const xml::attributes_wc_ptr & Attributes ); -public: - _CP_OPT(std::wstring) chart_dimension_; - _CP_OPT(std::wstring) chart_name_; - common_chart_attlist common_attlist_; + _CP_OPT(std::wstring) chart_dimension_; + _CP_OPT(std::wstring) chart_name_; + _CP_OPT(odf_types::chart_axis_type) axis_type_; + + common_chart_attlist common_attlist_; }; // chart:axis @@ -348,9 +348,7 @@ private: public: chart_axis_attlist attlist_; office_element_ptr_array content_; - }; - CP_REGISTER_OFFICE_ELEMENT2(chart_axis); class chart_grid_attlist diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 3ac44e2d7d..457af2e38c 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -2187,6 +2187,11 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, Object oAnnot, oObj; std::string sType; oAnnots.arrayGet(i, &oAnnot); + if (!oAnnot.isDict()) + { + oAnnot.free(); + continue; + } if (oAnnot.dictLookup("Subtype", &oObj)->isName()) sType = oObj.getName(); oObj.free(); oAnnot.free(); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 5523a40641..57eb61c19d 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2525,6 +2525,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (nFlags & (1 << 13)) { pTextWidget->SetAPV(); + m_pFont14 = NULL; m_pFont = NULL; + m_bNeedUpdateTextFont = true; LONG nLen = 0; BYTE* pRender = pPr->GetRender(nLen); @@ -2544,7 +2546,9 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (m_bNeedUpdateTextFont) UpdateFont(); - if (m_pFont) + if (m_pFont14) + pFont = m_pFont14; + else if (m_pFont) pFont = m_pDocument->CreateTrueTypeFont(m_pFont); } if (pFont) @@ -2592,6 +2596,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (nFlags & (1 << 15)) { pChoiceWidget->SetAPV(); + m_pFont14 = NULL; m_pFont = NULL; + m_bNeedUpdateTextFont = true; LONG nLen = 0; BYTE* pRender = pPr->GetRender(nLen); @@ -2611,7 +2617,9 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (m_bNeedUpdateTextFont) UpdateFont(); - if (m_pFont) + if (m_pFont14) + pFont = m_pFont14; + else if (m_pFont) pFont = m_pDocument->CreateTrueTypeFont(m_pFont); } if (pFont) diff --git a/PdfFile/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index 68c8cc630b..dafb7955ce 100644 --- a/PdfFile/SrcReader/Adaptors.cpp +++ b/PdfFile/SrcReader/Adaptors.cpp @@ -203,15 +203,24 @@ bool GlobalParamsAdaptor::InRedact(double dX, double dY) double x4 = m_arrRedactBox[i + 4]; double y4 = m_arrRedactBox[i + 5]; + if (x1 == x2 && x2 == x3 && x3 == x4 && y1 == y2 && y2 == y3 && y3 == y4) + { + if (dX == x1 && dY == y1) + return true; + continue; + } + // Проверяем знаки векторных произведений для всех сторон double cross1 = crossProduct(x1, y1, x2, y2, dX, dY); double cross2 = crossProduct(x2, y2, x3, y3, dX, dY); double cross3 = crossProduct(x3, y3, x4, y4, dX, dY); double cross4 = crossProduct(x4, y4, x1, y1, dX, dY); + bool allPositive = (cross1 >= 0 && cross2 >= 0 && cross3 >= 0 && cross4 >= 0); + bool allNegative = (cross1 <= 0 && cross2 <= 0 && cross3 <= 0 && cross4 <= 0); + // Точка внутри, если все векторные произведения имеют одинаковый знак - if ((cross1 >= 0 && cross2 >= 0 && cross3 >= 0 && cross4 >= 0) || - (cross1 <= 0 && cross2 <= 0 && cross3 <= 0 && cross4 <= 0)) + if ((allPositive || allNegative) && !(cross1 == 0 && cross2 == 0 && cross3 == 0 && cross4 == 0)) return true; } return false; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 5da48648f9..f05f1f9ee6 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -515,6 +515,45 @@ CAnnot::CBorderType* getBorder(Object* oBorder, bool bBSorBorder) return pBorderType; } +std::string GetRCFromDS(const std::string& sDS, Object* pContents, const std::vector& arrCFromDA) +{ + NSStringUtils::CStringBuilder oRC; + + oRC += L"

"; + TextString* s = new TextString(pContents->getString()); + std::wstring wsContents = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength()); + delete s; + oRC.WriteEncodeXmlString(wsContents); + oRC += L"

"; + + std::wstring wsRC = oRC.GetData(); + return U_TO_UTF8(wsRC); +} //------------------------------------------------------------------------ // Fonts @@ -637,29 +676,43 @@ std::map CAnnotFonts::GetAllFonts(PDFDoc* pdfDoc, NS } oSubtype.free(); + std::string sRC; Object oObj; if (!oAnnot.dictLookup("RC", &oObj)->isString()) { oObj.free(); - if (oAnnot.dictLookup("AP", &oObj)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength()) + if (oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength()) { - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; - std::wstring wsFontName = L"Helvetica"; - NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); - if (pMemoryStorage && !pMemoryStorage->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) - pMemoryStorage->Add(wsFontName, (BYTE*)pData14, nSize14, false); - mFonts[L"Helvetica"] = L"Helvetica"; - } - oAnnot.free(); oObj.free(); - continue; - } - oAnnot.free(); + std::string sDS; + Object oObj2; + if (oAnnot.dictLookup("DS", &oObj2)->isString()) + { + TextString* s = new TextString(oObj2.getString()); + sDS = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj2.free(); - TextString* s = new TextString(oObj.getString()); - std::string sRC = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - delete s; - oObj.free(); + sRC = GetRCFromDS(sDS, &oObj, {}); + if (sRC.find("font-family:Helvetica") != std::string::npos) + { + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + std::wstring wsFontName = L"Helvetica"; + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (pMemoryStorage && !pMemoryStorage->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) + pMemoryStorage->Add(wsFontName, (BYTE*)pData14, nSize14, false); + mFonts[L"Helvetica"] = L"Helvetica"; + } + } + } + else + { + TextString* s = new TextString(oObj.getString()); + sRC = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oObj.free(); oAnnot.free(); Object oAnnotRef; oAnnots.arrayGetNF(i, &oAnnotRef); @@ -2135,27 +2188,9 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex } oObj.free(); - if (oAnnot.dictLookup("AP", &oObj)->isNull() && oAnnot.dictLookup("RC", &oObj2)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength()) + if (oAnnot.dictLookup("RC", &oObj2)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength()) { - NSStringUtils::CStringBuilder oRC; - - oRC += L"

"; - TextString* s = new TextString(oObj.getString()); - std::wstring wsContents = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength()); - delete s; - oRC.WriteEncodeXmlString(wsContents); - oRC += L"

"; - - std::wstring wsRC = oRC.GetData(); - m_arrRC = CAnnotMarkup::ReadRC(U_TO_UTF8(wsRC)); + m_arrRC = CAnnotMarkup::ReadRC(GetRCFromDS(m_sDS, &oObj, m_arrCFromDA)); if (m_arrRC.empty()) m_unFlags &= ~(1 << 3); else