Implement GradientFillLinear and GradientFillConcentric for wxSVGFileDC

This commit is contained in:
Maarten Bent 2019-08-11 18:25:09 +02:00
parent 26b273bef9
commit dfe76430cc
2 changed files with 95 additions and 0 deletions

View File

@ -220,6 +220,16 @@ private:
return false;
}
virtual void DoGradientFillLinear(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
wxDirection nDirection = wxEAST) wxOVERRIDE;
virtual void DoGradientFillConcentric(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
const wxPoint& circleCenter) wxOVERRIDE;
virtual void DoGetSize(int * x, int *y) const wxOVERRIDE
{
if ( x )
@ -276,6 +286,9 @@ private:
// incremented in each SetClippingRegion() call.
size_t m_clipUniqueId;
// Unique ID for every gradient.
size_t m_gradientUniqueId;
wxDECLARE_ABSTRACT_CLASS(wxSVGFileDCImpl);
wxDECLARE_NO_COPY_CLASS(wxSVGFileDCImpl);
};

View File

@ -500,6 +500,8 @@ void wxSVGFileDCImpl::Init(const wxString &filename, int Width, int Height,
m_clipUniqueId = 0;
m_clipNestingLevel = 0;
m_gradientUniqueId = 0;
m_mm_to_pix_x = dpi / 25.4;
m_mm_to_pix_y = dpi / 25.4;
@ -1015,6 +1017,86 @@ void wxSVGFileDCImpl::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord
write(arcLine);
}
void wxSVGFileDCImpl::DoGradientFillLinear(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
wxDirection nDirection)
{
NewGraphicsIfNeeded();
float initOpacity;
float destOpacity;
wxString initCol = Col2SVG(initialColour, &initOpacity);
wxString destCol = Col2SVG(destColour, &destOpacity);
const int x1 = ((nDirection & wxLEFT) > 0) ? 100 : 0;
const int y1 = ((nDirection & wxUP) > 0) ? 100 : 0;
const int x2 = ((nDirection & wxRIGHT) > 0) ? 100 : 0;
const int y2 = ((nDirection & wxDOWN) > 0) ? 100 : 0;
wxString s;
s += wxS(" <defs>\n");
s += wxString::Format(wxS(" <linearGradient id=\"gradient%zu\" x1=\"%d%%\" y1=\"%d%%\" x2=\"%d%%\" y2=\"%d%%\">\n"),
m_gradientUniqueId, x1, y1, x2, y2);
s += wxString::Format(wxS(" <stop offset=\"0%%\" style=\"stop-color:%s; stop-opacity:%s\"/>\n"),
initCol, NumStr(initOpacity));
s += wxString::Format(wxS(" <stop offset=\"100%%\" style=\"stop-color:%s; stop-opacity:%s\"/>\n"),
destCol, NumStr(destOpacity));
s += wxS(" </linearGradient>\n");
s += wxS(" </defs>\n");
s += wxString::Format(wxS(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"url(#gradient%zu)\" %s %s %s/>\n"),
rect.x, rect.y, rect.width, rect.height, m_gradientUniqueId,
wxRenderMode(m_renderingMode), wxGetPenPattern(m_pen), wxGetBrushFill(m_brush));
m_gradientUniqueId++;
write(s);
CalcBoundingBox(rect.x, rect.y);
CalcBoundingBox(rect.x + rect.width, rect.y + rect.height);
}
void wxSVGFileDCImpl::DoGradientFillConcentric(const wxRect& rect,
const wxColour& initialColour,
const wxColour& destColour,
const wxPoint& circleCenter)
{
NewGraphicsIfNeeded();
float initOpacity;
float destOpacity;
wxString initCol = Col2SVG(initialColour, &initOpacity);
wxString destCol = Col2SVG(destColour, &destOpacity);
const double cx = circleCenter.x * 100.0 / rect.GetWidth();
const double cy = circleCenter.y * 100.0 / rect.GetHeight();
const double fx = cx;
const double fd = cy;
wxString s;
s += wxS(" <defs>\n");
s += wxString::Format(wxS(" <radialGradient id=\"gradient%zu\" cx=\"%s%%\" cy=\"%s%%\" fx=\"%s%%\" fy=\"%s%%\">\n"),
m_gradientUniqueId, NumStr(cx), NumStr(cy), NumStr(fx), NumStr(fd));
s += wxString::Format(wxS(" <stop offset=\"0%%\" style=\"stop-color:%s; stop-opacity:%s\" />\n"),
initCol, NumStr(initOpacity));
s += wxString::Format(wxS(" <stop offset=\"100%%\" style=\"stop-color:%s; stop-opacity:%s\" />\n"),
destCol, NumStr(destOpacity));
s += wxS(" </radialGradient>\n");
s += wxS(" </defs>\n");
s += wxString::Format(wxS(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"url(#gradient%zu)\" %s %s %s/>\n"),
rect.x, rect.y, rect.width, rect.height, m_gradientUniqueId,
wxRenderMode(m_renderingMode), wxGetPenPattern(m_pen), wxGetBrushFill(m_brush));
m_gradientUniqueId++;
write(s);
CalcBoundingBox(rect.x, rect.y);
CalcBoundingBox(rect.x + rect.width, rect.y + rect.height);
}
void wxSVGFileDCImpl::DoSetClippingRegion(int x, int y, int width, int height)
{
wxString svg;