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_gdkwindow)
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 );
+ gdk_pango_context_set_colormap( m_context, m_cmap ); // not needed in gtk+ >= 2.6
bool underlined = m_font.IsOk() && m_font.GetUnderlined();
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.
+ // If there is a user or actually any scale applied to
+ // the device context, scale the font.
- // scale font description
+ // 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);
- if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
- {
- gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor());
- gdk_draw_rectangle(m_gdkwindow, m_textGC, true, x, y, w, h);
- gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor());
- }
// Draw layout.
int x_rtl = x;
if (m_window && m_window->GetLayoutDirection() == wxLayout_RightToLeft)
x_rtl -= w;
- gdk_draw_layout(m_gdkwindow, m_textGC, x_rtl, y, m_layout);
+
+ 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)
{
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);
wxUnusedVar(y);
wxUnusedVar(angle);
#endif // wxUSE_IMAGE/!wxUSE_IMAGE
+ }
}
void wxWindowDCImpl::DoGetTextExtent(const wxString &string,
case wxCOPY: mode = GDK_COPY; break;
case wxNO_OP: mode = GDK_NOOP; break;
case wxSRC_INVERT: mode = GDK_COPY_INVERT; break;
-
- // unsupported by GTK
- case wxNOR: mode = GDK_COPY; break;
+ case wxNOR: mode = GDK_NOR; break;
default:
wxFAIL_MSG( wxT("unsupported logical function") );
mode = GDK_COPY;
wxCHECK_RET( IsOk(), wxT("invalid window dc") );
m_backgroundMode = mode;
-
- if (!m_gdkwindow) return;
-
- // CMB 21/7/98: fill style of cross-hatch brushes is affected by
- // transparent/solid background mode
-
- if (m_brush.GetStyle() != wxBRUSHSTYLE_SOLID && m_brush.GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
- {
- gdk_gc_set_fill( m_brushGC,
- (m_backgroundMode == wxBRUSHSTYLE_TRANSPARENT) ? GDK_STIPPLED : GDK_OPAQUE_STIPPLED);
- }
}
void wxWindowDCImpl::SetPalette( const wxPalette& WXUNUSED(palette) )
wxCoord xx, yy, ww, hh;
m_currentClippingRegion.GetBox( xx, yy, ww, hh );
-#if wxUSE_NEW_DC
wxGTKDCImpl::DoSetClippingRegion( xx, yy, ww, hh );
-#else
- wxDC::DoSetClippingRegion( xx, yy, ww, hh );
-#endif
GdkRegion* gdkRegion = m_currentClippingRegion.GetRegion();
gdk_gc_set_clip_region(m_penGC, gdkRegion);
gdk_gc_set_clip_region(m_bgGC, gdkRegion);
}
-void wxWindowDCImpl::DoSetClippingRegionAsRegion( const wxRegion ®ion )
+void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion ®ion )
{
wxCHECK_RET( IsOk(), wxT("invalid window dc") );
wxCoord xx, yy, ww, hh;
m_currentClippingRegion.GetBox( xx, yy, ww, hh );
-#if wxUSE_NEW_DC
wxGTKDCImpl::DoSetClippingRegion( xx, yy, ww, hh );
-#else
- wxDC::DoSetClippingRegion( xx, yy, ww, hh );
-#endif
GdkRegion* gdkRegion = m_currentClippingRegion.GetRegion();
gdk_gc_set_clip_region(m_penGC, gdkRegion);
{
wxCHECK_RET( IsOk(), wxT("invalid window dc") );
-#if wxUSE_NEW_DC
wxDCImpl::DestroyClippingRegion();
-#else
- wxDC::DestroyClippingRegion();
-#endif
m_currentClippingRegion.Clear();
{
const wxRealPoint origScale(m_scaleX, m_scaleY);
-#if wxUSE_NEW_DC
wxDCImpl::ComputeScaleAndOrigin();
-#else
- wxDC::ComputeScaleAndOrigin();
-#endif
// if scale has changed call SetPen to recalulate the line width
if ( wxRealPoint(m_scaleX, m_scaleY) != origScale && m_pen.IsOk() )