[gimp] Bug 681968 - Disabling 'Dot for Dot' glitches display
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 681968 - Disabling 'Dot for Dot' glitches display
- Date: Sun, 20 Apr 2014 20:06:30 +0000 (UTC)
commit 051a3e4af48b04dca113b08eb510b7b2fa2d5db9
Author: Michael Natterer <mitch gimp org>
Date: Sun Apr 20 18:06:52 2014 +0200
Bug 681968 - Disabling 'Dot for Dot' glitches display
Enhance the existing but unused display scaling (hidpi/retina) support
to work independently in x and y direction, and adjust the scaling
factors accordingly when dot-for-dot is off and xres != yres.
Increase GIMP_DISPLAY_RENDER_MAX_SCALE from 2.0 to 4.0 and adjust the
rendering chunk size dynamically so we never render chunks that do
not fit into the GimpDisplayXfer buffers.
app/display/gimpdisplayshell-draw.c | 24 +++++++--
app/display/gimpdisplayshell-render.c | 94 +++++++++++++++++++++------------
app/display/gimpdisplayxfer.h | 8 +---
3 files changed, 82 insertions(+), 44 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 408f2ab..643a673 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -137,6 +137,8 @@ gimp_display_shell_draw_image (GimpDisplayShell *shell,
{
gint x1, y1, x2, y2;
gint i, j;
+ gint chunk_width;
+ gint chunk_height;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (gimp_display_get_image (shell->display));
@@ -180,14 +182,28 @@ gimp_display_shell_draw_image (GimpDisplayShell *shell,
/* display the image in RENDER_BUF_WIDTH x RENDER_BUF_HEIGHT
* sized chunks
*/
- for (i = y1; i < y2; i += GIMP_DISPLAY_RENDER_BUF_HEIGHT)
+ chunk_width = GIMP_DISPLAY_RENDER_BUF_WIDTH;
+ chunk_height = GIMP_DISPLAY_RENDER_BUF_HEIGHT;
+
+ if ((shell->scale_x / shell->scale_y) > 2.0)
+ {
+ while ((chunk_width / chunk_height) < (shell->scale_x / shell->scale_y))
+ chunk_height /= 2;
+ }
+ else if ((shell->scale_y / shell->scale_x) > 2.0)
+ {
+ while ((chunk_height / chunk_width) < (shell->scale_y / shell->scale_x))
+ chunk_width /= 2;
+ }
+
+ for (i = y1; i < y2; i += chunk_height)
{
- for (j = x1; j < x2; j += GIMP_DISPLAY_RENDER_BUF_WIDTH)
+ for (j = x1; j < x2; j += chunk_width)
{
gint dx, dy;
- dx = MIN (x2 - j, GIMP_DISPLAY_RENDER_BUF_WIDTH);
- dy = MIN (y2 - i, GIMP_DISPLAY_RENDER_BUF_HEIGHT);
+ dx = MIN (x2 - j, chunk_width);
+ dy = MIN (y2 - i, chunk_height);
gimp_display_shell_render (shell, cr, j, i, dx, dy);
}
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index 158422c..8956f28 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -20,6 +20,7 @@
#include <gegl.h>
#include <gtk/gtk.h>
+#include "libgimpmath/gimpmath.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
@@ -44,6 +45,9 @@
#include "gimpdisplayxfer.h"
+/* #define GIMP_DISPLAY_RENDER_ENABLE_SCALING 1 */
+
+
void
gimp_display_shell_render (GimpDisplayShell *shell,
cairo_t *cr,
@@ -55,11 +59,17 @@ gimp_display_shell_render (GimpDisplayShell *shell,
GimpImage *image;
GimpProjection *projection;
GeglBuffer *buffer;
- gdouble window_scale = 1.0;
+ gdouble scale_x = 1.0;
+ gdouble scale_y = 1.0;
+ gdouble buffer_scale = 1.0;
gint viewport_offset_x;
gint viewport_offset_y;
gint viewport_width;
gint viewport_height;
+ gint scaled_x;
+ gint scaled_y;
+ gint scaled_width;
+ gint scaled_height;
cairo_surface_t *xfer;
gint xfer_src_x;
gint xfer_src_y;
@@ -78,22 +88,46 @@ gimp_display_shell_render (GimpDisplayShell *shell,
#ifdef GIMP_DISPLAY_RENDER_ENABLE_SCALING
/* if we had this future API, things would look pretty on hires (retina) */
- window_scale = gdk_window_get_scale_factor (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET
(shell))));
+ scale_x = gdk_window_get_scale_factor (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET
(shell))));
#endif
- window_scale = MIN (window_scale, GIMP_DISPLAY_RENDER_MAX_SCALE);
+ scale_x = MIN (scale_x, GIMP_DISPLAY_RENDER_MAX_SCALE);
+ scale_y = scale_x;
+
+ if (shell->scale_x > shell->scale_y)
+ {
+ scale_y *= (shell->scale_x / shell->scale_y);
+
+ buffer_scale = shell->scale_y * scale_y;
+ }
+ else if (shell->scale_y > shell->scale_x)
+ {
+ scale_x *= (shell->scale_y / shell->scale_x);
+
+ buffer_scale = shell->scale_x * scale_x;
+ }
+ else
+ {
+ buffer_scale = shell->scale_x * scale_x;
+ }
gimp_display_shell_scroll_get_scaled_viewport (shell,
&viewport_offset_x,
&viewport_offset_y,
&viewport_width,
&viewport_height);
+
+ scaled_x = floor ((x + viewport_offset_x) * scale_x);
+ scaled_y = floor ((y + viewport_offset_y) * scale_y);
+ scaled_width = ceil (w * scale_x);
+ scaled_height = ceil (h * scale_y);
+
if (shell->rotate_transform)
{
xfer = cairo_surface_create_similar_image (cairo_get_target (cr),
CAIRO_FORMAT_ARGB32,
- w * window_scale,
- h * window_scale);
+ scaled_width,
+ scaled_height);
cairo_surface_mark_dirty (xfer);
xfer_src_x = 0;
xfer_src_y = 0;
@@ -101,8 +135,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
else
{
xfer = gimp_display_xfer_get_surface (shell->xfer,
- w * window_scale,
- h * window_scale,
+ scaled_width,
+ scaled_height,
&xfer_src_x,
&xfer_src_y);
}
@@ -136,11 +170,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
}
gegl_buffer_get (buffer,
- GEGL_RECTANGLE ((x + viewport_offset_x) * window_scale,
- (y + viewport_offset_y) * window_scale,
- w * window_scale,
- h * window_scale),
- shell->scale_x * window_scale,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ buffer_scale,
filter_format, shell->filter_data,
shell->filter_stride, GEGL_ABYSS_CLAMP);
@@ -148,13 +180,13 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gimp_color_display_stack_convert_buffer (shell->filter_stack,
shell->filter_buffer,
GEGL_RECTANGLE (0, 0,
- w * window_scale,
- h * window_scale));
+ scaled_width,
+ scaled_height));
gegl_buffer_get (shell->filter_buffer,
GEGL_RECTANGLE (0, 0,
- w * window_scale,
- h * window_scale),
+ scaled_width,
+ scaled_height),
1.0,
babl_format ("cairo-ARGB32"),
data, stride,
@@ -163,11 +195,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
else
{
gegl_buffer_get (buffer,
- GEGL_RECTANGLE ((x + viewport_offset_x) * window_scale,
- (y + viewport_offset_y) * window_scale,
- w * window_scale,
- h * window_scale),
- shell->scale_x * window_scale,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ buffer_scale,
babl_format ("cairo-ARGB32"),
data, stride,
GEGL_ABYSS_CLAMP);
@@ -194,20 +224,18 @@ gimp_display_shell_render (GimpDisplayShell *shell,
data += mask_src_y * stride + mask_src_x * 4;
gegl_buffer_get (shell->mask,
- GEGL_RECTANGLE ((x + viewport_offset_x) * window_scale,
- (y + viewport_offset_y) * window_scale,
- w * window_scale,
- h * window_scale),
- shell->scale_x * window_scale,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ buffer_scale,
babl_format ("Y u8"),
data, stride,
GEGL_ABYSS_CLAMP);
/* invert the mask so what is *not* the foreground object is masked */
- mask_height = h * window_scale;
+ mask_height = scaled_height;
while (mask_height--)
{
- gint mask_width = w * window_scale;
+ gint mask_width = scaled_width;
guchar *d = data;
while (mask_width--)
@@ -226,11 +254,11 @@ gimp_display_shell_render (GimpDisplayShell *shell,
cairo_rectangle (cr, x, y, w, h);
- cairo_scale (cr, 1.0 / window_scale, 1.0 / window_scale);
+ cairo_scale (cr, 1.0 / scale_x, 1.0 / scale_y);
cairo_set_source_surface (cr, xfer,
- (x - xfer_src_x) * window_scale,
- (y - xfer_src_y) * window_scale);
+ x * scale_x - xfer_src_x,
+ y * scale_y - xfer_src_y);
if (shell->rotate_transform)
{
@@ -252,8 +280,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
{
gimp_cairo_set_source_rgba (cr, &shell->mask_color);
cairo_mask_surface (cr, shell->mask_surface,
- (x - mask_src_x) * window_scale,
- (y - mask_src_y) * window_scale);
+ (x - mask_src_x) * scale_x,
+ (y - mask_src_y) * scale_y);
}
cairo_restore (cr);
diff --git a/app/display/gimpdisplayxfer.h b/app/display/gimpdisplayxfer.h
index beb0b91..df1b890 100644
--- a/app/display/gimpdisplayxfer.h
+++ b/app/display/gimpdisplayxfer.h
@@ -19,16 +19,10 @@
#define __GIMP_DISPLAY_XFER_H__
-/* #define GIMP_DISPLAY_RENDER_ENABLE_SCALING 1 */
-
#define GIMP_DISPLAY_RENDER_BUF_WIDTH 256
#define GIMP_DISPLAY_RENDER_BUF_HEIGHT 256
-#ifdef GIMP_DISPLAY_RENDER_ENABLE_SCALING
-#define GIMP_DISPLAY_RENDER_MAX_SCALE 2.0
-#else
-#define GIMP_DISPLAY_RENDER_MAX_SCALE 1.0
-#endif
+#define GIMP_DISPLAY_RENDER_MAX_SCALE 4.0
GimpDisplayXfer * gimp_display_xfer_realize (GtkWidget *widget);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]