Merge remote-tracking branch 'origin/release/v9.2.0' into develop

This commit is contained in:
Elena Subbotina
2025-11-11 10:21:53 +03:00
54 changed files with 568 additions and 227 deletions

View File

@ -68,6 +68,10 @@ namespace MetaFile
#ifdef METAFILE_SUPPORT_SVM
m_oSvmFile.SetFontManager(m_pFontManager);
#endif
#ifdef METAFILE_SUPPORT_SVG
m_oSvgFile.SetFontManager(m_pFontManager);
#endif
m_lType = 0;
}
@ -84,7 +88,6 @@ namespace MetaFile
std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight)
{
#ifdef METAFILE_SUPPORT_WMF_EMF
if (c_lMetaWmf == m_lType)
{

View File

@ -68,7 +68,13 @@ bool CSvgFile::MarkObject(SVG::CObject *pObject)
if (NULL == pObject || pObject->GetId().empty())
return false;
pObject->AddRef();
pObject->Mark();
const MarkedMap::const_iterator itFound = m_mMarkedObjects.find(pObject->GetId());
if (m_mMarkedObjects.cend() != itFound)
RELEASEINTERFACE(m_mMarkedObjects[pObject->GetId()])
m_mMarkedObjects[pObject->GetId()] = pObject;
return true;
@ -153,8 +159,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d
dTranslateY -= oViewBox.m_oY.ToDouble(NSCSS::Pixel) * dScaleY * dM22;
}
const double dMinScale = std::min(dScaleX, dScaleY);
pRenderer->SetTransform(dM11 * dMinScale, 0, 0, dM22 * dMinScale, dTranslateX, dTranslateY);
pRenderer->SetTransform(dM11 * dScaleX, 0, 0, dM22 * dScaleY, dTranslateX, dTranslateY);
bool bResult = m_pContainer->Draw(pRenderer, this);
@ -165,7 +170,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d
void CSvgFile::Clear()
{
RELEASEOBJECT(m_pContainer);
RELEASEINTERFACE(m_pContainer);
m_oSvgCalculator.Clear();
for (MarkedMap::reference oIter : m_mMarkedObjects)

View File

@ -117,7 +117,7 @@ namespace SVG
ScanStyles(oReader, pFile);
oReader.MoveToStart();
RELEASEOBJECT(pContainer);
RELEASEINTERFACE(pContainer);
pContainer = CObject::Create<CGraphicsContainer>(oReader, pFile);
@ -224,7 +224,7 @@ namespace SVG
pObject = CObject::Create<CGraphicsContainer>(oReader, pFile, pParent);
if (!ReadChildrens(oReader, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
{
RELEASEOBJECT(pObject);
RELEASEINTERFACE(pObject);
return false;
}
}
@ -290,21 +290,21 @@ namespace SVG
if (ReadChildrens(oReader, (CSymbol*)pObject, pFile))
return true;
else
RELEASEOBJECT(pObject);
RELEASEINTERFACE(pObject);
}
else if ("font" == sElementName)
{
pObject = CObject::Create<CFont>(oReader, pFile);
pObject = CObject::Create<CFont>(oReader, pFile, pFile);
}
if (NULL == pObject)
return false;
if ((RendererObject == pObject->GetType() && AddObject((ObjectType*)pObject, pContainer)) ||
if ((RendererObject == pObject->GetType() && (AddObject((ObjectType*)pObject, pContainer) || pObject->Marked())) ||
AppliedObject == pObject->GetType())
return true;
RELEASEOBJECT(pObject);
RELEASEINTERFACE(pObject);
return false;
}

View File

@ -2,22 +2,23 @@
namespace SVG
{
CGlyph::CGlyph(CSvgReader& oReader)
CGlyph::CGlyph(CSvgReader& oReader, CSvgFile* pFile)
: CPath(oReader)
{
START_READ_ATTRIBUTES(oReader)
{
if ("unicode" == sAttributeName)
{
const std::wstring wsUnicode{oReader.GetText()};
{}
if (!wsUnicode.empty())
m_wchUnicode = wsUnicode[0];
}
else if ("horiz-adv-x" == sAttributeName)
m_oHorizAdvX.SetValue(oReader.GetText());
void CGlyph::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("unicode" == sName)
{
const std::wstring wsUnicode{oReader.GetText()};
if (!wsUnicode.empty())
m_wchUnicode = wsUnicode[0];
}
END_READ_ATTRIBUTES(oReader)
else if ("horiz-adv-x" == sName)
m_oHorizAdvX.SetValue(oReader.GetText());
else
CPath::SetAttribute(sName, oReader);
}
wchar_t CGlyph::GetUnicode() const
@ -28,10 +29,10 @@ namespace SVG
CFontFace::CFontFace(CSvgReader& oReader)
{}
CFont::CFont(CSvgReader& oReader)
CFont::CFont(CSvgReader& oReader, CSvgFile* pFile)
: CAppliedObject(oReader), m_pMissingGlyph(NULL)
{
ParseGlyphs(oReader);
ParseGlyphs(oReader, pFile);
}
CFont::~CFont()
@ -95,7 +96,7 @@ namespace SVG
{ \
oMatrix.Scale(1. / dGlyphScale, -1. / dGlyphScale); \
pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \
} \
}
for (wchar_t wchGlyph : wsText)
{
@ -128,13 +129,13 @@ namespace SVG
return true;
}
void CFont::ParseGlyphs(CSvgReader& oReader)
void CFont::ParseGlyphs(CSvgReader& oReader, CSvgFile* pFile)
{
WHILE_READ_NEXT_NODE_WITH_NAME(oReader)
{
if ("glyph" == sNodeName)
{
CGlyph *pGlyph = new CGlyph(oReader);
CGlyph *pGlyph = CObject::Create<CGlyph>(oReader, pFile, pFile);
if (NULL == pGlyph)
continue;

View File

@ -8,7 +8,9 @@ namespace SVG
class CGlyph : public CPath
{
public:
CGlyph(CSvgReader& oReader);
CGlyph(CSvgReader& oReader, CSvgFile* pFile = nullptr);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
wchar_t GetUnicode() const;
private:
@ -37,7 +39,7 @@ namespace SVG
class CFont : public CAppliedObject
{
friend class CObject;
CFont(CSvgReader& oReader);
CFont(CSvgReader& oReader, CSvgFile* pFile = nullptr);
public:
~CFont();
@ -48,7 +50,7 @@ namespace SVG
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
bool Draw(const std::wstring& wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
private:
void ParseGlyphs(CSvgReader& oReader);
void ParseGlyphs(CSvgReader& oReader, CSvgFile* pFile = nullptr);
TFontArguments m_oArguments;

View File

@ -9,7 +9,7 @@ namespace SVG
ObjectType CStopElement::GetType() const
{
return AppliedObject;
return DataObject;
}
SvgDigit CStopElement::GetOffset() const
@ -62,16 +62,7 @@ namespace SVG
return;
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, "stop")
{
CStopElement *pStopElement = new CStopElement(oReader);
if (NULL == pStopElement)
continue;
pSvgFile->GetSvgCalculator()->SetData(pStopElement);
AddObject(pStopElement);
}
AddObject(CObject::Create<CStopElement>(oReader, pSvgFile));
END_WHILE
}

View File

@ -42,6 +42,18 @@ namespace SVG
: m_oXmlNode(oObject.m_oXmlNode), m_oTransformation(oObject.m_oTransformation)
{}
void CObject::Mark()
{
this->AddRef();
}
bool CObject::Marked() const
{
//Так как по логике кода объект может храниться только в одном контейнере и в списке маркированных элементов,
//то хватит и такой проверки
return 1 != m_lRef;
}
void CObject::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("class" == sName)

View File

@ -34,7 +34,8 @@ namespace SVG
enum ObjectType
{
RendererObject,
AppliedObject
AppliedObject,
DataObject
};
class CObject : public IGrObject
@ -48,6 +49,9 @@ namespace SVG
virtual ObjectType GetType() const = 0;
void Mark();
bool Marked() const;
virtual void SetAttribute(const std::string& sName, CSvgReader& oReader);
void SetData(const std::wstring wsStyles, unsigned short ushLevel, bool bHardMode = false);
@ -92,7 +96,8 @@ namespace SVG
if (NULL == pSvgFile)
return pObject;
if (!pSvgFile->MarkObject(pObject) && AppliedObject == pObject->GetType())
if (DataObject != pObject->GetType() &&
(!pSvgFile->MarkObject(pObject) && AppliedObject == pObject->GetType()))
{
delete pObject;
return NULL;

View File

@ -32,7 +32,7 @@ namespace SVG
const std::vector<NSCSS::CNode> arSelectors = pSvgObject->GetFullPath();
std::vector<std::wstring> arNodes = m_pInternal->CalculateAllNodes(arSelectors);
std::vector<std::wstring> arNodes = m_pInternal->CalculateAllNodes(arSelectors, 0, arSelectors.size());
std::vector<std::wstring> arPrevNodes;
for (size_t i = 0; i < arSelectors.size(); ++i)

View File

@ -9,6 +9,8 @@
#include "../../../../Common/3dParty/html/css/src/StaticFunctions.h"
#include <cctype>
#ifndef MININT8
#define MAXUINT8 ((unsigned char)~((unsigned char)0))
#define MAXINT8 ((char)(MAXUINT8 >> 1))
@ -136,7 +138,7 @@ namespace SVG
const char* pCheckValue = pValue;
while ('\0' != *pCheckValue)
{
if (0x32 >= *pCheckValue++)
if (std::isprint(static_cast<unsigned char>(*pCheckValue++)))
{
bFoundedSymbol = true;
break;
@ -161,9 +163,9 @@ namespace SVG
else if (eNodeType == XmlUtils::XmlNodeType_Element && "tspan" == oReader.GetName())
{
const TBounds oBounds{GetBounds()};
const Point oPoint{oBounds.m_dRight, oBounds.m_dTop};
const Point oPoint{oBounds.m_dRight, oBounds.m_dBottom};
AddObject(CRenderedObject::Create<CTSpan>(oReader, pSvgFile, this, m_pFontManager, oPoint));
AddObject(CObject::Create<CTSpan>(oReader, pSvgFile, this, m_pFontManager, oPoint));
}
}
}
@ -185,8 +187,14 @@ namespace SVG
{
if (!m_wsText.empty())
{
ApplyFont(pRenderer, dX, dY);
Aggplus::CMatrix oCurrentMatrix;
ApplyFont(pRenderer, dX, dY, oCurrentMatrix);
pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0);
pRenderer->SetTransform(oCurrentMatrix.sx(), oCurrentMatrix.shy(),
oCurrentMatrix.shx(), oCurrentMatrix.sy(),
oCurrentMatrix.tx(), oCurrentMatrix.ty());
}
}
@ -228,12 +236,12 @@ namespace SVG
nTypePath += c_nWindingFillMode;
}
void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const
void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY, Aggplus::CMatrix& oOldMatrix) const
{
std::wstring wsFontFamily = DefaultFontFamily;
double dFontSize = ((!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE) * 72. / 25.4;
Normalize(pRenderer, dX, dY, dFontSize);
Normalize(pRenderer, dX, dY, dFontSize, oOldMatrix);
if (!m_oFont.GetFamily().Empty())
{
@ -327,7 +335,7 @@ namespace SVG
pRenderer->put_FontStyle(nStyle);
pRenderer->put_BrushType(c_BrushTypeSolid);
pRenderer->put_BrushColor1(m_oStyles.m_oFill.ToInt());
pRenderer->put_BrushAlpha1(255);
pRenderer->put_BrushAlpha1(255 * m_oStyles.m_oFill.GetOpacity());
}
void CTSpan::UpdateFontSize()
@ -338,7 +346,7 @@ namespace SVG
if (NULL != pParentTSpan)
{
m_oFont.UpdateSize((!pParentTSpan->m_oFont.GetSize().Empty()) ? pParentTSpan->m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
m_oFont.UpdateSize((!pParentTSpan->m_oFont.GetSize().Empty()) ? pParentTSpan->m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
return;
}
}
@ -476,7 +484,7 @@ namespace SVG
dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop);
}
void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight) const
void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight, Aggplus::CMatrix& oOldMatrix) const
{
if (NULL == pRenderer)
return;
@ -519,6 +527,8 @@ namespace SVG
pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);
oOldMatrix.SetElements(dM11, dM12, dM21, dM22, dDx, dDy);
Aggplus::CMatrix oMatrix(dM11, dM12, dM21, dM22, dDx, dDy);
oMatrix.Scale(dXScale, dYScale);

View File

@ -32,7 +32,7 @@ namespace SVG
void InheritStyles(const CTSpan* pTSpan);
private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
void ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const;
void ApplyFont(IRenderer* pRenderer, double& dX, double& dY, Aggplus::CMatrix& oOldMatrix) const;
void UpdateFontSize();
bool UseExternalFont(const CSvgFile* pFile, double dX, double dY, IRenderer* pRenderer, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
@ -44,7 +44,7 @@ namespace SVG
void CalculatePosition(double& dX, double& dY) const;
void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight) const;
void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight, Aggplus::CMatrix& oOldMatrix) const;
void SetPosition(const Point& oPosition);
void SetPositionFromParent(CRenderedObject* pParent);