[eog] Bug 491197 – Avoiding zoom-in blurriness
- From: Felix Riemann <friemann src gnome org>
- To: svn-commits-list gnome org
- Subject: [eog] Bug 491197 – Avoiding zoom-in blurriness
- Date: Tue, 12 May 2009 06:54:08 -0400 (EDT)
commit 5fb71180039a1bc7992c7d2271f9c66a8811b2f3
Author: Brad Greco <grecobrad gmail com>
Date: Tue May 12 12:47:47 2009 +0200
Bug 491197 â?? Avoiding zoom-in blurriness
Split the antialiasing setting up into interpolation and extrapolation.
This way it can be disabled on zoom-in independently from the zoom-out
setting and vice versa.
UI changes by Evert Verhellen.
---
ChangeLog | 20 ++++++++++
data/eog-preferences-dialog.glade | 63 ++++++++++++++++++++++++++++++--
data/eog-preferences-dialog.ui | 60 +++++++++++++++++++++++++++++--
data/eog.schemas.in | 16 ++++++++-
src/eog-config-keys.h | 1 +
src/eog-preferences-dialog.c | 16 ++++++++
src/eog-scroll-view.c | 73 +++++++++++++++++++++++++++++++------
src/eog-scroll-view.h | 2 +
src/eog-window.c | 64 +++++++++++++++++++++++++++------
9 files changed, 285 insertions(+), 30 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3c1fda8..71ad905 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2009-05-12 Felix Riemann <friemann svn gnome org>
+
+ * data/eog-preferences-dialog.glade:
+ * data/eog-preferences-dialog.ui:
+ * data/eog.schemas.in:
+ * src/eog-config-keys.h:
+ * src/eog-preferences-dialog.c
+ (eog_preferences_dialog_constructor):
+ * src/eog-scroll-view.c (is_zoomed_in), (is_zoomed_out),
+ (paint_iteration_idle), (request_paint_area),
+ (eog_scroll_view_set_antialiasing_in),
+ (eog_scroll_view_set_antialiasing_out),
+ (eog_scroll_view_set_image), (eog_scroll_view_init):
+ * src/eog-scroll-view.h:
+ * src/eog-window.c (eog_window_interp_in_type_changed_cb),
+ (eog_window_interp_out_type_changed_cb), (eog_window_construct_ui),
+ (eog_window_init):
+ Split the antialiasing setting to be able to disable smoothing when
+ zooming in. Fixes bug #491197 (Brad Greco, Evert Verhellen).
+
2009-05-08 Felix Riemann <friemann svn gnome org>
* src/eog-window.c (eog_window_cmd_about):
diff --git a/data/eog-preferences-dialog.glade b/data/eog-preferences-dialog.glade
index 31ec030..3ca79de 100644
--- a/data/eog-preferences-dialog.glade
+++ b/data/eog-preferences-dialog.glade
@@ -115,13 +115,13 @@
</child>
<child>
- <widget class="GtkHBox" id="hbox3">
+ <widget class="GtkHBox" id="hbox_interpolate">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
- <widget class="GtkLabel" id="label7">
+ <widget class="GtkLabel" id="label_interpolate">
<property name="visible">True</property>
<property name="label"> </property>
<property name="use_underline">False</property>
@@ -149,7 +149,64 @@
<widget class="GtkCheckButton" id="interpolate_check">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="label" translatable="yes">Smooth images when _zoomed</property>
+ <property name="label" translatable="yes">Smooth images when zoomed-_out</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox_extrapolate">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label_extrapolate">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="extrapolate_check">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Smooth images when zoomed-_in</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
diff --git a/data/eog-preferences-dialog.ui b/data/eog-preferences-dialog.ui
index 198865f..09cc25b 100644
--- a/data/eog-preferences-dialog.ui
+++ b/data/eog-preferences-dialog.ui
@@ -110,12 +110,12 @@
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox3">
+ <object class="GtkHBox" id="hbox_interpolate">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
- <object class="GtkLabel" id="label7">
+ <object class="GtkLabel" id="label_interpolate">
<property name="visible">True</property>
<property name="label"> </property>
<property name="use_underline">False</property>
@@ -142,7 +142,61 @@
<object class="GtkCheckButton" id="interpolate_check">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="label" translatable="yes">Smooth images when _zoomed</property>
+ <property name="label" translatable="yes">Smooth images when zoomed-_out</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox_extrapolate">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+ <child>
+ <object class="GtkLabel" id="label_extrapolate">
+ <property name="visible">True</property>
+ <property name="label"> </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="extrapolate_check">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Smooth images when zoomed-_in</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
diff --git a/data/eog.schemas.in b/data/eog.schemas.in
index 46be04e..7fff4c5 100644
--- a/data/eog.schemas.in
+++ b/data/eog.schemas.in
@@ -21,13 +21,27 @@
<default>1</default>
<locale name="C">
<short>Interpolate Image</short>
- <long>Whether the image should be interpolated on zoom or not.
+ <long>Whether the image should be interpolated on zoom-out or not.
This leads to better quality but is somewhat slower than non
interpolated images.</long>
</locale>
</schema>
<schema>
+ <key>/schemas/apps/eog/view/extrapolate</key>
+ <applyto>/apps/eog/view/extrapolate</applyto>
+ <owner>eog</owner>
+ <type>bool</type>
+ <default>1</default>
+ <locale name="C">
+ <short>Extrapolate Image</short>
+ <long>Whether the image should be extrapolated on zoom-in or not.
+ This leads to blurry quality and is somewhat slower than non
+ extrapolated images.</long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/eog/view/transparency</key>
<applyto>/apps/eog/view/transparency</applyto>
<owner>eog</owner>
diff --git a/src/eog-config-keys.h b/src/eog-config-keys.h
index 2ffd3fe..f4da034 100644
--- a/src/eog-config-keys.h
+++ b/src/eog-config-keys.h
@@ -34,6 +34,7 @@
#define EOG_CONF_DESKTOP_CAN_SETUP_PAGE "/desktop/gnome/lockdown/disable_print_setup"
#define EOG_CONF_VIEW_INTERPOLATE "/apps/eog/view/interpolate"
+#define EOG_CONF_VIEW_EXTRAPOLATE "/apps/eog/view/extrapolate"
#define EOG_CONF_VIEW_SCROLL_WHEEL_ZOOM "/apps/eog/view/scroll_wheel_zoom"
#define EOG_CONF_VIEW_ZOOM_MULTIPLIER "/apps/eog/view/zoom_multiplier"
#define EOG_CONF_VIEW_AUTOROTATE "/apps/eog/view/autorotate"
diff --git a/src/eog-preferences-dialog.c b/src/eog-preferences-dialog.c
index d7e8757..75276ac 100644
--- a/src/eog-preferences-dialog.c
+++ b/src/eog-preferences-dialog.c
@@ -191,6 +191,7 @@ eog_preferences_dialog_constructor (GType type,
EogPreferencesDialogPrivate *priv;
GtkWidget *dlg;
GtkWidget *interpolate_check;
+ GtkWidget *extrapolate_check;
GtkWidget *autorotate_check;
GtkWidget *color_radio;
GtkWidget *checkpattern_radio;
@@ -217,6 +218,7 @@ eog_preferences_dialog_constructor (GType type,
eog_dialog_get_controls (EOG_DIALOG (object),
"eog_preferences_dialog", &dlg,
"interpolate_check", &interpolate_check,
+ "extrapolate_check", &extrapolate_check,
"autorotate_check", &autorotate_check,
"color_radio", &color_radio,
"checkpattern_radio", &checkpattern_radio,
@@ -238,15 +240,29 @@ eog_preferences_dialog_constructor (GType type,
EOG_CONF_VIEW_INTERPOLATE,
NULL));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extrapolate_check),
+ gconf_client_get_bool (priv->client,
+ EOG_CONF_VIEW_EXTRAPOLATE,
+ NULL));
+
g_object_set_data (G_OBJECT (interpolate_check),
GCONF_OBJECT_KEY,
EOG_CONF_VIEW_INTERPOLATE);
+ g_object_set_data (G_OBJECT (extrapolate_check),
+ GCONF_OBJECT_KEY,
+ EOG_CONF_VIEW_EXTRAPOLATE);
+
g_signal_connect (G_OBJECT (interpolate_check),
"toggled",
G_CALLBACK (pd_check_toggle_cb),
priv->client);
+ g_signal_connect (G_OBJECT (extrapolate_check),
+ "toggled",
+ G_CALLBACK (pd_check_toggle_cb),
+ priv->client);
+
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autorotate_check),
gconf_client_get_bool (priv->client,
EOG_CONF_VIEW_AUTOROTATE,
diff --git a/src/eog-scroll-view.c b/src/eog-scroll-view.c
index e9d54c8..6972077 100644
--- a/src/eog-scroll-view.c
+++ b/src/eog-scroll-view.c
@@ -105,8 +105,11 @@ struct _EogScrollViewPrivate {
/* handler ID for paint idle callback */
guint idle_id;
- /* Interpolation type */
- GdkInterpType interp_type;
+ /* Interpolation type when zoomed in*/
+ GdkInterpType interp_type_in;
+
+ /* Interpolation type when zoomed out*/
+ GdkInterpType interp_type_out;
/* Scroll wheel zoom */
gboolean scroll_wheel_zoom;
@@ -428,6 +431,26 @@ is_unity_zoom (EogScrollView *view)
return DOUBLE_EQUAL (priv->zoom, 1.0);
}
+/* Returns whether the image is zoomed in */
+static gboolean
+is_zoomed_in (EogScrollView *view)
+{
+ EogScrollViewPrivate *priv;
+
+ priv = view->priv;
+ return priv->zoom - 1.0 > DOUBLE_EQUAL_MAX_DIFF;
+}
+
+/* Returns whether the image is zoomed out */
+static gboolean
+is_zoomed_out (EogScrollView *view)
+{
+ EogScrollViewPrivate *priv;
+
+ priv = view->priv;
+ return DOUBLE_EQUAL_MAX_DIFF + priv->zoom - 1.0 < 0.0;
+}
+
/* Returns wether the image is movable, that means if it is larger then
* the actual visible area.
*/
@@ -734,9 +757,15 @@ paint_iteration_idle (gpointer data)
if (eog_irect_empty (&rect)) {
eog_uta_free (priv->uta);
priv->uta = NULL;
- } else
- paint_rectangle (view, &rect, priv->interp_type);
-
+ } else {
+ if (is_zoomed_in (view))
+ paint_rectangle (view, &rect, priv->interp_type_in);
+ else if (is_zoomed_out (view))
+ paint_rectangle (view, &rect, priv->interp_type_out);
+ else
+ paint_rectangle (view, &rect, GDK_INTERP_NEAREST);
+ }
+
if (!priv->uta) {
priv->idle_id = 0;
return FALSE;
@@ -774,7 +803,8 @@ request_paint_area (EogScrollView *view, GdkRectangle *area)
return;
/* Do nearest neighbor, 1:1 zoom or active progressive loading synchronously for speed. */
- if (priv->interp_type == GDK_INTERP_NEAREST ||
+ if ((is_zoomed_in (view) && priv->interp_type_in == GDK_INTERP_NEAREST) ||
+ (is_zoomed_out (view) && priv->interp_type_out == GDK_INTERP_NEAREST) ||
is_unity_zoom (view) ||
priv->progressive_state == PROGRESSIVE_LOADING) {
paint_rectangle (view, &r, GDK_INTERP_NEAREST);
@@ -1664,7 +1694,25 @@ eog_scroll_view_set_zoom_upscale (EogScrollView *view, gboolean upscale)
}
void
-eog_scroll_view_set_antialiasing (EogScrollView *view, gboolean state)
+eog_scroll_view_set_antialiasing_in (EogScrollView *view, gboolean state)
+{
+ EogScrollViewPrivate *priv;
+ GdkInterpType new_interp_type;
+
+ g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
+
+ priv = view->priv;
+
+ new_interp_type = state ? GDK_INTERP_BILINEAR : GDK_INTERP_NEAREST;
+
+ if (priv->interp_type_in != new_interp_type) {
+ priv->interp_type_in = new_interp_type;
+ gtk_widget_queue_draw (GTK_WIDGET (priv->display));
+ }
+}
+
+void
+eog_scroll_view_set_antialiasing_out (EogScrollView *view, gboolean state)
{
EogScrollViewPrivate *priv;
GdkInterpType new_interp_type;
@@ -1675,8 +1723,8 @@ eog_scroll_view_set_antialiasing (EogScrollView *view, gboolean state)
new_interp_type = state ? GDK_INTERP_BILINEAR : GDK_INTERP_NEAREST;
- if (priv->interp_type != new_interp_type) {
- priv->interp_type = new_interp_type;
+ if (priv->interp_type_out != new_interp_type) {
+ priv->interp_type_out = new_interp_type;
gtk_widget_queue_draw (GTK_WIDGET (priv->display));
}
}
@@ -1874,8 +1922,8 @@ eog_scroll_view_set_image (EogScrollView *view, EogImage *image)
gtk_widget_queue_draw (GTK_WIDGET (priv->display));
}
- else if (priv->interp_type != GDK_INTERP_NEAREST &&
- !is_unity_zoom (view))
+ else if ((is_zoomed_in (view) && priv->interp_type_in != GDK_INTERP_NEAREST) ||
+ (is_zoomed_out (view) && priv->interp_type_out != GDK_INTERP_NEAREST))
{
/* paint antialiased image version */
priv->progressive_state = PROGRESSIVE_POLISHING;
@@ -1916,7 +1964,8 @@ eog_scroll_view_init (EogScrollView *view)
priv->zoom_mode = ZOOM_MODE_FIT;
priv->upscale = FALSE;
priv->uta = NULL;
- priv->interp_type = GDK_INTERP_BILINEAR;
+ priv->interp_type_in = GDK_INTERP_BILINEAR;
+ priv->interp_type_out = GDK_INTERP_BILINEAR;
priv->scroll_wheel_zoom = FALSE;
priv->zoom_multiplier = IMAGE_VIEW_ZOOM_MULTIPLIER;
priv->image = NULL;
diff --git a/src/eog-scroll-view.h b/src/eog-scroll-view.h
index 2771071..1e77f69 100644
--- a/src/eog-scroll-view.h
+++ b/src/eog-scroll-view.h
@@ -46,6 +46,8 @@ void eog_scroll_view_set_scroll_wheel_zoom (EogScrollView *view, gboolean sc
void eog_scroll_view_set_zoom_upscale (EogScrollView *view, gboolean upscale);
void eog_scroll_view_set_zoom_multiplier (EogScrollView *view, gdouble multiplier);
void eog_scroll_view_set_antialiasing (EogScrollView *view, gboolean state);
+void eog_scroll_view_set_antialiasing_in (EogScrollView *view, gboolean state);
+void eog_scroll_view_set_antialiasing_out (EogScrollView *view, gboolean state);
void eog_scroll_view_set_transparency (EogScrollView *view, EogTransparencyStyle style, GdkColor *color);
gboolean eog_scroll_view_scrollbars_visible (EogScrollView *view);
void eog_scroll_view_set_popup (EogScrollView *view, GtkMenu *menu);
diff --git a/src/eog-window.c b/src/eog-window.c
index e0deaa3..58db63d 100644
--- a/src/eog-window.c
+++ b/src/eog-window.c
@@ -117,6 +117,7 @@ static gint signals[SIGNAL_LAST];
/* GConfNotifications */
enum {
EOG_WINDOW_NOTIFY_INTERPOLATE,
+ EOG_WINDOW_NOTIFY_EXTRAPOLATE,
EOG_WINDOW_NOTIFY_SCROLLWHEEL_ZOOM,
EOG_WINDOW_NOTIFY_ZOOM_MULTIPLIER,
EOG_WINDOW_NOTIFY_TRANSPARENCY,
@@ -223,13 +224,13 @@ eog_window_error_quark (void)
}
static void
-eog_window_interp_type_changed_cb (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer user_data)
+eog_window_interp_in_type_changed_cb (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
{
EogWindowPrivate *priv;
- gboolean interpolate = TRUE;
+ gboolean interpolate_in = TRUE;
eog_debug (DEBUG_PREFERENCES);
@@ -240,11 +241,36 @@ eog_window_interp_type_changed_cb (GConfClient *client,
g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
- interpolate = gconf_value_get_bool (entry->value);
+ interpolate_in = gconf_value_get_bool (entry->value);
}
- eog_scroll_view_set_antialiasing (EOG_SCROLL_VIEW (priv->view),
- interpolate);
+ eog_scroll_view_set_antialiasing_in (EOG_SCROLL_VIEW (priv->view),
+ interpolate_in);
+}
+
+static void
+eog_window_interp_out_type_changed_cb (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ EogWindowPrivate *priv;
+ gboolean interpolate_out = TRUE;
+
+ eog_debug (DEBUG_PREFERENCES);
+
+ g_return_if_fail (EOG_IS_WINDOW (user_data));
+
+ priv = EOG_WINDOW (user_data)->priv;
+
+ g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
+
+ if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
+ interpolate_out = gconf_value_get_bool (entry->value);
+ }
+
+ eog_scroll_view_set_antialiasing_out (EOG_SCROLL_VIEW (priv->view),
+ interpolate_out);
}
static void
@@ -4127,11 +4153,21 @@ eog_window_construct_ui (EogWindow *window)
gtk_box_pack_end (GTK_BOX (priv->cbox), priv->layout, TRUE, TRUE, 0);
+
+ entry = gconf_client_get_entry (priv->client,
+ EOG_CONF_VIEW_EXTRAPOLATE,
+ NULL, TRUE, NULL);
+ if (entry != NULL) {
+ eog_window_interp_in_type_changed_cb (priv->client, 0, entry, window);
+ gconf_entry_unref (entry);
+ entry = NULL;
+ }
+
entry = gconf_client_get_entry (priv->client,
EOG_CONF_VIEW_INTERPOLATE,
NULL, TRUE, NULL);
if (entry != NULL) {
- eog_window_interp_type_changed_cb (priv->client, 0, entry, window);
+ eog_window_interp_out_type_changed_cb (priv->client, 0, entry, window);
gconf_entry_unref (entry);
entry = NULL;
}
@@ -4222,10 +4258,16 @@ eog_window_init (EogWindow *window)
gconf_client_add_dir (window->priv->client, EOG_CONF_DIR,
GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+ priv->client_notifications[EOG_WINDOW_NOTIFY_EXTRAPOLATE] =
+ gconf_client_notify_add (window->priv->client,
+ EOG_CONF_VIEW_EXTRAPOLATE,
+ eog_window_interp_in_type_changed_cb,
+ window, NULL, NULL);
+
priv->client_notifications[EOG_WINDOW_NOTIFY_INTERPOLATE] =
gconf_client_notify_add (window->priv->client,
- EOG_CONF_VIEW_INTERPOLATE,
- eog_window_interp_type_changed_cb,
+ EOG_CONF_VIEW_INTERPOLATE,
+ eog_window_interp_out_type_changed_cb,
window, NULL, NULL);
priv->client_notifications[EOG_WINDOW_NOTIFY_SCROLLWHEEL_ZOOM] =
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]