[gnome-photos] gegl-gtk-view-helper, tool-crop: Fix cropping on HiDpi
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos] gegl-gtk-view-helper, tool-crop: Fix cropping on HiDpi
- Date: Fri, 4 Dec 2015 10:59:17 +0000 (UTC)
commit e8ac92d28fc470e9f808a96d726c95bf4cff699a
Author: Debarshi Ray <debarshir gnome org>
Date: Thu Dec 3 13:03:36 2015 +0100
gegl-gtk-view-helper, tool-crop: Fix cropping on HiDpi
Just like other higher level Cairo and GTK+ API, GeglGtkView's public
API should only use logical window co-ordinates, and the scaling logic
for sharper rendering on HiDpi should remain internal to the widget.
On the other hand, GEGL is unaware of the scale factor and only deals
in device pixels. So, whenever we touch the pipeline we should
continue using the device pixels.
We simplify the arithmetic a bit (see below) by continuing to use
device pixels in photos_base_item_get_bbox_source, but keeping the
extents of the zoomed source in logical co-ordinates.
This means that ToolCrop, which is mostly drawing and event handling
code, doesn't need to worry about the scale factor. In theory, we
would have to convert from logical co-ordinates to device pixels when
interfacing with GEGL, but, in practice, things line up nicely that we
don't have to.
https://bugzilla.gnome.org/show_bug.cgi?id=758352
src/gegl-gtk-view-helper.c | 37 +++++++++++++++++++++----------------
src/gegl-gtk-view-helper.h | 3 +++
src/photos-tool-crop.c | 6 ++++++
3 files changed, 30 insertions(+), 16 deletions(-)
---
diff --git a/src/gegl-gtk-view-helper.c b/src/gegl-gtk-view-helper.c
index 38a4c63..33b2b37 100644
--- a/src/gegl-gtk-view-helper.c
+++ b/src/gegl-gtk-view-helper.c
@@ -131,7 +131,7 @@ update_autoscale(ViewHelper *self)
} else if (self->autoscale_policy == GEGL_GTK_VIEW_AUTOSCALE_CONTENT) {
/* Calculate and set scaling factor to make the content fit inside */
- float zoom = 1.0;
+ float zoom_scaled = 1.0;
const gint real_viewport_height = viewport.height * self->scale_factor;
const gint real_viewport_width = viewport.width * self->scale_factor;
@@ -140,19 +140,23 @@ update_autoscale(ViewHelper *self)
float height_ratio = bbox.height / (float)real_viewport_height;
float max_ratio = width_ratio >= height_ratio ? width_ratio : height_ratio;
- zoom = 1.0 / max_ratio;
+ zoom_scaled = 1.0 / max_ratio;
- bbox.width = (gint) (zoom * bbox.width + 0.5);
- bbox.height = (gint) (zoom * bbox.height + 0.5);
- bbox.x = (gint) (zoom * bbox.x + 0.5);
- bbox.y = (gint) (zoom * bbox.y + 0.5);
+ bbox.width = (gint) (zoom_scaled * bbox.width + 0.5);
+ bbox.height = (gint) (zoom_scaled * bbox.height + 0.5);
+ bbox.x = (gint) (zoom_scaled * bbox.x + 0.5);
+ bbox.y = (gint) (zoom_scaled * bbox.y + 0.5);
}
- self->zoom = zoom;
+ self->zoom_scaled = zoom_scaled;
+ self->zoom = self->zoom_scaled / (gdouble) self->scale_factor;
/* At this point, viewport is definitely bigger than bbox. */
- self->x = (bbox.width - real_viewport_width) / 2.0 + bbox.x;
- self->y = (bbox.height - real_viewport_height) / 2.0 + bbox.y;
+ self->x_scaled = (bbox.width - real_viewport_width) / 2.0 + bbox.x;
+ self->y_scaled = (bbox.height - real_viewport_height) / 2.0 + bbox.y;
+
+ self->x = self->x_scaled / (gfloat) self->scale_factor;
+ self->y = self->y_scaled / (gfloat) self->scale_factor;
}
}
@@ -191,8 +195,8 @@ view_helper_draw(ViewHelper *self, cairo_t *cr, GdkRectangle *rect)
gint64 end;
gint64 start;
- roi.x = (gint) self->x + rect->x * self->scale_factor;
- roi.y = (gint) self->y + rect->y * self->scale_factor;
+ roi.x = (gint) self->x_scaled + rect->x * self->scale_factor;
+ roi.y = (gint) self->y_scaled + rect->y * self->scale_factor;
roi.width = rect->width * self->scale_factor;
roi.height = rect->height * self->scale_factor;
@@ -202,7 +206,7 @@ view_helper_draw(ViewHelper *self, cairo_t *cr, GdkRectangle *rect)
start = g_get_monotonic_time ();
gegl_node_blit(self->node,
- self->zoom,
+ self->zoom_scaled,
&roi,
babl_format("cairo-ARGB32"),
(gpointer)buf,
@@ -286,6 +290,7 @@ view_helper_set_zoom(ViewHelper *self, float zoom)
return;
self->zoom = zoom;
+ self->zoom_scaled = self->zoom * self->scale_factor;
update_autoscale(self);
trigger_redraw(self, NULL);
}
@@ -313,13 +318,13 @@ void view_helper_get_transformation(ViewHelper *self, GeglMatrix3 *matrix)
/* XXX: Below gives the right result, but is it really the
* way we want transformations to work? */
- matrix->coeff [0][0] = self->zoom; /* xx */
+ matrix->coeff [0][0] = self->zoom_scaled; /* xx */
matrix->coeff [0][1] = 0.0; /* xy */
- matrix->coeff [0][2] = -self->x; /* x0 */
+ matrix->coeff [0][2] = -self->x_scaled; /* x0 */
matrix->coeff [1][0] = 0.0; /* yx */
- matrix->coeff [1][1] = self->zoom; /* yy */
- matrix->coeff [1][2] = -self->y; /* y0 */
+ matrix->coeff [1][1] = self->zoom_scaled; /* yy */
+ matrix->coeff [1][2] = -self->y_scaled; /* y0 */
matrix->coeff [2][0] = 0.0;
matrix->coeff [2][1] = 0.0;
diff --git a/src/gegl-gtk-view-helper.h b/src/gegl-gtk-view-helper.h
index 5689d19..ecee13e 100644
--- a/src/gegl-gtk-view-helper.h
+++ b/src/gegl-gtk-view-helper.h
@@ -44,8 +44,11 @@ struct _ViewHelper {
GeglNode *node;
gfloat x;
+ gfloat x_scaled;
gfloat y;
+ gfloat y_scaled;
gdouble zoom;
+ gdouble zoom_scaled;
gint scale_factor;
gboolean block; /* blocking render */
GeglGtkViewAutoscale autoscale_policy;
diff --git a/src/photos-tool-crop.c b/src/photos-tool-crop.c
index 539e216..334c434 100644
--- a/src/photos-tool-crop.c
+++ b/src/photos-tool-crop.c
@@ -986,6 +986,12 @@ photos_tool_crop_deactivate (PhotosTool *tool)
zoom = gegl_gtk_view_get_zoom (GEGL_GTK_VIEW (self->view));
+ /* GEGL needs the parameters to be in device pixels. So, we
+ * should multiply the extents of the crop rectangle and the
+ * zoom by the scale factor to convert them. However, the scale
+ * factor will cancel itself in the numerator and denominator,
+ * so, in practice, the conversion is unnecessary.
+ */
parameter_type = g_variant_type_new ("a{sd}");
g_variant_builder_init (¶meter, parameter_type);
g_variant_builder_add (¶meter, "{sd}", "height", self->crop_height / zoom);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]