From 403695b3236ce0ccca5ba7493736926566c9addc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Apr 2011 16:37:54 +0000 Subject: [PATCH] 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 --- docs/changes.txt | 1 + interface/wx/dc.h | 13 ++++-- src/common/dcsvg.cpp | 106 +++++++++++++++++++++++++------------------ 3 files changed, 71 insertions(+), 49 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 297b4a2737..a633e0bfa1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -499,6 +499,7 @@ All (GUI): - wxComboCtrl, wxOwnerDrawnComboBox: better support for themed and custom panel backgrounds, especially on OS X. - Add WXK_CONTROL_A..WXK_CONTROL_Z constants (Jan van Dijk). +- Add support for alpha channel in colours in wxSVGFileDC (snowleopard). GTK: diff --git a/interface/wx/dc.h b/interface/wx/dc.h index d3e8875f60..32b986bd1e 100644 --- a/interface/wx/dc.h +++ b/interface/wx/dc.h @@ -113,7 +113,7 @@ struct wxFontMetrics wxWidgets offers an alternative drawing API based on the modern drawing backends GDI+, CoreGraphics and Cairo. See wxGraphicsContext, wxGraphicsRenderer and related classes. There is also a wxGCDC linking the APIs by offering - the wxDC API ontop of a wxGraphicsContext. + the wxDC API on top of a wxGraphicsContext. wxDC is an abstract base class and cannot be created directly. Use wxPaintDC, wxClientDC, wxWindowDC, wxScreenDC, wxMemoryDC or @@ -153,9 +153,14 @@ struct wxFontMetrics @section dc_alpha_support Support for Transparency / Alpha Channel - On Mac OS X colours with alpha channel are supported. Instances of wxPen - or wxBrush that are built from wxColour use the colour's alpha values - when stroking or filling. + In general wxDC methods don't support alpha transparency and the alpha + component of wxColour is simply ignored and you need to use wxGraphicsContext + 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} diff --git a/src/common/dcsvg.cpp b/src/common/dcsvg.cpp index 3a9a945d0a..21798cffab 100644 --- a/src/common/dcsvg.cpp +++ b/src/common/dcsvg.cpp @@ -40,26 +40,6 @@ namespace inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } -wxString wxBrushString ( wxColour c, int style ) -{ - wxString s = wxT("fill:") + c.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; "); - switch ( style ) - { - case wxBRUSHSTYLE_SOLID : - s = s + wxT("fill-opacity:1.0; "); - break; - case wxBRUSHSTYLE_TRANSPARENT: - s = s + wxT("fill-opacity:0.0; "); - break; - - default : - wxASSERT_MSG(false, wxT("wxSVGFileDC::Requested Brush Style not available")); - - } - s = s + wxT("\n"); - 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 @@ -69,6 +49,58 @@ 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("; "); + // 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 ) + { + case wxBRUSHSTYLE_SOLID: + s = s + wxT("fill-opacity:1.0; "); + break; + case wxBRUSHSTYLE_TRANSPARENT: + s = s + wxT("fill-opacity:0.0; "); + break; + default : + wxASSERT_MSG(false, wxT("wxSVGFileDC::Requested Brush Style not available")); + } + } + return s; +} + } // anonymous namespace // ---------------------------------------------------------- @@ -230,10 +262,10 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background wxASSERT_MSG(!wxSVG_DEBUG, wxT("wxSVGFileDC::Draw Rotated Text Call plotting text background")); - sTmp.Printf ( wxT(" "), NumStr(-angle), x,y ); + sTmp.Printf ( wxT(" "), NumStr(-angle), x,y ); s = s + sTmp + wxT("\n"); 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") }; 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 + 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 ); s = s + sTmp + sText + wxT(" ") + wxT("\n"); if (m_OK) @@ -516,14 +549,10 @@ void wxSVGFileDCImpl::SetPen(const wxPen& pen) void wxSVGFileDCImpl::NewGraphics () { - - int w = m_pen.GetWidth (); - wxColour c = m_pen.GetColour (); - wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast, sWarn; sBrush = wxT("\n \n"); - } - 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; write(s); -- 2.45.2