* src/xterm.h (struct x_bitmap_record) [USE_CAIRO]: Remove unused member img.
Add member stipple.
(x_bitmap_stipple) [USE_CAIRO]: Add extern.
* src/image.c (x_bitmap_stipple) [HAVE_X_WINDOWS && USE_CAIRO]: New function.
(image_create_bitmap_from_data, image_create_bitmap_from_file)
(x_create_bitmap_from_xpm_data) [HAVE_X_WINDOWS && USE_CAIRO]: Initialize
stipple member of struct x_bitmap_record.
(free_bitmap_record) [HAVE_X_WINDOWS && USE_CAIRO]: Destroy stipple member.
* src/xterm.c (x_fill_rectangle) [USE_CAIRO]: Inspect gc and draw stipple if
necessary. Use x_bitmap_stipple.
{
return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width;
}
+
+#ifdef USE_CAIRO
+cairo_pattern_t *
+x_bitmap_stipple (struct frame *f, Pixmap pixmap)
+{
+ Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ for (ptrdiff_t i = 0; i < dpyinfo->bitmaps_last; i++)
+ {
+ struct x_bitmap_record *bm = dpyinfo->bitmaps + i;
+
+ if (bm->refcount && bm->pixmap == pixmap && bm->depth == 1)
+ {
+ if (bm->stipple == NULL)
+ {
+ cairo_surface_t *surface
+ = cairo_xlib_surface_create_for_bitmap (FRAME_X_DISPLAY (f),
+ pixmap,
+ FRAME_X_SCREEN (f),
+ bm->width, bm->height);
+ cairo_pattern_t *pattern
+ = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ bm->stipple = pattern;
+ }
+
+ return bm->stipple;
+ }
+ }
+
+ return NULL;
+}
+
+#endif /* USE_CAIRO */
#endif
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
dpyinfo->bitmaps[id - 1].pixmap = bitmap;
dpyinfo->bitmaps[id - 1].have_mask = false;
dpyinfo->bitmaps[id - 1].depth = 1;
+#ifdef USE_CAIRO
+ dpyinfo->bitmaps[id - 1].stipple = NULL;
+#endif /* USE_CAIRO */
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NTGUI
dpyinfo->bitmaps[id - 1].depth = 1;
dpyinfo->bitmaps[id - 1].height = height;
dpyinfo->bitmaps[id - 1].width = width;
+#ifdef USE_CAIRO
+ dpyinfo->bitmaps[id - 1].stipple = NULL;
+#endif /* USE_CAIRO */
return id;
#endif /* HAVE_X_WINDOWS */
XFreePixmap (dpyinfo->display, bm->pixmap);
if (bm->have_mask)
XFreePixmap (dpyinfo->display, bm->mask);
+#ifdef USE_CAIRO
+ if (bm->stipple)
+ cairo_pattern_destroy (bm->stipple);
+#endif /* USE_CAIRO */
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NTGUI
dpyinfo->bitmaps[id - 1].width = attrs.width;
dpyinfo->bitmaps[id - 1].depth = attrs.depth;
dpyinfo->bitmaps[id - 1].refcount = 1;
+#ifdef USE_CAIRO
+ dpyinfo->bitmaps[id - 1].stipple = NULL;
+#endif /* USE_CAIRO */
#ifdef ALLOC_XPM_COLORS
xpm_free_color_cache ();
x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
{
#ifdef USE_CAIRO
+ Display *dpy = FRAME_X_DISPLAY (f);
cairo_t *cr;
+ XGCValues xgcv;
cr = x_begin_cr_clip (f, gc);
- x_set_cr_source_with_gc_foreground (f, gc);
- cairo_rectangle (cr, x, y, width, height);
- cairo_fill (cr);
+ XGetGCValues (dpy, gc, GCFillStyle | GCStipple, &xgcv);
+ if (xgcv.fill_style == FillSolid
+ /* Invalid resource ID (one or more of the three most
+ significant bits set to 1) is obtained if the GCStipple
+ component has never been explicitly set. It should be
+ regarded as Pixmap of unspecified size filled with ones. */
+ || (xgcv.stipple & ((Pixmap) 7 << (sizeof (Pixmap) * CHAR_BIT - 3))))
+ {
+ x_set_cr_source_with_gc_foreground (f, gc);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill (cr);
+ }
+ else
+ {
+ eassert (xgcv.fill_style == FillOpaqueStippled);
+ eassert (xgcv.stipple != None);
+ x_set_cr_source_with_gc_background (f, gc);
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_fill_preserve (cr);
+
+ cairo_pattern_t *pattern = x_bitmap_stipple (f, xgcv.stipple);
+ if (pattern)
+ {
+ x_set_cr_source_with_gc_foreground (f, gc);
+ cairo_clip (cr);
+ cairo_mask (cr, pattern);
+ }
+ }
x_end_cr_clip (f);
#else
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
struct x_bitmap_record
{
#ifdef USE_CAIRO
- void *img;
+ cairo_pattern_t *stipple;
#endif
Pixmap pixmap;
bool have_mask;
/* Clipping rectangles. */
XRectangle clip_rects[MAX_CLIP_RECTS];
};
+
+extern cairo_pattern_t *x_bitmap_stipple (struct frame *, Pixmap);
#endif
\f