]> git.eshelyaron.com Git - emacs.git/commitdiff
Rework x_scroll_run on cairo
authorYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
Sat, 15 Jun 2019 03:36:26 +0000 (12:36 +0900)
committerYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
Sat, 15 Jun 2019 03:36:26 +0000 (12:36 +0900)
* src/xterm.c (x_scroll_run) [USE_CAIRO]: Use FRAME_CR_CONTEXT or surface type
for conditions to call XCopyArea rather than FRAME_X_DOUBLE_BUFFERED_P.
Set compositing operator to CAIRO_OPERATOR_SOURCE when copying image.

src/xterm.c

index 3cd95b7a65d6d379d7a4f1dc7d6b7c582234d4fc..1608621fc499d8404bfbb622a4aca9c3f1808960 100644 (file)
@@ -4393,51 +4393,53 @@ x_scroll_run (struct window *w, struct run *run)
   gui_clear_cursor (w);
 
 #ifdef USE_CAIRO
-  if (FRAME_X_DOUBLE_BUFFERED_P (f))
-    {
-      cairo_t *cr = FRAME_CR_CONTEXT (f);
-      if (cr)
-       cairo_surface_flush (cairo_get_target (cr));
-      XCopyArea (FRAME_X_DISPLAY (f),
-                FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
-                f->output_data.x->normal_gc,
-                x, from_y,
-                width, height,
-                x, to_y);
-      if (cr)
-       cairo_surface_mark_dirty_rectangle (cairo_get_target (cr),
-                                           x, to_y, width, height);
-    }
-  else if (FRAME_CR_CONTEXT (f))
+  if (FRAME_CR_CONTEXT (f))
     {
-      cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                                      width, height);
-      cairo_t *cr = cairo_create (s);
-      cairo_set_source_surface (cr, cairo_get_target (FRAME_CR_CONTEXT (f)),
-                               -x, -from_y);
-      cairo_paint (cr);
-      cairo_destroy (cr);
+      cairo_surface_t *surface = cairo_get_target (FRAME_CR_CONTEXT (f));
+      if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
+       {
+         eassert (cairo_xlib_surface_get_display (surface)
+                  == FRAME_X_DISPLAY (f));
+         eassert (cairo_xlib_surface_get_drawable (surface)
+                  == FRAME_X_RAW_DRAWABLE (f));
+         cairo_surface_flush (surface);
+         XCopyArea (FRAME_X_DISPLAY (f),
+                    FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
+                    f->output_data.x->normal_gc,
+                    x, from_y,
+                    width, height,
+                    x, to_y);
+         cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
+       }
+      else
+       {
+         cairo_surface_t *s
+           = cairo_surface_create_similar (surface,
+                                           cairo_surface_get_content (surface),
+                                           width, height);
+         cairo_t *cr = cairo_create (s);
+         cairo_set_source_surface (cr, surface, -x, -from_y);
+         cairo_paint (cr);
+         cairo_destroy (cr);
 
-      cr = FRAME_CR_CONTEXT (f);
-      cairo_save (cr);
-      cairo_set_source_surface (cr, s, x, to_y);
-      cairo_rectangle (cr, x, to_y, width, height);
-      cairo_fill (cr);
-      cairo_restore (cr);
-      cairo_surface_destroy (s);
+         cr = FRAME_CR_CONTEXT (f);
+         cairo_save (cr);
+         cairo_set_source_surface (cr, s, x, to_y);
+         cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+         cairo_rectangle (cr, x, to_y, width, height);
+         cairo_fill (cr);
+         cairo_restore (cr);
+         cairo_surface_destroy (s);
+       }
     }
   else
-    {
-      SET_FRAME_GARBAGED (f);
-    }
-#else
-  XCopyArea (FRAME_X_DISPLAY (f),
-             FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
-            f->output_data.x->normal_gc,
-            x, from_y,
-            width, height,
-            x, to_y);
-#endif
+#endif /* USE_CAIRO */
+    XCopyArea (FRAME_X_DISPLAY (f),
+              FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
+              f->output_data.x->normal_gc,
+              x, from_y,
+              width, height,
+              x, to_y);
 
   unblock_input ();
 }