emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master cc71a82: Add stipple support on cairo


From: YAMAMOTO Mitsuharu
Subject: [Emacs-diffs] master cc71a82: Add stipple support on cairo
Date: Thu, 30 May 2019 04:17:08 -0400 (EDT)

branch: master
commit cc71a82fc705a73fa3ef6cda3ec6bee1cb654d7e
Author: YAMAMOTO Mitsuharu <address@hidden>
Commit: YAMAMOTO Mitsuharu <address@hidden>

    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.
---
 src/image.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/xterm.c | 33 ++++++++++++++++++++++++++++++---
 src/xterm.h |  4 +++-
 3 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/src/image.c b/src/image.c
index c5d97e0..a2e4aa9 100644
--- a/src/image.c
+++ b/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 ();
diff --git a/src/xterm.c b/src/xterm.c
index 03458cb..e955147 100644
--- a/src/xterm.c
+++ b/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),
diff --git a/src/xterm.h b/src/xterm.h
index ce1443c..2bd2c01 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -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
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]