diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp
index 76617ed6a1..ee46db33ee 100644
--- a/Common/3dParty/html/css/src/CCompiledStyle.cpp
+++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp
@@ -34,6 +34,9 @@ namespace NSCSS
CCompiledStyle& CCompiledStyle::operator+= (const CCompiledStyle &oElement)
{
+ if (oElement.Empty())
+ return *this;
+
m_oBackground += oElement.m_oBackground;
m_oBorder += oElement.m_oBorder;
m_oFont += oElement.m_oFont;
@@ -42,6 +45,9 @@ namespace NSCSS
m_oText += oElement.m_oText;
m_oDisplay += oElement.m_oDisplay;
+ if (!oElement.m_sId.empty())
+ m_sId += L'+' + oElement.m_sId;
+
return *this;
}
diff --git a/Common/3dParty/html/css/src/CCssCalculator.cpp b/Common/3dParty/html/css/src/CCssCalculator.cpp
index 3ece3b199f..bedad66c89 100644
--- a/Common/3dParty/html/css/src/CCssCalculator.cpp
+++ b/Common/3dParty/html/css/src/CCssCalculator.cpp
@@ -23,6 +23,11 @@ namespace NSCSS
return m_pInternal->GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure);
}
+ std::wstring CCssCalculator::CalculateStyleId(const CNode& oNode)
+ {
+ return m_pInternal->CalculateStyleId(oNode);
+ }
+
bool CCssCalculator::CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors)
{
return m_pInternal->CalculatePageStyle(oPageData, arSelectors);
diff --git a/Common/3dParty/html/css/src/CCssCalculator.h b/Common/3dParty/html/css/src/CCssCalculator.h
index 02bd6ed957..564adaa686 100644
--- a/Common/3dParty/html/css/src/CCssCalculator.h
+++ b/Common/3dParty/html/css/src/CCssCalculator.h
@@ -22,6 +22,7 @@ namespace NSCSS
CCompiledStyle GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const;
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const;
+ std::wstring CalculateStyleId(const CNode& oNode);
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors);
// void AddStyle(const std::vector& sSelectors, const std::string& sStyle);
diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp
index e6a9160dd0..25d13673ee 100644
--- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp
+++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp
@@ -157,28 +157,34 @@ namespace NSCSS
std::vector CCssCalculator_Private::FindElements(std::vector &arNodes, std::vector &arNextNodes, bool bIsSettings)
{
+ if (arNodes.empty())
+ return {};
+
std::vector arFindedElements;
std::wstring wsName, wsId;
std::vector arClasses;
- if (arNodes.back()[0] == L'#')
+ if (!arNodes.empty() && arNodes.back()[0] == L'#')
{
wsId = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsId);
}
- if (arNodes.back()[0] == L'.')
+ if (!arNodes.empty() && arNodes.back()[0] == L'.')
{
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
arNextNodes.push_back(arNodes.back());
arNodes.pop_back();
}
- wsName = arNodes.back();
- arNodes.pop_back();
- arNextNodes.push_back(wsName);
+ if (!arNodes.empty())
+ {
+ wsName = arNodes.back();
+ arNodes.pop_back();
+ arNextNodes.push_back(wsName);
+ }
const std::map::const_iterator oFindName = m_mData.find(wsName);
std::map::const_iterator oFindId;
@@ -561,7 +567,7 @@ namespace NSCSS
}
}
- oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes));
+ oStyle.SetID(CalculateStyleId(arSelectors.back()));
if (!bIsSettings && !oStyle.Empty())
m_mUsedStyles[arSelectors] = oStyle;
@@ -569,6 +575,11 @@ namespace NSCSS
return true;
}
+ std::wstring CCssCalculator_Private::CalculateStyleId(const CNode& oNode)
+ {
+ return oNode.m_wsName + ((!oNode.m_wsClass.empty()) ? L'.' + oNode.m_wsClass : L"") + ((oNode.m_wsId.empty()) ? L"" : L'#' + oNode.m_wsId) + L'-' + std::to_wstring(++m_nCountNodes);
+ }
+
bool CCssCalculator_Private::CalculatePageStyle(NSProperties::CPage &oPageData, const std::vector &arSelectors)
{
if (arSelectors.empty())
diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h
index 7bda5a7937..510bf0030d 100644
--- a/Common/3dParty/html/css/src/CCssCalculator_Private.h
+++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h
@@ -75,6 +75,7 @@ namespace NSCSS
CCompiledStyle GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point);
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point);
+ std::wstring CalculateStyleId(const CNode& oNode);
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors);
#endif
diff --git a/Common/3dParty/html/css/src/CNode.cpp b/Common/3dParty/html/css/src/CNode.cpp
index 8b2cdc27b8..8073a6266e 100644
--- a/Common/3dParty/html/css/src/CNode.cpp
+++ b/Common/3dParty/html/css/src/CNode.cpp
@@ -5,7 +5,7 @@ namespace NSCSS
CNode::CNode()
{}
- CNode::CNode(std::wstring wsName, std::wstring wsClass, std::wstring wsId)
+ CNode::CNode(const std::wstring& wsName, const std::wstring& wsClass, const std::wstring& wsId)
: m_wsName(wsName), m_wsClass(wsClass), m_wsId(wsId)
{}
diff --git a/Common/3dParty/html/css/src/CNode.h b/Common/3dParty/html/css/src/CNode.h
index a7c7de0539..57409a67a5 100644
--- a/Common/3dParty/html/css/src/CNode.h
+++ b/Common/3dParty/html/css/src/CNode.h
@@ -18,7 +18,7 @@ namespace NSCSS
public:
CNode();
- CNode(std::wstring wsName, std::wstring wsClass, std::wstring wsId);
+ CNode(const std::wstring& wsName, const std::wstring& wsClass, const std::wstring& wsId);
bool Empty() const;
diff --git a/Common/3dParty/html/css/src/StaticFunctions.cpp b/Common/3dParty/html/css/src/StaticFunctions.cpp
index ae49a17bae..6eee504aa0 100644
--- a/Common/3dParty/html/css/src/StaticFunctions.cpp
+++ b/Common/3dParty/html/css/src/StaticFunctions.cpp
@@ -141,7 +141,9 @@ namespace NS_STATIC_FUNCTIONS
while (std::wstring::npos != unEnd)
{
- arWords.emplace_back(wsLine.data() + unStart, unEnd - unStart + ((bWithSigns) ? 1 : 0));
+ if (unStart != unEnd)
+ arWords.emplace_back(wsLine.data() + unStart, unEnd - unStart + ((bWithSigns) ? 1 : 0));
+
unStart = wsLine.find_first_not_of(wsDelimiters, unEnd);
unEnd = wsLine.find_first_of(wsDelimiters, unStart);
}
diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp
index 513d4d604b..4874c22a7a 100644
--- a/Common/3dParty/html/css/src/StyleProperties.cpp
+++ b/Common/3dParty/html/css/src/StyleProperties.cpp
@@ -39,13 +39,17 @@ namespace NSCSS
std::wstring wsNewValue = wsValue;
- bool bImportant = CutImportant(wsNewValue);
+ const bool bImportant{CutImportant(wsNewValue)};
if (m_bImportant && !bImportant)
return false;
+ if (UINT_MAX == unLevel)
+ m_unLevel++;
+ else
+ m_unLevel = unLevel;
+
m_oValue = wsNewValue;
- m_unLevel = unLevel;
m_bImportant = bImportant;
return true;
@@ -58,15 +62,19 @@ namespace NSCSS
std::wstring wsNewValue = wsValue;
- bool bImportant = CutImportant(wsNewValue);
+ const bool bImportant{CutImportant(wsNewValue)};
if (m_bImportant && !bImportant)
return false;
if (arValiableValues.end() != std::find(arValiableValues.begin(), arValiableValues.end(), wsNewValue))
{
+ if (UINT_MAX == unLevel)
+ m_unLevel++;
+ else
+ m_unLevel = unLevel;
+
m_oValue = wsNewValue;
- m_unLevel = unLevel;
m_bImportant = bImportant;
return true;
@@ -82,7 +90,7 @@ namespace NSCSS
std::wstring wsNewValue = wsValue;
- bool bImportant = CutImportant(wsNewValue);
+ const bool bImportant{CutImportant(wsNewValue)};
if (m_bImportant && !bImportant)
return false;
@@ -91,8 +99,12 @@ namespace NSCSS
if (arValiableValues.end() != oFoundValue)
{
+ if (UINT_MAX == unLevel)
+ m_unLevel++;
+ else
+ m_unLevel = unLevel;
+
m_oValue = oFoundValue->second;
- m_unLevel = unLevel;
m_bImportant = bImportant;
return true;
@@ -109,7 +121,7 @@ namespace NSCSS
void CString::Clear()
{
m_oValue.clear();
- m_unLevel = NULL;
+ m_unLevel = 0;
m_bImportant = false;
}
@@ -183,7 +195,7 @@ namespace NSCSS
void CDigit::Clear()
{
m_oValue = DBL_MAX;
- m_unLevel = NULL;
+ m_unLevel = 0;
m_enUnitMeasure = None;
m_bImportant = false;
}
@@ -375,20 +387,24 @@ namespace NSCSS
bool CDigit::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
- if (wsValue.empty() || (CHECK_CONDITIONS && !bHardMode) || unLevel < m_unLevel)
+ if (wsValue.empty() || (CHECK_CONDITIONS && !bHardMode))
return false;
std::wstring wsNewValue = wsValue;
- bool bImportant = CutImportant(wsNewValue); //TODO:: иногда мы знаем, что "!important" точно не встретится
- // возможно стоит добавить ещё метод
+ const bool bImportant{CutImportant(wsNewValue)}; //TODO:: иногда мы знаем, что "!important" точно не встретится
+ // возможно стоит добавить ещё метод
if (m_bImportant && !bImportant)
return false;
if (!CUnitMeasureConverter::GetValue(wsValue, m_oValue, m_enUnitMeasure))
return false;
- m_unLevel = unLevel;
+ if (UINT_MAX == unLevel)
+ m_unLevel++;
+ else
+ m_unLevel = unLevel;
+
m_bImportant = bImportant;
return true;
@@ -420,6 +436,21 @@ namespace NSCSS
return true;
}
+ bool CDigit::SetValue(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ if (CHECK_CONDITIONS && !bHardMode)
+ return false;
+
+ m_oValue = dValue;
+
+ if (UINT_MAX == unLevel)
+ m_unLevel++;
+ else
+ m_unLevel = unLevel;
+
+ return true;
+ }
+
bool TRGB::Empty() const
{
return 0 == uchRed && 0 == uchGreen && 0 == uchBlue;
@@ -432,6 +463,13 @@ namespace NSCSS
uchBlue == oRGB.uchBlue;
}
+ bool TRGB::operator!=(const TRGB& oRGB) const
+ {
+ return uchRed != oRGB.uchRed ||
+ uchGreen != oRGB.uchGreen ||
+ uchBlue != oRGB.uchBlue;
+ }
+
TRGB CColor::ConvertHEXtoRGB(const std::wstring &wsValue)
{
TRGB oRGB;
@@ -459,38 +497,168 @@ namespace NSCSS
return std::wstring(arTemp, 6);
}
- std::wstring CColor::CutURL(const std::wstring &wsValue)
+ bool CColor::operator==(const CColor& oColor) const
{
- if (wsValue.length() < 6)
- return std::wstring();
+ if (m_enType != oColor.m_enType || m_oOpacity != oColor.m_oOpacity)
+ return false;
- size_t unBegin = wsValue.find(L"(#");
-
- if (std::wstring::npos == unBegin || unBegin < 3 || wsValue.length() - unBegin < 2)
- return std::wstring();
-
- std::wstring wsCopyValue(wsValue);
-
- std::transform(wsCopyValue.begin(), wsCopyValue.begin() + unBegin, wsCopyValue.begin(), std::towlower);
-
- if (std::wstring::npos == wsCopyValue.find(L"url(#"))
- return std::wstring();
-
- return wsCopyValue.substr(unBegin + 2, wsCopyValue.find(L')') - unBegin - 2);
+ switch(m_enType)
+ {
+ case ColorEmpty:
+ case ColorNone:
+ return true;
+ case ColorRGB:
+ return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue));
+ case ColorHEX:
+ return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue));
+ case ColorUrl:
+ return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue));
+ }
}
-
- void CColor::SetEmpty(unsigned int unLevel)
+
+ bool CColor::operator!=(const CColor& oColor) const
{
- m_oValue.Clear();
- m_oValue.m_enType = ColorEmpty;
- m_unLevel = unLevel;
- m_bImportant = false;
+ if (m_enType != oColor.m_enType || m_oOpacity != oColor.m_oOpacity)
+ return true;
+
+ switch(m_enType)
+ {
+ case ColorEmpty:
+ case ColorNone:
+ return false;
+ case ColorRGB:
+ return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue));
+ case ColorHEX:
+ return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue));
+ case ColorUrl:
+ return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue));
+ }
+ }
+
+ CColor& CColor::operator =(const CColor& oColor)
+ {
+ m_enType = oColor.m_enType;
+ m_oOpacity = oColor.m_oOpacity;
+ m_unLevel = oColor.m_unLevel;
+
+ switch(m_enType)
+ {
+ case ColorEmpty:
+ case ColorNone:
+ break;
+ case ColorRGB:
+ {
+ m_oValue = new TRGB{(*static_cast(oColor.m_oValue))};
+ break;
+ }
+ case ColorHEX:
+ {
+ m_oValue = new std::wstring(*static_cast(oColor.m_oValue));
+ break;
+ }
+ case ColorUrl:
+ {
+ m_oValue = new CURL(*static_cast(oColor.m_oValue));
+ break;
+ }
+ }
+
+ return *this;
+ }
+
+ CColor& CColor::operator+=(const CColor& oColor)
+ {
+ if (m_unLevel > oColor.m_unLevel || (m_bImportant && !oColor.m_bImportant) || oColor.Empty())
+ return *this;
+
+ *this = oColor;
+
+ return *this;
}
CColor::CColor()
- : CValue({}, 0, false), m_oOpacity(1.)
+ : CValue(NULL, 0, false), m_oOpacity(1.), m_enType(ColorEmpty)
{}
+ void CColor::SetEmpty(unsigned int unLevel)
+ {
+ Clear();
+ m_enType = ColorEmpty;
+ m_unLevel = unLevel;
+ m_bImportant = false;
+ }
+
+ void CColor::SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB)
+ {
+ Clear();
+
+ m_oValue = new TRGB{uchR, uchG, uchB};
+
+ if (NULL == m_oValue)
+ return;
+
+ m_enType = ColorRGB;
+ }
+
+ void CColor::SetRGB(const TRGB &oRGB)
+ {
+ Clear();
+
+ m_oValue = new TRGB{oRGB};
+
+ if (NULL == m_oValue)
+ return;
+
+ m_enType = ColorRGB;
+ }
+
+ void CColor::SetHEX(const std::wstring &wsValue)
+ {
+ Clear();
+
+ if (6 != wsValue.length() && 3 != wsValue.length())
+ return;
+
+ if (6 == wsValue.length())
+ m_oValue = new std::wstring(wsValue);
+ else
+ m_oValue = new std::wstring({wsValue[0], wsValue[0], wsValue[1], wsValue[1], wsValue[2], wsValue[2]});
+
+ if (NULL == m_oValue)
+ return;
+
+ m_enType = ColorHEX;
+ }
+
+ void CColor::SetUrl(const std::wstring &wsValue)
+ {
+ Clear();
+
+ if (wsValue.empty())
+ return;
+
+ CURL *pURL = new CURL();
+
+ if (NULL == pURL)
+ return;
+
+ if (!pURL->SetValue(wsValue))
+ {
+ delete pURL;
+ return;
+ }
+
+ m_oValue = pURL;
+ m_enType = ColorUrl;
+ }
+
+ void CColor::SetNone()
+ {
+ Clear();
+
+ m_enType = ColorNone;
+ }
+
bool CColor::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
if ((CHECK_CONDITIONS && !bHardMode) || (wsValue.empty() && unLevel == m_unLevel))
@@ -504,33 +672,25 @@ namespace NSCSS
std::wstring wsNewValue(wsValue);
- bool bImportant = CutImportant(wsNewValue);
+ const bool bImportant = CutImportant(wsNewValue);
std::transform(wsNewValue.begin(), wsNewValue.end(), wsNewValue.begin(), std::towlower);
+ NS_STATIC_FUNCTIONS::RemoveSpaces(wsNewValue);
if (m_bImportant && !bImportant)
return false;
+ bool bResult{false};
+
if (wsNewValue[0] == L'#')
{
- m_oValue.SetHEX(wsNewValue.substr(1, wsNewValue.length() - 1));
- m_unLevel = unLevel;
- m_bImportant = bImportant;
- return true;
+ SetHEX(wsNewValue.substr(1, wsNewValue.length() - 1));
+ bResult = true;
}
- else if (L"none" == wsNewValue)
+ else if (L"none" == wsNewValue || wsNewValue == L"transparent")
{
- m_oValue.SetNone();
- m_unLevel = unLevel;
- m_bImportant = bImportant;
- return true;
- }
- else if (wsNewValue == L"transparent")
- {
- m_oValue.SetNone();
- m_unLevel = unLevel;
- m_bImportant = bImportant;
- return true;
+ SetNone();
+ bResult = true;
}
else if (10 <= wsNewValue.length() && wsNewValue.substr(0, 3) == L"rgb")
{
@@ -558,38 +718,43 @@ namespace NSCSS
if (255 < nGreen) nGreen = 255;
if (255 < nBlue) nBlue = 255;
- m_oValue.SetRGB(nRed, nGreen, nBlue);
+ SetRGB(nRed, nGreen, nBlue);
if (wsNewValue.substr(0, 4) == L"rgba" && 4 == arValues.size())
m_oOpacity.SetValue(arValues[3], unLevel, bHardMode);
- m_unLevel = unLevel;
- m_bImportant = bImportant;
- return true;
+ bResult = true;
}
if (5 <= wsNewValue.length())
{
- m_oValue.SetUrl(CutURL(wsValue));
+ SetUrl(wsValue);
- if (m_oValue.m_enType == ColorUrl)
+ if (m_enType == ColorUrl)
+ bResult = true;
+ }
+
+ if (!bResult)
+ {
+ const std::map::const_iterator oHEX = NSConstValues::COLORS.find(wsNewValue);
+ if (oHEX != NSConstValues::COLORS.end())
{
- m_unLevel = unLevel;
- m_bImportant = bImportant;;
- return true;
+ SetHEX(oHEX->second);
+ bResult = true;
}
}
- const std::map::const_iterator oHEX = NSConstValues::COLORS.find(wsNewValue);
- if (oHEX != NSConstValues::COLORS.end())
- {
- m_oValue.SetHEX(oHEX->second);
- m_unLevel = unLevel;
- m_bImportant = bImportant;
- return true;
- }
+ if (!bResult)
+ return false;
- return false;
+ m_bImportant = bImportant;
+
+ if (UINT_MAX == unLevel)
+ m_unLevel++;
+ else
+ m_unLevel = unLevel;
+
+ return true;
}
bool CColor::SetOpacity(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@@ -602,29 +767,53 @@ namespace NSCSS
bool CColor::Empty() const
{
- return m_oValue.Empty();
+ return ColorEmpty == m_enType;
}
bool CColor::None() const
{
- return ColorNone == m_oValue.m_enType;
+ return ColorNone == m_enType;
}
bool CColor::Url() const
{
- return ColorUrl == m_oValue.m_enType;
+ return ColorUrl == m_enType;
}
void CColor::Clear()
{
- m_oValue.Clear();
+ switch (m_enType)
+ {
+ case ColorRGB:
+ {
+ TRGB *pRGB = static_cast(m_oValue);
+ RELEASEOBJECT(pRGB);
+ break;
+ }
+ case ColorHEX:
+ {
+ std::wstring* pValue = static_cast(m_oValue);
+ RELEASEOBJECT(pValue);
+ break;
+ }
+ case ColorUrl:
+ {
+ CURL *pURL = static_cast(m_oValue);
+ RELEASEOBJECT(pURL);
+ break;
+ }
+ default:
+ break;
+ }
+
+ m_enType = ColorEmpty;
m_unLevel = NULL;
m_bImportant = false;
}
ColorType CColor::GetType() const
{
- return m_oValue.m_enType;
+ return m_enType;
}
double CColor::GetOpacity() const
@@ -643,16 +832,16 @@ namespace NSCSS
int CColor::ToInt() const
{
- switch(m_oValue.m_enType)
+ switch(m_enType)
{
case ColorRGB:
{
- TRGB* pRGB = static_cast(m_oValue.m_pColor);
+ TRGB* pRGB = static_cast(m_oValue);
return RGB_TO_INT(pRGB->uchRed, pRGB->uchGreen, pRGB->uchBlue);
}
case ColorHEX:
{
- std::wstring *pValue = static_cast(m_oValue.m_pColor);
+ std::wstring *pValue = static_cast(m_oValue);
TRGB oRGB = ConvertHEXtoRGB(*pValue);
return RGB_TO_INT(oRGB.uchRed, oRGB.uchGreen, oRGB.uchBlue);
}
@@ -668,10 +857,11 @@ namespace NSCSS
std::wstring CColor::ToWString() const
{
- switch(m_oValue.m_enType)
+ switch(m_enType)
{
- case ColorRGB: return ConvertRGBtoHEX(*static_cast(m_oValue.m_pColor));
- case ColorHEX: case ColorUrl: return *static_cast(m_oValue.m_pColor);
+ case ColorRGB: return ConvertRGBtoHEX(*static_cast(m_oValue));
+ case ColorHEX: return *static_cast(m_oValue);
+ case ColorUrl: return static_cast(m_oValue)->GetValue();
default: return std::wstring();
}
}
@@ -683,10 +873,10 @@ namespace NSCSS
TRGB oCurrentColor;
- switch(m_oValue.m_enType)
+ switch(m_enType)
{
- case ColorRGB: oCurrentColor = *static_cast(m_oValue.m_pColor); break;
- case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor)); break;
+ case ColorRGB: oCurrentColor = *static_cast(m_oValue); break;
+ case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast(m_oValue)); break;
default: return L"none";
}
@@ -710,10 +900,10 @@ namespace NSCSS
TRGB CColor::ToRGB() const
{
- switch(m_oValue.m_enType)
+ switch(m_enType)
{
- case ColorRGB: return *static_cast(m_oValue.m_pColor);
- case ColorHEX: return ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor));
+ case ColorRGB: return *static_cast(m_oValue);
+ case ColorHEX: return ConvertHEXtoRGB(*static_cast(m_oValue));
default: return TRGB();
}
}
@@ -1397,6 +1587,10 @@ namespace NSCSS
: m_bBlock(false)
{}
+ CBorderSide::CBorderSide(const CBorderSide& oBorderSide)
+ : m_oWidth(oBorderSide.m_oWidth), m_oStyle(oBorderSide.m_oStyle), m_oColor(oBorderSide.m_oColor), m_bBlock(oBorderSide.m_bBlock)
+ {}
+
void CBorderSide::Clear()
{
m_oWidth.Clear();
@@ -1418,9 +1612,7 @@ namespace NSCSS
if (L"none" == wsValue)
{
- SetColor(L"#ffffff", unLevel, bHardMode);
- SetStyle(L"solid", unLevel, bHardMode);
- SetWidth(L"0",unLevel,bHardMode);
+ SetNone(unLevel, bHardMode);
return true;
}
@@ -1460,6 +1652,11 @@ namespace NSCSS
return m_oWidth.SetValue(wsNewValue, unLevel, bHardMode);
}
+ bool CBorderSide::SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oWidth.SetValue(dValue, unLevel, bHardMode);
+ }
+
bool CBorderSide::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oStyle.SetValue(wsValue, {std::make_pair(L"dotted", L"dotted"), std::make_pair(L"dashed", L"dashed"), std::make_pair(L"solid", L"single"),
@@ -1472,6 +1669,13 @@ namespace NSCSS
return m_oColor.SetValue(wsValue, unLevel, bHardMode);
}
+ void CBorderSide::SetNone(unsigned int unLevel, bool bHardMode)
+ {
+ SetColor(L"#ffffff", unLevel, bHardMode);
+ SetStyle(L"solid", unLevel, bHardMode);
+ SetWidth(L"0",unLevel,bHardMode);
+ }
+
void CBorderSide::Block()
{
m_bBlock = true;
@@ -1544,6 +1748,13 @@ namespace NSCSS
m_oColor == oBorderSide.m_oColor;
}
+ bool CBorderSide::operator!=(const CBorderSide& oBorderSide) const
+ {
+ return m_oWidth != oBorderSide.m_oWidth ||
+ m_oStyle != oBorderSide.m_oStyle ||
+ m_oColor != oBorderSide.m_oColor;
+ }
+
CBorderSide &CBorderSide::operator =(const CBorderSide &oBorderSide)
{
m_oWidth = oBorderSide.m_oWidth;
@@ -1561,9 +1772,29 @@ namespace NSCSS
void CBorder::Clear()
{
- m_oLeft .Clear();
- m_oTop .Clear();
- m_oRight .Clear();
+ ClearLeftSide();
+ ClearTopSide();
+ ClearRightSide();
+ ClearBottomSide();
+ }
+
+ void CBorder::ClearLeftSide()
+ {
+ m_oLeft.Clear();
+ }
+
+ void CBorder::ClearTopSide()
+ {
+ m_oTop.Clear();
+ }
+
+ void CBorder::ClearRightSide()
+ {
+ m_oRight.Clear();
+ }
+
+ void CBorder::ClearBottomSide()
+ {
m_oBottom.Clear();
}
@@ -1599,6 +1830,18 @@ namespace NSCSS
return bResult;
}
+ bool CBorder::SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ bool bResult = false;
+
+ if (m_oLeft .SetWidth(dValue, unLevel, bHardMode)) bResult = true;
+ if (m_oTop .SetWidth(dValue, unLevel, bHardMode)) bResult = true;
+ if (m_oRight .SetWidth(dValue, unLevel, bHardMode)) bResult = true;
+ if (m_oBottom.SetWidth(dValue, unLevel, bHardMode)) bResult = true;
+
+ return bResult;
+ }
+
bool CBorder::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
bool bResult = false;
@@ -1638,6 +1881,11 @@ namespace NSCSS
return m_oLeft.SetWidth(wsValue, unLevel, bHardMode);
}
+ bool CBorder::SetWidthLeftSide(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oLeft.SetWidth(dValue, unLevel, bHardMode);
+ }
+
bool CBorder::SetStyleLeftSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oLeft.SetStyle(wsValue, unLevel, bHardMode);
@@ -1658,6 +1906,11 @@ namespace NSCSS
return m_oTop.SetWidth(wsValue, unLevel, bHardMode);
}
+ bool CBorder::SetWidthTopSide(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oTop.SetWidth(dValue, unLevel, bHardMode);
+ }
+
bool CBorder::SetStyleTopSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oTop.SetStyle(wsValue, unLevel, bHardMode);
@@ -1678,6 +1931,11 @@ namespace NSCSS
return m_oRight.SetWidth(wsValue, unLevel, bHardMode);
}
+ bool CBorder::SetWidthRightSide(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oRight.SetWidth(dValue, unLevel, bHardMode);
+ }
+
bool CBorder::SetStyleRightSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oRight.SetStyle(wsValue, unLevel, bHardMode);
@@ -1698,6 +1956,11 @@ namespace NSCSS
return m_oBottom.SetWidth(wsValue, unLevel, bHardMode);
}
+ bool CBorder::SetWidthBottomSide(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oBottom.SetWidth(dValue, unLevel, bHardMode);
+ }
+
bool CBorder::SetStyleBottomSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oBottom.SetStyle(wsValue, unLevel, bHardMode);
@@ -1708,6 +1971,14 @@ namespace NSCSS
return m_oBottom.SetColor(wsValue, unLevel, bHardMode);
}
+ void CBorder::SetNone(unsigned int unLevel, bool bHardMode)
+ {
+ m_oLeft .SetNone(unLevel, bHardMode);
+ m_oTop .SetNone(unLevel, bHardMode);
+ m_oRight .SetNone(unLevel, bHardMode);
+ m_oBottom.SetNone(unLevel, bHardMode);
+ }
+
void CBorder::Block()
{
m_oLeft .Block();
@@ -1789,6 +2060,14 @@ namespace NSCSS
m_oBottom == oBorder.m_oBottom;
}
+ bool CBorder::operator!=(const CBorder& oBorder) const
+ {
+ return m_oLeft != oBorder.m_oLeft ||
+ m_oTop != oBorder.m_oTop ||
+ m_oRight != oBorder.m_oRight ||
+ m_oBottom != oBorder.m_oBottom;
+ }
+
CBorder &CBorder::operator =(const CBorder &oBorder)
{
m_oLeft = oBorder.m_oLeft;
@@ -1811,6 +2090,7 @@ namespace NSCSS
CString::Equation(oFirstText.m_oAlign, oSecondText.m_oAlign);
// CString::Equation(oFirstText.m_oDecoration, oSecondText.m_oDecoration);
CColor ::Equation(oFirstText.m_oColor, oSecondText.m_oColor);
+ CColor ::Equation(oFirstText.m_oHighlight, oSecondText.m_oHighlight);
}
bool CText::SetIndent(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@@ -1846,6 +2126,11 @@ namespace NSCSS
return m_oColor.SetValue(wsValue, unLevel, bHardMode);
}
+ bool CText::SetHighlight(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oHighlight.SetValue(wsValue, unLevel, bHardMode);
+ }
+
const CDigit& CText::GetIndent() const
{
return m_oIndent;
@@ -1866,6 +2151,11 @@ namespace NSCSS
return m_oColor;
}
+ const CColor& CText::GetHighlight() const
+ {
+ return m_oHighlight;
+ }
+
bool CText::Empty() const
{
return m_oIndent.Empty() && m_oAlign.Empty() &&
@@ -1893,6 +2183,7 @@ namespace NSCSS
m_oAlign += oText.m_oAlign;
m_oDecoration += oText.m_oDecoration;
m_oColor += oText.m_oColor;
+ m_oHighlight += oText.m_oHighlight;
return *this;
}
@@ -1902,7 +2193,8 @@ namespace NSCSS
return m_oIndent == oText.m_oIndent &&
m_oAlign == oText.m_oAlign &&
m_oDecoration == oText.m_oDecoration &&
- m_oColor == oText.m_oColor;
+ m_oColor == oText.m_oColor &&
+ m_oHighlight == oText.m_oHighlight;
}
// MARGIN
@@ -1965,21 +2257,41 @@ namespace NSCSS
return m_oTop.SetValue(wsValue, unLevel, bHardMode);
}
+ bool CIndent::SetTop(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oTop.SetValue(dValue, unLevel, bHardMode);
+ }
+
bool CIndent::SetRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oRight.SetValue(wsValue, unLevel, bHardMode);
}
+ bool CIndent::SetRight(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oRight.SetValue(dValue, unLevel, bHardMode);
+ }
+
bool CIndent::SetBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oBottom.SetValue(wsValue, unLevel, bHardMode);
}
+ bool CIndent::SetBottom(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oBottom.SetValue(dValue, unLevel, bHardMode);
+ }
+
bool CIndent::SetLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oLeft.SetValue(wsValue, unLevel, bHardMode);
}
+ bool CIndent::SetLeft(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oLeft.SetValue(dValue, unLevel, bHardMode);
+ }
+
void CIndent::UpdateAll(double dFontSize)
{
UpdateTop (dFontSize);
@@ -2249,10 +2561,10 @@ namespace NSCSS
bool CFont::SetSize(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
const std::vector> arAbsoluteFontValues =
- {{L"xx-small", L"7.5pt"}, {L"xx-large", L"36pt" },
- {L"x-small", L"10pt" }, {L"x-large", L"24pt" },
- {L"small", L"12pt" }, {L"medium", L"13.5pt"},
- {L"large", L"18pt" }};
+ {{L"xx-small", L"7.5pt"}, {L"xx-large", L"36pt" },
+ {L"x-small", L"10pt" }, {L"x-large", L"24pt" },
+ {L"small", L"12pt" }, {L"medium", L"13.5pt"},
+ {L"large", L"18pt" }};
size_t unFoundPos = std::wstring::npos;
std::wstring wsNewValue(wsValue);
@@ -2267,6 +2579,11 @@ namespace NSCSS
return m_oSize.SetValue(wsNewValue, unLevel, bHardMode);
}
+ bool CFont:: SetSize(const double& dValue, unsigned int unLevel, bool bHardMode)
+ {
+ return m_oSize.SetValue(dValue, unLevel, bHardMode);
+ }
+
bool CFont::SetLineHeight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oLineHeight.SetValue(wsValue, unLevel, bHardMode);
@@ -2274,13 +2591,13 @@ namespace NSCSS
bool CFont::SetFamily(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
- std::wstring wsNewFamily(wsValue);
+ // std::wstring wsNewFamily(wsValue);
// if (wsNewFamily.end() == wsNewFamily.erase(std::remove(wsNewFamily.begin(), wsNewFamily.end(), L'\''), wsNewFamily.end()) &&
// wsNewFamily.end() == wsNewFamily.erase(std::remove(wsNewFamily.begin(), wsNewFamily.end(), L'"'), wsNewFamily.end()))
// return false;
- std::vector arWords = NS_STATIC_FUNCTIONS::GetWordsW(wsNewFamily, false, L"\"\',");
+ std::vector arWords = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L"\"\',");
for (std::vector::iterator iWord = arWords.begin(); iWord != arWords.end(); ++iWord)
{
@@ -2421,175 +2738,58 @@ namespace NSCSS
m_oWeight == oFont.m_oWeight;
}
- CColorValue::CColorValue()
- : m_enType(ColorEmpty), m_pColor(NULL)
+ CURL::CURL()
{}
- CColorValue::CColorValue(const CColorValue &oColorValue)
- : m_enType()
+ bool CURL::Empty() const
{
- switch(oColorValue.m_enType)
- {
- case ColorRGB: SetRGB(*static_cast(oColorValue.m_pColor)); break;
- case ColorHEX: SetHEX(*static_cast(oColorValue.m_pColor)); break;
- case ColorUrl: SetUrl(*static_cast(oColorValue.m_pColor)); break;
- default: m_enType = oColorValue.m_enType; break;
- }
-
+ return m_wsValue.empty();
}
- CColorValue::~CColorValue()
+ bool CURL::LinkToId() const
{
- Clear();
+ return m_wsValue.length() > 1 && L'#' == m_wsValue.front();
+ }
+
+ void CURL::Clear()
+ {
+ m_wsValue.clear();
}
- void CColorValue::SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB)
+ bool CURL::SetValue(const std::wstring &wsValue)
{
- Clear();
-
- m_pColor = new TRGB{uchR, uchG, uchB};
-
- if (NULL == m_pColor)
- {
- m_enType = ColorEmpty;
- return;
- }
-
- m_enType = ColorRGB;
- }
-
- void CColorValue::SetRGB(const TRGB &oRGB)
- {
- Clear();
-
- m_pColor = new TRGB{oRGB};
-
- if (NULL == m_pColor)
- {
- m_enType = ColorEmpty;
- return;
- }
-
- m_enType = ColorRGB;
- }
-
- void CColorValue::SetHEX(const std::wstring &wsValue)
- {
- Clear();
-
- if (6 != wsValue.length() && 3 != wsValue.length())
- {
- m_enType = ColorEmpty;
- return;
- }
-
- if (6 == wsValue.length())
- m_pColor = new std::wstring(wsValue);
- else
- m_pColor = new std::wstring({wsValue[0], wsValue[0], wsValue[1], wsValue[1], wsValue[2], wsValue[2]});
-
- if (NULL == m_pColor)
- {
- m_enType = ColorEmpty;
- return;
- }
-
- m_enType = ColorHEX;
- }
-
- void CColorValue::SetUrl(const std::wstring &wsValue)
- {
- Clear();
-
- m_pColor = new std::wstring(wsValue);
-
- if (NULL == m_pColor || ((std::wstring*)m_pColor)->empty())
- {
- m_enType = ColorEmpty;
- return;
- }
-
- m_enType = ColorUrl;
- }
-
- void CColorValue::SetNone()
- {
- Clear();
-
- m_enType = ColorNone;
- }
-
- bool CColorValue::Empty() const
- {
- return ColorEmpty == m_enType;
- }
-
- std::wstring CColorValue::GetColor() const
- {
- return *(std::wstring*)m_pColor;
- }
-
- bool CColorValue::operator==(const CColorValue &oColorValue) const
- {
- if (m_enType != oColorValue.m_enType)
+ if (wsValue.empty())
return false;
- if (ColorEmpty == m_enType ||
- ColorNone == m_enType)
- return true;
+ std::wregex oRegex(L"url\\s*\\(\\s*(?:'|\"|)([#]?[^'\"()]+)(?:'|\"|)\\s*\\)");
+ std::wsmatch oMatch;
- switch (m_enType)
- {
- case ColorRGB:
- return *static_cast(m_pColor) == *static_cast(oColorValue.m_pColor);
- case ColorHEX:
- case ColorUrl:
- return *static_cast(m_pColor) == *static_cast(oColorValue.m_pColor);
- default:
- break;
- }
+ if (!std::regex_search(wsValue.cbegin(), wsValue.cend(), oMatch, oRegex) || oMatch[1].str().empty())
+ return false;
- return false;
+ m_wsValue = oMatch[1].str();
+ NS_STATIC_FUNCTIONS::RemoveSpaces(m_wsValue);
+
+ return true;
+ }
+
+ std::wstring CURL::GetValue() const
+ {
+ return m_wsValue;
}
- CColorValue &CColorValue::operator=(const CColorValue &oColorValue)
+ bool CURL::operator==(const CURL& oValue) const
{
- switch(oColorValue.m_enType)
- {
- case ColorRGB: SetRGB(*static_cast(oColorValue.m_pColor)); break;
- case ColorHEX: SetHEX(*static_cast(oColorValue.m_pColor)); break;
- case ColorUrl: SetUrl(*static_cast(oColorValue.m_pColor)); break;
- default: m_enType = oColorValue.m_enType; break;
- }
-
- return *this;
+ return m_wsValue == oValue.m_wsValue;
}
- void CColorValue::Clear()
+ bool CURL::operator!=(const CURL& oValue) const
{
- switch (m_enType)
- {
- case ColorRGB:
- {
- TRGB *pRGB = static_cast(m_pColor);
- RELEASEOBJECT(pRGB);
- break;
- }
- case ColorHEX: case ColorUrl:
- {
- std::wstring* pValue = static_cast(m_pColor);
- RELEASEOBJECT(pValue);
- break;
- }
- default:
- break;
- }
-
- m_enType = ColorEmpty;
+ return m_wsValue != oValue.m_wsValue;
}
CEnum::CEnum()
- : CValue(INT_MAX, 0, false){}
+ : CValue(INT_MAX, 0, false){}
bool CEnum::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
@@ -2726,5 +2926,6 @@ namespace NSCSS
{
return m_oHeader;
}
+
}
}
diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h
index 13ea54f67c..b8a9e20d0a 100644
--- a/Common/3dParty/html/css/src/StyleProperties.h
+++ b/Common/3dParty/html/css/src/StyleProperties.h
@@ -13,6 +13,8 @@ namespace NSCSS
{
namespace NSProperties
{
+ #define NEXT_LEVEL UINT_MAX, true
+
template
class CValue
{
@@ -21,6 +23,7 @@ namespace NSCSS
friend class CDigit;
friend class CColor;
friend class CEnum;
+ friend class CURL;
T m_oValue;
unsigned int m_unLevel;
@@ -74,13 +77,13 @@ namespace NSCSS
return *this;
}
- CValue& operator =(const T& oValue)
+ virtual CValue& operator =(const T& oValue)
{
//m_oValue = oValue.m_oValue;
return *this;
}
- CValue& operator+=(const CValue& oValue)
+ virtual CValue& operator+=(const CValue& oValue)
{
if (m_unLevel > oValue.m_unLevel || (m_bImportant && !oValue.m_bImportant) || oValue.Empty())
return *this;
@@ -92,10 +95,15 @@ namespace NSCSS
return *this;
}
- bool operator==(const CValue& oValue) const
+ virtual bool operator==(const CValue& oValue) const
{
return m_oValue == oValue.m_oValue;
}
+
+ virtual bool operator!=(const CValue& oValue) const
+ {
+ return m_oValue != oValue.m_oValue;
+ }
};
class CString : public CValue
@@ -130,6 +138,7 @@ namespace NSCSS
bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override;
bool SetValue(const CDigit& oValue);
+ bool SetValue(const double& dValue, unsigned int unLevel, bool bHardMode);
bool Empty() const override;
bool Zero() const;
@@ -178,8 +187,28 @@ namespace NSCSS
bool Empty() const;
bool operator==(const TRGB& oRGB) const;
+ bool operator!=(const TRGB& oRGB) const;
};
+ class CURL
+ {
+ public:
+ CURL();
+
+ bool Empty() const;
+ bool LinkToId() const;
+
+ void Clear();
+
+ bool SetValue(const std::wstring& wsValue);
+ std::wstring GetValue() const;
+
+ bool operator==(const CURL& oValue) const;
+ bool operator!=(const CURL& oValue) const;
+ private:
+ std::wstring m_wsValue;
+ };
+
typedef enum
{
ColorEmpty,
@@ -189,39 +218,8 @@ namespace NSCSS
ColorUrl
} ColorType;
- class Q_DECL_EXPORT CColorValue
+ class CColor : public CValue
{
- public:
- CColorValue();
- CColorValue(const CColorValue& oColorValue);
- ~CColorValue();
-
- void SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB);
- void SetRGB(const TRGB& oRGB);
- void SetHEX(const std::wstring& wsValue);
- void SetUrl(const std::wstring& wsValue);
- void SetNone();
-
- void Clear();
-
- bool Empty() const;
-
- ColorType m_enType;
- void* m_pColor = NULL;
-
- std::wstring GetColor() const;
-
- bool operator==(const CColorValue& oColorValue) const;
- CColorValue& operator= (const CColorValue& oColorValue);
- };
-
- class CColor : public CValue
- {
- CDigit m_oOpacity;
- static TRGB ConvertHEXtoRGB(const std::wstring& wsValue);
- static std::wstring ConvertRGBtoHEX(const TRGB& oValue);
- static std::wstring CutURL(const std::wstring& wsValue);
- void SetEmpty(unsigned int unLevel = 0);
public:
CColor();
@@ -242,6 +240,25 @@ namespace NSCSS
std::wstring ToWString() const override;
std::wstring EquateToColor(const std::vector>& arColors) const;
TRGB ToRGB() const;
+
+ static TRGB ConvertHEXtoRGB(const std::wstring& wsValue);
+ static std::wstring ConvertRGBtoHEX(const TRGB& oValue);
+
+ bool operator==(const CColor& oColor) const;
+ bool operator!=(const CColor& oColor) const;
+
+ CColor& operator =(const CColor& oColor);
+ CColor& operator+=(const CColor& oColor);
+ private:
+ CDigit m_oOpacity;
+ ColorType m_enType;
+
+ void SetEmpty(unsigned int unLevel = 0);
+ void SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB);
+ void SetRGB(const TRGB& oRGB);
+ void SetHEX(const std::wstring& wsValue);
+ void SetUrl(const std::wstring& wsValue);
+ void SetNone();
};
typedef enum
@@ -427,6 +444,7 @@ namespace NSCSS
{
public:
CBorderSide();
+ CBorderSide(const CBorderSide& oBorderSide);
void Clear();
@@ -434,9 +452,12 @@ namespace NSCSS
bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ void SetNone(unsigned int unLevel, bool bHardMode);
+
void Block();
void Unblock();
@@ -452,6 +473,7 @@ namespace NSCSS
CBorderSide& operator+=(const CBorderSide& oBorderSide);
bool operator==(const CBorderSide& oBorderSide) const;
+ bool operator!=(const CBorderSide& oBorderSide) const;
CBorderSide& operator =(const CBorderSide& oBorderSide);
private:
CDigit m_oWidth;
@@ -473,39 +495,50 @@ namespace NSCSS
CBorder();
void Clear();
+ void ClearLeftSide();
+ void ClearTopSide();
+ void ClearRightSide();
+ void ClearBottomSide();
static void Equation(CBorder &oFirstBorder, CBorder &oSecondBorder);
- bool SetSides(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
- bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
- bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
- bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetSides(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetCollapse(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Left Side
bool SetLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidthLeftSide (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetStyleLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Top Side
bool SetTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidthTopSide (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetStyleTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Right Side
bool SetRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidthRightSide (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetStyleRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Bottom Side
bool SetBottomSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetWidthBottomSide(const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetStyleBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ void SetNone(unsigned int unLevel, bool bHardMode = false);
+
void Block();
void Unblock();
@@ -522,7 +555,7 @@ namespace NSCSS
CBorder& operator+=(const CBorder& oBorder);
bool operator==(const CBorder& oBorder) const;
-
+ bool operator!=(const CBorder& oBorder) const;
CBorder& operator =(const CBorder& oBorder);
private:
CBorderSide m_oLeft;
@@ -574,11 +607,13 @@ namespace NSCSS
bool SetAlign (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetDecoration(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColor (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetHighlight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
const CDigit& GetIndent() const;
const CString& GetAlign() const;
const TTextDecoration& GetDecoration() const;
const CColor& GetColor() const;
+ const CColor& GetHighlight() const;
bool Empty() const;
@@ -593,6 +628,7 @@ namespace NSCSS
CDigit m_oIndent;
CString m_oAlign;
CColor m_oColor;
+ CColor m_oHighlight;
};
class CIndent
@@ -610,9 +646,13 @@ namespace NSCSS
bool SetValues (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetTop (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetTop (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetRight (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetBottom (const double& dValue, unsigned int unLevel, bool bHardMode = false);
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);
@@ -652,6 +692,7 @@ namespace NSCSS
bool SetValue (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetSize (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
+ bool SetSize (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetLineHeight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetFamily (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetStretch (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp
index 19bd8087b7..c69d7ffa9c 100644
--- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp
+++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp
@@ -341,12 +341,14 @@ namespace NSCSS
sSpacingValue.reserve(128);
if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero())
- sSpacingValue += L"w:before=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetTop(), NSCSS::Twips)) + L"\" w:beforeAutospacing=\"0\" ";
+ sSpacingValue += L"w:before=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetTop(), NSCSS::Twips)) + L"\" w:beforeAutospacing=\"0\"";
+ else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable)
+ sSpacingValue += L"w:before=\"0\" w:beforeAutospacing=\"0\"";
if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero())
- sSpacingValue += L"w:after=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetBottom(), NSCSS::Twips)) + L"\" w:afterAutospacing=\"0\" ";
+ sSpacingValue += L" w:after=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetBottom(), NSCSS::Twips)) + L"\" w:afterAutospacing=\"0\"";
else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable)
- sSpacingValue += L"w:after=\"0\" ";
+ sSpacingValue += L" w:after=\"0\" w:afterAutospacing=\"0\"";
if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero())
{
@@ -356,7 +358,7 @@ namespace NSCSS
sSpacingValue += L" w:line=\"" + wsLine + L"\" w:lineRule=\"" + wsLineRule + L"\"";
}
else if (oStyle.m_oFont.GetLineHeight().Zero() || bInTable)
- sSpacingValue += L"w:lineRule=\"auto\" w:line=\"240\"";
+ sSpacingValue += L" w:lineRule=\"auto\" w:line=\"240\"";
if (!sSpacingValue.empty())
oXmlElement.AddPropertiesInP(PProperties::P_Spacing, sSpacingValue);
@@ -491,17 +493,15 @@ namespace NSCSS
if (!oStyle.m_oBackground.GetColor().Empty() && !oStyle.m_oBackground.GetColor().None() && !oStyle.m_oBackground.GetColor().Url())
oXmlElement.AddPropertiesInR(RProperties::R_Shd, oStyle.m_oBackground.GetColor().ToWString());
- /*
- const std::wstring wsHighlight{oStyle.m_oBackground.GetColor().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
- {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
- {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"},
- {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"},
- {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"},
- {{211, 211, 211}, L"lightGray"}})};
+ const std::wstring wsHighlight{oStyle.m_oText.GetHighlight().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
+ {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
+ {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"},
+ {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"},
+ {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"},
+ {{211, 211, 211}, L"lightGray"}})};
if (L"none" != wsHighlight)
oXmlElement.AddPropertiesInR(RProperties::R_Highlight, wsHighlight);
- */
oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString());
@@ -523,10 +523,7 @@ namespace NSCSS
Clear();
if(oStyle.GetId().empty())
- {
- m_sId = L"normal";
return false;
- }
CStyleUsed structStyle(oStyle, false);
@@ -589,10 +586,7 @@ namespace NSCSS
Clear();
if(oStyle.GetId().empty())
- {
- m_sId = L"normal";
- return true;
- }
+ return false;
CStyleUsed structStyle(oStyle, true);
std::vector::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle);
diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp
index 5f9db69058..6eb112e02a 100644
--- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp
+++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp
@@ -27,7 +27,7 @@ CXmlElement::CXmlElement(const std::wstring& sNameDefaultElement)
bool CXmlElement::Empty() const
{
- return m_mPStyleValues.empty() && m_mRStyleValues.empty() && m_mBasicValues.find(CSSProperties::BasicProperties::B_BasedOn) == m_mBasicValues.end();
+ return m_mPStyleValues.empty() && m_mRStyleValues.empty() && GetBasedOn().empty();
}
void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
@@ -35,7 +35,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
if (!Empty())
Clear();
- if (sNameDefaultElement == L"p")
+/* if (sNameDefaultElement == L"p")
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p");
@@ -47,7 +47,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
- else if (sNameDefaultElement == L"li")
+ else */if (sNameDefaultElement == L"li")
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"li");
@@ -203,7 +203,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"15");
AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold");
}
- else if (sNameDefaultElement == L"div-c")
+ /*else if (sNameDefaultElement == L"div-c")
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"div-c");
@@ -219,7 +219,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Div paragraph");
AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal");
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"div-c");
- }
+ }*/
else if (sNameDefaultElement == L"a-c")
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
diff --git a/DesktopEditor/graphics/pro/metafile.pri b/DesktopEditor/graphics/pro/metafile.pri
index 605b7e9dd9..43680e07db 100644
--- a/DesktopEditor/graphics/pro/metafile.pri
+++ b/DesktopEditor/graphics/pro/metafile.pri
@@ -117,6 +117,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
$$METAFILE_PATH/svg/SvgObjects/CText.h \
$$METAFILE_PATH/svg/SvgObjects/CUse.h \
$$METAFILE_PATH/svg/SvgObjects/CPolyline.h \
+ $$METAFILE_PATH/svg/SvgObjects/CFont.h \
$$METAFILE_PATH/svg/SvgObjects/CStyle.h \
$$METAFILE_PATH/svg/SvgObjects/CObjectBase.h \
$$METAFILE_PATH/svg/SvgUtils.h
@@ -141,6 +142,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
$$METAFILE_PATH/svg/SvgObjects/CText.cpp \
$$METAFILE_PATH/svg/SvgObjects/CUse.cpp \
$$METAFILE_PATH/svg/SvgObjects/CPolyline.cpp \
+ $$METAFILE_PATH/svg/SvgObjects/CFont.cpp \
$$METAFILE_PATH/svg/SvgObjects/CObjectBase.cpp \
$$METAFILE_PATH/svg/SvgObjects/CStyle.cpp
diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp
index 08a7727073..f6df395d0f 100644
--- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp
+++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp
@@ -1,6 +1,7 @@
#include "CSvgFile.h"
#include "SvgObjects/CContainer.h"
+#include "SvgObjects/CFont.h"
#define SVG_FILE_WIDTH 300
#define SVG_FILE_HEIGHT 150
@@ -132,6 +133,16 @@ SVG::CObject *CSvgFile::GetMarkedObject(const std::wstring &wsId) const
return NULL;
}
+SVG::CFont *CSvgFile::GetFont(const std::wstring &wsFontFamily) const
+{
+ FontsFaceMap::const_iterator itFound = std::find_if(m_mFontsFace.cbegin(), m_mFontsFace.cend(), [&wsFontFamily](const std::pair& oValue){ return wsFontFamily == oValue.first; });
+
+ if (m_mFontsFace.cend() == itFound)
+ return NULL;
+
+ return dynamic_cast(GetMarkedObject(itFound->second));
+}
+
std::wstring CSvgFile::GetWorkingDirectory() const
{
return m_wsWorkingDirectory;
@@ -142,6 +153,11 @@ void CSvgFile::AddStyles(const std::wstring &wsStyles)
m_oSvgCalculator.AddStyles(wsStyles);
}
+void CSvgFile::AddFontFace(const SVG::TFontArguments& oArguments, const std::wstring &wsId)
+{
+ m_mFontsFace.insert(std::make_pair(oArguments.m_wsFontFamily, wsId));
+}
+
bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer || m_oContainer.Empty())
diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.h b/DesktopEditor/raster/Metafile/svg/CSvgFile.h
index 1f2c71e60c..5f1af3e39f 100644
--- a/DesktopEditor/raster/Metafile/svg/CSvgFile.h
+++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.h
@@ -9,6 +9,12 @@
#define SVG_DECL_IMPORT Q_DECL_IMPORT
+namespace SVG
+{
+ struct TFontArguments;
+ class CFont;
+}
+
class SVG_DECL_IMPORT CSvgFile
{
public:
@@ -28,9 +34,12 @@ class SVG_DECL_IMPORT CSvgFile
bool MarkObject(SVG::CObject* pObject);
SVG::CObject* GetMarkedObject(const std::wstring& wsId) const;
+ SVG::CFont* GetFont(const std::wstring& wsFontFamily) const;
+
std::wstring GetWorkingDirectory() const;
-
+
void AddStyles(const std::wstring& wsStyles);
+ void AddFontFace(const SVG::TFontArguments& oArguments, const std::wstring& wsId);
bool Draw(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight);
private:
@@ -44,6 +53,9 @@ class SVG_DECL_IMPORT CSvgFile
MarkedMap m_mMarkedObjects;
std::wstring m_wsWorkingDirectory;
+
+ typedef std::map FontsFaceMap;
+ FontsFaceMap m_mFontsFace;
};
#endif // CSVGFILE_H
diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp b/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp
index 3bcf39a95a..9026263cdc 100644
--- a/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp
+++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.cpp
@@ -6,7 +6,6 @@
#include "CSvgFile.h"
-#include "SvgObjects/CContainer.h"
#include "SvgObjects/CPolyline.h"
#include "SvgObjects/CGradient.h"
#include "SvgObjects/CClipPath.h"
@@ -21,6 +20,7 @@
#include "SvgObjects/CRect.h"
#include "SvgObjects/CLine.h"
#include "SvgObjects/CPath.h"
+#include "SvgObjects/CFont.h"
#include "SvgObjects/CText.h"
#include "SvgObjects/CMask.h"
#include "SvgObjects/CUse.h"
@@ -95,7 +95,7 @@ namespace SVG
if (L"style" == wsElementName)
{
- pFile->AddStyles(oElement.GetText());
+ ParseStyles(oElement.GetText(), pFile);
return true;
}
@@ -116,6 +116,61 @@ namespace SVG
return bScanResult;
}
+
+ void CSvgParser::ParseStyles(const std::wstring &wsStyles, CSvgFile *pFile) const
+ {
+ if (NULL == pFile)
+ return;
+
+ pFile->AddStyles(wsStyles);
+
+ std::wregex oRegex(L"@font-face\\s*(\\{[^}]*\\})");
+ std::wsmatch oMatch;
+ std::wstring::const_iterator oSearchStart(wsStyles.cbegin());
+
+ while (std::regex_search(oSearchStart, wsStyles.cend(), oMatch, oRegex))
+ {
+ if (oMatch[1].str().empty())
+ continue;
+
+ std::wstring wsValue{oMatch[1].str()};
+
+ std::wstring::const_iterator itStart = std::find_if(wsValue.cbegin(), wsValue.cend(), [](const wchar_t& wChar) { return !std::iswspace(wChar) && L'{' != wChar; });
+ std::wstring::const_reverse_iterator itEnd = std::find_if(wsValue.crbegin(), wsValue.crend(), [](const wchar_t& wChar) { return !std::iswspace(wChar) && L'}' != wChar; });
+
+ if (wsValue.cend() != itStart && wsValue.crend() != itEnd)
+ wsValue = std::wstring(itStart, itEnd.base());
+
+ const std::vector arWords{NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(wsValue, true, L":;")};
+
+ SvgURL oURL;
+ TFontArguments m_oArguments;
+
+ for (unsigned int unIndex = 0; unIndex < arWords.size(); ++unIndex)
+ {
+ if (arWords[unIndex].length() > 3 && L"src" == arWords[unIndex].substr(0, 3) && L':' == arWords[unIndex].back() &&
+ unIndex + 1 < arWords.size() && oURL.SetValue(arWords[++unIndex]))
+ {
+ continue;
+ }
+ else if (arWords[unIndex].length() > 11 && L"font-family" == arWords[unIndex].substr(0, 11) && L':' == arWords[unIndex].back() &&
+ unIndex + 1 < arWords.size())
+ {
+ const std::vector arFontFamily{NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords[++unIndex], false, L"\"\',;")};
+
+ if (arFontFamily.empty())
+ continue;
+
+ m_oArguments.m_wsFontFamily = arFontFamily.back();
+ }
+ }
+
+ if (!oURL.Empty() && !m_oArguments.m_wsFontFamily.empty())
+ pFile->AddFontFace(m_oArguments, oURL.GetValue());
+
+ oSearchStart = oMatch.suffix().first;
+ }
+ }
template
bool CSvgParser::ReadObject(XmlUtils::CXmlNode &oElement, CContainer *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
@@ -229,6 +284,10 @@ namespace SVG
else
RELEASEOBJECT(pObject);
}
+ else if (L"font" == wsElementName)
+ {
+ pObject = new CFont(oElement);
+ }
if (NULL != pObject)
{
diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.h b/DesktopEditor/raster/Metafile/svg/CSvgParser.h
index 060aecea5d..b0b298c3d6 100644
--- a/DesktopEditor/raster/Metafile/svg/CSvgParser.h
+++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.h
@@ -2,6 +2,7 @@
#define CSVGPARSER_H
#include "../../../common/Directory.h"
+#include "../../../graphics/pro/Fonts.h"
#include "../../../xml/include/xmlutils.h"
#include "SvgObjects/CContainer.h"
@@ -29,6 +30,7 @@ namespace SVG
bool ReadChildrens(XmlUtils::CXmlNode& oElement, CContainer* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ScanStyles(XmlUtils::CXmlNode& oElement, CSvgFile* pFile) const;
+ void ParseStyles(const std::wstring& wsStyles, CSvgFile *pFile) const;
void UpdateStyles(CObject* pObject, CSvgFile* pFile) const;
bool MarkObject(CObject* pObject, CSvgFile* pFile) const;
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h
index 83da8b305e..3097507504 100644
--- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h
@@ -3,8 +3,6 @@
#include "CObjectBase.h"
-#include "../../../../graphics/pro/Fonts.h"
-
class CSvgFile;
namespace SVG
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp
new file mode 100644
index 0000000000..276a106b15
--- /dev/null
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp
@@ -0,0 +1,143 @@
+#include "CFont.h"
+
+namespace SVG
+{
+ CGlyph::CGlyph(XmlUtils::CXmlNode &oNode)
+ : CPath(oNode)
+ {
+ std::wstring wsUnicode(oNode.GetAttribute(L"unicode"));
+
+ if (!wsUnicode.empty())
+ m_wchUnicode = wsUnicode[0];
+
+ m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x"));
+ }
+
+ wchar_t CGlyph::GetUnicode() const
+ {
+ return m_wchUnicode;
+ }
+
+ CFontFace::CFontFace(XmlUtils::CXmlNode &oNode)
+ {
+
+ }
+
+ CFont::CFont(XmlUtils::CXmlNode &oNode)
+ : CAppliedObject(oNode), m_pMissingGlyph(NULL)
+ {
+ ParseGlyphs(oNode);
+
+ m_oArguments.m_wsFontVariant = oNode.GetAttribute(L"font-variant");
+ m_oArguments.m_wsFontStyle = oNode.GetAttribute(L"font-style");
+ m_oArguments.m_wsFontWidght = oNode.GetAttribute(L"font-weight");
+
+ m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x"));
+ }
+
+ CFont::~CFont()
+ {
+ for (std::pair oElement : m_mGlyphs)
+ RELEASEOBJECT(oElement.second);
+
+ RELEASEOBJECT(m_pMissingGlyph);
+ }
+
+ void CFont::SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode)
+ {
+ }
+
+ bool CFont::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
+ {
+ return false;
+ }
+
+ bool CFont::Draw(const std::wstring &wsText, double dX, double dY, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles) const
+ {
+ if (NULL == pRenderer)
+ return false;
+
+ double dM11, dM12, dM21, dM22, dRx, dRy;
+
+ pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dRx, &dRy);
+
+ Aggplus::CMatrix oMatrix(dM11, dM12, dM21, dM22, dRx, dRy);
+ oMatrix.Translate(dX, dY);
+
+ pRenderer->SetTransform(dM11, dM12, dM21, -dM22, oMatrix.tx(), oMatrix.ty());
+
+ MGlyphsMap::const_iterator itFound;
+ TBounds oGlyphBounds;
+
+ for (wchar_t wchGlyph : wsText)
+ {
+ itFound = m_mGlyphs.find(wchGlyph);
+
+ if (m_mGlyphs.cend() == itFound)
+ {
+ if (NULL == m_pMissingGlyph)
+ continue;
+
+ m_pMissingGlyph->Draw(pRenderer, pFile, oMode, pStyles);
+ oMatrix.Translate(m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0);
+ }
+ else
+ {
+ itFound->second->Draw(pRenderer, pFile, oMode, pStyles);
+
+ if (!itFound->second->m_oHorizAdvX.Empty())
+ oMatrix.Translate(itFound->second->m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0);
+ else
+ oMatrix.Translate(m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0);
+ }
+
+ oMatrix.Translate(std::abs(oGlyphBounds.m_dRight - oGlyphBounds.m_dLeft), 0);
+
+ pRenderer->SetTransform(dM11, dM12, dM21, -dM22, oMatrix.tx(), oMatrix.ty());
+ }
+
+ pRenderer->SetTransform(dM11, dM12, dM21, dM22, dRx, dRy);
+
+ return true;
+ }
+
+ void CFont::ParseGlyphs(XmlUtils::CXmlNode &oNode)
+ {
+ std::vector arChilds;
+
+ if (!oNode.GetChilds(arChilds) || arChilds.empty())
+ return;
+
+ for (XmlUtils::CXmlNode& oChild : arChilds)
+ {
+ if (L"glyph" == oChild.GetName())
+ {
+ CGlyph *pGlyph = new CGlyph(oChild);
+
+ if (NULL == pGlyph)
+ continue;
+
+ if (m_mGlyphs.end() == m_mGlyphs.find(pGlyph->GetUnicode()))
+ m_mGlyphs.insert(std::make_pair(pGlyph->GetUnicode(), pGlyph));
+ else
+ delete pGlyph;
+ }
+ else if (L"missing-glyph" == oChild.GetName())
+ {
+ std::vector arMissingGlyphChilds;
+ if (!oChild.GetChilds(arMissingGlyphChilds) || arMissingGlyphChilds.empty())
+ continue;
+
+ for (XmlUtils::CXmlNode& oChildMissingGlyph : arMissingGlyphChilds)
+ {
+ if (L"path" == oChildMissingGlyph.GetName())
+ {
+ m_pMissingGlyph = new CPath(oChildMissingGlyph);
+ if (NULL != m_pMissingGlyph)
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h
new file mode 100644
index 0000000000..bb1b1627ad
--- /dev/null
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h
@@ -0,0 +1,61 @@
+#ifndef CFONT_H
+#define CFONT_H
+
+#include "CPath.h"
+
+namespace SVG
+{
+ class CGlyph : public CPath
+ {
+ public:
+ CGlyph(XmlUtils::CXmlNode& oNode);
+
+ wchar_t GetUnicode() const;
+ private:
+ wchar_t m_wchUnicode;
+ SvgDigit m_oHorizAdvX;
+
+ friend class CFont;
+ };
+
+ class CFontFace
+ {
+ public:
+ CFontFace(XmlUtils::CXmlNode& oNode);
+ private:
+ std::wstring m_wsSrcFaceName;
+ };
+
+ struct TFontArguments
+ {
+ std::wstring m_wsFontFamily;
+ std::wstring m_wsFontVariant;
+ std::wstring m_wsFontStyle;
+ std::wstring m_wsFontWidght;
+ };
+
+ class CFont : public CAppliedObject
+ {
+ public:
+ CFont(XmlUtils::CXmlNode& oNode);
+ ~CFont();
+
+ void SetData(const std::map &mAttributes, unsigned short ushLevel, bool bHardMode) override;
+
+ bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
+ bool Draw(const std::wstring& wsText, double dX, double dY, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL) const;
+ private:
+ void ParseGlyphs(XmlUtils::CXmlNode& oNode);
+
+ TFontArguments m_oArguments;
+
+ typedef std::map MGlyphsMap;
+
+ MGlyphsMap m_mGlyphs;
+ CPath *m_pMissingGlyph;
+
+ SvgDigit m_oHorizAdvX;
+ };
+}
+
+#endif // CFONT_H
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h
index 2833568720..7ac81c88b8 100644
--- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CPattern.h
@@ -2,6 +2,7 @@
#define CPATTERN_H
#include "CContainer.h"
+#include "../../../../graphics/pro/Fonts.h"
namespace SVG
{
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h
index f98f623ad4..7efe2b10fe 100644
--- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CSymbol.h
@@ -2,6 +2,7 @@
#define CSYMBOL_H
#include "CContainer.h"
+#include "../../../graphics/pro/Fonts.h"
namespace SVG
{
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp
index 9c6f1165fd..377b5d36a6 100644
--- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp
@@ -4,6 +4,7 @@
#include "../SvgUtils.h"
#include "../CSvgFile.h"
#include "CContainer.h"
+#include "CFont.h"
#include "CStyle.h"
#ifndef MININT8
@@ -152,12 +153,15 @@ namespace SVG
double dX, dY;
CalculatePosition(dX, dY);
- ApplyFont(pRenderer, dX, dY);
-
- pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0);
-
- for (const CRenderedObject* pTSpan : m_arObjects)
- pTSpan->Draw(pRenderer, pFile, oMode, pOtherStyles);
+ if (!UseExternalFont(pFile, dX, dY, pRenderer, pFile, oMode, pOtherStyles))
+ {
+ ApplyFont(pRenderer, dX, dY);
+
+ pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0);
+
+ for (const CRenderedObject* pTSpan : m_arObjects)
+ pTSpan->Draw(pRenderer, pFile, oMode, pOtherStyles);
+ }
EndPath(pRenderer, pFile, oOldMatrix, oMode, pOtherStyles);
@@ -292,6 +296,26 @@ 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, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
+ {
+ std::wstring wsFontFamily = DefaultFontFamily;
+
+ if (!m_oFont.GetFamily().Empty())
+ {
+ wsFontFamily = m_oFont.GetFamily().ToWString();
+ CorrectFontFamily(wsFontFamily);
+ }
+
+ CFont *pFont = pFile->GetFont(wsFontFamily);
+
+ if (NULL == pFont)
+ return false;
+
+ pFont->Draw(m_wsText, dX, dY, pRenderer, pFile, oMode, pOtherStyles);
+
+ return true;
+ }
TBounds CTSpan::GetBounds() const
{
diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h
index b67e5390fe..840807d01f 100644
--- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h
+++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h
@@ -31,6 +31,8 @@ namespace SVG
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath) const override;
void ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const;
+ bool UseExternalFont(const CSvgFile* pFile, double dX, double dY, IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const;
+
TBounds GetBounds() const override;
double GetWidth() const;
diff --git a/DesktopEditor/raster/Metafile/svg/SvgTypes.h b/DesktopEditor/raster/Metafile/svg/SvgTypes.h
index 38ea443a6d..13a563466b 100644
--- a/DesktopEditor/raster/Metafile/svg/SvgTypes.h
+++ b/DesktopEditor/raster/Metafile/svg/SvgTypes.h
@@ -14,6 +14,7 @@ namespace SVG
#define SvgDigit NSCSS::NSProperties::CDigit
#define SvgString NSCSS::NSProperties::CString
#define SvgColor NSCSS::NSProperties::CColor
+ #define SvgURL NSCSS::NSProperties::CURL
#define SvgEnum NSCSS::NSProperties::CEnum
#define SvgTransform NSCSS::NSProperties::CTransform
diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro
index 97f6dd3cde..c898f45034 100644
--- a/HtmlFile2/HtmlFile2.pro
+++ b/HtmlFile2/HtmlFile2.pro
@@ -11,6 +11,7 @@ CONFIG += plugin
DEFINES += HTMLFILE2_USE_DYNAMIC_LIBRARY
DEFINES += CSSCALCULATOR_LIBRARY_STATIC
DEFINES += CSS_CALCULATOR_WITH_XHTML
+DEFINES += DESABLE_RUBY_SUPPORT
CORE_ROOT_DIR = $$PWD/..
PWD_ROOT_DIR = $$PWD
diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp
index 17fda94882..f0433d7f60 100644
--- a/HtmlFile2/htmlfile2.cpp
+++ b/HtmlFile2/htmlfile2.cpp
@@ -46,9 +46,16 @@
#define DEFAULT_FONT_FAMILY std::wstring(L"Times New Roman")
#define DEFAULT_FONT_SIZE 24
+#define DEFAULT_IMAGE_WIDTH 304800
+#define DEFAULT_IMAGE_HEIGHT 304800
+
#define SAVE_NORMALIZED_HTML 0
-std::wstring rStyle = L" a area b strong bdo bdi big br center cite dfn em i var code kbd samp tt del s font img ins u mark q rt sup small sub svg input basefont button label data object noscript output abbr time ruby progress hgroup meter span acronym ";
+#define RELEASE_VECTOR_PTR(vector_object, object_type) \
+ for (object_type* pElement : vector_object) \
+ RELEASEOBJECT(pElement) \
+
+const static double HTML_FONTS[7] = {7.5, 10, 12, 13.5, 18, 24, 36};
// Ячейка таблицы
struct CTc
@@ -72,26 +79,30 @@ struct CTextSettings
{
bool bBdo; // Реверс текста
bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк)
+ bool bQ; // Цитата
bool bAddSpaces; // Добавлять пробелы перед текстом?
bool bMergeText; // Объединять подяр идущий текст в 1?
int nLi; // Уровень списка
- std::wstring sRStyle; // w:rStyle
- std::wstring sPStyle; // w:pStyle
- CTextSettings(bool _bBdo, bool _bPre, bool _bAddSpaces, bool _bMergeText, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) :
- bBdo(_bBdo), bPre(_bPre), bAddSpaces(_bAddSpaces), bMergeText(_bMergeText), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle)
+ std::wstring sPStyle;
+
+ enum ETextMode
+ {
+ Normal,
+ Superscript,
+ Subscript
+ } eTextMode;
+
+ NSCSS::CCompiledStyle oAdditionalStyle;
+
+ CTextSettings()
+ : bBdo(false), bPre(false), bQ(false), bAddSpaces(true), bMergeText(false), nLi(-1), eTextMode(Normal)
{}
CTextSettings(const CTextSettings& oTS) :
- bBdo(oTS.bBdo), bPre(oTS.bPre), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle)
+ bBdo(oTS.bBdo), bPre(oTS.bPre), bQ(oTS.bQ), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sPStyle(oTS.sPStyle)
{}
- void AddRStyle(const std::wstring& wsStyle)
- {
- if (std::wstring::npos == sRStyle.find(wsStyle))
- sRStyle += wsStyle;
- }
-
void AddPStyle(const std::wstring& wsStyle)
{
if (std::wstring::npos == sPStyle.find(wsStyle))
@@ -99,38 +110,30 @@ struct CTextSettings
}
};
-std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL)
+struct TImageData
{
- if (oBorder.EqualSides() && (NULL == pPadding || pPadding->Equals()))
+ UINT m_unWidth;
+ UINT m_unHeight;
+
+ int m_nHSpace;
+ int m_nVSpace;
+
+ std::wstring m_wsAlign;
+
+ TImageData()
+ : m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left")
+ {}
+
+ bool ZeroSize() const
{
- const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetLeft()))));
-
- return L"" +
- L"" +
- L"" +
- L"";
- }
- else
- {
- std::wstring wsTable;
-
- if (oBorder.GetTopBorder().Valid())
- wsTable += L"GetTop())))) + L"/>";
-
- if (oBorder.GetLeftBorder().Valid())
- wsTable += L"GetLeft())))) + L"/>";
-
- if (oBorder.GetBottomBorder().Valid())
- wsTable += L"GetBottom())))) + L"/>";
-
- if (oBorder.GetRightBorder().Valid())
- wsTable += L"GetRight())))) + L"/>";
-
- return wsTable;
+ return 0 == m_unWidth || 0 == m_unHeight;
}
- return L"";
-}
+ bool ZeroSpaces() const
+ {
+ return 0 == m_nHSpace && 0 == m_nVSpace;
+ }
+};
void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false, bool bInP = false)
{
@@ -151,10 +154,19 @@ void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = fal
pXml->WriteString(L"");
}
-void WriteLine(NSStringUtils::CStringBuilder* pXml, double dHeight, const std::wstring& wsColor)
+void WriteLine(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsAlign, const std::wstring& wsColor, bool bShade, double dSize, double dWidth)
{
+ if (dWidth < 0)
+ dWidth = -dWidth;
+
+ if (dSize < 0)
+ dSize = -dSize;
+
+ if (dWidth > 100)
+ dWidth = 0;
+
pXml->WriteNodeBegin(L"w:pict");
- pXml->WriteString(L"");
+ pXml->WriteString(L"");
pXml->WriteNodeEnd(L"w:pict");
}
@@ -163,6 +175,71 @@ bool ElementInTable(const std::vector& arSelectors)
return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; });
}
+UINT GetFontSizeLevel(UINT unFontSize)
+{
+ if (unFontSize <= 18)
+ return 1;
+ else if (unFontSize <= 22)
+ return 2;
+ else if (unFontSize <= 26)
+ return 3;
+ else if (unFontSize <= 30)
+ return 4;
+ else if (unFontSize <= 40)
+ return 5;
+ else if (unFontSize <= 59)
+ return 6;
+ else
+ return 7;
+}
+
+UINT GetFontSizeByLevel(UINT unLevel)
+{
+ if (0 == unLevel)
+ return 15;
+ else if (unLevel > 7)
+ return 72;
+
+ switch (unLevel)
+ {
+ case 1: return 15;
+ case 2: return 20;
+ case 3: return 24;
+ case 4: return 27;
+ case 5: return 36;
+ case 6: return 48;
+ case 7: return 72;
+ }
+ return 24;
+}
+
+int CalculateFontChange(const std::vector& arSelectors)
+{
+ int nFontChange = 0;
+
+ for (const NSCSS::CNode& oNode : arSelectors)
+ {
+ if (L"big" == oNode.m_wsName)
+ ++nFontChange;
+ else if (L"small" == oNode.m_wsName)
+ --nFontChange;
+ }
+
+ return nFontChange;
+}
+
+#define FIRST_ELEMENT 0x00000001
+#define LAST_ELEMENT 0x00000002
+#define MID_ELEMENT 0x00000004
+
+#define PARSE_MODE_HEADER 0x00000100
+#define PARSE_MODE_BODY 0x00000200
+#define PARSE_MODE_FOOTHER 0x00000400
+
+#define COL_POSITION_MASK 0x0000000F
+#define ROW_POSITION_MASK 0x000000F0
+#define PARSE_MODE_MASK 0x00000F00
+
typedef enum
{
ParseModeHeader,
@@ -179,20 +256,94 @@ struct TTableStyles
NSCSS::NSProperties::CDigit m_oWidth;
int m_nCellSpacing;
- bool m_bHaveBorderAttribute;
std::wstring m_wsAlign;
+ enum ETableRules
+ {
+ All,
+ Groups,
+ Cols,
+ None,
+ Rows
+ } m_enRules;
+
TTableStyles()
- : m_nCellSpacing(-1), m_bHaveBorderAttribute(false)
+ : m_nCellSpacing(-1), m_enRules(None)
{}
bool Empty() const
{
- return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && false == m_bHaveBorderAttribute && m_wsAlign.empty();
+ return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && m_wsAlign.empty();
}
};
+std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL, bool bAddIntermediateLines = false, TTableStyles::ETableRules enTableRule = TTableStyles::ETableRules::None)
+{
+ std::wstring wsTable;
+
+ if (oBorder.EqualSides() && (NULL == pPadding || pPadding->Equals()))
+ {
+ const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetLeft()))));
+
+ wsTable = L"" + L"" +
+ L"" + L"";
+ }
+ else
+ {
+ if (oBorder.GetTopBorder().Valid())
+ wsTable += L"GetTop())))) + L"/>";
+
+ if (oBorder.GetLeftBorder().Valid())
+ wsTable += L"GetLeft())))) + L"/>";
+
+ if (oBorder.GetBottomBorder().Valid())
+ wsTable += L"GetBottom())))) + L"/>";
+
+ if (oBorder.GetRightBorder().Valid())
+ wsTable += L"GetRight())))) + L"/>";
+ }
+
+ if (!bAddIntermediateLines)
+ return wsTable;
+
+ if (TTableStyles::ETableRules::Rows == enTableRule || TTableStyles::ETableRules::All == enTableRule)
+ {
+ NSCSS::NSProperties::CBorderSide oNewSide(oBorder.GetBottomBorder());
+ oNewSide.SetWidth(L"1pt", 0, true);
+
+ wsTable += L"";
+ }
+
+ if (TTableStyles::ETableRules::Cols == enTableRule || TTableStyles::ETableRules::All == enTableRule)
+ {
+ NSCSS::NSProperties::CBorderSide oNewSide(oBorder.GetRightBorder());
+ oNewSide.SetWidth(L"1pt", 0, true);
+
+ wsTable += L"";
+ }
+
+ return wsTable;
+}
+
+std::wstring CreateBorders(const std::wstring& wsStyle, UINT unSize, UINT unSpace, const std::wstring& wsAuto)
+{
+ const std::wstring wsBodyBorder{L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(unSize) + L"\" w:space=\"" + std::to_wstring(unSpace) + L"\" w:color=\"" + wsAuto + L"\""};
+
+ return L"" +
+ L"" +
+ L"" +
+ L"";
+}
+
+#define CreateOutsetBorders(enType) CreateBorders(L"outset", 6, 0, L"auto", enType)
+
+std::wstring CreateDefaultBorder(std::wstring wsSideName)
+{
+ std::transform(wsSideName.begin(), wsSideName.end(), wsSideName.begin(), std::towlower);
+ return L"";
+}
+
struct TTableRowStyle
{
UINT m_unMaxIndex;
@@ -241,22 +392,44 @@ struct TTableCellStyle
m_wsHAlign = pTableCellStyle->m_wsHAlign;
m_wsVAlign = pTableCellStyle->m_wsVAlign;
}
+
+ TTableCellStyle& operator+=(const TTableCellStyle* pCellStyle)
+ {
+ if (NULL == pCellStyle)
+ return *this;
+
+ m_oWidth += pCellStyle->m_oWidth;
+ m_oHeight += pCellStyle->m_oHeight;
+ m_oBorder += pCellStyle->m_oBorder;
+ m_oPadding += pCellStyle->m_oPadding;
+ m_oBackground += pCellStyle->m_oBackground;
+
+ if (m_wsHAlign.empty())
+ m_wsHAlign = pCellStyle->m_wsHAlign;
+
+ if (m_wsVAlign.empty())
+ m_wsVAlign = pCellStyle->m_wsVAlign;
+
+ return *this;
+ }
};
+class CTable;
+
class CTableCell
{
public:
CTableCell()
- : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false), m_enMode(ParseModeBody)
+ : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false)
{}
CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty)
- : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_bIsEmpty(bIsEmpty), m_enMode(ParseModeBody)
+ : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_bIsEmpty(bIsEmpty)
{}
CTableCell(CTableCell& oCell)
: m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged),
- m_bIsEmpty(oCell.m_bIsEmpty), m_enMode(oCell.m_enMode), m_oStyles(oCell.m_oStyles)
+ m_bIsEmpty(oCell.m_bIsEmpty), m_oStyles(oCell.m_oStyles)
{
m_oData.SetText(oCell.m_oData.GetData());
}
@@ -280,9 +453,13 @@ public:
return pCell;
}
- void SetMode(ERowParseMode eMode)
+ static CTableCell* CreateEmpty(const TTableCellStyle* pStyle)
{
- m_enMode = eMode;
+ CTableCell *pCell = new CTableCell(1, 1, false, true);
+
+ pCell->m_oStyles.Copy(pStyle);
+
+ return pCell;
}
void SetColspan(UINT unColspan, UINT unCurrentIndex)
@@ -318,6 +495,11 @@ public:
return &m_oStyles;
}
+ TTableCellStyle* GetStyles()
+ {
+ return &m_oStyles;
+ }
+
void SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
{
m_oStyles.m_oWidth = oWidth;
@@ -338,6 +520,26 @@ public:
m_oStyles.m_oBorder = oBorder;
}
+ void ClearTopBorder()
+ {
+ m_oStyles.m_oBorder.SetTopSide(L"none", 0, true);
+ }
+
+ void ClearLeftBorder()
+ {
+ m_oStyles.m_oBorder.SetLeftSide(L"none", 0, true);
+ }
+
+ void ClearBottomBorder()
+ {
+ m_oStyles.m_oBorder.SetBottomSide(L"none", 0, true);
+ }
+
+ void ClearRightBorder()
+ {
+ m_oStyles.m_oBorder.SetRightSide(L"none", 0, true);
+ }
+
void SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
{
m_oStyles.m_oPadding = oPadding;
@@ -358,102 +560,13 @@ public:
m_oStyles.m_oBackground = oColor;
}
- std::wstring ConvertToOOXML(const TTableStyles& oTableStyles)
- {
- NSStringUtils::CStringBuilder oCell;
-
- oCell.WriteNodeBegin(L"w:tc");
- oCell.WriteNodeBegin(L"w:tcPr");
-
- if (ParseModeHeader == m_enMode)
- oCell += L"";
-
- if (!m_oStyles.m_oWidth.Empty())
- {
- if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure())
- oCell += L"";
- else
- {
- if (!m_oStyles.m_oWidth.Zero())
- {
- int nWidth;
- if (NSCSS::UnitMeasure::None != m_oStyles.m_oWidth.GetUnitMeasure())
- nWidth = m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips);
- else
- nWidth = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(m_oStyles.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5);
-
- oCell += L"";
- }
- else
- oCell += L"";
- }
- }
- else
- oCell += L"";
-
- if (1 != m_unColspan)
- oCell += L"";
-
- if (m_bIsMerged)
- oCell += L"";
- else if (1 < m_unRowSpan)
- oCell += L"";
-
- if (!m_oStyles.m_oBorder.Zero() && !m_oStyles.m_oBorder.Empty())
- oCell += L"" + CreateBorders(m_oStyles.m_oBorder) + L"";
- else if (oTableStyles.m_bHaveBorderAttribute)
- oCell += L"";
-
- if (!m_oStyles.m_oBackground.Empty())
- {
- const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == m_oStyles.m_oBackground.GetType()) ? L"auto" : m_oStyles.m_oBackground.ToWString()};
- oCell += L"";
- }
-
- if (!m_oStyles.m_wsVAlign.empty())
- oCell += L"";
- else
- oCell += L"";
-
- if (!m_oStyles.m_oPadding.Empty() && oTableStyles.m_oPadding != m_oStyles.m_oPadding)
- {
- const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT),
- m_oStyles .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
- const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH),
- m_oStyles .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH));
- const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT),
- m_oStyles .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
- const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH),
- m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH));
-
- oCell += L""
- ""
- ""
- ""
- ""
- "";
- }
-
- oCell += L"";
- oCell.WriteNodeEnd(L"w:tcPr");
-
- if (0 != m_oData.GetCurSize())
- oCell += m_oData.GetData();
- else
- WriteEmptyParagraph(&oCell);
-
- oCell.WriteNodeEnd(L"w:tc");
-
- return oCell.GetData();
- }
-
+ std::wstring ConvertToOOXML(const CTable& oTable, UINT unColumnNumber, int nInstruction);
private:
UINT m_unColspan;
UINT m_unRowSpan;
bool m_bIsMerged;
bool m_bIsEmpty;
- ERowParseMode m_enMode;
TTableCellStyle m_oStyles;
NSStringUtils::CStringBuilder m_oData;
@@ -561,37 +674,7 @@ public:
return m_arCells.size();
}
- std::wstring ConvertToOOXML(const TTableStyles& oTableStyles)
- {
- if (m_arCells.empty())
- return std::wstring();
-
- NSStringUtils::CStringBuilder oRow;
- oRow.WriteNodeBegin(L"w:tr");
-
- if (!m_oStyles.Empty() || 0 < oTableStyles.m_nCellSpacing)
- {
- oRow.WriteNodeBegin(L"w:trPr");
-
- if (m_oStyles.m_bIsHeader)
- oRow += L"";
-
- if (0 < m_oStyles.m_unMaxHeight)
- oRow += L"";
-
- if (0 < oTableStyles.m_nCellSpacing)
- oRow += L"";
-
- oRow.WriteNodeEnd(L"w:trPr");
- }
-
- for (CTableCell* pCell : m_arCells)
- oRow += pCell->ConvertToOOXML(oTableStyles);
-
- oRow.WriteNodeEnd(L"w:tr");
-
- return oRow.GetData();
- }
+ std::wstring ConvertToOOXML(const CTable& oTable, int nInstruction);
CTableCell* operator[](UINT unIndex)
{
@@ -605,16 +688,99 @@ private:
std::vector m_arCells;
};
+class CTableCol
+{
+public:
+ CTableCol(UINT unSpan)
+ : m_unSpan(unSpan)
+ {}
+
+ CTableCol(XmlUtils::CXmlLiteReader& oLiteReader)
+ : m_unSpan(1)
+ {
+ while (oLiteReader.MoveToNextAttribute())
+ {
+ if (L"span" == oLiteReader.GetName())
+ m_unSpan = NSStringFinder::ToInt(oLiteReader.GetText(), 1);
+ }
+
+ oLiteReader.MoveToElement();
+ }
+
+ UINT GetSpan() const
+ {
+ return m_unSpan;
+ }
+
+ TTableCellStyle* GetStyle()
+ {
+ return &m_oStyle;
+ }
+
+ const TTableCellStyle* GetStyle() const
+ {
+ return &m_oStyle;
+ }
+private:
+ UINT m_unSpan;
+ TTableCellStyle m_oStyle;
+};
+
+class CTableColgroup
+{
+public:
+ CTableColgroup(XmlUtils::CXmlLiteReader& oLiteReader)
+ : m_unWidth(0)
+ {
+ while (oLiteReader.MoveToNextAttribute())
+ {
+ if (L"width" == oLiteReader.GetName())
+ m_unWidth = NSStringFinder::ToInt(oLiteReader.GetText());
+ }
+
+ oLiteReader.MoveToElement();
+ }
+
+ ~CTableColgroup()
+ {
+ RELEASE_VECTOR_PTR(m_arCols, CTableCol)
+ }
+
+ bool Empty() const
+ {
+ return m_arCols.empty();
+ }
+
+ void AddCol(CTableCol* pCol)
+ {
+ if (NULL != pCol)
+ m_arCols.push_back(pCol);
+ }
+
+ const std::vector& GetCols() const
+ {
+ return m_arCols;
+ }
+private:
+ std::vector m_arCols;
+ UINT m_unWidth;
+};
+
class CTable
{
public:
CTable()
+ : m_unMaxColumns(0)
{}
~CTable()
{
- for (CTableRow* pRow : m_arRows)
- RELEASEOBJECT(pRow);
+ for (std::vector& arHeaders : m_arHeaders)
+ RELEASE_VECTOR_PTR(arHeaders, CTableRow)
+
+ RELEASE_VECTOR_PTR(m_arFoother, CTableRow)
+ RELEASE_VECTOR_PTR(m_arRows, CTableRow)
+ RELEASE_VECTOR_PTR(m_arColgroups, CTableColgroup)
}
CTableRow* operator[](UINT unIndex)
@@ -635,12 +801,84 @@ public:
return 0 != m_oCaption.GetCurSize();
}
+ bool HaveColgroups() const
+ {
+ return !m_arColgroups.empty();
+ }
+
UINT GetRowCount() const
{
return m_arRows.size();
}
- void AddRow(CTableRow* pRow)
+ TTableStyles GetTableStyles() const
+ {
+ return m_oStyles;
+ }
+
+ const TTableCellStyle* GetColStyle(UINT unColumnNumber) const
+ {
+ if (m_arColgroups.empty())
+ return NULL;
+
+ UINT unCurrentNumber = 0;
+
+ for (const CTableColgroup* pColgroup : m_arColgroups)
+ {
+ for (const CTableCol* pCol : pColgroup->GetCols())
+ {
+ unCurrentNumber += pCol->GetSpan();
+
+ if (unCurrentNumber >= unColumnNumber)
+ return pCol->GetStyle();
+ }
+ }
+
+ return NULL;
+ }
+
+ std::wstring CalculateSidesToClean(UINT unColumnNumber) const
+ {
+ if (m_arColgroups.empty())
+ return std::wstring();
+
+ UINT unCurrentNumber = 0;
+
+ for (const CTableColgroup* pColgroup : m_arColgroups)
+ {
+ for (const CTableCol* pCol : pColgroup->GetCols())
+ {
+ if (unCurrentNumber + 1 == unCurrentNumber)
+ return (1 != pCol->GetSpan()) ? L"" : std::wstring();
+
+ unCurrentNumber += pCol->GetSpan();
+
+ if (unColumnNumber == unCurrentNumber)
+ return (1 != pCol->GetSpan()) ? L"" : std::wstring();
+ else if (unColumnNumber < unCurrentNumber)
+ return std::wstring((1 != unColumnNumber) ? L"" : L"") + std::wstring((m_unMaxColumns != unColumnNumber) ? L"" : L"");
+ }
+ }
+
+ return std::wstring();
+ }
+
+ void AddRows(std::vector& m_arRows, ERowParseMode eParseMode = ERowParseMode::ParseModeBody)
+ {
+ if (m_arRows.empty())
+ return;
+
+ if (ERowParseMode::ParseModeFoother == eParseMode && !m_arFoother.empty())
+ eParseMode = ERowParseMode::ParseModeHeader;
+
+ if (ERowParseMode::ParseModeHeader == eParseMode)
+ m_arHeaders.push_back({});
+
+ for (CTableRow* pRow : m_arRows)
+ AddRow(pRow, eParseMode);
+ }
+
+ void AddRow(CTableRow* pRow, ERowParseMode eParseMode = ERowParseMode::ParseModeBody)
{
if (NULL == pRow)
return;
@@ -653,7 +891,28 @@ public:
m_arMinColspan[unIndex] = (*pRow)[unIndex]->GetColspan();
}
- m_arRows.push_back(pRow);
+ switch (eParseMode)
+ {
+ default:
+ case ERowParseMode::ParseModeBody:
+ {
+ m_arRows.push_back(pRow);
+ break;
+ }
+ case ERowParseMode::ParseModeHeader:
+ {
+ if (m_arHeaders.empty())
+ m_arHeaders.push_back({});
+
+ m_arHeaders.back().push_back(pRow);
+ break;
+ }
+ case ERowParseMode::ParseModeFoother:
+ {
+ m_arFoother.push_back(pRow);
+ break;
+ }
+ }
}
void AddCaption(NSStringUtils::CStringBuilder& oCaption)
@@ -696,29 +955,38 @@ public:
m_oStyles.m_wsAlign = wsValue;
}
- void HaveBorderAttribute()
+ void SetRules(const std::wstring& wsValue)
{
- m_oStyles.m_bHaveBorderAttribute = true;
+ if (wsValue.empty())
+ return;
+
+ if (NSStringFinder::Equals(wsValue, L"all"))
+ m_oStyles.m_enRules = TTableStyles::ETableRules::All;
+ else if (NSStringFinder::Equals(wsValue, L"groups"))
+ m_oStyles.m_enRules = TTableStyles::ETableRules::Groups;
+ else if (NSStringFinder::Equals(wsValue, L"cols"))
+ m_oStyles.m_enRules = TTableStyles::ETableRules::Cols;
+ else if (NSStringFinder::Equals(wsValue, L"none"))
+ m_oStyles.m_enRules = TTableStyles::ETableRules::None;
+ else if (NSStringFinder::Equals(wsValue, L"rows"))
+ m_oStyles.m_enRules = TTableStyles::ETableRules::Rows;
}
- bool IsHaveBorderAttribute() const
+ void AddColgroup(CTableColgroup* pElement)
{
- return m_oStyles.m_bHaveBorderAttribute;
+ if (NULL != pElement)
+ m_arColgroups.push_back(pElement);
}
- UINT GetMaxColumns()
+ void RecalculateMaxColumns()
{
- UINT unMaxColumns = 0;
-
for (const CTableRow* pRow : m_arRows)
- unMaxColumns = std::max(unMaxColumns, pRow->GetIndex());
-
- return unMaxColumns;
+ m_unMaxColumns = std::max(m_unMaxColumns, pRow->GetIndex());
}
void Shorten()
{
- UINT unIndex = 0;
+ UINT unIndex = 0;
CTableCell* pCell = NULL;
UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка
@@ -777,9 +1045,14 @@ public:
for (CTableRow* pRow : m_arRows)
{
+ if (NULL == pRow || 0 == pRow->GetCount())
+ continue;
+
for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex)
pRow->InsertCell(CTableCell::CreateEmpty(), unIndex);
}
+
+ RecalculateMaxColumns();
}
std::wstring ConvertToOOXML()
@@ -817,7 +1090,7 @@ public:
oTable += L"";
if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero())
- oTable += L"" + CreateBorders(m_oStyles.m_oBorder) + L"";
+ oTable += L"" + CreateBorders(m_oStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == m_oStyles.m_enRules && !m_arColgroups.empty()) ? TTableStyles::ETableRules::Cols : m_oStyles.m_enRules) + L"";
if (!m_oStyles.m_oPadding.Empty() && !m_oStyles.m_oPadding.Zero())
{
@@ -854,7 +1127,7 @@ public:
oTable.WriteNodeBegin(L"w:tc");
oTable.WriteNodeBegin(L"w:tcPr");
oTable += L"";
- oTable += L"";
+ oTable += L"";
oTable += L"";
oTable += L"";
oTable += L"";
@@ -864,20 +1137,64 @@ public:
oTable.WriteNodeEnd(L"w:tr");
}
- for (CTableRow* pRow : m_arRows)
- oTable += pRow->ConvertToOOXML(m_oStyles);
+ #define CONVERT_ROWS(rows, mode) \
+ { \
+ for (UINT unRowIndex = 0; unRowIndex < rows.size(); ++unRowIndex) \
+ { \
+ int nInstruction = 0; \
+ if (0 == unRowIndex) \
+ nInstruction |= FIRST_ELEMENT << 4; \
+ if (rows.size() - 1 == unRowIndex) \
+ nInstruction |= LAST_ELEMENT << 4; \
+ else if (0 != unRowIndex) \
+ nInstruction |= MID_ELEMENT << 4; \
+ nInstruction |= mode; \
+ oTable += rows[unRowIndex]->ConvertToOOXML(*this, nInstruction); \
+ } \
+ }
+
+ for (std::vector& arRows : m_arHeaders)
+ CONVERT_ROWS(arRows, PARSE_MODE_HEADER)
+
+ CONVERT_ROWS(m_arRows, PARSE_MODE_BODY)
+ CONVERT_ROWS(m_arFoother, PARSE_MODE_FOOTHER)
oTable.WriteNodeEnd(L"w:tbl");
return oTable.GetData();
}
private:
- std::vector m_arRows;
+ std::vector> m_arHeaders;
+ std::vector m_arFoother;
+ std::vector m_arRows;
+
std::vector m_arMinColspan;
NSStringUtils::CStringBuilder m_oCaption;
+ std::vector m_arColgroups;
+
TTableStyles m_oStyles;
+
+ UINT m_unMaxColumns;
+};
+
+enum class EAbstructNumType
+{
+ Bullet,
+ CardinalText,
+ Chicago,
+ Decimal,
+ DecimalEnclosedCircle,
+ DecimalEnclosedFullstop,
+ DecimalEnclosedParen,
+ DecimalZero,
+ LowerLetter,
+ LowerRoman,
+ None,
+ OrdinalText,
+ UpperLetter,
+ UpperRoman
};
void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2)
@@ -961,6 +1278,7 @@ private:
NSStringUtils::CStringBuilder m_oDocXml; // document.xml
NSStringUtils::CStringBuilder m_oNoteXml; // footnotes.xml
NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml
+ NSStringUtils::CStringBuilder m_oWebSettings; // webSettings.xml
struct TState
{
@@ -979,6 +1297,7 @@ private:
std::vector m_arrImages; // Картинки
std::map m_mFootnotes; // Сноски
std::map m_mBookmarks; // Закладки
+ std::map m_mDivs; // Div элементы
public:
CHtmlFile2_Private()
@@ -1001,6 +1320,7 @@ public:
m_oDocXml .Clear();
m_oNoteXml .Clear();
m_oNumberXml .Clear();
+ m_oWebSettings .Clear();
}
// Проверяет наличие тэга html
@@ -1082,15 +1402,6 @@ public:
oSettingsWriter.CloseFile();
}
- // webSettings.xml
- std::wstring sWebSettings = L"";
- NSFile::CFileBinary oWebWriter;
- if (oWebWriter.CreateFileW(m_sDst + L"/word/webSettings.xml"))
- {
- oWebWriter.WriteStringUTF8(sWebSettings);
- oWebWriter.CloseFile();
- }
-
// numbering.xml
// Маркированный список
m_oNumberXml += L"";
m_oNoteXml += L"";
m_oStylesXml += L"";
+ m_oWebSettings += L"";
m_nId += 7;
@@ -1186,7 +1498,7 @@ public:
m_oStylesXml += L"";
m_oStylesXml += L"";
m_oStylesXml += L"";
- m_oStylesXml += L"";
+ m_oStylesXml += L"";
// m_oStylesXml += L"";
}
@@ -1209,6 +1521,8 @@ public:
// m_oStylesXml += L"";
// Сноски
m_oStylesXml += L"";
+ // Web стиль по-умолчанию
+ m_oStylesXml += L"";
}
// Читает файл
@@ -1303,6 +1617,18 @@ public:
oNumberingWriter.WriteStringUTF8(m_oNumberXml.GetData());
oNumberingWriter.CloseFile();
}
+
+ // webSettings.xml
+ if (!m_mDivs.empty())
+ m_oWebSettings.WriteString(L"");
+
+ m_oWebSettings.WriteString(L"");
+ NSFile::CFileBinary oWebSettingsWriter;
+ if (oWebSettingsWriter.CreateFileW(m_sDst + L"/word/webSettings.xml"))
+ {
+ oWebSettingsWriter.WriteStringUTF8(m_oWebSettings.GetData());
+ oWebSettingsWriter.CloseFile();
+ }
}
// Конвертирует html в xhtml
@@ -1649,6 +1975,17 @@ private:
m_oState.m_bInP = false;
}
+ void WriteSpace(NSStringUtils::CStringBuilder* pXml)
+ {
+ if (NULL == pXml)
+ return;
+
+ OpenR(pXml);
+ pXml->WriteString(L" ");
+ CloseR(pXml);
+ m_oState.m_bWasSpace = true;
+ }
+
void WriteBookmark(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsId)
{
if (NULL == pXml)
@@ -1674,6 +2011,67 @@ private:
pXml->WriteString(L"\"/>");
}
+ std::wstring WriteDiv(NSStringUtils::CStringBuilder* pXml, std::vector& sSelectors, CTextSettings& oTS)
+ {
+ if (NULL == pXml || sSelectors.empty())
+ return std::wstring();
+
+ const std::wstring wsKeyWord{sSelectors.back().m_wsName};
+
+ std::map::const_iterator itFound = m_mDivs.find(wsKeyWord);
+
+ if (m_mDivs.end() != itFound)
+ return std::to_wstring(itFound->second);
+
+ const std::wstring wsId{std::to_wstring(m_mDivs.size() + 1)};
+
+ if (m_mDivs.empty())
+ pXml->WriteString(L"");
+
+ NSCSS::CCompiledStyle oStyle;
+ m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors);
+
+ INT nMarLeft = 720;
+ INT nMarRight = 720;
+ INT nMarTop = 100;
+ INT nMarBottom = 100;
+
+ if (!oStyle.m_oMargin.GetLeft().Empty() && !oStyle.m_oMargin.GetLeft().Zero())
+ nMarLeft = oStyle.m_oMargin.GetLeft().ToInt(NSCSS::Twips, m_oPageData.GetWidth().ToInt(NSCSS::Twips));
+
+ if (!oStyle.m_oMargin.GetRight().Empty() && !oStyle.m_oMargin.GetRight().Zero())
+ nMarRight = oStyle.m_oMargin.GetRight().ToInt(NSCSS::Twips, m_oPageData.GetWidth().ToInt(NSCSS::Twips));
+
+ if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero())
+ nMarTop = oStyle.m_oMargin.GetTop().ToInt(NSCSS::Twips, m_oPageData.GetHeight().ToInt(NSCSS::Twips));
+
+ if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero())
+ nMarBottom = oStyle.m_oMargin.GetBottom().ToInt(NSCSS::Twips, m_oPageData.GetHeight().ToInt(NSCSS::Twips));
+
+ if (L"blockquote" == wsKeyWord)
+ {
+ sSelectors.back().m_mAttributes.insert({L"margin", L"0px"});
+
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ }
+
+ m_mDivs.insert(std::make_pair(wsKeyWord, m_mDivs.size() + 1));
+
+ return wsId;
+ }
+
std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors)
{
NSCSS::CNode oNode;
@@ -1749,10 +2147,11 @@ private:
m_oDocXml.WriteString(L"\"/>");
*/
- readStream(&m_oDocXml, sSelectors, { false, false, true, false, -1, L"", L"" });
+ CTextSettings oTS;
+ readStream(&m_oDocXml, sSelectors, oTS);
}
- bool readInside (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& sName)
+ bool readInside (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, const std::wstring& sName)
{
//TODO:: обработать все варианты return'а
@@ -1763,65 +2162,87 @@ private:
if (sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar);}))
return false;
- bool bInT = m_oState.m_bInT;
+ if(oTS.bBdo)
+ std::reverse(sText.begin(), sText.end());
- if (!oTS.sRStyle.empty() || oTS.bPre)
+ const bool bInT = m_oState.m_bInT;
+
+ if (oTS.bPre)
{
CloseT(oXml);
CloseR(oXml);
}
- if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace)
- {
- oXml->WriteString(L" ");
- m_oState.m_bWasSpace = true;
- }
+ if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace && CTextSettings::Normal == oTS.eTextMode)
+ WriteSpace(oXml);
- std::wstring sPStyle = wrP(oXml, sSelectors, oTS);
+ OpenP(oXml);
+
+ NSStringUtils::CStringBuilder oPPr;
+
+ std::wstring sPStyle = wrP(&oPPr, sSelectors, oTS);
+
+ oXml->WriteString(oPPr.GetData());
+
+ NSStringUtils::CStringBuilder oRPr;
std::wstring sRStyle;
if (OpenR(oXml))
{
- sRStyle = wrRPr(oXml, sSelectors, oTS);
- OpenT(oXml);
+ sRStyle = wrRPr(&oRPr, sSelectors, oTS);
+
+ oXml->WriteString(oRPr.GetData());
+
+ if (oTS.bQ)
+ oXml->WriteString(L""");
}
- if(oTS.bBdo)
- std::reverse(sText.begin(), sText.end());
+ if (oTS.bQ)
+ oXml->WriteString(L""");
if(oTS.bPre)
{
- size_t nAfter = sText.find_first_of(L"\n\r");
+ if (L'\n' == sText.front() || L'\r' == sText.front())
+ sText.erase(0, 1);
+
+ size_t nAfter = sText.find_first_of(L"\n\r\t");
while(nAfter != std::wstring::npos)
{
+ if (L'\t' == sText[0])
+ {
+ oXml->WriteString(L"");
+ sText.erase(0, 1);
+
+ if (0 == nAfter)
+ {
+ nAfter = sText.find_first_of(L"\n\r\t");
+ continue;
+ }
+
+ nAfter--;
+ }
+
+ OpenT(oXml);
oXml->WriteEncodeXmlString(sText.c_str(), nAfter);
- oXml->WriteString(L"");
- if(!sPStyle.empty() || !oTS.sPStyle.empty())
+ CloseT(oXml);
+ CloseR(oXml);
+
+ if (L'\t' == sText[nAfter])
{
- oXml->WriteNodeBegin(L"w:pPr");
-
- if (!sPStyle.empty())
- oXml->WriteString(L"");
-
- oXml->WriteString(oTS.sPStyle);
-
- oXml->WriteNodeEnd(L"w:pPr");
+ sText.erase(0, nAfter);
+ nAfter = 1;
}
- oXml->WriteNodeBegin(L"w:r");
- if (!sRStyle.empty() || !oTS.sRStyle.empty())
+ else
{
- oXml->WriteNodeBegin(L"w:rPr");
-
- if (!sRStyle.empty())
- oXml->WriteString(L"");
-
- oXml->WriteString(oTS.sRStyle);
-
- oXml->WriteNodeEnd(L"w:rPr");
+ CloseP(oXml, sSelectors);
+ OpenP(oXml);
+ oXml->WriteString(oPPr.GetData());
+ sText.erase(0, nAfter + 1);
+ nAfter = 0;
}
- oXml->WriteString(L"");
- sText.erase(0, nAfter + 1);
- nAfter = sText.find_first_of(L"\n\r");
+ OpenR(oXml);
+ oXml->WriteString(oRPr.GetData());
+ nAfter = sText.find_first_of(L"\n\r\t", nAfter);
}
if (sText.empty())
@@ -1830,16 +2251,29 @@ private:
else
ReplaceSpaces(sText);
- if (std::iswspace(sText.front()) && m_oState.m_bWasSpace)
+ if (!sText.empty() && L'\t' == sText[0])
+ {
+ oXml->WriteString(L"");
+ sText.erase(0, 1);
+ }
+
+ if (!oTS.bPre && !sText.empty() && std::iswspace(sText.front()) && m_oState.m_bWasSpace)
sText.erase(0, 1);
- if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT)
- oXml->WriteEncodeXmlString(L" ");
-
if (!sText.empty())
+ {
+ OpenT(oXml);
+
+ if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT && !oTS.bPre)
+ oXml->WriteEncodeXmlString(L" ");
+
m_oState.m_bWasSpace = std::iswspace(sText.back());
- oXml->WriteEncodeXmlString(sText);
+ oXml->WriteEncodeXmlString(sText);
+ }
+
+ if (oTS.bQ)
+ oXml->WriteString(L""");
if (!oTS.bMergeText)
{
@@ -1856,22 +2290,34 @@ private:
// Область ссылки
if(sName == L"a" || sName == L"area")
readA(oXml, sSelectors, oTS, sNote);
+ else if (sName == L"abbr")
+ {
+ if (!sNote.empty())
+ {
+ wrP(oXml, sSelectors, oTS);
+ const std::wstring wsName{L"Bookmark" + std::to_wstring(m_mBookmarks.size() + 1)};
+ m_mBookmarks.insert(std::make_pair(wsName, m_mBookmarks.size() + 1));
+ oXml->WriteString(L"HYPERLINK \\l \"" + wsName + L"\" \\o \"");
+ oXml->WriteEncodeXmlString(sNote);
+ oXml->WriteString(L"\"");
+ oXml->WriteString(L"");
+ bResult = readStream(oXml, sSelectors, oTS);
+ oXml->WriteString(L"");
+ sNote.clear();
+ }
+ }
// Полужирный текст
// Акцентированный текст
else if(sName == L"b" || sName == L"strong")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSR);
}
// Направление текста
else if(sName == L"bdo")
{
- std::wstring sDir;
- while(m_oLightReader.MoveToNextAttribute())
- if(m_oLightReader.GetName() == L"dir")
- sDir = m_oLightReader.GetText();
- m_oLightReader.MoveToElement();
+ const std::wstring sDir{GetArgumentValue(L"dir")};
CTextSettings oTSBdo(oTS);
oTSBdo.bBdo = (sDir == L"rtl");
@@ -1884,23 +2330,17 @@ private:
oTSBdo.bBdo = false;
bResult = readStream(oXml, sSelectors, oTSBdo);
}
- // Увеличивает размер шрифта
- else if(sName == L"big")
- {
- CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
- bResult = readStream(oXml, sSelectors, oTSR);
- }
// Перенос строки
else if(sName == L"br")
{
if (m_oState.m_bInP)
{
- oXml->WriteString(L"");
+ OpenR(oXml);
NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors);
if(oStyle.m_oText.GetAlign() == L"both")
oXml->WriteString(L"");
- oXml->WriteString(L"");
+ oXml->WriteString(L"");
+ CloseR(oXml);
}
else
WriteEmptyParagraph(oXml, false, m_oState.m_bInP);
@@ -1910,7 +2350,7 @@ private:
else if(sName == L"center")
{
CTextSettings oTSP(oTS);
- oTSP.AddPStyle(L"");
+ oTSP.oAdditionalStyle.m_oText.SetAlign(L"center", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSP);
}
// Цитата, обычно выделяется курсивом
@@ -1921,34 +2361,51 @@ private:
else if(sName == L"cite" || sName == L"dfn" || sName == L"em" || sName == L"i" || sName == L"var")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oFont.SetStyle(L"italic", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSR);
}
// Код
- // Моноширинный шрифт, например, Consolas
+ // Моноширинный шрифт, например, Courier New
// Результат скрипта
- else if(sName == L"code" || sName == L"kbd" || sName == L"samp" || sName == L"tt")
+ else if(sName == L"code" || sName == L"tt")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true);
+ oTSR.oAdditionalStyle.m_oFont.SetSize(20, UINT_MAX, true);
+ bResult = readStream(oXml, sSelectors, oTSR);
+ }
+ else if (sName == L"kbd")
+ {
+ CTextSettings oTSR(oTS);
+ oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true);
+ oTSR.oAdditionalStyle.m_oFont.SetSize(20, UINT_MAX, true);
+ oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
+ bResult = readStream(oXml, sSelectors, oTSR);
+ }
+ else if (sName == L"samp")
+ {
+ CTextSettings oTSR(oTS);
+ oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSR);
}
// Зачеркнутый текст
- else if(sName == L"del" || sName == L"s")
+ else if(sName == L"del" || sName == L"s" || sName == L"strike")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oText.SetDecoration(L"line-through", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSR);
}
else if(sName == L"font")
{
+ CTextSettings oTSR(oTS);
+
while(m_oLightReader.MoveToNextAttribute())
{
std::wstring sAName = m_oLightReader.GetName();
if(sAName == L"color")
- sSelectors.back().m_wsStyle += L"; color: " + m_oLightReader.GetText();
+ oTSR.oAdditionalStyle.m_oText.SetColor(m_oLightReader.GetText(), UINT_MAX, true);
else if(sAName == L"face")
- sSelectors.back().m_wsStyle += L"; font-family: " + m_oLightReader.GetText();
+ oTSR.oAdditionalStyle.m_oFont.SetFamily(m_oLightReader.GetText(), UINT_MAX, true);
else if(sAName == L"size")
{
int nSize = 3;
@@ -1963,23 +2420,15 @@ private:
nSize = NSStringFinder::ToInt(sSize);
}
- switch (nSize)
- {
- case 1: nSize = 10; break;
- case 2: nSize = 12; break;
- case 3:
- default: nSize = 14; break;
- case 4: nSize = 18; break;
- case 5: nSize = 24; break;
- case 6: nSize = 32; break;
- case 7: nSize = 48; break;
- }
-
- sSelectors.back().m_wsStyle += L"; font-size: " + std::to_wstring(nSize) + L"px";
+ if (nSize < 1 || nSize > 7)
+ nSize = 3;
+
+ oTSR.oAdditionalStyle.m_oFont.SetSize(HTML_FONTS[nSize - 1], UINT_MAX, true);
}
}
m_oLightReader.MoveToElement();
- bResult = readStream(oXml, sSelectors, oTS);
+ bResult = readStream(oXml, sSelectors, oTSR);
+ m_oState.m_bWasSpace = true;
}
// Картинки
else if(sName == L"img")
@@ -1988,59 +2437,35 @@ private:
else if(sName == L"ins" || sName == L"u")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oText.SetDecoration(L"underline", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSR);
}
// Выделенный текст, обычно выделяется желтым
else if(sName == L"mark")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oText.SetHighlight(L"yellow", UINT_MAX, true);
bResult = readStream(oXml, sSelectors, oTSR);
}
// Цитата, выделенная кавычками, обычно выделяется курсивом
else if(sName == L"q")
{
- wrP(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
- std::wstring sRStyle = wrRPr(oXml, sSelectors, oTS);
- oXml->WriteString(L""");
-
- CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
- readStream(oXml, sSelectors, oTSR);
-
- wrP(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
- if (!sRStyle.empty())
- {
- oXml->WriteString(L"WriteString(sRStyle);
- oXml->WriteString(L"\"/>");
- oXml->WriteString(oTS.sRStyle);
- oXml->WriteString(L"");
- }
- oXml->WriteString(L""");
+ CTextSettings oTSQ(oTS);
+ oTSQ.bQ = true;
+ bResult = readStream(oXml, sSelectors, oTSQ);
}
// Текст верхнего регистра
- else if(sName == L"rt" || sName == L"sup")
+ else if(sName == L"sup")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
- bResult = readStream(oXml, sSelectors, oTSR);
- }
- // Уменьшает размер шрифта
- else if(sName == L"small")
- {
- CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.eTextMode = CTextSettings::Superscript;
bResult = readStream(oXml, sSelectors, oTSR);
}
// Текст нижнего регистра
else if(sName == L"sub")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.eTextMode = CTextSettings::Subscript;
bResult = readStream(oXml, sSelectors, oTSR);
}
// Векторная картинка
@@ -2053,7 +2478,7 @@ private:
else if(sName == L"input")
readInput(oXml, sSelectors, oTS);
// Игнорируются тэги выполняющие скрипт
- else if(sName == L"template" || sName == L"canvas" || sName == L"video" || sName == L"math" || sName == L"rp" ||
+ else if(sName == L"template" || sName == L"canvas" || sName == L"video" || sName == L"math" ||
sName == L"command" || sName == L"iframe" || sName == L"embed" || sName == L"wbr" || sName == L"audio" ||
sName == L"bgsound" || sName == L"applet" || sName == L"blink" || sName == L"keygen"|| sName == L"script" ||
sName == L"comment" || sName == L"title" || sName == L"style")
@@ -2077,10 +2502,44 @@ private:
oTSPre.bPre = true;
bResult = readStream(oXml, sSelectors, oTSPre);
}
+ else if (sName == L"basefont")
+ {
+ if (!m_oLightReader.MoveToFirstAttribute())
+ return false;
+
+ do
+ {
+ if (L"face" == m_oLightReader.GetName())
+ oTS.oAdditionalStyle.m_oFont.SetFamily(m_oLightReader.GetText(), UINT_MAX, true);
+ else if (L"size" == m_oLightReader.GetName())
+ {
+ switch(NSStringFinder::ToInt(m_oLightReader.GetText(), 3))
+ {
+ case 1: oTS.oAdditionalStyle.m_oFont.SetSize(7.5, UINT_MAX, true); break;
+ case 2: oTS.oAdditionalStyle.m_oFont.SetSize(10, UINT_MAX, true); break;
+ default:
+ case 3: oTS.oAdditionalStyle.m_oFont.SetSize(12, UINT_MAX, true); break;
+ case 4: oTS.oAdditionalStyle.m_oFont.SetSize(13.5, UINT_MAX, true); break;
+ case 5: oTS.oAdditionalStyle.m_oFont.SetSize(18, UINT_MAX, true); break;
+ case 6: oTS.oAdditionalStyle.m_oFont.SetSize(24, UINT_MAX, true); break;
+ case 7: oTS.oAdditionalStyle.m_oFont.SetSize(36, UINT_MAX, true); break;
+ }
+ }
+ else if (L"color" == m_oLightReader.GetName())
+ oTS.oAdditionalStyle.m_oText.SetColor(m_oLightReader.GetText(), UINT_MAX, true);
+ } while (m_oLightReader.MoveToNextAttribute());
+
+ m_oLightReader.MoveToElement();
+
+ oTS.oAdditionalStyle.SetID(m_oStylesCalculator.CalculateStyleId(sSelectors.back()));
+
+ sSelectors.pop_back();
+ return true;
+ }
// Без нового абзаца
- else if(sName == L"basefont" || sName == L"button" || sName == L"label" || sName == L"data" || sName == L"object" ||
- sName == L"noscript" || sName == L"output" || sName == L"abbr" || sName == L"time" || sName == L"ruby" ||
- sName == L"progress" || sName == L"hgroup" || sName == L"meter" || sName == L"acronym")
+ else if(sName == L"button" || sName == L"label" || sName == L"data" || sName == L"object" ||
+ sName == L"noscript" || sName == L"output" || sName == L"time" || sName == L"small" ||
+ sName == L"progress" || sName == L"hgroup" || sName == L"meter" || sName == L"acronym" || sName == L"big")
bResult = readStream(oXml, sSelectors, oTS);
// С нового абзаца
else
@@ -2094,14 +2553,14 @@ private:
if(sName == L"address")
{
CTextSettings oTSR(oTS);
- oTSR.AddRStyle(L"");
+ oTSR.oAdditionalStyle.m_oFont.SetStyle(L"italic", UINT_MAX, true);
bResult = readStream(&oXmlData, sSelectors, oTSR);
}
// Определение термина, отступ от левого края
else if(sName == L"dd")
{
CTextSettings oTSP(oTS);
- oTSP.sPStyle += L"";
+ oTSP.oAdditionalStyle.m_oMargin.SetLeft(720, UINT_MAX, true);
bResult = readStream(&oXmlData, sSelectors, oTSP);
}
// aside возможно использовать для сносок в epub
@@ -2141,10 +2600,16 @@ private:
else
bResult = readStream(&oXmlData, sSelectors, oTS);
}
+ else if (sName == L"blockquote")
+ {
+ CTextSettings oNewTS{oTS};
+ oNewTS.sPStyle += L"";
+ bResult = readStream(&oXmlData, sSelectors, oNewTS);
+ }
// С нового абзаца
- else if(sName == L"article" || sName == L"header" || sName == L"blockquote" || sName == L"main" || sName == L"dir" ||
+ else if(sName == L"article" || sName == L"header" || sName == L"main" ||
sName == L"summary" || sName == L"footer" || sName == L"nav" || sName == L"figcaption" || sName == L"form" ||
- sName == L"details" || sName == L"option" || sName == L"dt" || sName == L"p" ||
+ sName == L"option" || sName == L"dt" || sName == L"p" ||
sName == L"section" || sName == L"figure" || sName == L"dl" || sName == L"legend" || sName == L"map" ||
sName == L"h1" || sName == L"h2" || sName == L"h3" || sName == L"h4" || sName == L"h5" || sName == L"h6")
bResult = readStream(&oXmlData, sSelectors, oTS);
@@ -2162,18 +2627,53 @@ private:
}
if (bPrint)
{
+ NSCSS::NSProperties::CDigit oSize, oWidth;
+ NSCSS::NSProperties::CColor oColor;
+ bool bShade = false;
+ std::wstring wsAlign{L"center"};
+
+ if (m_oLightReader.MoveToFirstAttribute())
+ {
+ std::wstring wsAttributeName;
+ do
+ {
+ wsAttributeName = m_oLightReader.GetName();
+
+ if (L"align" == wsAttributeName)
+ {
+ const std::wstring wsValue{m_oLightReader.GetText()};
+
+ if (NSStringFinder::Equals(L"left", wsValue))
+ wsAlign = L"left";
+ else if (NSStringFinder::Equals(L"right", wsValue))
+ wsAlign = L"right";
+ else if (NSStringFinder::Equals(L"center", wsValue))
+ wsAlign = L"center";
+ }
+ if (L"color" == wsAttributeName)
+ oColor.SetValue(m_oLightReader.GetText());
+ else if (L"noshade" == wsAttributeName)
+ bShade = true;
+ else if (L"size" == wsAttributeName)
+ oSize.SetValue(m_oLightReader.GetText());
+ else if (L"width" == wsAttributeName)
+ oWidth.SetValue(m_oLightReader.GetText());
+ } while (m_oLightReader.MoveToNextAttribute());
+
+ m_oLightReader.MoveToElement();
+ }
+
const bool bOpenedP = OpenP(&oXmlData);
OpenR(&oXmlData);
- WriteLine(&oXmlData, 1.5, L"a0a0a0");
+ WriteLine(&oXmlData, wsAlign, (!oColor.Empty()) ? oColor.ToWString() : L"a0a0a0", bShade, (!oSize.Empty()) ? oSize.ToDouble(NSCSS::Point) : 1.5, (NSCSS::UnitMeasure::Percent == oWidth.GetUnitMeasure()) ? oWidth.ToDouble() : 0);
CloseR(&oXmlData);
if (bOpenedP)
CloseP(&oXmlData, sSelectors);
}
-// oXml->WriteString(L"");
}
// Меню
// Маркированный список
- else if(sName == L"menu" || sName == L"ul" || sName == L"select" || sName == L"datalist")
+ else if(sName == L"ul" || sName == L"menu" || sName == L"select" || sName == L"datalist" || sName == L"dir")
readLi(&oXmlData, sSelectors, oTS, true);
// Нумерованный список
else if(sName == L"ol")
@@ -2182,13 +2682,18 @@ private:
else if(sName == L"pre" || sName == L"xmp")
{
CTextSettings oTSPre(oTS);
- sSelectors.back().m_wsStyle += L"; font-family:Consolas";
+ oTSPre.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", NEXT_LEVEL);
+ oTSPre.oAdditionalStyle.m_oFont.SetSize(20, NEXT_LEVEL);
+ oTSPre.oAdditionalStyle.m_oMargin.SetTop(0, NEXT_LEVEL);
+ oTSPre.oAdditionalStyle.m_oMargin.SetBottom(0, NEXT_LEVEL);
oTSPre.bPre = true;
bResult = readStream(&oXmlData, sSelectors, oTSPre);
}
// Таблицы
else if(sName == L"table")
- ParseTable(&oXmlData, sSelectors, oTS);
+ bResult = ParseTable(&oXmlData, sSelectors, oTS);
+ else if(sName == L"ruby")
+ bResult = ParseRuby(&oXmlData, sSelectors, oTS);
// Текст с границами
else if(sName == L"textarea" || sName == L"fieldset")
{
@@ -2196,6 +2701,70 @@ private:
oTSP.AddPStyle(L"");
bResult = readStream(&oXmlData, sSelectors, oTSP);
}
+ else if (sName == L"details")
+ {
+ bool bOpened = false;
+ if (m_oLightReader.MoveToFirstAttribute())
+ {
+ do
+ {
+ bOpened = (L"open" == m_oLightReader.GetName());
+ } while (m_oLightReader.MoveToNextAttribute() && !bOpened);
+ }
+ m_oLightReader.MoveToElement();
+
+ int nDeath = m_oLightReader.GetDepth();
+ if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode2(nDeath))
+ {
+ sSelectors.pop_back();
+ return false;
+ }
+
+ NSStringUtils::CStringBuilder oSummary;
+ NSStringUtils::CStringBuilder oBody;
+
+ const TState oCurrentState{m_oState};
+ TState oSummaryState{m_oState};
+ TState oBodyState{m_oState};
+
+ do
+ {
+ if (L"summary" == m_oLightReader.GetName())
+ {
+ m_oState = oSummaryState;
+ if (0 == oSummary.GetSize())
+ {
+ OpenP(&oSummary);
+ OpenR(&oSummary);
+ OpenT(&oSummary);
+ oSummary.WriteString((bOpened) ? L"\u25BD" : L"\u25B7");
+ }
+
+ readStream(&oSummary, sSelectors, oTS);
+ CloseP(&oSummary, sSelectors);
+ oSummaryState = m_oState;
+ m_oState = oCurrentState;
+ }
+ else if (bOpened)
+ {
+ m_oState = oBodyState;
+ readStream(&oBody, sSelectors, oTS);
+ CloseP(&oBody, sSelectors);
+ oBodyState = m_oState;
+ m_oState = oCurrentState;
+ }
+ } while (m_oLightReader.ReadNextSiblingNode2(nDeath));
+
+ oXmlData.WriteString(oSummary.GetData());
+
+ if (bOpened)
+ {
+ m_oState = oBodyState;
+ oXmlData.WriteString(oBody.GetData());
+ }
+
+ bResult = true;
+ }
else if (sName == L"xml")
{
sSelectors.pop_back();
@@ -2206,7 +2775,6 @@ private:
bResult = readStream(&oXmlData, sSelectors, oTS);
readNote(&oXmlData, sSelectors, sNote);
- sNote = L"";
CloseP(&oXmlData, sSelectors);
@@ -2220,7 +2788,7 @@ private:
return bResult;
}
- bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, bool bInsertEmptyP = false)
+ bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, bool bInsertEmptyP = false)
{
int nDeath = m_oLightReader.GetDepth();
if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode2(nDeath))
@@ -2254,26 +2822,24 @@ private:
return bResult;
}
- void CalculateCellStyles(CTableCell* pCell, const std::vector& arSelectors)
+ void CalculateCellStyles(TTableCellStyle* pCellStyle, const std::vector& arSelectors)
{
- if (NULL == pCell)
+ if (NULL == pCellStyle)
return;
- std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(arSelectors.begin(), arSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), arSelectors.cend()};
-
NSCSS::CCompiledStyle oStyle;
- m_oStylesCalculator.GetCompiledStyle(oStyle, arNewSelectors);
+ m_oStylesCalculator.GetCompiledStyle(oStyle, arSelectors);
- pCell->SetVAlign(oStyle.m_oDisplay.GetVAlign().ToWString());
- pCell->SetHAlign(oStyle.m_oDisplay.GetHAlign().ToWString());
- pCell->SetBackground(oStyle.m_oBackground.GetColor());
- pCell->SetHeight(oStyle.m_oDisplay.GetHeight());
- pCell->SetWidth(oStyle.m_oDisplay.GetWidth());
- pCell->SetPadding(oStyle.m_oPadding);
- pCell->SetBorder(oStyle.m_oBorder);
+ pCellStyle->m_wsVAlign = oStyle.m_oDisplay.GetVAlign().ToWString();
+ pCellStyle->m_wsHAlign = oStyle.m_oDisplay.GetHAlign().ToWString();
+ pCellStyle->m_oBackground = oStyle.m_oBackground.GetColor();
+ pCellStyle->m_oHeight = oStyle.m_oDisplay.GetHeight();
+ pCellStyle->m_oWidth = oStyle.m_oDisplay.GetWidth();
+ pCellStyle->m_oPadding = oStyle.m_oPadding;
+ pCellStyle->m_oBorder = oStyle.m_oBorder;
- if (pCell->GetStyles()->m_wsHAlign.empty())
- pCell->SetHAlign(oStyle.m_oText.GetAlign().ToWString());
+ if (pCellStyle->m_wsHAlign.empty())
+ pCellStyle->m_wsHAlign = oStyle.m_oText.GetAlign().ToWString();
}
void ParseTableCaption(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS)
@@ -2294,6 +2860,58 @@ private:
sSelectors.pop_back();
return;
}
+
+ void ParseTableColspan(CTable& oTable)
+ {
+ CTableColgroup *pColgroup = new CTableColgroup(m_oLightReader);
+
+ if (NULL == pColgroup)
+ return;
+
+ std::vector arNodes;
+
+ GetSubClass(NULL, arNodes);
+
+ oTable.AddColgroup(pColgroup);
+
+ const int nDeath = m_oLightReader.GetDepth();
+ if (!m_oLightReader.IsEmptyNode() && m_oLightReader.ReadNextSiblingNode2(nDeath))
+ {
+ do
+ {
+ if (L"col" != m_oLightReader.GetName())
+ continue;
+
+ CTableCol *pCol = new CTableCol(m_oLightReader);
+
+ if (NULL == pCol)
+ continue;
+
+ GetSubClass(NULL, arNodes);
+ CalculateCellStyles(pCol->GetStyle(), arNodes);
+ arNodes.pop_back();
+
+ if (NULL == pCol)
+ continue;
+
+ pColgroup->AddCol(pCol);
+ } while(m_oLightReader.ReadNextSiblingNode2(nDeath));
+ }
+
+ if(pColgroup->Empty())
+ {
+ std::map::const_iterator itFound = arNodes.begin()->m_mAttributes.find(L"span");
+
+ CTableCol *pCol = new CTableCol((arNodes.begin()->m_mAttributes.cend() != itFound) ? NSStringFinder::ToInt(itFound->second, 1) : 1);
+
+ if (NULL == pCol)
+ return;
+
+ CalculateCellStyles(pCol->GetStyle(), arNodes);
+
+ pColgroup->AddCol(pCol);
+ }
+ }
struct TRowspanElement
{
@@ -2306,9 +2924,10 @@ private:
{}
};
- void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS, ERowParseMode eMode)
+ void ParseTableRows(CTable& oTable, std::vector& sSelectors, CTextSettings& oTS, ERowParseMode eMode)
{
std::vector arRowspanElements;
+ std::vector arRows;
int nDeath = m_oLightReader.GetDepth();
while (m_oLightReader.ReadNextSiblingNode(nDeath))
@@ -2340,10 +2959,11 @@ private:
if (NULL == pCell)
continue;
- pCell->SetMode(eMode);
-
GetSubClass(pCell->GetData(), sSelectors);
- CalculateCellStyles(pCell, sSelectors);
+
+ const std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(sSelectors.begin(), sSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), sSelectors.cend()};
+
+ CalculateCellStyles(pCell->GetStyles(), arNewSelectors);
while(m_oLightReader.MoveToNextAttribute())
{
@@ -2367,9 +2987,10 @@ private:
CTextSettings oTSR(oTS);
if (pCell->GetStyles()->m_wsHAlign.empty())
- oTSR.sPStyle += L"";
+ oTSR.oAdditionalStyle.m_oText.SetAlign(L"center", NEXT_LEVEL);
+
+ oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", NEXT_LEVEL);
- oTSR.AddRStyle(L"");
readStream(pCell->GetData(), sSelectors, oTSR, true);
}
// Читаем td. Ячейка таблицы
@@ -2403,37 +3024,211 @@ private:
}
sSelectors.pop_back();
-
- oTable.AddRow(pRow);
+ arRows.push_back(pRow);
}
+
+ oTable.AddRows(arRows, eMode);
}
- void ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS)
+ bool ParseRuby(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS)
{
if(m_oLightReader.IsEmptyNode())
- return;
+ return false;
+
+ const int nDepth = m_oLightReader.GetDepth();
+
+ #ifdef DESABLE_RUBY_SUPPORT
+
+ wrP(oXml, sSelectors, oTS);
+
+ while (m_oLightReader.ReadNextSiblingNode2(nDepth))
+ {
+ GetSubClass(NULL, sSelectors);
+
+ if (L"rp" == sSelectors.back().m_wsName)
+ {
+ sSelectors.pop_back();
+ continue;
+ }
+ else if (L"rt" == sSelectors.back().m_wsName)
+ readStream(oXml, sSelectors, oTS);
+ else
+ readInside(oXml, sSelectors, oTS, sSelectors.back().m_wsName);
+
+ sSelectors.pop_back();
+ }
+
+ CloseP(oXml, sSelectors);
+
+ return true;
+ #endif
+
+ NSStringUtils::CStringBuilder oBase;
+ NSStringUtils::CStringBuilder oRT;
+
+ TState oRtState{m_oState};
+ oRtState.m_bInP = true;
+
+ TState oBaseState{m_oState};
+ oBaseState.m_bInP = true;
+
+ while (m_oLightReader.ReadNextSiblingNode2(nDepth))
+ {
+ GetSubClass(NULL, sSelectors);
+
+ CTextSettings oNewSettings{oTS};
+
+ NSCSS::CCompiledStyle oStyle{m_oStylesCalculator.GetCompiledStyle(sSelectors)};
+
+ const std::wstring wsHighlight{oStyle.m_oBackground.GetColor().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
+ {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
+ {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"},
+ {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"},
+ {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"},
+ {{211, 211, 211}, L"lightGray"}})};
+
+ if (L"none" != wsHighlight)
+ oNewSettings.oAdditionalStyle.m_oText.SetHighlight(oStyle.m_oBackground.GetColor().ToWString(), NEXT_LEVEL);
+ // oNewSettings.AddRStyle(L"");
+
+ if (L"rt" == sSelectors.back().m_wsName)
+ {
+ std::swap(m_oState, oRtState);
+ readStream(&oRT, sSelectors, oNewSettings);
+ std::swap(m_oState, oRtState);
+ }
+ else if (L"rp" == sSelectors.back().m_wsName)
+ {
+ sSelectors.pop_back();
+ continue;
+ }
+ else if (L"#text" == sSelectors.back().m_wsName)
+ {
+ std::swap(m_oState, oBaseState);
+ readInside(&oBase, sSelectors, oNewSettings, sSelectors.back().m_wsName);
+ std::swap(m_oState, oBaseState);
+ }
+ sSelectors.pop_back();
+ }
+
+ WriteSpace(&oBase);
+
+ wrP(oXml, sSelectors, oTS);
+
+ if (0 != oRT.GetSize())
+ {
+ NSCSS::CCompiledStyle oStyle{m_oStylesCalculator.GetCompiledStyle(sSelectors)};
+
+ int nFontSize = 24;
+
+ if (!oStyle.m_oFont.GetSize().Empty() && !oStyle.m_oFont.GetSize().Zero())
+ nFontSize = oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2;
+
+ bool bConsistsChineseCharacters = false;
+
+ const std::vector::const_reverse_iterator oFound{std::find_if(sSelectors.crbegin(), sSelectors.crend(), [](const NSCSS::CNode& oNode){ return oNode.m_mAttributes.cend() != oNode.m_mAttributes.find(L"lang");})};
+
+ if (sSelectors.crend() != oFound)
+ {
+ const size_t unFound{oFound->m_mAttributes.at(L"lang").find(L"-")};
+
+ if (std::wstring::npos != unFound)
+ bConsistsChineseCharacters = ConsistsChineseCharacters(oFound->m_mAttributes.at(L"lang").substr(0, unFound));
+ }
+
+ OpenR(oXml);
+ oXml->WriteString(L"");
+ oXml->WriteString(L"" + oRT.GetData() + L"");
+ oXml->WriteString(L"" + oBase.GetData() + L"");
+ oXml->WriteString(L"");
+ CloseR(oXml);
+ }
+ else
+ oXml->WriteString(oBase.GetData());
+
+ CloseP(oXml, sSelectors);
+
+ return true;
+ }
+
+ bool ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS)
+ {
+ if(m_oLightReader.IsEmptyNode())
+ return false;
CTable oTable;
- //Table styles
- if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border"))
- {
- const int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]);
-
- if (0 < nWidth)
- {
- sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto";
- oTable.HaveBorderAttribute();
- }
- else
- sSelectors.back().m_mAttributes[L"border"] = L"none";
- }
-
NSCSS::CCompiledStyle oStyle;
m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors);
- if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding"))
- oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true);
+ //Table styles
+ std::wstring wsFrame;
+
+ for (const std::pair oArgument : sSelectors.back().m_mAttributes)
+ {
+ if (L"border" == oArgument.first)
+ {
+ const int nWidth = NSStringFinder::ToInt(oArgument.second);
+
+ if (0 < nWidth)
+ {
+ oStyle.m_oBorder.SetStyle(L"outset", 0, true);
+ oStyle.m_oBorder.SetWidth(nWidth, 0, true);
+ oStyle.m_oBorder.SetColor(L"auto", 0, true);
+ oTable.SetRules(L"all");
+ }
+ else
+ {
+ oStyle.m_oBorder.SetNone(0, true);
+ oTable.SetRules(L"none");
+ }
+ }
+ else if (L"cellpadding" == oArgument.first)
+ oStyle.m_oPadding.SetValues(oArgument.second + L"px", 0, true);
+ else if (L"rules" == oArgument.first)
+ oTable.SetRules(oArgument.second);
+ else if (L"frame" == oArgument.first)
+ wsFrame = oArgument.second;
+ }
+
+ if (!wsFrame.empty() && oStyle.m_oBorder.Empty())
+ {
+ #define SetDefaultBorderSide(side) \
+ oStyle.m_oBorder.SetStyle##side(L"solid", 0, true); \
+ oStyle.m_oBorder.SetWidth##side(1, 0, true); \
+ oStyle.m_oBorder.SetColor##side(L"black", 0, true);
+
+ if (NSStringFinder::Equals(L"border", wsFrame))
+ {
+ SetDefaultBorderSide()
+ }
+ else if (NSStringFinder::Equals(L"above", wsFrame))
+ {
+ SetDefaultBorderSide(TopSide)
+ }
+ else if (NSStringFinder::Equals(L"below", wsFrame))
+ {
+ SetDefaultBorderSide(BottomSide)
+ }
+ else if (NSStringFinder::Equals(L"hsides", wsFrame))
+ {
+ SetDefaultBorderSide(TopSide)
+ SetDefaultBorderSide(BottomSide)
+ }
+ else if (NSStringFinder::Equals(L"vsides", wsFrame))
+ {
+ SetDefaultBorderSide(LeftSide)
+ SetDefaultBorderSide(RightSide)
+ }
+ else if (NSStringFinder::Equals(L"rhs", wsFrame))
+ {
+ SetDefaultBorderSide(RightSide)
+ }
+ else if (NSStringFinder::Equals(L"lhs", wsFrame))
+ {
+ SetDefaultBorderSide(LeftSide)
+ }
+ }
if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Collapse)
oTable.SetCellSpacing(0);
@@ -2458,11 +3253,13 @@ private:
if(sName == L"caption")
ParseTableCaption(oTable, sSelectors, oTS);
if(sName == L"thead")
- ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeHeader);
+ ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeHeader);
if(sName == L"tbody")
ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeBody);
else if(sName == L"tfoot")
- ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeFoother);
+ ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeFoother);
+ else if (sName == L"colgroup")
+ ParseTableColspan(oTable);
sSelectors.pop_back();
}
@@ -2471,9 +3268,11 @@ private:
oTable.CompleteTable();
oXml->WriteString(oTable.ConvertToOOXML());
WriteEmptyParagraph(oXml, true);
+
+ return true;
}
- void readInput (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS)
+ void readInput (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS)
{
std::wstring sValue;
std::wstring sAlt;
@@ -2496,31 +3295,32 @@ private:
if(!sValue.empty())
{
wrP(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
+ OpenR(oXml);
wrRPr(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
+ OpenT(oXml);
oXml->WriteEncodeXmlString(sValue + L' ');
- oXml->WriteString(L"");
+ CloseT(oXml);
+ CloseR(oXml);
}
readStream(oXml, sSelectors, oTS, ElementInTable(sSelectors));
}
- void readLi (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, bool bType)
+ void readLi (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, bool bType)
{
if(m_oLightReader.IsEmptyNode())
return;
- std::wstring sStart = L"1";
+ int nStart = 1;
while(m_oLightReader.MoveToNextAttribute())
if(m_oLightReader.GetName() == L"start")
- sStart = m_oLightReader.GetText();
+ nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1);
m_oLightReader.MoveToElement();
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nDeath))
{
- std::wstring sName = m_oLightReader.GetName();
+ const std::wstring sName = m_oLightReader.GetName();
if (sName == L"optgroup")
{
GetSubClass(oXml, sSelectors);
@@ -2528,13 +3328,15 @@ private:
{
if(m_oLightReader.GetName() != L"label")
continue;
+
CloseP(oXml, sSelectors);
wrP(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
+ OpenR(oXml);
wrRPr(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
+ OpenT(oXml);
oXml->WriteEncodeXmlString(m_oLightReader.GetText());
- oXml->WriteString(L"");
+ CloseT(oXml);
+ CloseR(oXml);
}
m_oLightReader.MoveToElement();
readLi(oXml, sSelectors, oTS, true);
@@ -2547,18 +3349,62 @@ private:
continue;
}
- GetSubClass(oXml, sSelectors);
- while(m_oLightReader.MoveToNextAttribute())
- if(m_oLightReader.GetName() == L"value")
- sStart = m_oLightReader.GetText();
- m_oLightReader.MoveToElement();
-
CloseP(oXml, sSelectors);
CTextSettings oTSLiP(oTS);
+
+ std::wstring wsValue;
+ const std::wstring wsParentName{(!sSelectors.empty()) ? sSelectors.back().m_wsName : L""};
+
+ GetSubClass(oXml, sSelectors);
+
+ std::wstring wsArgumentName;
+
+ while(m_oLightReader.MoveToNextAttribute())
+ {
+ wsArgumentName = m_oLightReader.GetName();
+
+ if(L"value" == wsArgumentName && L"datalist" == wsParentName)
+ {
+ if (sName == L"option")
+ wsValue = m_oLightReader.GetText();
+ else
+ nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1);
+ }
+ else if (L"disabled" == wsArgumentName)
+ oTSLiP.oAdditionalStyle.m_oText.SetColor(L"#808080", NEXT_LEVEL);
+ else if (L"selected" == wsArgumentName)
+ oTSLiP.oAdditionalStyle.m_oText.SetDecoration(L"underline", NEXT_LEVEL);
+ // oTSLiP.AddRStyle(L"");
+ }
+ m_oLightReader.MoveToElement();
+
+ if (std::wstring::npos != oTS.sPStyle.find(L""))
+ {
+ wrP(oXml, sSelectors, oTS);
+ CloseP(oXml, sSelectors);
+ oTSLiP.sPStyle.clear();
+ }
+
oTSLiP.nLi++;
+
+ const std::wstring wsOldPStyle{oTSLiP.sPStyle};
+
oTSLiP.sPStyle += L"";
+
+ wrP(oXml, sSelectors, oTSLiP);
+ oTSLiP.sPStyle = wsOldPStyle;
+
+ if (!wsValue.empty())
+ {
+ OpenR(oXml);
+ OpenT(oXml);
+ oXml->WriteEncodeXmlString(wsValue);
+ CloseT(oXml);
+ CloseR(oXml);
+ }
+
readStream(oXml, sSelectors, oTSLiP);
CloseP(oXml, sSelectors);
@@ -2568,31 +3414,32 @@ private:
// Нумерованный список
if(!bType)
{
+ const std::wstring wsStart(std::to_wstring(nStart));
m_oNumberXml.WriteString(L"");
+ m_oNumberXml.WriteString(wsStart);
+ m_oNumberXml.WriteString(L"\"/>");
}
}
- void readA (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, std::wstring& sNote)
+ void readA (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS, std::wstring& sNote)
{
std::wstring sRef;
std::wstring sAlt;
@@ -2618,6 +3465,7 @@ private:
sFootnote = L"href";
}
m_oLightReader.MoveToElement();
+
if(sNote.empty())
sNote = sRef;
@@ -2661,11 +3509,12 @@ private:
if(!readStream(oXml, sSelectors, oTS))
{
- oXml->WriteString(L"");
+ OpenR(oXml);
wrRPr(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
+ OpenT(oXml);
oXml->WriteEncodeXmlString(!sAlt.empty() ? sAlt : L" ");
- oXml->WriteString(L"");
+ CloseT(oXml);
+ CloseR(oXml);
}
if (m_oState.m_bInP)
@@ -2689,13 +3538,19 @@ private:
if (!bFootnote)
{
std::wstring sFootnoteID = std::to_wstring(m_nFootnoteId++);
- oXml->WriteString(L"WriteString(L"WriteString(sFootnoteID);
- oXml->WriteString(L"\"/>");
+ oXml->WriteString(L"\"/>");
+ CloseR(oXml);
m_mFootnotes.insert(std::make_pair(sFootnote, sFootnoteID));
}
else
- oXml->WriteString(L"");
+ {
+ OpenR(oXml);
+ oXml->WriteString(L"");
+ CloseR(oXml);
+ }
}
CloseP(oXml, sSelectors);
@@ -2783,56 +3638,61 @@ private:
sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && sExtention != L"wmz";
}
- void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc)
+ void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData)
{
- if (wsAlt.empty())
- {
- //TODO:: реализовать отображение того, что картинку не удалось получить
- if (wsSrc.empty())
- WriteEmptyParagraph(oXml, false, m_oState.m_bInP);
- else
- {
- m_oDocXmlRels.WriteString(L"");
+ m_oDocXmlRels.WriteString(L"");
- const bool bOpenedP{OpenP(oXml)};
+ const bool bOpenedP{OpenP(oXml)};
- WriteEmptyImage(oXml, 304800, 304800);
+ WriteEmptyImage(oXml, (0 != oImageData.m_unWidth) ? oImageData.m_unWidth : DEFAULT_IMAGE_WIDTH, (0 != oImageData.m_unHeight) ? oImageData.m_unHeight : DEFAULT_IMAGE_HEIGHT, L"", wsAlt);
- if (bOpenedP)
- CloseP(oXml, sSelectors);
- }
- return;
- }
-
- wrP(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
- wrRPr(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
- oXml->WriteEncodeXmlString(wsAlt);
- oXml->WriteString(L"");
+ if (bOpenedP)
+ CloseP(oXml, sSelectors);
}
void readImage (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS)
{
std::wstring wsAlt, sSrcM;
bool bRes = false;
+ TImageData oImageData;
+
+ #define READ_IMAGE_DATA(data) \
+ { \
+ NSCSS::NSProperties::CDigit oDigit; \
+ if (oDigit.SetValue(m_oLightReader.GetText())) \
+ { \
+ if (NSCSS::UnitMeasure::None == oDigit.GetUnitMeasure()) \
+ data = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(oDigit.ToDouble(), NSCSS::Inch, 96) * 914400); \
+ else \
+ data = static_cast(oDigit.ToDouble(NSCSS::Inch) * 914400); \
+ } \
+ }\
+
while (m_oLightReader.MoveToNextAttribute())
{
- std::wstring wsName = m_oLightReader.GetName();
+ const std::wstring wsName = m_oLightReader.GetName();
if (wsName == L"alt")
wsAlt = m_oLightReader.GetText();
else if (wsName == L"src")
sSrcM = m_oLightReader.GetText();
+ else if (wsName == L"width")
+ READ_IMAGE_DATA(oImageData.m_unWidth)
+ else if (wsName == L"height")
+ READ_IMAGE_DATA(oImageData.m_unHeight)
+ else if (wsName == L"hspace")
+ READ_IMAGE_DATA(oImageData.m_nHSpace)
+ else if (wsName == L"vspace")
+ READ_IMAGE_DATA(oImageData.m_nVSpace)
}
m_oLightReader.MoveToElement();
if (sSrcM.empty())
{
- ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM);
+ ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData);
return;
}
@@ -2863,7 +3723,7 @@ private:
std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
if (NotValidExtension(sExtention))
{
- ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM);
+ ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData);
return;
}
@@ -2909,11 +3769,11 @@ private:
}
if (!bRes)
- ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM);
+ ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData);
else
{
wrP(oXml, sSelectors, oTS);
- ImageRels(oXml, nImageId, sImageSrc, sExtention);
+ ImageRels(oXml, nImageId, sImageSrc, sExtention, oImageData);
}
}
@@ -2924,51 +3784,25 @@ private:
if (m_oState.m_bWasPStyle)
return L"";
- std::vector> temporary;
- size_t i = 0;
- while(i != sSelectors.size())
- {
- if (sSelectors[i].Empty() && rStyle.find(L' ' + sSelectors[i].m_wsName + L' ') != std::wstring::npos)
- {
- temporary.push_back(std::make_pair(i, sSelectors[i]));
- sSelectors.erase(sSelectors.begin() + i);
- }
- else
- i++;
- }
- NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true);
- NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors);
+ NSCSS::CCompiledStyle oStyleSetting{m_oStylesCalculator.GetCompiledStyle(sSelectors, true)};
+ NSCSS::CCompiledStyle oStyle{m_oStylesCalculator.GetCompiledStyle(sSelectors)};
NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting);
+ oStyleSetting += oTS.oAdditionalStyle;
+
std::wstring sPStyle = GetStyle(oStyle, true);
+ if (sPStyle.empty() && !ElementInTable(sSelectors))
+ sPStyle = L"normal-web";
+
if (sPStyle.empty() && oTS.sPStyle.empty())
return L"";
m_oXmlStyle.WriteLitePStyle(oStyleSetting);
- std::wstring sPSettings = m_oXmlStyle.GetStyle();
+ const std::wstring sPSettings = m_oXmlStyle.GetStyle();
m_oXmlStyle.Clear();
- for(int i = temporary.size() - 1; i >= 0; i--)
- sSelectors.insert(sSelectors.begin() + temporary[i].first, temporary[i].second);
-
- // Если в таблице, то игнориуются Paragraph Borders
- bool bInTable = false;
- for (const NSCSS::CNode& item : sSelectors)
- if (item.m_wsName == L"table")
- bInTable = true;
- if (bInTable)
- {
- size_t nBdr = sPSettings.find(L"");
- if (nBdr != std::wstring::npos)
- {
- size_t nBdrEnd = sPSettings.find(L"", nBdr);
- if (nBdrEnd != std::wstring::npos)
- sPSettings.erase(nBdr, nBdrEnd + 9 - nBdr);
- }
- }
-
oXml->WriteNodeBegin(L"w:pPr");
if (!sPStyle.empty())
@@ -2978,7 +3812,7 @@ private:
oXml->WriteString(L"\"/>");
}
- oXml->WriteString(oTS.sPStyle + L' ' + sPSettings);
+ oXml->WriteString(oTS.sPStyle + sPSettings);
oXml->WriteNodeEnd(L"w:pPr");
m_oState.m_bWasPStyle = true;
@@ -2991,6 +3825,9 @@ private:
return L"";
NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true);
+
+ oStyleSetting += oTS.oAdditionalStyle;
+
NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors);
NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting);
@@ -3001,7 +3838,22 @@ private:
const std::wstring sRSettings = m_oXmlStyle.GetStyle();
m_oXmlStyle.Clear();
- if (!sRStyle.empty() || !oTS.sRStyle.empty())
+ std::wstring wsFontSize;
+
+ const int nCalculatedFontChange{CalculateFontChange(sSelectors)};
+
+ if (0 != nCalculatedFontChange)
+ {
+ int nFontSizeLevel{static_cast((oStyle.m_oFont.Empty()) ? 3 : GetFontSizeLevel(oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2))};
+
+ nFontSizeLevel += nCalculatedFontChange;
+
+ const UINT unFontSize{GetFontSizeByLevel(nFontSizeLevel)};
+
+ wsFontSize += L"";
+ }
+
+ if (!sRStyle.empty() || CTextSettings::Normal != oTS.eTextMode || !wsFontSize.empty() || !sRSettings.empty())
{
oXml->WriteString(L"");
if (!sRStyle.empty())
@@ -3011,45 +3863,101 @@ private:
oXml->WriteString(L"\"/>");
}
- oXml->WriteString(oTS.sRStyle + L' ' + sRSettings);
+ switch (oTS.eTextMode)
+ {
+ case CTextSettings::Subscript:
+ {
+ oXml->WriteString(L"");
+ break;
+ }
+ case CTextSettings::Superscript:
+ {
+ oXml->WriteString(L"");
+ break;
+ }
+ default:
+ break;
+ }
+
+ oXml->WriteString(sRSettings + wsFontSize);
oXml->WriteString(L"");
}
return sRStyle;
}
- void WriteImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight, const std::wstring& wsId)
+ void WriteImage(NSStringUtils::CStringBuilder* pXml, const TImageData& oImageData, const std::wstring& wsId)
{
+ if (NULL == pXml)
+ return;
+
+ OpenR(pXml);
+
// Пишем в document.xml
- pXml->WriteString(L"WriteString(std::to_wstring(nWidth));
- pXml->WriteString(L"\" cy=\"");
- pXml->WriteString(std::to_wstring(nHeight));
- pXml->WriteString(L"\"/>WriteString(wsId);
- pXml->WriteString(L"\" name=\"\"/>WriteString(wsId);
- pXml->WriteString(L"\" name=\"\"/>WriteString(wsId);
- pXml->WriteString(L"\"/>WriteString(std::to_wstring(nWidth));
- pXml->WriteString(L"\" cy=\"");
- pXml->WriteString(std::to_wstring(nHeight));
- pXml->WriteString(L"\"/>");
+ if (oImageData.ZeroSpaces())
+ {
+ pXml->WriteString(L"WriteString(std::to_wstring(oImageData.m_unWidth));
+ pXml->WriteString(L"\" cy=\"");
+ pXml->WriteString(std::to_wstring(oImageData.m_unHeight));
+ pXml->WriteString(L"\"/>WriteString(wsId);
+ pXml->WriteString(L"\" name=\"Picture " + wsId + L"\"/>WriteString(wsId);
+ pXml->WriteString(L"\" name=\"Picture " + wsId + L"\"/>WriteString(wsId);
+ pXml->WriteString(L"\"/>WriteString(std::to_wstring(oImageData.m_unWidth));
+ pXml->WriteString(L"\" cy=\"");
+ pXml->WriteString(std::to_wstring(oImageData.m_unHeight));
+ pXml->WriteString(L"\"/>");
+ }
+ else
+ {
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"" + oImageData.m_wsAlign + L"");
+ pXml->WriteString(L"0");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
+ pXml->WriteString(L"00");
+ pXml->WriteString(L"");
+ }
+
+ CloseR(pXml);
}
- void WriteEmptyImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight)
+ void WriteEmptyImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight, const std::wstring& wsName = L"", const std::wstring& wsDescr = L"")
{
- pXml->WriteString(L"");
- pXml->WriteString(L"");
+ if (NULL == pXml)
+ return;
+
+ OpenR(pXml);
+
+ pXml->WriteString(L"");
+ pXml->WriteString(L"");
pXml->WriteString(L"");
pXml->WriteString(L"");
- pXml->WriteString(L"");
+ pXml->WriteString(L"");
pXml->WriteString(L"");
pXml->WriteString(L"");
- pXml->WriteString(L"");
+ pXml->WriteString(L"");
+
+ CloseR(pXml);
}
- void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention)
+ void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention, const TImageData& oImageData = TImageData())
{
bool bNew = nImageId < 0;
if (bNew)
@@ -3075,35 +3983,41 @@ private:
m_oDocXmlRels.WriteString(L"\"/>");
}
+ if (!oImageData.ZeroSize())
+ return WriteImage(oXml, oImageData, sImageId);
+
+ TImageData oNewImageData{oImageData};
+
// Получаем размеры картинки
- int nHy = oBgraFrame.get_Height();
- int nWx = oBgraFrame.get_Width();
- if (nWx > nHy)
+ oNewImageData.m_unWidth = oBgraFrame.get_Width();
+ oNewImageData.m_unHeight = oBgraFrame.get_Height();
+
+ if (oNewImageData.m_unWidth > oNewImageData.m_unHeight)
{
- int nW = nWx * 9525;
+ int nW = oNewImageData.m_unWidth * 9525;
nW = (nW > 7000000 ? 7000000 : nW);
- nHy = (int)((double)nHy * (double)nW / (double)nWx);
- nWx = nW;
+ oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth);
+ oNewImageData.m_unWidth = nW;
}
else
{
- int nH = nHy * 9525;
+ int nH = oNewImageData.m_unHeight * 9525;
nH = (nH > 8000000 ? 8000000 : nH);
- int nW = (int)((double)nWx * (double)nH / (double)nHy);
+ int nW = (int)((double)oNewImageData.m_unWidth * (double)nH / (double)oNewImageData.m_unHeight);
if (nW > 7000000)
{
nW = 7000000;
- nHy = (int)((double)nHy * (double)nW / (double)nWx);
+ oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth);
}
else
- nHy = nH;
- nWx = nW;
+ oNewImageData.m_unHeight = nH;
+ oNewImageData.m_unWidth = nW;
}
- WriteImage(oXml, nWx, nHy, sImageId);
+ WriteImage(oXml, oNewImageData, sImageId);
}
- void readNote (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const std::wstring& sNote)
+ void readNote (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, std::wstring& sNote)
{
if(sNote.empty())
return;
@@ -3118,6 +4032,8 @@ private:
m_oNoteXml.WriteString(L"\">");
m_oNoteXml.WriteEncodeXmlString(sNote);
m_oNoteXml.WriteString(L"");
+
+ sNote.clear();
}
bool readSVG (const std::wstring& wsSvg)
@@ -3340,3 +4256,159 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector& sSrc, const s
m_internal->write();
return S_OK;
}
+
+std::wstring CTableRow::ConvertToOOXML(const CTable& oTable, int nInstruction)
+{
+ if (m_arCells.empty())
+ return std::wstring();
+
+ NSStringUtils::CStringBuilder oRow;
+ oRow.WriteNodeBegin(L"w:tr");
+
+ const TTableStyles oTableStyles{oTable.GetTableStyles()};
+
+ if (!m_oStyles.Empty() || 0 < oTableStyles.m_nCellSpacing)
+ {
+ oRow.WriteNodeBegin(L"w:trPr");
+
+ if (m_oStyles.m_bIsHeader)
+ oRow += L"";
+
+ if (0 < m_oStyles.m_unMaxHeight)
+ oRow += L"";
+
+ if (0 < oTableStyles.m_nCellSpacing)
+ oRow += L"";
+
+ oRow.WriteNodeEnd(L"w:trPr");
+ }
+
+ for (UINT unIndex = 0; unIndex < m_arCells.size();)
+ {
+ int nNewInstruction{nInstruction};
+
+ if (0 == unIndex)
+ nNewInstruction |= FIRST_ELEMENT;
+ if (m_arCells.size() - 1 == unIndex)
+ nNewInstruction |= LAST_ELEMENT;
+ else if (0 != unIndex)
+ nNewInstruction |= MID_ELEMENT;
+
+ oRow += m_arCells[unIndex]->ConvertToOOXML(oTable, ++unIndex, nNewInstruction);
+ }
+
+ oRow.WriteNodeEnd(L"w:tr");
+
+ return oRow.GetData();
+}
+
+std::wstring CTableCell::ConvertToOOXML(const CTable& oTable, UINT unColumnNumber, int nInstruction)
+{
+ NSStringUtils::CStringBuilder oCell;
+
+ oCell.WriteNodeBegin(L"w:tc");
+ oCell.WriteNodeBegin(L"w:tcPr");
+
+ if (PARSE_MODE_HEADER == (nInstruction & PARSE_MODE_MASK))
+ oCell += L"";
+
+ TTableCellStyle oCellStyle(m_oStyles);
+
+ const TTableCellStyle* pColStyle = oTable.GetColStyle(unColumnNumber);
+
+ if (NULL != pColStyle)
+ oCellStyle += pColStyle;
+
+ if (!oCellStyle.m_oWidth.Empty())
+ {
+ if (NSCSS::UnitMeasure::Percent == oCellStyle.m_oWidth.GetUnitMeasure())
+ oCell += L"";
+ else
+ {
+ if (!oCellStyle.m_oWidth.Zero())
+ {
+ int nWidth;
+ if (NSCSS::UnitMeasure::None != oCellStyle.m_oWidth.GetUnitMeasure())
+ nWidth = oCellStyle.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips);
+ else
+ nWidth = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(oCellStyle.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5);
+
+ oCell += L"";
+ }
+ else
+ oCell += L"";
+ }
+ }
+ else
+ oCell += L"";
+
+ if (1 != m_unColspan)
+ oCell += L"";
+
+ if (m_bIsMerged)
+ oCell += L"";
+ else if (1 < m_unRowSpan)
+ oCell += L"";
+
+ const TTableStyles oTableStyles{oTable.GetTableStyles()};
+
+ if (!oCellStyle.m_oBorder.Empty() && !oCellStyle.m_oBorder.Zero() /*&& oCellStyle.m_oBorder != oTableStyles.m_oBorder*/)
+ oCell += L"" + CreateBorders(oCellStyle.m_oBorder, &oCellStyle.m_oPadding) + L"";
+ else if (TTableStyles::ETableRules::Groups == oTable.GetTableStyles().m_enRules)
+ {
+ std::wstring wsBorders;
+
+ if (oTable.HaveColgroups())
+ wsBorders += oTable.CalculateSidesToClean(unColumnNumber);
+
+ if (PARSE_MODE_HEADER == (nInstruction & PARSE_MODE_MASK) && (((nInstruction & ROW_POSITION_MASK) >> 4) & LAST_ELEMENT))
+ wsBorders += CreateDefaultBorder(L"bottom");
+ else if (PARSE_MODE_FOOTHER == (nInstruction & PARSE_MODE_MASK) && (((nInstruction & ROW_POSITION_MASK) >> 4) & FIRST_ELEMENT))
+ wsBorders += CreateDefaultBorder(L"top");
+
+ if (!wsBorders.empty())
+ oCell += L"" + wsBorders + L"";
+ }
+
+ if (!oCellStyle.m_oBackground.Empty())
+ {
+ const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == oCellStyle.m_oBackground.GetType()) ? L"auto" : oCellStyle.m_oBackground.ToWString()};
+ oCell += L"";
+ }
+
+ if (!oCellStyle.m_wsVAlign.empty())
+ oCell += L"";
+ else
+ oCell += L"";
+
+ if (!oCellStyle.m_oPadding.Empty() && oTableStyles.m_oPadding != oCellStyle.m_oPadding)
+ {
+ const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT),
+ oCellStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
+ const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH),
+ oCellStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH));
+ const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT),
+ oCellStyle .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
+ const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH),
+ oCellStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH));
+
+ oCell += L""
+ ""
+ ""
+ ""
+ ""
+ "";
+ }
+
+ oCell += L"";
+ oCell.WriteNodeEnd(L"w:tcPr");
+
+ if (0 != m_oData.GetCurSize())
+ oCell += m_oData.GetData();
+ else
+ WriteEmptyParagraph(&oCell);
+
+ oCell.WriteNodeEnd(L"w:tc");
+
+ return oCell.GetData();
+}
diff --git a/HtmlFile2/src/Languages.h b/HtmlFile2/src/Languages.h
index e267415ebe..a0449f94ef 100644
--- a/HtmlFile2/src/Languages.h
+++ b/HtmlFile2/src/Languages.h
@@ -81,4 +81,11 @@ static std::wstring IndentifyLanguage(std::wstring wsLanguage)
return std::wstring();
}
+static bool ConsistsChineseCharacters(std::wstring wsLanguage)
+{
+ std::transform(wsLanguage.begin(), wsLanguage.end(), wsLanguage.begin(), towlower);
+
+ return L"zh" == wsLanguage || L"ja" == wsLanguage || L"ko" == wsLanguage;
+}
+
#endif // LANGUAGES_LIST_H