mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
493 lines
13 KiB
C++
493 lines
13 KiB
C++
#include "CCompiledStyle.h"
|
|
|
|
#include <cwctype>
|
|
#include <vector>
|
|
#include <numeric>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <map>
|
|
|
|
#include <iostream>
|
|
#include "../../../../../DesktopEditor/common/File.h"
|
|
#include "StaticFunctions.h"
|
|
#include "ConstValues.h"
|
|
|
|
namespace NSCSS
|
|
{
|
|
typedef std::map<std::wstring, std::wstring>::const_iterator styles_iterator;
|
|
|
|
CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point){}
|
|
|
|
CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) :
|
|
m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId),
|
|
m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure),
|
|
m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground),
|
|
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){}
|
|
|
|
CCompiledStyle::~CCompiledStyle()
|
|
{
|
|
m_arParentsStyles.clear();
|
|
}
|
|
|
|
CCompiledStyle& CCompiledStyle::operator+= (const CCompiledStyle &oElement)
|
|
{
|
|
m_oBackground += oElement.m_oBackground;
|
|
m_oBorder += oElement.m_oBorder;
|
|
m_oFont += oElement.m_oFont;
|
|
m_oMargin += oElement.m_oMargin;
|
|
m_oPadding += oElement.m_oPadding;
|
|
m_oText += oElement.m_oText;
|
|
m_oDisplay += oElement.m_oDisplay;
|
|
|
|
return *this;
|
|
}
|
|
|
|
CCompiledStyle& CCompiledStyle::operator= (const CCompiledStyle &oElement)
|
|
{
|
|
m_sId = oElement.m_sId;
|
|
m_arParentsStyles = oElement.m_arParentsStyles;
|
|
|
|
m_nDpi = oElement.m_nDpi;
|
|
m_UnitMeasure = oElement.m_UnitMeasure;
|
|
|
|
m_oBackground = oElement.m_oBackground;
|
|
m_oBorder = oElement.m_oBorder;
|
|
m_oFont = oElement.m_oFont;
|
|
m_oMargin = oElement.m_oMargin;
|
|
m_oPadding = oElement.m_oPadding;
|
|
m_oText = oElement.m_oText;
|
|
m_oDisplay = oElement.m_oDisplay;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool CCompiledStyle::operator== (const CCompiledStyle& oStyle) const
|
|
{
|
|
return GetId()[0] == oStyle.GetId()[0] &&
|
|
m_arParentsStyles == oStyle.m_arParentsStyles &&
|
|
m_oBackground == oStyle.m_oBackground &&
|
|
m_oBorder == oStyle.m_oBorder &&
|
|
m_oFont == oStyle.m_oFont &&
|
|
m_oMargin == oStyle.m_oMargin &&
|
|
m_oPadding == oStyle.m_oPadding &&
|
|
m_oText == oStyle.m_oText &&
|
|
m_oDisplay == oStyle.m_oDisplay;
|
|
}
|
|
|
|
void CCompiledStyle::StyleEquation(CCompiledStyle &oFirstStyle, CCompiledStyle &oSecondStyle)
|
|
{
|
|
NSProperties::CFont ::Equation(oFirstStyle.m_oFont, oSecondStyle.m_oFont);
|
|
NSProperties::CIndent ::Equation(oFirstStyle.m_oMargin, oSecondStyle.m_oMargin);
|
|
NSProperties::CIndent ::Equation(oFirstStyle.m_oPadding, oSecondStyle.m_oPadding);
|
|
NSProperties::CBackground::Equation(oFirstStyle.m_oBackground, oSecondStyle.m_oBackground);
|
|
NSProperties::CText ::Equation(oFirstStyle.m_oText, oSecondStyle.m_oText);
|
|
NSProperties::CBorder ::Equation(oFirstStyle.m_oBorder, oSecondStyle.m_oBorder);
|
|
NSProperties::CDisplay ::Equation(oFirstStyle.m_oDisplay, oSecondStyle.m_oDisplay);
|
|
}
|
|
|
|
void CCompiledStyle::SetDpi(const unsigned short &uiDpi)
|
|
{
|
|
m_nDpi = uiDpi;
|
|
}
|
|
|
|
void CCompiledStyle::SetUnitMeasure(const UnitMeasure &enUnitMeasure)
|
|
{
|
|
m_UnitMeasure = enUnitMeasure;
|
|
}
|
|
|
|
void CCompiledStyle::SetSizeSourceWindow(const CSizeWindow &oSizeWindow)
|
|
{
|
|
m_oSourceWindow = oSizeWindow;
|
|
}
|
|
|
|
void CCompiledStyle::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow)
|
|
{
|
|
m_oDeviceWindow = oSizeWindow;
|
|
}
|
|
|
|
bool CCompiledStyle::Empty() const
|
|
{
|
|
return m_oBackground.Empty() && m_oBorder.Empty() && m_oFont.Empty() &&
|
|
m_oMargin.Empty() && m_oPadding.Empty() && m_oText.Empty() && m_oDisplay.Empty();
|
|
}
|
|
|
|
void CCompiledStyle::AddPropSel(const std::wstring& sProperty, const std::wstring& sValue, const unsigned int unLevel, const bool& bHardMode)
|
|
{
|
|
AddStyle({{sProperty, sValue}}, unLevel, bHardMode);
|
|
}
|
|
|
|
void CCompiledStyle::AddStyle(const std::map<std::wstring, std::wstring>& mStyle, const unsigned int unLevel, const bool& bHardMode)
|
|
{
|
|
const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true;
|
|
|
|
for (std::pair<std::wstring, std::wstring> pPropertie : mStyle)
|
|
{
|
|
std::transform(pPropertie.first.begin(), pPropertie.first.end(), pPropertie.first.begin(), tolower);
|
|
SWITCH(pPropertie.first)
|
|
{
|
|
//FONT
|
|
CASE(L"font"):
|
|
{
|
|
m_oFont.SetValue(pPropertie.second.c_str(), unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"font-size"):
|
|
CASE(L"font-size-adjust"):
|
|
{
|
|
m_oFont.SetSize(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"font-stretch"):
|
|
{
|
|
m_oFont.SetStretch(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"font-style"):
|
|
{
|
|
m_oFont.SetStyle(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"font-variant"):
|
|
{
|
|
m_oFont.SetVariant(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"font-weight"):
|
|
{
|
|
m_oFont.SetWeight(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"font-family"):
|
|
{
|
|
m_oFont.SetFamily(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"line-height"):
|
|
{
|
|
m_oFont.SetLineHeight(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//MARGIN
|
|
CASE(L"margin"):
|
|
{
|
|
if (bIsThereBorder)
|
|
break;
|
|
|
|
m_oMargin.AddValue(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"margin-top"):
|
|
{
|
|
if (bIsThereBorder)
|
|
break;
|
|
|
|
m_oMargin.AddTop(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"margin-right"):
|
|
CASE(L"margin-block-end"):
|
|
{
|
|
if (bIsThereBorder)
|
|
break;
|
|
|
|
m_oMargin.AddRight(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"margin-bottom"):
|
|
{
|
|
if (bIsThereBorder)
|
|
break;
|
|
|
|
m_oMargin.AddBottom(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"margin-left"):
|
|
CASE(L"margin-block-start"):
|
|
{
|
|
if (bIsThereBorder)
|
|
break;
|
|
|
|
m_oMargin.AddLeft(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//PADDING
|
|
CASE(L"padding"):
|
|
CASE(L"mso-padding-alt"):
|
|
{
|
|
m_oPadding.AddValue(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"padding-top"):
|
|
CASE(L"mso-padding-top-alt"):
|
|
{
|
|
m_oPadding.AddTop(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"padding-right"):
|
|
CASE(L"mso-padding-right-alt"):
|
|
{
|
|
m_oPadding.AddRight(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"padding-bottom"):
|
|
CASE(L"mso-padding-bottom-alt"):
|
|
{
|
|
m_oPadding.AddBottom(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"padding-left"):
|
|
CASE(L"mso-padding-left-alt"):
|
|
{
|
|
m_oPadding.AddLeft(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
// TEXT
|
|
CASE(L"text-align"):
|
|
{
|
|
m_oText.SetAlign(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"text-indent"):
|
|
{
|
|
m_oText.SetIndent(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"text-decoration"):
|
|
{
|
|
m_oText.SetDecoration(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"text-color"):
|
|
CASE(L"color"):
|
|
{
|
|
m_oText.SetColor(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//BORDER
|
|
CASE(L"border"):
|
|
CASE(L"mso-border-alt"):
|
|
{
|
|
m_oBorder.SetSides(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-width"):
|
|
{
|
|
m_oBorder.SetWidth(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-style"):
|
|
{
|
|
m_oBorder.SetStyle(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-color"):
|
|
{
|
|
m_oBorder.SetColor(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//BORDER TOP
|
|
CASE(L"border-top"):
|
|
{
|
|
m_oBorder.SetTopSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-top-width"):
|
|
{
|
|
m_oBorder.SetWidthTopSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-top-style"):
|
|
{
|
|
m_oBorder.SetStyleTopSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-top-color"):
|
|
{
|
|
m_oBorder.SetColorTopSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//BORDER RIGHT
|
|
CASE(L"border-right"):
|
|
{
|
|
m_oBorder.SetRightSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-right-width"):
|
|
{
|
|
m_oBorder.SetWidthRightSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-right-style"):
|
|
{
|
|
m_oBorder.SetStyleRightSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-right-color"):
|
|
{
|
|
m_oBorder.SetColorRightSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//BORDER bottom
|
|
CASE(L"border-bottom"):
|
|
{
|
|
m_oBorder.SetBottomSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-bottom-width"):
|
|
{
|
|
m_oBorder.SetWidthBottomSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-bottom-style"):
|
|
{
|
|
m_oBorder.SetStyleBottomSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-bottom-color"):
|
|
{
|
|
m_oBorder.SetColorBottomSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
//BORDER LEFT
|
|
CASE(L"border-left"):
|
|
{
|
|
m_oBorder.SetLeftSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-left-width"):
|
|
{
|
|
m_oBorder.SetWidthLeftSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-left-style"):
|
|
{
|
|
m_oBorder.SetStyleLeftSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"border-left-color"):
|
|
{
|
|
m_oBorder.SetColorLeftSide(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
// BACKGROUND
|
|
CASE(L"background-color"):
|
|
{
|
|
m_oBackground.SetColor(pPropertie.second, unLevel, bHardMode);
|
|
|
|
if (bIsThereBorder)
|
|
m_oBackground.InBorder();
|
|
|
|
break;
|
|
}
|
|
CASE(L"background"):
|
|
{
|
|
m_oBackground.SetBackground(pPropertie.second, unLevel, bHardMode);
|
|
|
|
if (bIsThereBorder)
|
|
m_oBackground.InBorder();
|
|
|
|
break;
|
|
}
|
|
//DISPLAY
|
|
CASE(L"display"):
|
|
{
|
|
m_oDisplay.SetDisplay(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"width"):
|
|
{
|
|
m_oDisplay.SetWidth(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"height"):
|
|
{
|
|
m_oDisplay.SetHeight(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"align"):
|
|
{
|
|
m_oDisplay.SetHAlign(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
CASE(L"vertical-align"):
|
|
{
|
|
m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode);
|
|
break;
|
|
}
|
|
default: AddOtherStyle(pPropertie, unLevel, bHardMode);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCompiledStyle::AddStyle(const std::wstring& sStyle, const unsigned int unLevel, const bool& bHardMode)
|
|
{
|
|
if (sStyle.empty())
|
|
return;
|
|
|
|
const std::vector<std::wstring> arWords = NS_STATIC_FUNCTIONS::GetWordsW(sStyle, true, L":;");
|
|
|
|
std::wstring sProperty, sValue;
|
|
|
|
for (std::vector<std::wstring>::const_iterator iWord = arWords.begin(); iWord != arWords.end(); ++iWord)
|
|
{
|
|
if ((*iWord).back() == L':')
|
|
{
|
|
sProperty = *iWord;
|
|
sProperty.pop_back();
|
|
}
|
|
else
|
|
{
|
|
sValue += *iWord;
|
|
|
|
if (L' ' == sValue.front())
|
|
sValue.erase(0, 1);
|
|
|
|
if (!sValue.empty() && ((*iWord).back() == L';' || iWord == (arWords.end() - 1)))
|
|
{
|
|
if (sValue.back() == L';')
|
|
sValue.pop_back();
|
|
|
|
std::transform(sProperty.begin(), sProperty.end(), sProperty.begin(), tolower);
|
|
std::transform(sValue.begin(), sValue.end(), sValue.begin(), tolower);
|
|
AddPropSel(sProperty, sValue, unLevel, bHardMode);
|
|
sProperty.clear();
|
|
sValue.clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!sProperty.empty() && !sValue.empty())
|
|
AddPropSel(sProperty, sValue, bHardMode);
|
|
}
|
|
|
|
void CCompiledStyle::AddParent(const std::wstring& sParentName)
|
|
{
|
|
if (!sParentName.empty())
|
|
m_arParentsStyles.insert(sParentName);
|
|
}
|
|
|
|
std::vector<std::wstring> CCompiledStyle::GetParentsName() const
|
|
{
|
|
if (m_arParentsStyles.empty())
|
|
return std::vector<std::wstring>();
|
|
|
|
std::vector<std::wstring> arParentsName;
|
|
|
|
for (std::set<std::wstring>::iterator iParentName = m_arParentsStyles.begin(); iParentName != m_arParentsStyles.end(); ++iParentName)
|
|
arParentsName.push_back(*iParentName);
|
|
|
|
return arParentsName;
|
|
}
|
|
|
|
void CCompiledStyle::SetID(const std::wstring& sId)
|
|
{
|
|
m_sId = sId;
|
|
}
|
|
|
|
std::wstring CCompiledStyle::GetId() const
|
|
{
|
|
return m_sId;
|
|
}
|
|
}
|
|
|