X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/77416abdc5e242946d16e1b087e1adea25f2a0d6..739e366ac91d526da389d01bb230cb628b16450a:/src/gtk1/dcclient.cpp diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 6ecc0ace44..e07a871f76 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -3,7 +3,7 @@ // Purpose: // Author: Robert Roebling // RCS-ID: $Id$ -// Copyright: (c) 1998 Robert Roebling, Markus Holzem, Chris Breeze +// Copyright: (c) 1998 Robert Roebling, Chris Breeze // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -298,6 +298,7 @@ wxWindowDC::wxWindowDC() m_owner = (wxWindow *)NULL; #ifdef __WXGTK20__ m_context = (PangoContext *)NULL; + m_layout = (PangoLayout *)NULL; m_fontdesc = (PangoFontDescription *)NULL; #endif } @@ -318,9 +319,9 @@ wxWindowDC::wxWindowDC( wxWindow *window ) GtkWidget *widget = window->m_wxwindow; - // some controls don't have m_wxwindow - like wxStaticBox, but the user + // Some controls don't have m_wxwindow - like wxStaticBox, but the user // code should still be able to create wxClientDCs for them, so we will - // use the parent window here then + // use the parent window here then. if ( !widget ) { window = window->GetParent(); @@ -331,16 +332,17 @@ wxWindowDC::wxWindowDC( wxWindow *window ) #ifdef __WXGTK20__ m_context = window->GtkGetPangoDefaultContext(); - m_fontdesc = widget->style->font_desc; + m_layout = pango_layout_new( m_context ); + m_fontdesc = pango_font_description_copy( widget->style->font_desc ); #endif GtkPizza *pizza = GTK_PIZZA( widget ); m_window = pizza->bin_window; - /* not realized ? */ + // Window not realized ? if (!m_window) { - /* don't report problems */ + // Don't report problems as per MSW. m_ok = TRUE; return; @@ -363,6 +365,13 @@ wxWindowDC::wxWindowDC( wxWindow *window ) wxWindowDC::~wxWindowDC() { Destroy(); + +#ifdef __WXGTK20__ + if (m_layout) + g_object_unref( G_OBJECT( m_layout ) ); + if (m_fontdesc) + pango_font_description_free( m_fontdesc ); +#endif } void wxWindowDC::SetUpDC() @@ -1418,38 +1427,63 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) wxCHECK_RET( font, wxT("invalid font") ); #endif -#ifdef __WXGTK20__ - wxCHECK_RET( m_context, wxT("no Pango context") ); -#endif - x = XLOG2DEV(x); y = YLOG2DEV(y); #ifdef __WXGTK20__ - // TODO: the layout engine should be abstracted at a higher level! - PangoLayout *layout = pango_layout_new(m_context); - pango_layout_set_font_description(layout, m_fontdesc); - { + wxCHECK_RET( m_context, wxT("no Pango context") ); + wxCHECK_RET( m_layout, wxT("no Pango layout") ); + wxCHECK_RET( m_fontdesc, wxT("no Pango font description") ); + #if wxUSE_UNICODE - const wxCharBuffer data = wxConvUTF8.cWC2MB( text ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + const wxCharBuffer data = wxConvUTF8.cWC2MB( text ); #else - const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text ); - const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + const wxWCharBuffer wdata = wxConvLocal.cMB2WC( text ); + const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); #endif + pango_layout_set_text( m_layout, (const char*) data, strlen( (const char*) data )); + + if (m_scaleY != 1.0) + { + // If there is a user or actually any scale applied to + // the device context, scale the font. + + // scale font description + gint oldSize = pango_font_description_get_size( m_fontdesc ); + double size = oldSize; + size = size * m_scaleY; + pango_font_description_set_size( m_fontdesc, (gint)size ); + + // actually apply scaled font + pango_layout_set_font_description( m_layout, m_fontdesc ); + + // Draw layout. + gdk_draw_layout( m_window, m_textGC, x, y, m_layout ); + + // reset unscaled size + pango_font_description_set_size( m_fontdesc, oldSize ); + + // actually apply unscaled font + pango_layout_set_font_description( m_layout, m_fontdesc ); + } + else + { + // Draw layout. + gdk_draw_layout( m_window, m_textGC, x, y, m_layout ); } - // Measure layout. +#if 0 + // Measure layout int w,h; - pango_layout_get_pixel_size(layout, &w, &h); + pango_layout_get_pixel_size( m_layout, &w, &h ); +#else + int w = 10; + int h = 10; +#endif + wxCoord width = w; wxCoord height = h; - // Draw layout. - gdk_draw_layout( m_window, m_textGC, x, y, layout ); - - g_object_unref( G_OBJECT( layout ) ); #else // GTK+ 1.x wxCoord width = gdk_string_width( font, text.mbc_str() ); wxCoord height = font->ascent + font->descent; @@ -1473,7 +1507,6 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) } #endif // GTK+ 2.0/1.x - width = wxCoord(width / m_scaleX); height = wxCoord(height / m_scaleY); CalcBoundingBox (x + width, y + height); @@ -1492,6 +1525,10 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, if (!m_window) return; +#ifdef __WXGTK20__ + // implement later without GdkFont for GTK 2.0 + return; +#else GdkFont *font = m_font.GetInternalFont( m_scaleY ); wxCHECK_RET( font, wxT("invalid font") ); @@ -1590,6 +1627,7 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, // update the bounding box CalcBoundingBox(x + minX, y + minY); CalcBoundingBox(x + maxX, y + maxY); +#endif } void wxWindowDC::DoGetTextExtent(const wxString &string, @@ -1605,26 +1643,22 @@ void wxWindowDC::DoGetTextExtent(const wxString &string, } #ifdef __WXGTK20__ - // Create layout and set font description - PangoLayout *layout = pango_layout_new(m_context); + // Set new font description if (theFont) - pango_layout_set_font_description( layout, theFont->GetNativeFontInfo()->description ); - else - pango_layout_set_font_description(layout, m_fontdesc); + pango_layout_set_font_description( m_layout, theFont->GetNativeFontInfo()->description ); // Set layout's text #if wxUSE_UNICODE - const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); + pango_layout_set_text( m_layout, (const char*) data, strlen( (const char*) data )); #else - const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string ); - const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string ); + const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); + pango_layout_set_text( m_layout, (const char*) data, strlen( (const char*) data )); #endif - // Measure text. int w,h; - pango_layout_get_pixel_size(layout, &w, &h); + pango_layout_get_pixel_size( m_layout, &w, &h ); if (width) (*width) = (wxCoord) w; if (height) (*height) = (wxCoord) h; @@ -1635,7 +1669,9 @@ void wxWindowDC::DoGetTextExtent(const wxString &string, } if (externalLeading) (*externalLeading) = 0; // ?? - g_object_unref( G_OBJECT( layout ) ); + // Reset old font description + if (theFont) + pango_layout_set_font_description( m_layout, m_fontdesc ); #else wxFont fontToUse = m_font; if (theFont) fontToUse = *theFont; @@ -1651,13 +1687,9 @@ void wxWindowDC::DoGetTextExtent(const wxString &string, wxCoord wxWindowDC::GetCharWidth() const { #ifdef __WXGTK20__ - // There should be an easier way. - PangoLayout *layout = pango_layout_new(m_context); - pango_layout_set_font_description(layout, m_fontdesc); - pango_layout_set_text(layout, "H", 1 ); + pango_layout_set_text( m_layout, "H", 1 ); int w,h; - pango_layout_get_pixel_size(layout, &w, &h); - g_object_unref( G_OBJECT( layout ) ); + pango_layout_get_pixel_size( m_layout, &w, &h ); return w; #else GdkFont *font = m_font.GetInternalFont( m_scaleY ); @@ -1670,13 +1702,9 @@ wxCoord wxWindowDC::GetCharWidth() const wxCoord wxWindowDC::GetCharHeight() const { #ifdef __WXGTK20__ - // There should be an easier way. - PangoLayout *layout = pango_layout_new(m_context); - pango_layout_set_font_description(layout, m_fontdesc); - pango_layout_set_text(layout, "H", 1 ); + pango_layout_set_text( m_layout, "H", 1 ); int w,h; - pango_layout_get_pixel_size(layout, &w, &h); - g_object_unref( G_OBJECT( layout ) ); + pango_layout_get_pixel_size( m_layout, &w, &h ); return h; #else GdkFont *font = m_font.GetInternalFont( m_scaleY ); @@ -1726,23 +1754,41 @@ void wxWindowDC::Clear() void wxWindowDC::SetFont( const wxFont &font ) { - // It is common practice to set the font to wxNullFont, so - // don't consider it to be an error - // wxCHECK_RET( font.Ok(), _T("invalid font in wxWindowDC::SetFont") ); - m_font = font; + #ifdef __WXGTK20__ if (m_font.Ok()) { - m_fontdesc = m_font.GetNativeFontInfo()->description; + if (m_fontdesc) + pango_font_description_free( m_fontdesc ); + + m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description ); + if (m_owner) { + PangoContext *oldContext = m_context; + + // We might want to use the X11 context for faster + // rendering on screen if (m_font.GetNoAntiAliasing()) m_context = m_owner->GtkGetPangoX11Context(); else m_context = m_owner->GtkGetPangoDefaultContext(); + + // If we switch back/forth between different contexts + // we also have to create a new layout. I think so, + // at least, and it doesn't hurt to do it. + if (oldContext != m_context) + { + if (m_layout) + g_object_unref( G_OBJECT( m_layout ) ); + + m_layout = pango_layout_new( m_context ); + } } + + pango_layout_set_font_description( m_layout, m_fontdesc ); } #endif }