X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c92374f0a26608b5b80e079d35da8936fc881bf1..e4097f77c440b1f31a80fe273cc732c14d606096:/src/gtk/dcclient.cpp diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 35b0fd4ff6..2c4a716964 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -2,7 +2,6 @@ // Name: src/gtk/dcclient.cpp // Purpose: wxWindowDCImpl implementation // Author: Robert Roebling -// RCS-ID: $Id$ // Copyright: (c) 1998 Robert Roebling, Chris Breeze // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -64,8 +63,6 @@ static const double RAD2DEG = 180.0 / M_PI; static inline double dmax(double a, double b) { return a > b ? a : b; } static inline double dmin(double a, double b) { return a < b ? a : b; } -static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } - static GdkPixmap* GetHatch(int style) { wxASSERT(style >= wxBRUSHSTYLE_FIRST_HATCH && style <= wxBRUSHSTYLE_LAST_HATCH); @@ -1397,158 +1394,75 @@ void wxWindowDCImpl::DoDrawText(const wxString& text, wxCoord xLogical, wxCoord yLogical) { - wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - - if (!m_gdkwindow) return; - - if (text.empty()) return; - - wxCoord x = XLOG2DEV(xLogical), - y = YLOG2DEV(yLogical); - - 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") ); - - gdk_pango_context_set_colormap( m_context, m_cmap ); // not needed in gtk+ >= 2.6 - - wxCharBuffer data = wxGTK_CONV(text); - if ( !data ) - return; - - 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; - if (isScaled) - { - // 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); - - // Draw layout. - int x_rtl = x; - if (m_window && m_window->GetLayoutDirection() == wxLayout_RightToLeft) - x_rtl -= w; - - const GdkColor* bg_col = NULL; - if (m_backgroundMode == wxBRUSHSTYLE_SOLID) - bg_col = m_textBackgroundColour.GetColor(); - - gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x_rtl, y, m_layout, NULL, bg_col); - - 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 ); - } - if (setAttrs) - { - // undo underline attributes setting: - pango_layout_set_attributes(m_layout, NULL); - } - - CalcBoundingBox(xLogical + int(w / m_scaleX), yLogical + int(h / m_scaleY)); - CalcBoundingBox(xLogical, yLogical); + DoDrawRotatedText(text, xLogical, yLogical, 0); } -// 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 ) +void wxWindowDCImpl::DoDrawRotatedText(const wxString& text, int xLogical, int yLogical, double angle) { if (!m_gdkwindow || text.empty()) return; wxCHECK_RET( IsOk(), wxT("invalid window dc") ); - x = XLOG2DEV(x); - y = YLOG2DEV(y); - 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. - - // 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 (!wxIsSameDouble(m_scaleX, 1) || !wxIsSameDouble(m_scaleY, 1) || !wxIsNullDouble(angle)) + { + pango_matrix_scale(&matrix, m_scaleX, m_scaleY); + pango_matrix_rotate(&matrix, angle); + pango_context_set_matrix(m_context, &matrix); + pango_layout_context_changed(m_layout); + } - if (setAttrs) - pango_layout_set_attributes(m_layout, NULL); + int w, h; + pango_layout_get_pixel_size(m_layout, &w, &h); - // clean up the transformation matrix - pango_context_set_matrix(m_context, NULL); + int x = LogicalToDeviceX(xLogical); + int y = LogicalToDeviceY(yLogical); + if (m_window && m_window->GetLayoutDirection() == wxLayout_RightToLeft) + x -= LogicalToDeviceXRel(w); - if (isScaled) + if (wxIsNullDouble(angle)) { - // 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(xLogical, yLogical); + CalcBoundingBox(xLogical + w, yLogical + h); } + else + { + // 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. + // the rectangle vertices are counted clockwise with the first one + // being at (0, 0) + double x2 = w * matrix.xx; + double y2 = w * matrix.yx; + double x4 = h * matrix.xy; + double y4 = h * matrix.yy; + 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); + x += minX; + y += minY; + CalcBoundingBox(DeviceToLogicalX(x), DeviceToLogicalY(y)); + CalcBoundingBox(DeviceToLogicalX(x + maxX - minX), DeviceToLogicalY(y + maxY - minY)); + } + + gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x, y, m_layout, NULL, bg_col); - CalcBoundingBox(x+minX, y+minY); - CalcBoundingBox(x+maxX, y+maxY); + pango_context_set_matrix(m_context, NULL); + if (setAttrs) + pango_layout_set_attributes(m_layout, NULL); } void wxWindowDCImpl::DoGetTextExtent(const wxString &string, @@ -2075,7 +1989,7 @@ void wxWindowDCImpl::ComputeScaleAndOrigin() wxDCImpl::ComputeScaleAndOrigin(); - // if scale has changed call SetPen to recalulate the line width + // if scale has changed call SetPen to recalculate the line width if ( wxRealPoint(m_scaleX, m_scaleY) != origScale && m_pen.IsOk() ) { // this is a bit artificial, but we need to force wxDC to think the pen