Add support for alpha channel in colours in wxSVGFileDC.
Use stroke-opacity and fill-opacity SVG attributes to handle pens and brushes created from colours with alpha channel in wxSVGFileDC. Closes #13086. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67373 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -499,6 +499,7 @@ All (GUI):
|
|||||||
- wxComboCtrl, wxOwnerDrawnComboBox: better support for themed and custom
|
- wxComboCtrl, wxOwnerDrawnComboBox: better support for themed and custom
|
||||||
panel backgrounds, especially on OS X.
|
panel backgrounds, especially on OS X.
|
||||||
- Add WXK_CONTROL_A..WXK_CONTROL_Z constants (Jan van Dijk).
|
- Add WXK_CONTROL_A..WXK_CONTROL_Z constants (Jan van Dijk).
|
||||||
|
- Add support for alpha channel in colours in wxSVGFileDC (snowleopard).
|
||||||
|
|
||||||
GTK:
|
GTK:
|
||||||
|
|
||||||
|
@@ -153,9 +153,14 @@ struct wxFontMetrics
|
|||||||
|
|
||||||
@section dc_alpha_support Support for Transparency / Alpha Channel
|
@section dc_alpha_support Support for Transparency / Alpha Channel
|
||||||
|
|
||||||
On Mac OS X colours with alpha channel are supported. Instances of wxPen
|
In general wxDC methods don't support alpha transparency and the alpha
|
||||||
or wxBrush that are built from wxColour use the colour's alpha values
|
component of wxColour is simply ignored and you need to use wxGraphicsContext
|
||||||
when stroking or filling.
|
for full transparency support. There are, however, a few exceptions: first,
|
||||||
|
under Mac OS X colours with alpha channel are supported in all the normal
|
||||||
|
wxDC-derived classes as they use wxGraphicsContext internally. Second,
|
||||||
|
under all platforms wxSVGFileDC also fully supports alpha channel. In both
|
||||||
|
of these cases the instances of wxPen or wxBrush that are built from
|
||||||
|
wxColour use the colour's alpha values when stroking or filling.
|
||||||
|
|
||||||
|
|
||||||
@library{wxcore}
|
@library{wxcore}
|
||||||
|
@@ -40,9 +40,52 @@ namespace
|
|||||||
|
|
||||||
inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
|
inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
|
||||||
|
|
||||||
wxString wxBrushString ( wxColour c, int style )
|
// This function returns a string representation of a floating point number in
|
||||||
|
// C locale (i.e. always using "." for the decimal separator) and with the
|
||||||
|
// fixed precision (which is 2 for some unknown reason but this is what it was
|
||||||
|
// in this code originally).
|
||||||
|
inline wxString NumStr(double f)
|
||||||
|
{
|
||||||
|
return wxString::FromCDouble(f, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxPenString(wxColour c, int style = wxPENSTYLE_SOLID)
|
||||||
|
{
|
||||||
|
wxString s = wxT("stroke:") + c.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
||||||
|
// Use the color's alpha value (if not opaque) for the opacity.
|
||||||
|
// Note that a transparent pen will override the alpha value.
|
||||||
|
if (c.Alpha() != wxALPHA_OPAQUE && style != wxPENSTYLE_TRANSPARENT)
|
||||||
|
{
|
||||||
|
s = s + wxString::Format(wxT("stroke-opacity:%s; "), NumStr(c.Alpha()/255.));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch ( style )
|
||||||
|
{
|
||||||
|
case wxPENSTYLE_SOLID:
|
||||||
|
s = s + wxT("stroke-opacity:1.0; ");
|
||||||
|
break;
|
||||||
|
case wxPENSTYLE_TRANSPARENT:
|
||||||
|
s = s + wxT("stroke-opacity:0.0; ");
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
wxASSERT_MSG(false, wxT("wxSVGFileDC::Requested Pen Style not available"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxBrushString(wxColour c, int style = wxBRUSHSTYLE_SOLID)
|
||||||
{
|
{
|
||||||
wxString s = wxT("fill:") + c.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
wxString s = wxT("fill:") + c.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
||||||
|
// Use the color's alpha value (if not opaque) for the opacity.
|
||||||
|
// Note that a transparent brush will override the alpha value.
|
||||||
|
if (c.Alpha() != wxALPHA_OPAQUE && style != wxBRUSHSTYLE_TRANSPARENT)
|
||||||
|
{
|
||||||
|
s = s + wxString::Format(wxT("fill-opacity:%s; "), NumStr(c.Alpha()/255.));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
switch ( style )
|
switch ( style )
|
||||||
{
|
{
|
||||||
case wxBRUSHSTYLE_SOLID:
|
case wxBRUSHSTYLE_SOLID:
|
||||||
@@ -51,24 +94,13 @@ wxString wxBrushString ( wxColour c, int style )
|
|||||||
case wxBRUSHSTYLE_TRANSPARENT:
|
case wxBRUSHSTYLE_TRANSPARENT:
|
||||||
s = s + wxT("fill-opacity:0.0; ");
|
s = s + wxT("fill-opacity:0.0; ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
wxASSERT_MSG(false, wxT("wxSVGFileDC::Requested Brush Style not available"));
|
wxASSERT_MSG(false, wxT("wxSVGFileDC::Requested Brush Style not available"));
|
||||||
|
|
||||||
}
|
}
|
||||||
s = s + wxT("\n");
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function returns a string representation of a floating point number in
|
|
||||||
// C locale (i.e. always using "." for the decimal separator) and with the
|
|
||||||
// fixed precision (which is 2 for some unknown reason but this is what it was
|
|
||||||
// in this code originally).
|
|
||||||
inline wxString NumStr(double f)
|
|
||||||
{
|
|
||||||
return wxString::FromCDouble(f, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
@@ -231,9 +263,9 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor
|
|||||||
|
|
||||||
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background"));
|
wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background"));
|
||||||
sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x,y+desc-h, w, h );
|
sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x,y+desc-h, w, h );
|
||||||
s = sTmp + wxT("style=\"fill:") + m_textBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
s = sTmp + wxT("style=\"") + wxBrushString(m_textBackgroundColour);
|
||||||
s = s + wxT("stroke-width:1; stroke:") + m_textBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
s = s + wxT("stroke-width:1; ") + wxPenString(m_textBackgroundColour);
|
||||||
sTmp.Printf ( wxT("\" transform=\"rotate( %s %d %d ) \">"), NumStr(-angle), x,y );
|
sTmp.Printf ( wxT("\" transform=\"rotate( %s %d %d ) \" />"), NumStr(-angle), x,y );
|
||||||
s = s + sTmp + wxT("\n");
|
s = s + sTmp + wxT("\n");
|
||||||
write(s);
|
write(s);
|
||||||
}
|
}
|
||||||
@@ -250,9 +282,10 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor
|
|||||||
wxString fontstyles [5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
|
wxString fontstyles [5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
|
||||||
s = s + wxT("font-style:") + fontstyles[m_font.GetStyle() - wxNORMAL] + wxT("; ");
|
s = s + wxT("font-style:") + fontstyles[m_font.GetStyle() - wxNORMAL] + wxT("; ");
|
||||||
|
|
||||||
sTmp.Printf (wxT("font-size:%dpt; fill:"), m_font.GetPointSize () );
|
sTmp.Printf (wxT("font-size:%dpt; "), m_font.GetPointSize () );
|
||||||
s = s + sTmp;
|
s = s + sTmp;
|
||||||
s = s + m_textForegroundColour.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; stroke:") + m_textForegroundColour.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
//text will be solid, unless alpha value isn't opaque in the foreground colour
|
||||||
|
s = s + wxBrushString(m_textForegroundColour) + wxPenString(m_textForegroundColour);
|
||||||
sTmp.Printf ( wxT("stroke-width:0;\" transform=\"rotate( %s %d %d ) \" >"), NumStr(-angle), x,y );
|
sTmp.Printf ( wxT("stroke-width:0;\" transform=\"rotate( %s %d %d ) \" >"), NumStr(-angle), x,y );
|
||||||
s = s + sTmp + sText + wxT("</text> ") + wxT("\n");
|
s = s + sTmp + sText + wxT("</text> ") + wxT("\n");
|
||||||
if (m_OK)
|
if (m_OK)
|
||||||
@@ -516,14 +549,10 @@ void wxSVGFileDCImpl::SetPen(const wxPen& pen)
|
|||||||
|
|
||||||
void wxSVGFileDCImpl::NewGraphics ()
|
void wxSVGFileDCImpl::NewGraphics ()
|
||||||
{
|
{
|
||||||
|
|
||||||
int w = m_pen.GetWidth ();
|
|
||||||
wxColour c = m_pen.GetColour ();
|
|
||||||
|
|
||||||
wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast, sWarn;
|
wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast, sWarn;
|
||||||
|
|
||||||
sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour (), m_brush.GetStyle () )
|
sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour (), m_brush.GetStyle () )
|
||||||
+ wxT(" stroke:") + c.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
|
+ wxPenString(m_pen.GetColour(), m_pen.GetStyle());
|
||||||
|
|
||||||
switch ( m_pen.GetCap () )
|
switch ( m_pen.GetCap () )
|
||||||
{
|
{
|
||||||
@@ -550,21 +579,8 @@ void wxSVGFileDCImpl::NewGraphics ()
|
|||||||
sPenJoin = wxT("stroke-linejoin:round; ");
|
sPenJoin = wxT("stroke-linejoin:round; ");
|
||||||
};
|
};
|
||||||
|
|
||||||
switch ( m_pen.GetStyle () )
|
|
||||||
{
|
|
||||||
case wxPENSTYLE_SOLID :
|
|
||||||
sPenStyle = wxT("stroke-opacity:1.0; stroke-opacity:1.0; ");
|
|
||||||
break;
|
|
||||||
case wxPENSTYLE_TRANSPARENT :
|
|
||||||
sPenStyle = wxT("stroke-opacity:0.0; stroke-opacity:0.0; ");
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
wxASSERT_MSG(false, wxT("wxSVGFileDC::SetPen Call called to set a Style which is not available"));
|
|
||||||
sWarn = sWarn + wxT("<!--- wxSVGFileDC::SetPen Call called to set a Style which is not available --> \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
sLast.Printf( wxT("stroke-width:%d\" \n transform=\"translate(%s %s) scale(%s %s)\">"),
|
sLast.Printf( wxT("stroke-width:%d\" \n transform=\"translate(%s %s) scale(%s %s)\">"),
|
||||||
w, NumStr(m_logicalOriginX), NumStr(m_logicalOriginY), NumStr(m_scaleX), NumStr(m_scaleY) );
|
m_pen.GetWidth(), NumStr(m_logicalOriginX), NumStr(m_logicalOriginY), NumStr(m_scaleX), NumStr(m_scaleY) );
|
||||||
|
|
||||||
s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + wxT("\n") + sWarn;
|
s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + wxT("\n") + sWarn;
|
||||||
write(s);
|
write(s);
|
||||||
|
Reference in New Issue
Block a user