Redesigned bounds calculation in svg and refactoring

This commit is contained in:
Kirill Polyakov
2025-10-26 20:53:31 +03:00
parent 7156669830
commit df49a4fbde
27 changed files with 359 additions and 181 deletions

View File

@ -1326,6 +1326,23 @@ namespace NSCSS
return true; return true;
} }
CMatrix& CMatrix::operator+=(const CMatrix& oMatrix)
{
m_oValue.insert(m_oValue.end(), oMatrix.m_oValue.begin(), oMatrix.m_oValue.end());
return *this;
}
CMatrix& CMatrix::operator-=(const CMatrix& oMatrix)
{
for (MatrixValues::const_reverse_iterator itElement = oMatrix.m_oValue.crbegin(); itElement < oMatrix.m_oValue.crend(); ++itElement)
{
if (!m_oValue.empty() && m_oValue.back() == *itElement)
m_oValue.pop_back();
}
return *this;
}
// DISPLAY // DISPLAY
CDisplay::CDisplay() CDisplay::CDisplay()
{ {

View File

@ -302,6 +302,8 @@ namespace NSCSS
void ApplyTranform(Aggplus::CMatrix& oMatrix, Aggplus::MatrixOrder order = Aggplus::MatrixOrderPrepend) const; void ApplyTranform(Aggplus::CMatrix& oMatrix, Aggplus::MatrixOrder order = Aggplus::MatrixOrderPrepend) const;
bool operator==(const CMatrix& oMatrix) const; bool operator==(const CMatrix& oMatrix) const;
CMatrix& operator+=(const CMatrix& oMatrix);
CMatrix& operator-=(const CMatrix& oMatrix);
}; };
class CEnum : public CValue<int> class CEnum : public CValue<int>

View File

@ -45,53 +45,7 @@ bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight) const bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight) const
{ {
if (NULL == m_pContainer || m_pContainer->Empty()) return CalculateFinalSize(true, dX, dY, dWidth, dHeight);
return false;
SVG::TRect oWindow = m_pContainer->GetWindow();
dX = oWindow.m_oX.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
dY = oWindow.m_oY.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
dWidth = 0.;
dHeight = 0.;
if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero())
{
if (NSCSS::Percent == oWindow.m_oWidth.GetUnitMeasure())
{
if (!m_pContainer->GetViewBox().m_oWidth.Empty() && !m_pContainer->GetViewBox().m_oWidth.Zero())
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_pContainer->GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel));
else
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
}
else
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel);
}
else
dWidth = m_pContainer->GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel);
if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero())
{
if (NSCSS::Percent == oWindow.m_oHeight.GetUnitMeasure())
{
if (!m_pContainer->GetViewBox().m_oHeight.Empty() && !m_pContainer->GetViewBox().m_oHeight.Zero())
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_pContainer->GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel));
else
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
}
else
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
}
else
dHeight = m_pContainer->GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel);
if (DBL_EPSILON > dWidth)
dWidth = SVG_FILE_WIDTH;
if (DBL_EPSILON > dHeight)
dHeight = SVG_FILE_HEIGHT;
return true;
} }
const SVG::CSvgCalculator *CSvgFile::GetSvgCalculator() const const SVG::CSvgCalculator *CSvgFile::GetSvgCalculator() const
@ -170,64 +124,37 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d
if (NULL == pRenderer || NULL == m_pContainer || m_pContainer->Empty()) if (NULL == pRenderer || NULL == m_pContainer || m_pContainer->Empty())
return false; return false;
SVG::TRect oWindow = m_pContainer->GetWindow(); double dFileX, dFileY, dFileWidth, dFileHeight;
SVG::TRect oViewBox = m_pContainer->GetViewBox();
if (oWindow.m_oWidth.Empty() || oWindow.m_oWidth.Zero()) if (!CalculateFinalSize(false, dFileX, dFileY, dFileWidth, dFileHeight))
{
if (oViewBox.m_oWidth.Empty() || oViewBox.m_oWidth.Zero())
oWindow.m_oWidth = SVG_FILE_WIDTH;
else
{
oWindow.m_oWidth = oViewBox.m_oWidth;
oViewBox.m_oWidth.Clear();
}
}
if (oWindow.m_oHeight.Empty() || oWindow.m_oHeight.Zero())
{
if (oViewBox.m_oHeight.Empty() || oViewBox.m_oHeight.Zero())
oWindow.m_oHeight = SVG_FILE_HEIGHT;
else
{
oWindow.m_oHeight = oViewBox.m_oHeight;
oViewBox.m_oHeight.Clear();
}
}
double dViewBoxWidth = oViewBox.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
double dViewBoxHeight = oViewBox.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
double dWindowWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, dViewBoxWidth);
double dWindowHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, dViewBoxHeight);
if (SVG::Equals(0., dWindowWidth) || SVG::Equals(0., dWindowHeight))
return false; return false;
double oldTransform[6]; double oldTransform[6];
oldTransform[0] = oldTransform[3] = 1;
oldTransform[1] = oldTransform[2] = oldTransform[4] = oldTransform[5] = 0;
pRenderer->GetTransform(&oldTransform[0], &oldTransform[1], &oldTransform[2], &oldTransform[3], &oldTransform[4], &oldTransform[5]); pRenderer->GetTransform(&oldTransform[0], &oldTransform[1], &oldTransform[2], &oldTransform[3], &oldTransform[4], &oldTransform[5]);
pRenderer->ResetTransform(); pRenderer->ResetTransform();
double dM11 = dWidth / dWindowWidth; const double dM11 = dWidth / dFileWidth;
double dM22 = dHeight / dWindowHeight; const double dM22 = dHeight / dFileHeight;
double dScaleX = 1, dScaleY = 1; double dScaleX = 1.,
dScaleY = 1.;
double dTranslateX = dFileX * dM11,
dTranslateY = dFileY * dM22;
if (!SVG::Equals(0., dViewBoxWidth)) const SVG::TRect oViewBox{m_pContainer->GetViewBox()};
dScaleX = dWindowWidth / dViewBoxWidth;
if (!SVG::Equals(0., dViewBoxHeight)) if (!oViewBox.m_oWidth.Empty() && !oViewBox.m_oHeight.Empty())
dScaleY = dWindowHeight / dViewBoxHeight; {
dScaleX = dFileWidth / oViewBox.m_oWidth .ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH );
dScaleY = dFileHeight / oViewBox.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
double dMinScale = std::min(dScaleX, dScaleY); dTranslateX -= oViewBox.m_oX.ToDouble(NSCSS::Pixel) * dScaleX * dM11;
dTranslateY -= oViewBox.m_oY.ToDouble(NSCSS::Pixel) * dScaleY * dM22;
}
double dSkipX = -oViewBox.m_oX.ToDouble(NSCSS::Pixel) * dScaleX * dM11; const double dMinScale = std::min(dScaleX, dScaleY);
double dSkipY = -oViewBox.m_oY.ToDouble(NSCSS::Pixel) * dScaleY * dM22; pRenderer->SetTransform(dM11 * dMinScale, 0, 0, dM22 * dMinScale, dTranslateX, dTranslateY);
pRenderer->SetTransform(dM11 * dMinScale, 0, 0, dM22 * dMinScale, dSkipX, dSkipY);
bool bResult = m_pContainer->Draw(pRenderer, this); bool bResult = m_pContainer->Draw(pRenderer, this);
@ -247,3 +174,141 @@ void CSvgFile::Clear()
m_mMarkedObjects.clear(); m_mMarkedObjects.clear();
m_wsWorkingDirectory.clear(); m_wsWorkingDirectory.clear();
} }
bool CSvgFile::CalculateFinalSize(bool bUseViewBox, double& dX, double& dY, double& dWidth, double& dHeight) const
{
if (NULL == m_pContainer || m_pContainer->Empty())
return false;
const SVG::TRect oWindow = m_pContainer->GetWindow();
const SVG::TRect oViewBox = m_pContainer->GetViewBox();
const double dViewBoxWidth {oViewBox.m_oWidth .ToDouble()};
const double dViewBoxHeigth{oViewBox.m_oHeight.ToDouble()};
dX = 0.;
dY = 0.;
dWidth = 0.;
dHeight = 0.;
#define GET_PREV_WIDTH_VALUE ((NSCSS::UnitMeasure::Em == oWindow.m_oWidth.GetUnitMeasure() || NSCSS::UnitMeasure::Rem == oWindow.m_oWidth.GetUnitMeasure()) ? DEFAULT_FONT_SIZE : ((!SVG::Equals(0., dViewBoxWidth )) ? dViewBoxWidth : SVG_FILE_WIDTH))
#define GET_PREV_HEIGHT_VALUE ((NSCSS::UnitMeasure::Em == oWindow.m_oHeight.GetUnitMeasure() || NSCSS::UnitMeasure::Rem == oWindow.m_oHeight.GetUnitMeasure()) ? DEFAULT_FONT_SIZE : ((!SVG::Equals(0., dViewBoxHeigth )) ? dViewBoxHeigth : SVG_FILE_HEIGHT))
if (!oWindow.m_oWidth.Empty() && !oWindow.m_oHeight.Empty())
{
dWidth = oWindow.m_oWidth .ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
return true;
}
if (bUseViewBox)
{
if (!oViewBox.m_oWidth.Empty() && !oViewBox.m_oHeight.Empty())
{
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
const double dAspectRatio{dViewBoxWidth / dViewBoxHeigth};
dHeight = dWidth / dAspectRatio;
return true;
}
if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
const double dAspectRatio{dViewBoxWidth / dViewBoxHeigth};
dWidth = dHeight * dAspectRatio;
return true;
}
dX = oViewBox.m_oX.ToDouble();
dY = oViewBox.m_oY.ToDouble();
dWidth = dViewBoxWidth;
dHeight = dViewBoxHeigth;
return true;
}
}
if (!oWindow.m_oWidth.Empty() || !oWindow.m_oHeight.Empty())
{
if (!oViewBox.m_oWidth.Empty() && !oViewBox.m_oHeight.Empty())
{
const double dAspectRatio{dViewBoxWidth / dViewBoxHeigth};
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = dWidth / dAspectRatio;
}
else if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
dWidth = dHeight * dAspectRatio;
}
return true;
}
if (NULL != m_pContainer && !m_pContainer->Empty())
{
SVG::SvgMatrix oTransform;
const SVG::TBounds oBounds{m_pContainer->GetBounds(&oTransform)};
const double dContentWidth {oBounds.m_dRight - oBounds.m_dLeft};
const double dContentHeight{oBounds.m_dBottom - oBounds.m_dTop };
const double dAspectRatio{dContentWidth / dContentHeight};
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = dWidth / dAspectRatio;
}
else if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
dWidth = dHeight * dAspectRatio;
}
dX = oBounds.m_dLeft;
dY = oBounds.m_dTop;
return true;
}
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = SVG_FILE_HEIGHT;
}
else if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
dWidth = SVG_FILE_WIDTH;
}
return true;
}
if (NULL != m_pContainer && !m_pContainer->Empty())
{
SVG::SvgMatrix oTransform;
const SVG::TBounds oBounds{m_pContainer->GetBounds(&oTransform)};
dX = oBounds.m_dLeft;
dY = oBounds.m_dTop;
dWidth = oBounds.m_dRight - oBounds.m_dLeft;
dHeight = oBounds.m_dBottom - oBounds.m_dTop;
return true;
}
dWidth = SVG_FILE_WIDTH;
dHeight = SVG_FILE_HEIGHT;
return true;
}

View File

@ -43,6 +43,8 @@ class CSvgFile
private: private:
void Clear(); void Clear();
bool CalculateFinalSize(bool bUseViewBox, double& dX, double& dY, double& dWidth, double& dHeight) const;
SVG::CGraphicsContainer *m_pContainer; SVG::CGraphicsContainer *m_pContainer;
SVG::CSvgCalculator m_oSvgCalculator; SVG::CSvgCalculator m_oSvgCalculator;
NSFonts::IFontManager *m_pFontManager; NSFonts::IFontManager *m_pFontManager;

View File

@ -15,11 +15,11 @@ namespace SVG
void CCircle::SetAttribute(const std::string& sName, CSvgReader& oReader) void CCircle::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("cx" == sName) if ("cx" == sName)
m_oCx.SetValue(oReader.GetDouble()); m_oCx.SetValue(oReader.GetText());
else if ("cy" == sName) else if ("cy" == sName)
m_oCy.SetValue(oReader.GetDouble()); m_oCy.SetValue(oReader.GetText());
else if ("r" == sName) else if ("r" == sName)
m_oR.SetValue(oReader.GetDouble()); m_oR.SetValue(oReader.GetText());
else else
CRenderedObject::SetAttribute(sName, oReader); CRenderedObject::SetAttribute(sName, oReader);
} }
@ -62,7 +62,7 @@ namespace SVG
nTypePath += c_nWindingFillMode; nTypePath += c_nWindingFillMode;
} }
TBounds CCircle::GetBounds() const TBounds CCircle::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds; TBounds oBounds;
@ -71,6 +71,16 @@ namespace SVG
oBounds.m_dRight = (m_oCx + m_oR).ToDouble(NSCSS::Pixel); oBounds.m_dRight = (m_oCx + m_oR).ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = (m_oCy + m_oR).ToDouble(NSCSS::Pixel); oBounds.m_dBottom = (m_oCy + m_oR).ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds; return oBounds;
} }

View File

@ -18,7 +18,7 @@ namespace SVG
private: private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
SvgDigit m_oCx; SvgDigit m_oCx;
SvgDigit m_oCy; SvgDigit m_oCy;

View File

@ -12,13 +12,13 @@ namespace SVG
void CGraphicsContainer::SetAttribute(const std::string& sName, CSvgReader& oReader) void CGraphicsContainer::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("x" == sName) if ("x" == sName)
m_oWindow.m_oX.SetValue(oReader.GetDouble()); m_oWindow.m_oX.SetValue(oReader.GetText());
else if ("y" == sName) else if ("y" == sName)
m_oWindow.m_oY.SetValue(oReader.GetDouble()); m_oWindow.m_oY.SetValue(oReader.GetText());
else if ("width" == sName) else if ("width" == sName)
m_oWindow.m_oWidth.SetValue(oReader.GetDouble()); m_oWindow.m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName) else if ("height" == sName)
m_oWindow.m_oHeight.SetValue(oReader.GetDouble()); m_oWindow.m_oHeight.SetValue(oReader.GetText());
else if ("viewBox" == sName) else if ("viewBox" == sName)
{ {
const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())}; const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())};
@ -56,13 +56,10 @@ namespace SVG
TRect CGraphicsContainer::GetViewBox() const TRect CGraphicsContainer::GetViewBox() const
{ {
if (m_oViewBox.m_oWidth.Empty() || m_oViewBox.m_oHeight.Empty())
return m_oWindow;
return m_oViewBox; return m_oViewBox;
} }
TBounds CGraphicsContainer::GetBounds() const TBounds CGraphicsContainer::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds, oTempBounds; TBounds oBounds, oTempBounds;
@ -71,15 +68,21 @@ namespace SVG
oBounds.m_dRight += m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel); oBounds.m_dRight += m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom += m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel); oBounds.m_dBottom += m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
for (const CRenderedObject* pObject : m_arObjects) for (const CRenderedObject* pObject : m_arObjects)
{ {
oTempBounds = pObject->GetBounds(); oTempBounds = pObject->GetBounds(pTransform);
oBounds.m_dLeft = std::min(oBounds.m_dLeft, oTempBounds.m_dLeft); oBounds.m_dLeft = std::min(oBounds.m_dLeft, oTempBounds.m_dLeft);
oBounds.m_dTop = std::min(oBounds.m_dTop, oTempBounds.m_dTop); oBounds.m_dTop = std::min(oBounds.m_dTop, oTempBounds.m_dTop);
oBounds.m_dRight = std::max(oBounds.m_dRight, oTempBounds.m_dRight); oBounds.m_dRight = std::max(oBounds.m_dRight, oTempBounds.m_dRight);
oBounds.m_dBottom = std::max(oBounds.m_dBottom, oTempBounds.m_dBottom); oBounds.m_dBottom = std::max(oBounds.m_dBottom, oTempBounds.m_dBottom);
} }
if (nullptr != pTransform)
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
return oBounds; return oBounds;
} }

View File

@ -89,8 +89,8 @@ namespace SVG
TRect GetWindow() const; TRect GetWindow() const;
TRect GetViewBox() const; TRect GetViewBox() const;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
private: private:
TBounds GetBounds() const override;
friend class CPattern; friend class CPattern;
friend class CMarker; friend class CMarker;

View File

@ -19,13 +19,13 @@ namespace SVG
void CEllipse::SetAttribute(const std::string& sName, CSvgReader& oReader) void CEllipse::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("cx" == sName) if ("cx" == sName)
m_oCx.SetValue(oReader.GetDouble()); m_oCx.SetValue(oReader.GetText());
else if ("cy" == sName) else if ("cy" == sName)
m_oCy.SetValue(oReader.GetDouble()); m_oCy.SetValue(oReader.GetText());
else if ("rx" == sName) else if ("rx" == sName)
m_oRx.SetValue(oReader.GetDouble()); m_oRx.SetValue(oReader.GetText());
else if ("ry" == sName) else if ("ry" == sName)
m_oRy.SetValue(oReader.GetDouble()); m_oRy.SetValue(oReader.GetText());
else else
CRenderedObject::SetAttribute(sName, oReader); CRenderedObject::SetAttribute(sName, oReader);
} }
@ -64,7 +64,7 @@ namespace SVG
nTypePath += c_nWindingFillMode; nTypePath += c_nWindingFillMode;
} }
TBounds CEllipse::GetBounds() const TBounds CEllipse::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds; TBounds oBounds;
@ -73,6 +73,16 @@ namespace SVG
oBounds.m_dRight = oBounds.m_dLeft + m_oRx.ToDouble(NSCSS::Pixel); oBounds.m_dRight = oBounds.m_dLeft + m_oRx.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = oBounds.m_dTop + m_oRy.ToDouble(NSCSS::Pixel);; oBounds.m_dBottom = oBounds.m_dTop + m_oRy.ToDouble(NSCSS::Pixel);;
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds; return oBounds;
} }
} }

View File

@ -18,7 +18,7 @@ namespace SVG
private: private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
SvgDigit m_oCx; SvgDigit m_oCx;
SvgDigit m_oCy; SvgDigit m_oCy;

View File

@ -51,7 +51,7 @@ namespace SVG
else if ("font-weight" == sName) else if ("font-weight" == sName)
m_oArguments.m_wsFontWidght = oReader.GetText(); m_oArguments.m_wsFontWidght = oReader.GetText();
else if ("horiz-adv-x" == sName) else if ("horiz-adv-x" == sName)
m_oHorizAdvX.SetValue(oReader.GetDouble()); m_oHorizAdvX.SetValue(oReader.GetText());
else else
CAppliedObject::SetAttribute(sName, oReader); CAppliedObject::SetAttribute(sName, oReader);
} }

View File

@ -149,13 +149,13 @@ namespace SVG
void CLinearGradient::SetAttribute(const std::string& sName, CSvgReader& oReader) void CLinearGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("x1" == sName) if ("x1" == sName)
m_oX1.SetValue(oReader.GetDouble()); m_oX1.SetValue(oReader.GetText());
else if ("y1" == sName) else if ("y1" == sName)
m_oY1.SetValue(oReader.GetDouble()); m_oY1.SetValue(oReader.GetText());
else if ("x2" == sName) else if ("x2" == sName)
m_oX2.SetValue(oReader.GetDouble()); m_oX2.SetValue(oReader.GetText());
else if ("y2" == sName) else if ("y2" == sName)
m_oY2.SetValue(oReader.GetDouble()); m_oY2.SetValue(oReader.GetText());
else else
CGradient::SetAttribute(sName, oReader); CGradient::SetAttribute(sName, oReader);
} }
@ -210,11 +210,11 @@ namespace SVG
void CRadialGradient::SetAttribute(const std::string& sName, CSvgReader& oReader) void CRadialGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("cx" == sName) if ("cx" == sName)
m_oCx.SetValue(oReader.GetDouble()); m_oCx.SetValue(oReader.GetText());
else if ("cy" == sName) else if ("cy" == sName)
m_oCy.SetValue(oReader.GetDouble()); m_oCy.SetValue(oReader.GetText());
else if ("r" == sName) else if ("r" == sName)
m_oR.SetValue(oReader.GetDouble()); m_oR.SetValue(oReader.GetText());
else else
CGradient::SetAttribute(sName, oReader); CGradient::SetAttribute(sName, oReader);
} }

View File

@ -17,13 +17,13 @@ namespace SVG
void CImage::SetAttribute(const std::string& sName, CSvgReader& oReader) void CImage::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("x" == sName) if ("x" == sName)
m_oRect.m_oX.SetValue(oReader.GetDouble()); m_oRect.m_oX.SetValue(oReader.GetText());
else if ("y" == sName) else if ("y" == sName)
m_oRect.m_oY.SetValue(oReader.GetDouble()); m_oRect.m_oY.SetValue(oReader.GetText());
else if ("width" == sName) else if ("width" == sName)
m_oRect.m_oWidth.SetValue(oReader.GetDouble()); m_oRect.m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName) else if ("height" == sName)
m_oRect.m_oHeight.SetValue(oReader.GetDouble()); m_oRect.m_oHeight.SetValue(oReader.GetText());
else if ("href" == sName || "xlink:href" == sName) else if ("href" == sName || "xlink:href" == sName)
m_wsHref = oReader.GetText(); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок m_wsHref = oReader.GetText(); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
else else
@ -135,7 +135,7 @@ namespace SVG
return true; return true;
} }
TBounds CImage::GetBounds() const TBounds CImage::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds; TBounds oBounds;
@ -144,6 +144,16 @@ namespace SVG
oBounds.m_dRight = oBounds.m_dLeft + m_oRect.m_oWidth.ToDouble(NSCSS::Pixel); oBounds.m_dRight = oBounds.m_dLeft + m_oRect.m_oWidth.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = oBounds.m_dTop + m_oRect.m_oHeight.ToDouble(NSCSS::Pixel); oBounds.m_dBottom = oBounds.m_dTop + m_oRect.m_oHeight.ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds; return oBounds;
} }
} }

View File

@ -14,7 +14,7 @@ namespace SVG
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private: private:
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
TRect m_oRect; TRect m_oRect;
std::wstring m_wsHref; std::wstring m_wsHref;

View File

@ -20,13 +20,13 @@ namespace SVG
void CMarker::SetAttribute(const std::string& sName, CSvgReader& oReader) void CMarker::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("refX" == sName) if ("refX" == sName)
m_oWindow.m_oX.SetValue(oReader.GetDouble()); m_oWindow.m_oX.SetValue(oReader.GetText());
else if ("refY" == sName) else if ("refY" == sName)
m_oWindow.m_oY.SetValue(oReader.GetDouble()); m_oWindow.m_oY.SetValue(oReader.GetText());
else if ("markerWidth" == sName) else if ("markerWidth" == sName)
m_oWindow.m_oWidth.SetValue(oReader.GetDouble()); m_oWindow.m_oWidth.SetValue(oReader.GetText());
else if ("markerHeight" == sName) else if ("markerHeight" == sName)
m_oWindow.m_oHeight.SetValue(oReader.GetDouble()); m_oWindow.m_oHeight.SetValue(oReader.GetText());
else if ("viewBox" == sName) else if ("viewBox" == sName)
{ {
const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())}; const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())};

View File

@ -133,7 +133,7 @@ namespace SVG
virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContextObject = NULL) const = 0; virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContextObject = NULL) const = 0;
virtual TBounds GetBounds() const = 0; virtual TBounds GetBounds(SvgMatrix* pTransform = nullptr) const = 0;
std::vector<NSCSS::CNode> GetFullPath() const override; std::vector<NSCSS::CNode> GetFullPath() const override;
private: private:

View File

@ -703,7 +703,7 @@ namespace SVG
} }
} }
TBounds CPath::GetBounds() const TBounds CPath::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}, oTempBounds; TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}, oTempBounds;
@ -717,6 +717,16 @@ namespace SVG
oBounds.m_dBottom = std::max(oBounds.m_dBottom, oTempBounds.m_dBottom); oBounds.m_dBottom = std::max(oBounds.m_dBottom, oTempBounds.m_dBottom);
} }
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds; return oBounds;
} }

View File

@ -129,7 +129,7 @@ namespace SVG
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const; bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const; const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const;

View File

@ -14,17 +14,17 @@ namespace SVG
void CRect::SetAttribute(const std::string& sName, CSvgReader& oReader) void CRect::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("x" == sName) if ("x" == sName)
m_oRect.m_oX.SetValue(oReader.GetDouble()); m_oRect.m_oX.SetValue(oReader.GetText());
else if ("y" == sName) else if ("y" == sName)
m_oRect.m_oY.SetValue(oReader.GetDouble()); m_oRect.m_oY.SetValue(oReader.GetText());
else if ("width" == sName) else if ("width" == sName)
m_oRect.m_oWidth.SetValue(oReader.GetDouble()); m_oRect.m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName) else if ("height" == sName)
m_oRect.m_oHeight.SetValue(oReader.GetDouble()); m_oRect.m_oHeight.SetValue(oReader.GetText());
else if ("rx" == sName) else if ("rx" == sName)
m_oRx.SetValue(oReader.GetDouble()); m_oRx.SetValue(oReader.GetText());
else if ("ry" == sName) else if ("ry" == sName)
m_oRy.SetValue(oReader.GetDouble()); m_oRy.SetValue(oReader.GetText());
else else
CRenderedObject::SetAttribute(sName, oReader); CRenderedObject::SetAttribute(sName, oReader);
@ -103,7 +103,7 @@ namespace SVG
nTypePath += c_nWindingFillMode; nTypePath += c_nWindingFillMode;
} }
TBounds CRect::GetBounds() const TBounds CRect::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds; TBounds oBounds;
@ -112,6 +112,16 @@ namespace SVG
oBounds.m_dRight = oBounds.m_dLeft + m_oRect.m_oWidth.ToDouble(NSCSS::Pixel); oBounds.m_dRight = oBounds.m_dLeft + m_oRect.m_oWidth.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = oBounds.m_dTop + m_oRect.m_oHeight.ToDouble(NSCSS::Pixel); oBounds.m_dBottom = oBounds.m_dTop + m_oRect.m_oHeight.ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds; return oBounds;
} }
} }

View File

@ -21,7 +21,7 @@ namespace SVG
private: private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
TRect m_oRect; TRect m_oRect;

View File

@ -17,7 +17,7 @@ namespace SVG
return false; return false;
} }
TBounds CSwitch::GetBounds() const TBounds CSwitch::GetBounds(SvgMatrix* pTransform) const
{ {
for (const CRenderedObject* pObject : m_arObjects) for (const CRenderedObject* pObject : m_arObjects)
if (NULL != pObject) if (NULL != pObject)

View File

@ -12,7 +12,7 @@ namespace SVG
public: public:
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
}; };
} }
#endif // CSWITCH_H #endif // CSWITCH_H

View File

@ -19,7 +19,6 @@
namespace SVG namespace SVG
{ {
#define DEFAULT_TSPAN_FONT_SIZE 16
#define DefaultFontFamily L"Times New Roman" #define DefaultFontFamily L"Times New Roman"
#define MIN_FONT_SIZE 5 #define MIN_FONT_SIZE 5
#define MAX_FONT_SIZE 100 #define MAX_FONT_SIZE 100
@ -29,24 +28,18 @@ namespace SVG
CTSpan::CTSpan(CSvgReader& oReader, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, const Point &oPosition) CTSpan::CTSpan(CSvgReader& oReader, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, const Point &oPosition)
: CRenderedObject(oReader, pParent), m_pFontManager(pFontManager), : CRenderedObject(oReader, pParent), m_pFontManager(pFontManager),
m_oX(oPosition.dX), m_oY(oPosition.dY) m_oX(oPosition.dX), m_oY(oPosition.dY)
{ {}
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
}
CTSpan::CTSpan(const CTSpan& oTSpan, double dX, const std::wstring& wsText) CTSpan::CTSpan(const CTSpan& oTSpan, double dX, const std::wstring& wsText)
: CRenderedObject(oTSpan), m_pFontManager(oTSpan.m_pFontManager), : CRenderedObject(oTSpan), m_pFontManager(oTSpan.m_pFontManager),
m_oX(dX), m_oY(oTSpan.m_oY), m_wsText(wsText), m_oX(dX), m_oY(oTSpan.m_oY), m_wsText(wsText),
m_oFont(oTSpan.m_oFont), m_oText(oTSpan.m_oText) m_oFont(oTSpan.m_oFont), m_oText(oTSpan.m_oText)
{ {}
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
}
CTSpan::CTSpan(wchar_t wChar, const Point& oPosition, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager) CTSpan::CTSpan(wchar_t wChar, const Point& oPosition, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager)
: CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager), : CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager),
m_oX(oPosition.dX), m_oY(oPosition.dY) m_oX(oPosition.dX), m_oY(oPosition.dY)
{ {}
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
}
CTSpan::~CTSpan() CTSpan::~CTSpan()
{} {}
@ -54,9 +47,9 @@ namespace SVG
void CTSpan::SetAttribute(const std::string& sName, CSvgReader& oReader) void CTSpan::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("x" == sName) if ("x" == sName)
m_oX.SetValue(oReader.GetDouble()); m_oX.SetValue(oReader.GetText());
else if ("y" == sName) else if ("y" == sName)
m_oY.SetValue(oReader.GetDouble()); m_oY.SetValue(oReader.GetText());
else else
CRenderedObject::SetAttribute(sName, oReader); CRenderedObject::SetAttribute(sName, oReader);
} }
@ -70,13 +63,22 @@ namespace SVG
//FONT //FONT
if (mAttributes.end() != mAttributes.find(L"font")) if (mAttributes.end() != mAttributes.find(L"font"))
{
m_oFont.SetValue(mAttributes.at(L"font"), ushLevel, bHardMode); m_oFont.SetValue(mAttributes.at(L"font"), ushLevel, bHardMode);
UpdateFontSize();
}
if (mAttributes.end() != mAttributes.find(L"font-size")) if (mAttributes.end() != mAttributes.find(L"font-size"))
{
m_oFont.SetSize(mAttributes.at(L"font-size"), ushLevel, bHardMode); m_oFont.SetSize(mAttributes.at(L"font-size"), ushLevel, bHardMode);
UpdateFontSize();
}
if (mAttributes.end() != mAttributes.find(L"font-size-adjust")) if (mAttributes.end() != mAttributes.find(L"font-size-adjust"))
{
m_oFont.SetSize(mAttributes.at(L"font-size-adjust"), ushLevel, bHardMode); m_oFont.SetSize(mAttributes.at(L"font-size-adjust"), ushLevel, bHardMode);
UpdateFontSize();
}
if (mAttributes.end() != mAttributes.find(L"font-stretch")) if (mAttributes.end() != mAttributes.find(L"font-stretch"))
m_oFont.SetStretch(mAttributes.at(L"font-stretch"), ushLevel, bHardMode); m_oFont.SetStretch(mAttributes.at(L"font-stretch"), ushLevel, bHardMode);
@ -94,7 +96,10 @@ namespace SVG
m_oFont.SetFamily(mAttributes.at(L"font-family"), ushLevel, bHardMode); m_oFont.SetFamily(mAttributes.at(L"font-family"), ushLevel, bHardMode);
if (mAttributes.end() != mAttributes.find(L"line-height")) if (mAttributes.end() != mAttributes.find(L"line-height"))
{
m_oFont.SetLineHeight(mAttributes.at(L"line-height"), ushLevel, bHardMode); m_oFont.SetLineHeight(mAttributes.at(L"line-height"), ushLevel, bHardMode);
UpdateFontSize();
}
//TEXT //TEXT
if (mAttributes.end() != mAttributes.find(L"text-anchor")) if (mAttributes.end() != mAttributes.find(L"text-anchor"))
@ -131,7 +136,7 @@ namespace SVG
const char* pCheckValue = pValue; const char* pCheckValue = pValue;
while ('\0' != *pCheckValue) while ('\0' != *pCheckValue)
{ {
if (isprint(*pCheckValue++)) if (0x32 >= *pCheckValue++)
{ {
bFoundedSymbol = true; bFoundedSymbol = true;
break; break;
@ -226,7 +231,7 @@ namespace SVG
void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const
{ {
std::wstring wsFontFamily = DefaultFontFamily; std::wstring wsFontFamily = DefaultFontFamily;
double dFontSize = m_oFont.GetSize().ToDouble(NSCSS::Pixel) * 72. / 25.4; 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);
@ -260,7 +265,6 @@ namespace SVG
double dKoef = 25.4 / 72.; double dKoef = 25.4 / 72.;
NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile(); NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile();
if (pFontFile) if (pFontFile)
@ -326,6 +330,22 @@ namespace SVG
pRenderer->put_BrushAlpha1(255); pRenderer->put_BrushAlpha1(255);
} }
void CTSpan::UpdateFontSize()
{
if (NULL != m_pParent)
{
const CTSpan* pParentTSpan{dynamic_cast<const CTSpan*>(m_pParent)};
if (NULL != pParentTSpan)
{
m_oFont.UpdateSize((!pParentTSpan->m_oFont.GetSize().Empty()) ? pParentTSpan->m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
return;
}
}
m_oFont.UpdateSize(DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
}
bool CTSpan::UseExternalFont(const CSvgFile *pFile, double dX, double dY, IRenderer *pRenderer, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const bool CTSpan::UseExternalFont(const CSvgFile *pFile, double dX, double dY, IRenderer *pRenderer, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{ {
std::wstring wsFontFamily = DefaultFontFamily; std::wstring wsFontFamily = DefaultFontFamily;
@ -353,21 +373,30 @@ namespace SVG
return true; return true;
} }
TBounds CTSpan::GetBounds() const TBounds CTSpan::GetBounds(SvgMatrix* pTransform) const
{ {
TBounds oBounds; TBounds oBounds;
oBounds.m_dLeft = m_oX.ToDouble(NSCSS::Pixel); oBounds.m_dLeft = m_oX.ToDouble(NSCSS::Pixel);
oBounds.m_dTop = m_oY.ToDouble(NSCSS::Pixel);
oBounds.m_dRight = oBounds.m_dLeft + GetWidth(); oBounds.m_dRight = oBounds.m_dLeft + GetWidth();
oBounds.m_dBottom = oBounds.m_dTop + m_oFont.GetSize().ToDouble(NSCSS::Pixel) * 72. / 25.4;
oBounds.m_dBottom = m_oY.ToDouble(NSCSS::Pixel);
oBounds.m_dTop = oBounds.m_dBottom + ((!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
}
if (!m_arObjects.empty()) if (!m_arObjects.empty())
{ {
TBounds oTempBounds; TBounds oTempBounds;
for (const CRenderedObject* pObject : m_arObjects) for (const CRenderedObject* pObject : m_arObjects)
{ {
oTempBounds = pObject->GetBounds(); oTempBounds = pObject->GetBounds(pTransform);
oBounds.m_dLeft = std::min(oBounds.m_dLeft, oTempBounds.m_dLeft); oBounds.m_dLeft = std::min(oBounds.m_dLeft, oTempBounds.m_dLeft);
oBounds.m_dTop = std::min(oBounds.m_dTop, oTempBounds.m_dTop); oBounds.m_dTop = std::min(oBounds.m_dTop, oTempBounds.m_dTop);
oBounds.m_dRight = std::max(oBounds.m_dRight, oTempBounds.m_dRight); oBounds.m_dRight = std::max(oBounds.m_dRight, oTempBounds.m_dRight);
@ -375,6 +404,9 @@ namespace SVG
} }
} }
if (nullptr != pTransform)
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
return oBounds; return oBounds;
} }
@ -384,7 +416,7 @@ namespace SVG
return 0.; return 0.;
std::wstring wsName = DefaultFontFamily; std::wstring wsName = DefaultFontFamily;
double dSize = (!m_oFont.GetSize().Zero()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_TSPAN_FONT_SIZE; const double dSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE;
if (!m_oFont.GetFamily().Empty()) if (!m_oFont.GetFamily().Empty())
{ {
@ -545,7 +577,9 @@ namespace SVG
CText::CText(CSvgReader& oReader, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager) CText::CText(CSvgReader& oReader, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager)
: CTSpan(oReader, pParent, pFontManager) : CTSpan(oReader, pParent, pFontManager)
{} {
m_oFont.UpdateSize(DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
}
bool CText::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const bool CText::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{ {

View File

@ -34,9 +34,10 @@ namespace SVG
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override; 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) 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; bool UseExternalFont(const CSvgFile* pFile, double dX, double dY, IRenderer* pRenderer, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
double GetWidth() const; double GetWidth() const;
void CorrectFontFamily(std::wstring& wsFontFamily) const; void CorrectFontFamily(std::wstring& wsFontFamily) const;

View File

@ -13,13 +13,13 @@ namespace SVG
void CUse::SetAttribute(const std::string& sName, CSvgReader& oReader) void CUse::SetAttribute(const std::string& sName, CSvgReader& oReader)
{ {
if ("x" == sName) if ("x" == sName)
m_oX.SetValue(oReader.GetDouble()); m_oX.SetValue(oReader.GetText());
else if ("y" == sName) else if ("y" == sName)
m_oY.SetValue(oReader.GetDouble()); m_oY.SetValue(oReader.GetText());
else if ("width" == sName) else if ("width" == sName)
m_oWidth.SetValue(oReader.GetDouble()); m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName) else if ("height" == sName)
m_oHeight.SetValue(oReader.GetDouble()); m_oHeight.SetValue(oReader.GetText());
else if ("href" == sName || "xlink:href" == sName) else if ("href" == sName || "xlink:href" == sName)
m_wsHref = oReader.GetText(); m_wsHref = oReader.GetText();
else else
@ -73,7 +73,7 @@ namespace SVG
return bResult; return bResult;
} }
TBounds CUse::GetBounds() const TBounds CUse::GetBounds(SvgMatrix* pTransform) const
{ {
return TBounds{0., 0., 0., 0.}; return TBounds{0., 0., 0., 0.};
} }

View File

@ -19,7 +19,7 @@ namespace SVG
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override; bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private: private:
TBounds GetBounds() const override; TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
CRenderedObject *m_pUsedObject; CRenderedObject *m_pUsedObject;

View File

@ -9,17 +9,21 @@
namespace SVG namespace SVG
{ {
#define MapCI std::map<std::wstring, std::wstring>::const_iterator using MapCI = std::map<std::wstring, std::wstring>::const_iterator;
#define SvgDigit NSCSS::NSProperties::CDigit using SvgDigit = NSCSS::NSProperties::CDigit;
#define SvgString NSCSS::NSProperties::CString using SvgString = NSCSS::NSProperties::CString;
#define SvgColor NSCSS::NSProperties::CColor using SvgColor = NSCSS::NSProperties::CColor;
#define SvgURL NSCSS::NSProperties::CURL using SvgURL = NSCSS::NSProperties::CURL;
#define SvgEnum NSCSS::NSProperties::CEnum using SvgEnum = NSCSS::NSProperties::CEnum;
#define SvgTransform NSCSS::NSProperties::CTransform using SvgTransform = NSCSS::NSProperties::CTransform;
#define SvgFont NSCSS::NSProperties::CFont using SvgFont = NSCSS::NSProperties::CFont;
#define SvgText NSCSS::NSProperties::CText using SvgText = NSCSS::NSProperties::CText;
using SvgMatrix = NSCSS::NSProperties::CMatrix;
#define DEFAULT_FONT_SIZE 16
struct TStroke struct TStroke
{ {