]> git.saurik.com Git - wxWidgets.git/commitdiff
Add support for alpha channel in colours in wxSVGFileDC.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 2 Apr 2011 16:37:54 +0000 (16:37 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 2 Apr 2011 16:37:54 +0000 (16:37 +0000)
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
interface/wx/dc.h
src/common/dcsvg.cpp

index 297b4a2737c1c19fecab00b7c6eaca04b08ef479..a633e0bfa1e34de27ff4a571e83309575c00e620 100644 (file)
@@ -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).
 - 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:
 
 
 GTK:
 
index d3e8875f607af8e9f79af3a0fb56c5fa2c127b08..32b986bd1e97bc77b092c79a7196af42a92e9674 100644 (file)
@@ -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
     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
 
     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
 
 
     @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}
 
 
     @library{wxcore}
index 3a9a945d0a54439a2ef7c0d4e575e6c719f6360d..21798cffabe64efdcb21582f9948bd211d0a6ee2 100644 (file)
@@ -40,26 +40,6 @@ 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 )
-{
-    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
 // 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);
 }
 
     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
 
 // ----------------------------------------------------------
 } // 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"));
         // 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(" <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 = s + wxT("stroke-width:1; stroke:") + m_textBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX) + wxT("; ");
-        sTmp.Printf ( wxT("\" transform=\"rotate( %s %d %d )  \">"), NumStr(-angle), x,y );
+        sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x,y+desc-h, w, h );
+        s = sTmp + wxT("style=\"") + wxBrushString(m_textBackgroundColour);
+        s = s + wxT("stroke-width:1; ") + wxPenString(m_textBackgroundColour);
+        sTmp.Printf ( wxT("\" transform=\"rotate( %s %d %d )  \" />"), NumStr(-angle), x,y );
         s = s + sTmp + wxT("\n");
         write(s);
     }
         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("; ");
 
     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 + 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("</text> ") + wxT("\n");
     if (m_OK)
     sTmp.Printf ( wxT("stroke-width:0;\"  transform=\"rotate( %s %d %d )  \" >"),  NumStr(-angle), x,y );
     s = s + sTmp + sText + wxT("</text> ") + wxT("\n");
     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;
 
     sBrush = wxT("</g>\n<g style=\"") + wxBrushString ( m_brush.GetColour (), m_brush.GetStyle () )
     wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast, sWarn;
 
     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;
     write(s);
 
     s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + wxT("\n") + sWarn;
     write(s);