mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-31 04:41:23 -08:00
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.
This commit is contained in:
parent
ceca1740ea
commit
cc71a82fc7
3 changed files with 81 additions and 4 deletions
48
src/image.c
48
src/image.c
|
|
@ -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 ();
|
||||
|
|
|
|||
33
src/xterm.c
33
src/xterm.c
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue