Add logic for one color gradient

This commit is contained in:
Prokhorov Kirill
2025-02-10 20:58:02 +03:00
parent bbb9165a99
commit 68c9d3cfa5
3 changed files with 59 additions and 16 deletions

View File

@ -405,7 +405,7 @@ namespace NSStructures
{
discrete_step = 1.0f / n;
}
bool checkLuminosity()
bool checkLuminosity() const
{
if (shading.patch_colors.empty())
return false;
@ -417,6 +417,40 @@ namespace NSStructures
return true;
}
bool colorEqual(const agg::rgba8& c1, const agg::rgba8& c2) const
{
return c1.r == c2.r &&
c1.g == c2.g &&
c1.b == c2.b &&
c1.a == c2.a;
}
bool isOneColor() const
{
switch (shading.shading_type)
{
case ShadingInfo::FunctionOnly:
case ShadingInfo::Parametric:
return false;
case ShadingInfo::TriangleInterpolation:
return colorEqual(shading.triangle_colors[0], shading.triangle_colors[1]) &&
colorEqual(shading.triangle_colors[1], shading.triangle_colors[2]);
case ShadingInfo::CurveInterpolation:
case ShadingInfo::TensorCurveInterpolation:
return colorEqual(shading.patch_colors[0][0], shading.patch_colors[0][1]) &&
colorEqual(shading.patch_colors[0][1], shading.patch_colors[1][0]) &&
colorEqual(shading.patch_colors[1][0], shading.patch_colors[1][1]);
default:
return false;
}
}
agg::rgba8 getFillColor() const
{
if (!shading.triangle_colors.empty())
return shading.triangle_colors[0];
if (!shading.patch_colors.empty())
return shading.patch_colors[0][0];
return agg::rgba8(0, 0, 0);
}
void setFillColor(const agg::rgba8& color)
{
shading.fill_color = color;

View File

@ -44,6 +44,9 @@ namespace NSDocxRenderer
else
m_oClipVectorGraphics = std::move(m_oCurrVectorGraphics);
}
if (!m_arLuminosityShapes.empty() && !m_arOneColorGradientShape.empty())
FillLuminosityShapes();
}
void CPage::Clear()
@ -234,13 +237,13 @@ namespace NSDocxRenderer
{
if (m_oBrush.m_oGradientInfo.checkLuminosity())
m_arLuminosityShapes.push_back(shape);
else if (!m_arShapes.empty() && !m_bIsLuminosityShapesFiled)
FillLuminosityShapes();
else if (m_oBrush.m_oGradientInfo.shading.shading_type != NSStructures::ShadingInfo::TensorCurveInterpolation
|| !m_bIsLuminosityShapesFiled)
DrawGradient(shape);
else
else if (m_oBrush.m_oGradientInfo.isOneColor())
{
m_arOneColorGradientShape.push_back(shape);
skip_shape = true;
}
else
DrawGradient(shape);
m_bIsGradient = false;
}
@ -260,7 +263,6 @@ namespace NSDocxRenderer
fabs(shape->m_dWidth - m_dWidth) <= c_dSHAPE_X_OFFSET * 2 &&
shape->m_oBrush.Color1 == c_iWhiteColor)
return;
if (!skip_shape)
{
shape->m_nOrder = ++m_nShapeOrder;
@ -2183,15 +2185,21 @@ namespace NSDocxRenderer
void CPage::FillLuminosityShapes()
{
if (m_oBrush.m_oGradientInfo.shading.patch_colors.empty())
return;
for (auto s : m_arLuminosityShapes)
for (auto itt = m_arOneColorGradientShape.begin(); itt != m_arOneColorGradientShape.end();)
{
s->m_oBrush.m_oGradientInfo.setFillColor(m_oBrush.m_oGradientInfo.shading.patch_colors[0][0]);
DrawGradient(s);
for (auto it = m_arLuminosityShapes.begin(); it != m_arLuminosityShapes.end();)
{
if ((*it)->m_oVector.GetRight() > (*itt)->m_oVector.GetLeft() && (*it)->m_oVector.GetBottom() > (*itt)->m_oVector.GetTop() &&
(*it)->m_oVector.GetLeft() < (*itt)->m_oVector.GetRight() && (*it)->m_oVector.GetTop() < (*itt)->m_oVector.GetBottom())
{
(*it)->m_oBrush.m_oGradientInfo.setFillColor((*itt)->m_oBrush.m_oGradientInfo.getFillColor());
DrawGradient((*it));
it = m_arLuminosityShapes.erase(it);
}
else
++it;
}
itt = m_arOneColorGradientShape.erase(itt);
}
m_bIsLuminosityShapesFiled = true;
}
}

View File

@ -215,6 +215,7 @@ namespace NSDocxRenderer
// save the luminosity shapes for later filling
std::vector<shape_ptr_t> m_arLuminosityShapes;
std::vector<shape_ptr_t> m_arOneColorGradientShape;
size_t m_nShapeOrder = 0;
};