Commit cc71a82f authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu

Add stipple support on cairo

* 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.
parent ceca1740
Pipeline #1833 failed with stage
in 52 minutes and 38 seconds
......@@ -291,6 +291,41 @@ x_bitmap_width (struct frame *f, ptrdiff_t id)
{
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)
......@@ -389,6 +424,9 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
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
......@@ -470,6 +508,9 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
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 */
......@@ -484,6 +525,10 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
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
......@@ -3843,6 +3888,9 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
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 ();
......
......@@ -698,12 +698,39 @@ static void
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),
......
......@@ -130,7 +130,7 @@ struct xim_inst_t
struct x_bitmap_record
{
#ifdef USE_CAIRO
void *img;
cairo_pattern_t *stipple;
#endif
Pixmap pixmap;
bool have_mask;
......@@ -151,6 +151,8 @@ struct x_gc_ext_data
/* Clipping rectangles. */
XRectangle clip_rects[MAX_CLIP_RECTS];
};
extern cairo_pattern_t *x_bitmap_stipple (struct frame *, Pixmap);
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment