mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Added reading of custom fonts in svg
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
@ -459,37 +459,88 @@ namespace NSCSS
|
||||
return std::wstring(arTemp, 6);
|
||||
}
|
||||
|
||||
std::wstring CColor::CutURL(const std::wstring &wsValue)
|
||||
{
|
||||
if (wsValue.length() < 6)
|
||||
return std::wstring();
|
||||
CColor::CColor()
|
||||
: CValue(NULL, 0, false), m_oOpacity(1.)
|
||||
{}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void CColor::SetEmpty(unsigned int unLevel)
|
||||
{
|
||||
m_oValue.Clear();
|
||||
m_oValue.m_enType = ColorEmpty;
|
||||
Clear();
|
||||
m_enType = ColorEmpty;
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = false;
|
||||
}
|
||||
|
||||
void CColor::SetRGB(unsigned char uchR, unsigned char uchG, unsigned char uchB)
|
||||
{
|
||||
Clear();
|
||||
|
||||
CColor::CColor()
|
||||
: CValue({}, 0, false), m_oOpacity(1.)
|
||||
{}
|
||||
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)
|
||||
{
|
||||
@ -513,21 +564,21 @@ namespace NSCSS
|
||||
|
||||
if (wsNewValue[0] == L'#')
|
||||
{
|
||||
m_oValue.SetHEX(wsNewValue.substr(1, wsNewValue.length() - 1));
|
||||
SetHEX(wsNewValue.substr(1, wsNewValue.length() - 1));
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
else if (L"none" == wsNewValue)
|
||||
{
|
||||
m_oValue.SetNone();
|
||||
SetNone();
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
else if (wsNewValue == L"transparent")
|
||||
{
|
||||
m_oValue.SetNone();
|
||||
SetNone();
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
@ -558,7 +609,7 @@ 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);
|
||||
@ -570,9 +621,9 @@ namespace NSCSS
|
||||
|
||||
if (5 <= wsNewValue.length())
|
||||
{
|
||||
m_oValue.SetUrl(CutURL(wsValue));
|
||||
SetUrl(wsValue);
|
||||
|
||||
if (m_oValue.m_enType == ColorUrl)
|
||||
if (m_enType == ColorUrl)
|
||||
{
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;;
|
||||
@ -583,7 +634,7 @@ namespace NSCSS
|
||||
const std::map<std::wstring, std::wstring>::const_iterator oHEX = NSConstValues::COLORS.find(wsNewValue);
|
||||
if (oHEX != NSConstValues::COLORS.end())
|
||||
{
|
||||
m_oValue.SetHEX(oHEX->second);
|
||||
SetHEX(oHEX->second);
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
@ -602,29 +653,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<TRGB*>(m_oValue);
|
||||
RELEASEOBJECT(pRGB);
|
||||
break;
|
||||
}
|
||||
case ColorHEX:
|
||||
{
|
||||
std::wstring* pValue = static_cast<std::wstring*>(m_oValue);
|
||||
RELEASEOBJECT(pValue);
|
||||
break;
|
||||
}
|
||||
case ColorUrl:
|
||||
{
|
||||
CURL *pURL = static_cast<CURL*>(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 +718,16 @@ namespace NSCSS
|
||||
|
||||
int CColor::ToInt() const
|
||||
{
|
||||
switch(m_oValue.m_enType)
|
||||
switch(m_enType)
|
||||
{
|
||||
case ColorRGB:
|
||||
{
|
||||
TRGB* pRGB = static_cast<TRGB*>(m_oValue.m_pColor);
|
||||
TRGB* pRGB = static_cast<TRGB*>(m_oValue);
|
||||
return RGB_TO_INT(pRGB->uchRed, pRGB->uchGreen, pRGB->uchBlue);
|
||||
}
|
||||
case ColorHEX:
|
||||
{
|
||||
std::wstring *pValue = static_cast<std::wstring*>(m_oValue.m_pColor);
|
||||
std::wstring *pValue = static_cast<std::wstring*>(m_oValue);
|
||||
TRGB oRGB = ConvertHEXtoRGB(*pValue);
|
||||
return RGB_TO_INT(oRGB.uchRed, oRGB.uchGreen, oRGB.uchBlue);
|
||||
}
|
||||
@ -668,10 +743,11 @@ namespace NSCSS
|
||||
|
||||
std::wstring CColor::ToWString() const
|
||||
{
|
||||
switch(m_oValue.m_enType)
|
||||
switch(m_enType)
|
||||
{
|
||||
case ColorRGB: return ConvertRGBtoHEX(*static_cast<TRGB*>(m_oValue.m_pColor));
|
||||
case ColorHEX: case ColorUrl: return *static_cast<std::wstring*>(m_oValue.m_pColor);
|
||||
case ColorRGB: return ConvertRGBtoHEX(*static_cast<TRGB*>(m_oValue));
|
||||
case ColorHEX: return *static_cast<std::wstring*>(m_oValue);
|
||||
case ColorUrl: return static_cast<CURL*>(m_oValue)->GetValue();
|
||||
default: return std::wstring();
|
||||
}
|
||||
}
|
||||
@ -683,10 +759,10 @@ namespace NSCSS
|
||||
|
||||
TRGB oCurrentColor;
|
||||
|
||||
switch(m_oValue.m_enType)
|
||||
switch(m_enType)
|
||||
{
|
||||
case ColorRGB: oCurrentColor = *static_cast<TRGB*>(m_oValue.m_pColor); break;
|
||||
case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast<std::wstring*>(m_oValue.m_pColor)); break;
|
||||
case ColorRGB: oCurrentColor = *static_cast<TRGB*>(m_oValue); break;
|
||||
case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast<std::wstring*>(m_oValue)); break;
|
||||
default: return L"none";
|
||||
}
|
||||
|
||||
@ -710,10 +786,10 @@ namespace NSCSS
|
||||
|
||||
TRGB CColor::ToRGB() const
|
||||
{
|
||||
switch(m_oValue.m_enType)
|
||||
switch(m_enType)
|
||||
{
|
||||
case ColorRGB: return *static_cast<TRGB*>(m_oValue.m_pColor);
|
||||
case ColorHEX: return ConvertHEXtoRGB(*static_cast<std::wstring*>(m_oValue.m_pColor));
|
||||
case ColorRGB: return *static_cast<TRGB*>(m_oValue);
|
||||
case ColorHEX: return ConvertHEXtoRGB(*static_cast<std::wstring*>(m_oValue));
|
||||
default: return TRGB();
|
||||
}
|
||||
}
|
||||
@ -2421,175 +2497,48 @@ 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<TRGB*>(oColorValue.m_pColor)); break;
|
||||
case ColorHEX: SetHEX(*static_cast<std::wstring*>(oColorValue.m_pColor)); break;
|
||||
case ColorUrl: SetUrl(*static_cast<std::wstring*>(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<TRGB*>(m_pColor) == *static_cast<TRGB*>(oColorValue.m_pColor);
|
||||
case ColorHEX:
|
||||
case ColorUrl:
|
||||
return *static_cast<std::wstring*>(m_pColor) == *static_cast<std::wstring*>(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;
|
||||
}
|
||||
|
||||
CColorValue &CColorValue::operator=(const CColorValue &oColorValue)
|
||||
|
||||
std::wstring CURL::GetValue() const
|
||||
{
|
||||
switch(oColorValue.m_enType)
|
||||
{
|
||||
case ColorRGB: SetRGB(*static_cast<TRGB*>(oColorValue.m_pColor)); break;
|
||||
case ColorHEX: SetHEX(*static_cast<std::wstring*>(oColorValue.m_pColor)); break;
|
||||
case ColorUrl: SetUrl(*static_cast<std::wstring*>(oColorValue.m_pColor)); break;
|
||||
default: m_enType = oColorValue.m_enType; break;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CColorValue::Clear()
|
||||
{
|
||||
switch (m_enType)
|
||||
{
|
||||
case ColorRGB:
|
||||
{
|
||||
TRGB *pRGB = static_cast<TRGB*>(m_pColor);
|
||||
RELEASEOBJECT(pRGB);
|
||||
break;
|
||||
}
|
||||
case ColorHEX: case ColorUrl:
|
||||
{
|
||||
std::wstring* pValue = static_cast<std::wstring*>(m_pColor);
|
||||
RELEASEOBJECT(pValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_enType = ColorEmpty;
|
||||
return 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 +2675,6 @@ namespace NSCSS
|
||||
{
|
||||
return m_oHeader;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ namespace NSCSS
|
||||
friend class CDigit;
|
||||
friend class CColor;
|
||||
friend class CEnum;
|
||||
friend class CURL;
|
||||
|
||||
T m_oValue;
|
||||
unsigned int m_unLevel;
|
||||
@ -180,6 +181,22 @@ namespace NSCSS
|
||||
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;
|
||||
private:
|
||||
std::wstring m_wsValue;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ColorEmpty,
|
||||
@ -189,39 +206,8 @@ namespace NSCSS
|
||||
ColorUrl
|
||||
} ColorType;
|
||||
|
||||
class Q_DECL_EXPORT CColorValue
|
||||
class CColor : public CValue<void*>
|
||||
{
|
||||
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<CColorValue>
|
||||
{
|
||||
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 +228,19 @@ namespace NSCSS
|
||||
std::wstring ToWString() const override;
|
||||
std::wstring EquateToColor(const std::vector<std::pair<TRGB, std::wstring>>& arColors) const;
|
||||
TRGB ToRGB() const;
|
||||
|
||||
static TRGB ConvertHEXtoRGB(const std::wstring& wsValue);
|
||||
static std::wstring ConvertRGBtoHEX(const TRGB& oValue);
|
||||
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
|
||||
|
||||
@ -116,6 +116,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
|
||||
@ -139,6 +140,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
|
||||
|
||||
|
||||
@ -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<std::wstring, std::wstring>& oValue){ return wsFontFamily == oValue.first; });
|
||||
|
||||
if (m_mFontsFace.cend() == itFound)
|
||||
return NULL;
|
||||
|
||||
return dynamic_cast<SVG::CFont*>(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())
|
||||
|
||||
@ -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<std::wstring, std::wstring> FontsFaceMap;
|
||||
FontsFaceMap m_mFontsFace;
|
||||
};
|
||||
|
||||
#endif // CSVGFILE_H
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
#include "CSvgFile.h"
|
||||
|
||||
#include "SvgObjects/CContainer.h"
|
||||
#include "SvgObjects/CPolyline.h"
|
||||
#include "SvgObjects/CGradient.h"
|
||||
#include "SvgObjects/CClipPath.h"
|
||||
@ -20,6 +19,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"
|
||||
@ -94,7 +94,7 @@ namespace SVG
|
||||
|
||||
if (L"style" == wsElementName)
|
||||
{
|
||||
pFile->AddStyles(oElement.GetText());
|
||||
ParseStyles(oElement.GetText(), pFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -115,6 +115,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<std::wstring> 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<std::wstring> 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 <class ObjectType>
|
||||
bool CSvgParser::ReadObject(XmlUtils::CXmlNode &oElement, CContainer<ObjectType> *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
|
||||
@ -223,6 +278,10 @@ namespace SVG
|
||||
else
|
||||
RELEASEOBJECT(pObject);
|
||||
}
|
||||
else if (L"font" == wsElementName)
|
||||
{
|
||||
pObject = new CFont(oElement);
|
||||
}
|
||||
|
||||
if (NULL != pObject)
|
||||
{
|
||||
|
||||
@ -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<ObjectType>* 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;
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#include "CObjectBase.h"
|
||||
|
||||
#include "../../../../graphics/pro/Fonts.h"
|
||||
|
||||
class CSvgFile;
|
||||
|
||||
namespace SVG
|
||||
|
||||
90
DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp
Normal file
90
DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#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];
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
CFont::~CFont()
|
||||
{
|
||||
for (std::pair<wchar_t, CGlyph*> oElement : m_mGlyphs)
|
||||
RELEASEOBJECT(oElement.second);
|
||||
|
||||
RELEASEOBJECT(m_pMissingGlyph);
|
||||
}
|
||||
|
||||
void CFont::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{
|
||||
}
|
||||
|
||||
bool CFont::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CFont::ParseGlyphs(XmlUtils::CXmlNode &oNode)
|
||||
{
|
||||
std::vector<XmlUtils::CXmlNode> 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<XmlUtils::CXmlNode> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h
Normal file
53
DesktopEditor/raster/Metafile/svg/SvgObjects/CFont.h
Normal file
@ -0,0 +1,53 @@
|
||||
#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;
|
||||
};
|
||||
|
||||
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<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
|
||||
|
||||
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
|
||||
private:
|
||||
void ParseGlyphs(XmlUtils::CXmlNode& oNode);
|
||||
|
||||
TFontArguments m_oArguments;
|
||||
|
||||
std::map<wchar_t, CGlyph*> m_mGlyphs;
|
||||
CPath *m_pMissingGlyph;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CFONT_H
|
||||
@ -2,6 +2,7 @@
|
||||
#define CPATTERN_H
|
||||
|
||||
#include "CContainer.h"
|
||||
#include "../../../../graphics/pro/Fonts.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define CSYMBOL_H
|
||||
|
||||
#include "CContainer.h"
|
||||
#include "../../../graphics/pro/Fonts.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
|
||||
@ -152,12 +152,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))
|
||||
{
|
||||
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 +295,24 @@ namespace SVG
|
||||
pRenderer->put_BrushColor1(m_oStyles.m_oFill.ToInt());
|
||||
pRenderer->put_BrushAlpha1(255);
|
||||
}
|
||||
|
||||
bool CTSpan::UseExternalFont(const CSvgFile *pFile) 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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TBounds CTSpan::GetBounds() const
|
||||
{
|
||||
|
||||
@ -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) const;
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
double GetWidth() const;
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user