X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b666ade78496cd91d648fcfe2fd6b79ce2b15e33..14722c43c30918cd8fbba956b50ac3426d2fe339:/src/gtk/dcclient.cpp?ds=sidebyside diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 93788ede5b..680ab2c6cd 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -71,27 +71,42 @@ static GdkPixmap* GetHatch(int style) const int i = style - wxBRUSHSTYLE_FIRST_HATCH; if (hatches[i] == NULL) { + // This macro creates a bitmap from an XBM file included above. Notice + // the need for the cast because gdk_bitmap_create_from_data() doesn't + // accept unsigned data but the arrays in XBM need to be unsigned to + // avoid warnings (and even errors in C+0x mode) from g++. +#define CREATE_FROM_XBM_DATA(name) \ + gdk_bitmap_create_from_data \ + ( \ + NULL, \ + reinterpret_cast(name ## _bits), \ + name ## _width, \ + name ## _height \ + ) + switch (style) { case wxBRUSHSTYLE_BDIAGONAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, bdiag_bits, bdiag_width, bdiag_height); + hatches[i] = CREATE_FROM_XBM_DATA(bdiag); break; case wxBRUSHSTYLE_CROSSDIAG_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, cdiag_bits, cdiag_width, cdiag_height); + hatches[i] = CREATE_FROM_XBM_DATA(cdiag); break; case wxBRUSHSTYLE_CROSS_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, cross_bits, cross_width, cross_height); + hatches[i] = CREATE_FROM_XBM_DATA(cross); break; case wxBRUSHSTYLE_FDIAGONAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, fdiag_bits, fdiag_width, fdiag_height); + hatches[i] = CREATE_FROM_XBM_DATA(fdiag); break; case wxBRUSHSTYLE_HORIZONTAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, horiz_bits, horiz_width, horiz_height); + hatches[i] = CREATE_FROM_XBM_DATA(horiz); break; case wxBRUSHSTYLE_VERTICAL_HATCH: - hatches[i] = gdk_bitmap_create_from_data(NULL, verti_bits, verti_width, verti_height); + hatches[i] = CREATE_FROM_XBM_DATA(verti); break; } + +#undef CREATE_FROM_XBM_DATA } return hatches[i]; } @@ -114,7 +129,11 @@ enum wxPoolGCType wxTEXT_SCREEN, wxBG_SCREEN, wxPEN_SCREEN, - wxBRUSH_SCREEN + wxBRUSH_SCREEN, + wxTEXT_COLOUR_ALPHA, + wxBG_COLOUR_ALPHA, + wxPEN_COLOUR_ALPHA, + wxBRUSH_COLOUR_ALPHA }; struct wxGC @@ -269,6 +288,7 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) : m_font = window->GetFont(); GtkWidget *widget = window->m_wxwindow; + m_gdkwindow = window->GTKGetDrawingWindow(); // Some controls don't have m_wxwindow - like wxStaticBox, but the user // code should still be able to create wxClientDCs for them @@ -278,16 +298,15 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) : wxCHECK_RET(widget, "DC needs a widget"); - if (GTK_WIDGET_NO_WINDOW(widget)) + m_gdkwindow = widget->window; + if (!gtk_widget_get_has_window(widget)) SetDeviceLocalOrigin(widget->allocation.x, widget->allocation.y); } - m_context = window->GtkGetPangoDefaultContext(); + m_context = window->GTKGetPangoDefaultContext(); m_layout = pango_layout_new( m_context ); m_fontdesc = pango_font_description_copy( widget->style->font_desc ); - m_gdkwindow = widget->window; - // Window not realized ? if (!m_gdkwindow) { @@ -360,6 +379,18 @@ void wxWindowDCImpl::SetUpDC( bool isMemDC ) m_textGC = wxGetPoolGC( m_gdkwindow, wxTEXT_SCREEN ); m_bgGC = wxGetPoolGC( m_gdkwindow, wxBG_SCREEN ); } +#if GTK_CHECK_VERSION(2,12,0) + // gdk_screen_get_rgba_colormap was added in 2.8, but this code is for + // compositing which requires 2.12 + else if (gtk_check_version(2,12,0) == NULL && + m_cmap == gdk_screen_get_rgba_colormap(gdk_colormap_get_screen(m_cmap))) + { + m_penGC = wxGetPoolGC( m_gdkwindow, wxPEN_COLOUR_ALPHA ); + m_brushGC = wxGetPoolGC( m_gdkwindow, wxBRUSH_COLOUR_ALPHA ); + m_textGC = wxGetPoolGC( m_gdkwindow, wxTEXT_COLOUR_ALPHA ); + m_bgGC = wxGetPoolGC( m_gdkwindow, wxBG_COLOUR_ALPHA ); + } +#endif else { m_penGC = wxGetPoolGC( m_gdkwindow, wxPEN_COLOUR ); @@ -419,7 +450,7 @@ void wxWindowDCImpl::SetUpDC( bool isMemDC ) void wxWindowDCImpl::DoGetSize( int* width, int* height ) const { - wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") ); + wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") ); m_window->GetSize(width, height); } @@ -477,7 +508,7 @@ void wxWindowDCImpl::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { if (m_gdkwindow) gdk_draw_line( m_gdkwindow, m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) ); @@ -491,7 +522,7 @@ void wxWindowDCImpl::DoCrossHair( wxCoord x, wxCoord y ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { int w = 0; int h = 0; @@ -589,7 +620,7 @@ void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -601,11 +632,11 @@ void wxWindowDCImpl::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { gdk_draw_arc( m_gdkwindow, m_penGC, FALSE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - if ((m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) && (alpha2 - alpha1 != 360*64)) + if ( m_brush.IsNonTransparent() && (alpha2 - alpha1 != 360*64) ) { gdk_draw_line( m_gdkwindow, m_penGC, xx1, yy1, xxc, yyc ); gdk_draw_line( m_gdkwindow, m_penGC, xxc, yyc, xx2, yy2 ); @@ -635,7 +666,7 @@ void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxC wxCoord start = wxCoord(sa * 64.0); wxCoord end = wxCoord((ea-sa) * 64.0); - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -647,7 +678,7 @@ void wxWindowDCImpl::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxC gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) gdk_draw_arc( m_gdkwindow, m_penGC, FALSE, xx, yy, ww, hh, start, end ); } @@ -659,7 +690,7 @@ void wxWindowDCImpl::DoDrawPoint( wxCoord x, wxCoord y ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if ((m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) && m_gdkwindow) + if ( m_pen.IsNonTransparent() && m_gdkwindow ) gdk_draw_point( m_gdkwindow, m_penGC, XLOG2DEV(x), YLOG2DEV(y) ); CalcBoundingBox (x, y); @@ -669,9 +700,11 @@ void wxWindowDCImpl::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCo { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - if (m_pen.GetStyle() == wxPENSTYLE_TRANSPARENT) return; if (n <= 0) return; + if ( m_pen.IsTransparent() ) + return; + //Check, if scaling is necessary const bool doScale = xoffset != 0 || yoffset != 0 || XLOG2DEV(10) != 10 || YLOG2DEV(10) != 10; @@ -730,7 +763,7 @@ void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[], if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -742,7 +775,7 @@ void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[], gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { /* for (i = 0 ; i < n ; i++) @@ -781,7 +814,7 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -793,9 +826,8 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { -#if 1 if ((m_pen.GetWidth() == 2) && (m_pen.GetCap() == wxCAP_ROUND) && (m_pen.GetJoin() == wxJOIN_ROUND) && (m_pen.GetStyle() == wxPENSTYLE_SOLID)) { @@ -818,7 +850,6 @@ void wxWindowDCImpl::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoo gdk_gc_set_line_attributes( m_penGC, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND ); } else -#endif { // Just use X11 for other cases gdk_draw_rectangle( m_gdkwindow, m_penGC, FALSE, xx, yy, ww-1, hh-1 ); @@ -859,7 +890,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width // CMB: adjust size if outline is drawn otherwise the result is // 1 pixel too wide and high - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { ww--; hh--; @@ -874,7 +905,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width if (dd > hh) dd = hh; rr = dd / 2; - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -891,7 +922,7 @@ void wxWindowDCImpl::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) { gdk_draw_line( m_gdkwindow, m_penGC, xx+rr+1, yy, xx+ww-rr, yy ); gdk_draw_line( m_gdkwindow, m_penGC, xx+rr+1, yy+hh, xx+ww-rr, yy+hh ); @@ -924,7 +955,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord if (m_gdkwindow) { - if (m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT) + if ( m_brush.IsNonTransparent() ) { GdkGC* gc; bool originChanged; @@ -932,7 +963,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord // If the pen is transparent pen we increase the size // for better compatibility with other platforms. - if (m_pen.GetStyle() == wxPENSTYLE_TRANSPARENT) + if (m_pen.IsTransparent()) { ++ww; ++hh; @@ -944,7 +975,7 @@ void wxWindowDCImpl::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord gdk_gc_set_ts_origin(gc, 0, 0); } - if (m_pen.GetStyle() != wxPENSTYLE_TRANSPARENT) + if ( m_pen.IsNonTransparent() ) gdk_draw_arc( m_gdkwindow, m_penGC, false, xx, yy, ww, hh, 0, 360*64 ); } @@ -1059,8 +1090,11 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap, const int w = bitmap.GetWidth(); const int h = bitmap.GetHeight(); + // notice that as the bitmap is not drawn upside down (or right to left) + // even if the corresponding axis direction is inversed, we need to take it + // into account when calculating its bounding box CalcBoundingBox(x, y); - CalcBoundingBox(x + w, y + h); + CalcBoundingBox(x + m_signX*w, y + m_signY*h); // device coords int xx = LogicalToDeviceX(x); @@ -1335,7 +1369,9 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, return true; } -void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) +void wxWindowDCImpl::DoDrawText(const wxString& text, + wxCoord xLogical, + wxCoord yLogical) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); @@ -1343,8 +1379,8 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) if (text.empty()) return; - x = XLOG2DEV(x); - y = YLOG2DEV(y); + wxCoord x = XLOG2DEV(xLogical), + y = YLOG2DEV(yLogical); wxCHECK_RET( m_context, wxT("no Pango context") ); wxCHECK_RET( m_layout, wxT("no Pango layout") ); @@ -1352,69 +1388,12 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) gdk_pango_context_set_colormap( m_context, m_cmap ); // not needed in gtk+ >= 2.6 - bool underlined = m_font.IsOk() && m_font.GetUnderlined(); - wxCharBuffer data = wxGTK_CONV(text); if ( !data ) return; - size_t datalen = strlen(data); - - // in Pango >= 1.16 the "underline of leading/trailing spaces" bug - // has been fixed and thus the hack implemented below should never be used - static bool pangoOk = !wx_pango_version_check(1, 16, 0); - - bool needshack = underlined && !pangoOk; - - if (needshack) - { - // a PangoLayout which has leading/trailing spaces with underlined font - // is not correctly drawn by this pango version: Pango won't underline the spaces. - // This can be a problem; e.g. wxHTML rendering of underlined text relies on - // this behaviour. To workaround this problem, we use a special hack here - // suggested by pango maintainer Behdad Esfahbod: we prepend and append two - // empty space characters and give them a dummy colour attribute. - // This will force Pango to underline the leading/trailing spaces, too. - - wxCharBuffer data_tmp(datalen + 6); - // copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format - memcpy(data_tmp.data(), "\342\200\214", 3); - // copy the user string - memcpy(data_tmp.data() + 3, data, datalen); - // copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format - memcpy(data_tmp.data() + 3 + datalen, "\342\200\214", 3); - - data = data_tmp; - datalen += 6; - } - pango_layout_set_text(m_layout, data, datalen); - - if (underlined) - { - PangoAttrList *attrs = pango_attr_list_new(); - PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); - a->start_index = 0; - a->end_index = datalen; - pango_attr_list_insert(attrs, a); - - if (needshack) - { - // dummy colour for the leading space - a = pango_attr_foreground_new (0x0057, 0x52A9, 0xD614); - a->start_index = 0; - a->end_index = 1; - pango_attr_list_insert(attrs, a); - - // dummy colour for the trailing space - a = pango_attr_foreground_new (0x0057, 0x52A9, 0xD614); - a->start_index = datalen - 1; - a->end_index = datalen; - pango_attr_list_insert(attrs, a); - } - - pango_layout_set_attributes(m_layout, attrs); - pango_attr_list_unref(attrs); - } + pango_layout_set_text(m_layout, data, data.length()); + const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout); int oldSize = 0; const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001; @@ -1453,14 +1432,14 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) // actually apply unscaled font pango_layout_set_font_description( m_layout, m_fontdesc ); } - if (underlined) + if (setAttrs) { // undo underline attributes setting: pango_layout_set_attributes(m_layout, NULL); } - CalcBoundingBox(x + int(w / m_scaleX), y + int(h / m_scaleY)); - CalcBoundingBox(x, y); + CalcBoundingBox(xLogical + int(w / m_scaleX), yLogical + int(h / m_scaleY)); + CalcBoundingBox(xLogical, yLogical); } // TODO: When GTK2.6 is required, merge DoDrawText and DoDrawRotatedText to @@ -1472,197 +1451,80 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord 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); + x = XLOG2DEV(x); + y = YLOG2DEV(y); - 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); - } + pango_layout_set_text(m_layout, wxGTK_CONV(text), -1); + const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout); + 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. - 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)); - // 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 ); + } - // 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); - 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); + const GdkColor* bg_col = NULL; + if (m_backgroundMode == wxBRUSHSTYLE_SOLID) + bg_col = m_textBackgroundColour.GetColor(); - if (isScaled) - { - // reset unscaled size - pango_font_description_set_size( m_fontdesc, oldSize ); + // 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 (setAttrs) + pango_layout_set_attributes(m_layout, NULL); - // actually apply unscaled font - pango_layout_set_font_description( m_layout, m_fontdesc ); - } + // clean up the transformation matrix + pango_context_set_matrix(m_context, NULL); - CalcBoundingBox(x+minX, y+minY); - CalcBoundingBox(x+maxX, y+maxY); - } - else -#endif //__WXGTK26__ - { -#if wxUSE_IMAGE - if ( wxIsNullDouble(angle) ) + if (isScaled) { - DoDrawText(text, x, y); - return; - } - - wxCoord w; - wxCoord h; - - // TODO: implement later without GdkFont for GTK 2.0 - DoGetTextExtent(text, &w, &h, NULL,NULL, &m_font); - - // draw the string normally - wxBitmap src(w, h); - wxMemoryDC dc; - dc.SelectObject(src); - dc.SetFont(GetFont()); - dc.SetBackground(*wxBLACK_BRUSH); - dc.SetBrush(*wxBLACK_BRUSH); - dc.Clear(); - dc.SetTextForeground( *wxWHITE ); - dc.DrawText(text, 0, 0); - dc.SelectObject(wxNullBitmap); + // reset unscaled size + pango_font_description_set_size( m_fontdesc, oldSize ); - // Calculate the size of the rotated bounding box. - double rad = DegToRad(angle); - double dx = cos(rad), - dy = sin(rad); - - // the rectngle vertices are counted clockwise with the first one being at - // (0, 0) (or, rather, at (x, y)) - double x2 = w*dx, - y2 = -w*dy; // y axis points to the bottom, hence minus - double x4 = h*dy, - y4 = h*dx; - double x3 = x4 + x2, - y3 = y4 + y2; - - // calc max and min - wxCoord maxX = (wxCoord)(dmax(x2, dmax(x3, x4)) + 0.5), - maxY = (wxCoord)(dmax(y2, dmax(y3, y4)) + 0.5), - minX = (wxCoord)(dmin(x2, dmin(x3, x4)) - 0.5), - minY = (wxCoord)(dmin(y2, dmin(y3, y4)) - 0.5); - - - wxImage image = src.ConvertToImage(); - - image.ConvertColourToAlpha( m_textForegroundColour.Red(), - m_textForegroundColour.Green(), - m_textForegroundColour.Blue() ); - image = image.Rotate( rad, wxPoint(0,0) ); - - int i_angle = (int) angle; - i_angle = i_angle % 360; - if (i_angle < 0) - i_angle += 360; - int xoffset = 0; - if ((i_angle >= 90.0) && (i_angle < 270.0)) - xoffset = image.GetWidth(); - int yoffset = 0; - if ((i_angle >= 0.0) && (i_angle < 180.0)) - yoffset = image.GetHeight(); - - if ((i_angle >= 0) && (i_angle < 90)) - yoffset -= (int)( cos(rad)*h ); - if ((i_angle >= 90) && (i_angle < 180)) - xoffset -= (int)( sin(rad)*h ); - if ((i_angle >= 180) && (i_angle < 270)) - yoffset -= (int)( cos(rad)*h ); - if ((i_angle >= 270) && (i_angle < 360)) - xoffset -= (int)( sin(rad)*h ); - - int i_x = x - xoffset; - int i_y = y - yoffset; - - src = image; - DoDrawBitmap( src, i_x, i_y, true ); - - - // it would be better to draw with non underlined font and draw the line - // manually here (it would be more straight...) -#if 0 - if ( m_font.GetUnderlined() ) - { - gdk_draw_line( m_gdkwindow, m_textGC, - XLOG2DEV(x + x4), YLOG2DEV(y + y4 + font->descent), - XLOG2DEV(x + x3), YLOG2DEV(y + y3 + font->descent)); - } -#endif // 0 - - // update the bounding box - CalcBoundingBox(x + minX, y + minY); - CalcBoundingBox(x + maxX, y + maxY); -#else // !wxUSE_IMAGE - wxUnusedVar(text); - wxUnusedVar(x); - wxUnusedVar(y); - wxUnusedVar(angle); -#endif // wxUSE_IMAGE/!wxUSE_IMAGE + // actually apply unscaled font + pango_layout_set_font_description( m_layout, m_fontdesc ); } + + CalcBoundingBox(x+minX, y+minY); + CalcBoundingBox(x+maxX, y+maxY); } void wxWindowDCImpl::DoGetTextExtent(const wxString &string, @@ -1778,10 +1640,10 @@ wxCoord wxWindowDCImpl::GetCharWidth() const wxCoord wxWindowDCImpl::GetCharHeight() const { PangoFontMetrics *metrics = pango_context_get_metrics (m_context, m_fontdesc, pango_context_get_language(m_context)); - wxCHECK_MSG( metrics, -1, _T("failed to get pango font metrics") ); + wxCHECK_MSG( metrics, -1, wxT("failed to get pango font metrics") ); wxCoord h = PANGO_PIXELS (pango_font_metrics_get_descent (metrics) + - pango_font_metrics_get_ascent (metrics)); + pango_font_metrics_get_ascent (metrics)); pango_font_metrics_unref (metrics); return h; } @@ -1813,7 +1675,7 @@ void wxWindowDCImpl::SetFont( const wxFont &font ) { PangoContext *oldContext = m_context; - m_context = m_window->GtkGetPangoDefaultContext(); + m_context = m_window->GTKGetPangoDefaultContext(); // If we switch back/forth between different contexts // we also have to create a new layout. I think so, @@ -2081,6 +1943,9 @@ void wxWindowDCImpl::SetLogicalFunction( wxRasterOperationMode function ) case wxNO_OP: mode = GDK_NOOP; break; case wxSRC_INVERT: mode = GDK_COPY_INVERT; break; case wxNOR: mode = GDK_NOR; break; + default: + wxFAIL_MSG("unknown mode"); + return; } m_logicalFunction = function; @@ -2281,7 +2146,6 @@ int wxWindowDCImpl::GetDepth() const return gdk_drawable_get_depth(m_gdkwindow); } - //----------------------------------------------------------------------------- // wxClientDCImpl //----------------------------------------------------------------------------- @@ -2296,7 +2160,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner ) wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) : wxWindowDCImpl( owner, win ) { - wxCHECK_RET( win, _T("NULL window in wxClientDCImpl::wxClientDC") ); + wxCHECK_RET( win, wxT("NULL window in wxClientDCImpl::wxClientDC") ); #ifdef __WXUNIVERSAL__ wxPoint ptOrigin = win->GetClientAreaOrigin(); @@ -2309,7 +2173,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) void wxClientDCImpl::DoGetSize(int *width, int *height) const { - wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") ); + wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") ); m_window->GetClientSize( width, height ); }