summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinfirit <[email protected]>2014-07-24 15:42:17 +0200
committerinfirit <[email protected]>2014-07-24 20:17:46 +0200
commitc5fdcd1de29bc9fd3d64cfd2d24c62e467e4e6e8 (patch)
tree459331c22ba052aa1a2945b0f11f6dd23fc80390
parent45d1ebfc67a1bd33bc0232ed658dc5e02c13a612 (diff)
downloadeom-c5fdcd1de29bc9fd3d64cfd2d24c62e467e4e6e8.tar.bz2
eom-c5fdcd1de29bc9fd3d64cfd2d24c62e467e4e6e8.tar.xz
Fully rely on cairo to render the image in EomScrollView
Based on eog commit 919929eea1d63380f773f9c0a339a32149e592ba From Claudio Saavedra <[email protected]>
-rw-r--r--src/eom-scroll-view.c105
1 files changed, 92 insertions, 13 deletions
diff --git a/src/eom-scroll-view.c b/src/eom-scroll-view.c
index eb1d53b..56e77d1 100644
--- a/src/eom-scroll-view.c
+++ b/src/eom-scroll-view.c
@@ -623,6 +623,42 @@ get_transparency_params (EomScrollView *view, int *size, guint32 *color1, guint3
*size = CHECK_MEDIUM;
}
+static cairo_surface_t *
+create_background_surface (EomScrollView *view)
+{
+ int check_size;
+ guint32 check_1 = 0;
+ guint32 check_2 = 0;
+ cairo_surface_t *surface;
+
+ get_transparency_params (view, &check_size, &check_1, &check_2);
+ surface = gdk_window_create_similar_surface (gtk_widget_get_window (view->priv->display),
+ CAIRO_CONTENT_COLOR,
+ check_size * 2, check_size * 2);
+ cairo_t* cr = cairo_create (surface);
+ cairo_set_source_rgba (cr,
+ ((check_1 & 0xff0000) >> 16) / 255.,
+ ((check_1 & 0x00ff00) >> 8) / 255.,
+ (check_1 & 0x0000ff) / 255.,
+ 1.);
+ cairo_rectangle (cr, 0, 0, check_size, check_size);
+ cairo_rectangle (cr, check_size, check_size, check_size, check_size);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr,
+ ((check_2 & 0xff0000) >> 16) / 255.,
+ ((check_2 & 0x00ff00) >> 8) / 255.,
+ (check_2 & 0x0000ff) / 255.,
+ 1.);
+ cairo_rectangle (cr, 0, check_size, check_size, check_size);
+ cairo_rectangle (cr, check_size, 0, check_size, check_size);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+
+ return surface;
+}
+#if 0
#ifdef HAVE_RSVG
static cairo_surface_t *
create_background_surface (EomScrollView *view)
@@ -1060,6 +1096,7 @@ request_paint_area (EomScrollView *view, GdkRectangle *area)
priv->uta = uta_add_rect (priv->uta, r.x0, r.y0, r.x1, r.y1);
}
+#endif
/* =======================================
@@ -1121,10 +1158,12 @@ scroll_to (EomScrollView *view, int x, int y, gboolean change_adjustments)
twidth = (allocation.width + EOM_UTILE_SIZE - 1) >> EOM_UTILE_SHIFT;
theight = (allocation.height + EOM_UTILE_SIZE - 1) >> EOM_UTILE_SHIFT;
+#if 0
if (priv->uta)
g_assert (priv->idle_id != 0);
else
priv->idle_id = g_idle_add (paint_iteration_idle, view);
+#endif
priv->uta = uta_ensure_size (priv->uta, 0, 0, twidth, theight);
@@ -1727,18 +1766,16 @@ eom_scroll_view_focus_out_event (GtkWidget *widget,
return FALSE;
}
-/* Expose event handler for the drawing area. First we process the whole dirty
- * region by drawing a non-interpolated version, which is "instantaneous", and
- * we do this synchronously. Then, if we are set to use interpolation, we queue
- * an idle handler to handle interpolated drawing there.
- */
static gboolean
display_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
EomScrollView *view;
- GdkRectangle *rects;
- gint n_rects;
- int i;
+ EomScrollViewPrivate *priv;
+ cairo_t *cr;
+ GtkAllocation allocation;
+ int scaled_width, scaled_height;
+ int xofs, yofs;
+ EomIRect r, d;
g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
@@ -1746,14 +1783,56 @@ display_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
view = EOM_SCROLL_VIEW (data);
- gdk_region_get_rectangles (event->region, &rects, &n_rects);
+ priv = view->priv;
- for (i = 0; i < n_rects; i++) {
- request_paint_area (view, rects + i);
- }
+ if (priv->pixbuf == NULL)
+ return TRUE;
- g_free (rects);
+ compute_scaled_size (view, priv->zoom, &scaled_width, &scaled_height);
+ gtk_widget_get_allocation (GTK_WIDGET (priv->display), &allocation);
+
+ /* Compute image offsets with respect to the window */
+
+ if (scaled_width <= allocation.width)
+ xofs = (allocation.width - scaled_width) / 2;
+ else
+ xofs = -priv->xofs;
+
+ if (scaled_height <= allocation.height)
+ yofs = (allocation.height - scaled_height) / 2;
+ else
+ yofs = -priv->yofs;
+
+ eom_debug_message (DEBUG_WINDOW, "zoom %.2f, xofs: %i, yofs: %i scaled w: %i h: %i\n",
+ priv->zoom, xofs, yofs, scaled_width, scaled_height);
+
+ cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (GTK_WIDGET (view->priv->display))));
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
+ /* Paint the background */
+ cairo_set_source (cr, gdk_window_get_background_pattern (gtk_widget_get_window (priv->display)));
+ cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
+ cairo_rectangle (cr, MAX (0, xofs), MAX (0, yofs),
+ scaled_width, scaled_height);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_fill (cr);
+
+ if (gdk_pixbuf_get_has_alpha (priv->pixbuf)) {
+ if (priv->background_surface == NULL) {
+ priv->background_surface = create_background_surface (view);
+ }
+ cairo_set_source_surface (cr, priv->background_surface, xofs, yofs);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_rectangle (cr, xofs, yofs, scaled_width, scaled_height);
+ cairo_fill (cr);
+ }
+
+ cairo_scale (cr, priv->zoom, priv->zoom);
+ cairo_set_source_surface (cr, priv->surface, xofs/priv->zoom, yofs/priv->zoom);
+ cairo_paint (cr);
+ cairo_destroy (cr);
return TRUE;
}