]> git.saurik.com Git - wxWidgets.git/commitdiff
use Pango to draw rotated text if possible (this supports text background and should...
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 21 Aug 2008 22:31:36 +0000 (22:31 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 21 Aug 2008 22:31:36 +0000 (22:31 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55161 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/gtk/dcclient.cpp

index a56b5d849803b3d0b5f83ef83390a7b06677a0ec..4e480712b6f8051d1b1977a8dc101e3ceaa55c0d 100644 (file)
@@ -1479,19 +1479,106 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
     CalcBoundingBox(x, y);
 }
 
-
-// TODO: There is an example of rotating text with GTK2 that would probably be
-// a better approach here:
-//           http://www.daa.com.au/pipermail/pygtk/2003-April/005052.html
-
+// TODO: When GTK2.6 is required, merge DoDrawText and DoDrawRotatedText to 
+// avoid code duplication
 void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle )
 {
-#if wxUSE_IMAGE
     if (!m_gdkwindow || text.empty())
         return;
 
     wxCHECK_RET( IsOk(), wxT("invalid window dc") );
 
+#if __WXGTK26__
+    if (!gtk_check_version(2,6,0))
+    {
+        x = XLOG2DEV(x);
+        y = YLOG2DEV(y);
+
+        pango_layout_set_text(m_layout, wxGTK_CONV(text), -1);
+
+        if (m_font.GetUnderlined())
+        {
+            PangoAttrList *attrs = pango_attr_list_new();
+            PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
+            pango_attr_list_insert(attrs, a);
+            pango_layout_set_attributes(m_layout, attrs);
+            pango_attr_list_unref(attrs);
+        }
+
+        int oldSize = 0;
+        const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
+        if (isScaled)
+        {
+            //TODO: when Pango >= 1.6 is required, use pango_matrix_scale()
+             // If there is a user or actually any scale applied to
+             // the device context, scale the font.
+
+             // scale font description
+            oldSize = pango_font_description_get_size(m_fontdesc);
+            pango_font_description_set_size(m_fontdesc, int(oldSize * m_scaleY));
+
+             // actually apply scaled font
+             pango_layout_set_font_description( m_layout, m_fontdesc );
+        }
+
+        int w, h;
+        pango_layout_get_pixel_size(m_layout, &w, &h);
+
+        const GdkColor* bg_col = NULL;
+        if (m_backgroundMode == wxBRUSHSTYLE_SOLID) 
+            bg_col = m_textBackgroundColour.GetColor();
+
+        // rotate the text
+        PangoMatrix matrix = PANGO_MATRIX_INIT;
+        pango_matrix_rotate (&matrix, angle);
+        pango_context_set_matrix (m_context, &matrix);
+        pango_layout_context_changed (m_layout);
+
+        // To be compatible with MSW, the rotation axis must be in the old 
+        // top-left corner.
+        // Calculate the vertices of the rotated rectangle containing the text, 
+        // relative to the old top-left vertex.
+        // We could use the matrix for this, but it's simpler with trignonometry. 
+        double rad = DegToRad(angle);
+        // the rectangle vertices are counted clockwise with the first one 
+        // being at (0, 0)
+        double x2 = w * cos(rad);
+        double y2 = -w * sin(rad);   // y axis points to the bottom, hence minus
+        double x4 = h * sin(rad);
+        double y4 = h * cos(rad);
+        double x3 = x4 + x2;
+        double y3 = y4 + y2;
+        // Then we calculate max and min of the rotated rectangle.
+        wxCoord maxX = (wxCoord)(dmax(dmax(0, x2), dmax(x3, x4)) + 0.5),
+                maxY = (wxCoord)(dmax(dmax(0, y2), dmax(y3, y4)) + 0.5),
+                minX = (wxCoord)(dmin(dmin(0, x2), dmin(x3, x4)) - 0.5),
+                minY = (wxCoord)(dmin(dmin(0, y2), dmin(y3, y4)) - 0.5);
+
+        gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x+minX, y+minY, 
+                                    m_layout, NULL, bg_col);
+
+        if (m_font.GetUnderlined())
+            pango_layout_set_attributes(m_layout, NULL);
+
+        // clean up the transformation matrix
+        pango_context_set_matrix(m_context, NULL);
+
+        if (isScaled)
+        {
+             // reset unscaled size
+             pango_font_description_set_size( m_fontdesc, oldSize );
+
+             // actually apply unscaled font
+             pango_layout_set_font_description( m_layout, m_fontdesc );
+        }
+
+        CalcBoundingBox(x+minX, y+minY);
+        CalcBoundingBox(x+maxX, y+maxY);
+    }
+    else
+#endif //__WXGTK26__
+    {
+#if wxUSE_IMAGE
     if ( wxIsNullDouble(angle) )
     {
         DoDrawText(text, x, y);
@@ -1591,6 +1678,7 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord
     wxUnusedVar(y);
     wxUnusedVar(angle);
 #endif // wxUSE_IMAGE/!wxUSE_IMAGE
+    }
 }
 
 void wxWindowDCImpl::DoGetTextExtent(const wxString &string,