-// compare to current clipping region
-bool wxWindowDCImpl::IsOutsideOfClippingRegion(int x, int y, int w, int h)
-{
- if (m_currentClippingRegion.IsNull())
- return false;
-
- wxRegion region(x, y, w, h);
- region.Intersect( m_currentClippingRegion );
- return region.IsEmpty();
-}
-
-void wxWindowDCImpl::RemoveClipMask(GdkGC *gc)
-{
- gdk_gc_set_clip_mask(gc, NULL);
- gdk_gc_set_clip_origin(gc, 0, 0);
- if (!m_currentClippingRegion.IsNull())
- gdk_gc_set_clip_region(gc, m_currentClippingRegion.GetRegion());
-}
-
-// For drawing a mono-bitmap (XBitmap) we use the current text GC
-void wxWindowDCImpl::DoDrawMonoBitmap(const wxBitmap& bitmap,
- int bmp_w, int bmp_h,
- int xsrc, int ysrc,
- int xdest, int ydest,
- int width, int height)
-{
- wxGtkObject<GdkPixmap>
- bitmap2(gdk_pixmap_new( wxGetRootWindow()->window, bmp_w, bmp_h, -1 ));
- wxGtkObject<GdkGC> gc(gdk_gc_new( bitmap2 ));
- gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() );
- gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() );
- gdk_wx_draw_bitmap(bitmap2, gc, bitmap.GetPixmap(), 0, 0);
-
- gdk_draw_drawable(m_gdkwindow, m_textGC, bitmap2, xsrc, ysrc, xdest, ydest,
- width, height);
-}
-
-// Returns a new mask that is the intersection of the old mask
-// and m_currentClippingRegion with proper offsets
-GdkBitmap* wxWindowDCImpl::GetClippedMask(GdkBitmap* mask, int w, int h,
- int x, int y,
- int xsrcMask, int ysrcMask)
-{
- // create monochrome bitmap that will be used as the new mask
- GdkBitmap *new_mask = gdk_pixmap_new( wxGetRootWindow()->window, w, h, 1 );
-
- GdkColor c0, c1;
- c0.pixel = 0;
- c1.pixel = 1;
- wxGtkObject<GdkGC> gc(gdk_gc_new( new_mask ));
-
- // zero-ing new_mask
- gdk_gc_set_foreground( gc, &c0 );
- gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, w, h );
-
- // clipping region
- gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() );
- gdk_gc_set_clip_origin( gc, -x, -y );
-
- // copy the old mask to the new_mask in the clip region area
- gdk_gc_set_background( gc, &c0 );
- gdk_gc_set_foreground( gc, &c1 );
- gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED );
- gdk_gc_set_ts_origin( gc, -xsrcMask, -ysrcMask );
- gdk_gc_set_stipple( gc, mask );
- gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, w, h );
-
- return new_mask;
+// scale a pixbuf, return new pixbuf, unref old one
+static GdkPixbuf*
+Scale(GdkPixbuf* pixbuf, int dst_w, int dst_h, double sx, double sy)
+{
+ GdkPixbuf* pixbuf_scaled = gdk_pixbuf_new(
+ GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha(pixbuf), 8, dst_w, dst_h);
+ gdk_pixbuf_scale(pixbuf, pixbuf_scaled,
+ 0, 0, dst_w, dst_h, 0, 0, sx, sy, GDK_INTERP_NEAREST);
+ g_object_unref(pixbuf);
+ return pixbuf_scaled;
+}
+
+// scale part of a pixmap using pixbuf scaling, return pixbuf
+static GdkPixbuf*
+Scale(GdkPixmap* pixmap, int x, int y, int w, int h, int dst_w, int dst_h, double sx, double sy)
+{
+ GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(
+ NULL, pixmap, NULL, x, y, 0, 0, w, h);
+ return Scale(pixbuf, dst_w, dst_h, sx, sy);
+}
+
+// scale part of a mask pixmap, return new mask, unref old one
+static GdkPixmap*
+ScaleMask(GdkPixmap* mask, int x, int y, int w, int h, int dst_w, int dst_h, double sx, double sy)
+{
+ GdkPixbuf* pixbuf = Scale(mask, x, y, w, h, dst_w, dst_h, sx, sy);
+
+ // convert black and white pixbuf back to a mono pixmap
+ const unsigned out_rowstride = (dst_w + 7) / 8;
+ const size_t data_size = out_rowstride * size_t(dst_h);
+ char* data = new char[data_size];
+ char* out = data;
+ const guchar* row = gdk_pixbuf_get_pixels(pixbuf);
+ const int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+ memset(data, 0, data_size);
+ for (int j = 0; j < dst_h; j++, row += rowstride, out += out_rowstride)
+ {
+ const guchar* in = row;
+ for (int i = 0; i < dst_w; i++, in += 3)
+ if (*in)
+ out[i >> 3] |= 1 << (i & 7);
+ }
+ g_object_unref(pixbuf);
+ GdkPixmap* pixmap = gdk_bitmap_create_from_data(mask, data, dst_w, dst_h);
+ delete[] data;
+ g_object_unref(mask);
+ return pixmap;
+}
+
+// Make a new mask from part of a mask and a clip region.
+// Return new mask, unref old one.
+static GdkPixmap*
+ClipMask(GdkPixmap* mask, GdkRegion* clipRegion, int x, int y, int dst_x, int dst_y, int w, int h)
+{
+ GdkGCValues gcValues;
+ gcValues.foreground.pixel = 0;
+ GdkGC* gc = gdk_gc_new_with_values(mask, &gcValues, GDK_GC_FOREGROUND);
+ GdkPixmap* pixmap = gdk_pixmap_new(mask, w, h, 1);
+ // clear new mask, so clipped areas will be masked
+ gdk_draw_rectangle(pixmap, gc, true, 0, 0, w, h);
+ gdk_gc_set_clip_region(gc, clipRegion);
+ gdk_gc_set_clip_origin(gc, -dst_x, -dst_y);
+ // draw old mask onto new one, with clip
+ gdk_draw_drawable(pixmap, gc, mask, x, y, 0, 0, w, h);
+ g_object_unref(gc);
+ g_object_unref(mask);
+ return pixmap;
+}
+
+// make a color pixmap from part of a mono one, using text fg/bg colors
+GdkPixmap*
+wxWindowDCImpl::MonoToColor(GdkPixmap* monoPixmap, int x, int y, int w, int h) const
+{
+ GdkPixmap* pixmap = gdk_pixmap_new(m_gdkwindow, w, h, -1);
+ GdkGCValues gcValues;
+ gcValues.foreground.pixel = m_textForegroundColour.GetColor()->pixel;
+ gcValues.background.pixel = m_textBackgroundColour.GetColor()->pixel;
+ gcValues.stipple = monoPixmap;
+ gcValues.fill = GDK_OPAQUE_STIPPLED;
+ gcValues.ts_x_origin = -x;
+ gcValues.ts_y_origin = -y;
+ GdkGC* gc = gdk_gc_new_with_values(pixmap, &gcValues, GdkGCValuesMask(
+ GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_STIPPLE | GDK_GC_FILL |
+ GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN));
+ gdk_draw_rectangle(pixmap, gc, true, 0, 0, w, h);
+ g_object_unref(gc);
+ return pixmap;