[shotwell/wip/phako/hidpi] Fix device scale interpretation with HiDPI
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/phako/hidpi] Fix device scale interpretation with HiDPI
- Date: Thu, 15 Sep 2022 21:58:01 +0000 (UTC)
commit c01e9bf4a55f5000b7b897d21347ed47a01b6db4
Author: Jens Georg <mail jensge org>
Date: Thu Sep 15 23:53:06 2022 +0200
Fix device scale interpretation with HiDPI
Fixes #162
src/Dimensions.vala | 4 +++-
src/PhotoPage.vala | 14 ++++++++++++--
src/SinglePhotoPage.vala | 35 +++++++++++++++++++++++++++++------
src/main.vala | 1 +
src/util/image.vala | 7 +++++--
5 files changed, 50 insertions(+), 11 deletions(-)
---
diff --git a/src/Dimensions.vala b/src/Dimensions.vala
index 3b4163c9..4861b5f4 100644
--- a/src/Dimensions.vala
+++ b/src/Dimensions.vala
@@ -59,8 +59,9 @@ public struct Dimensions {
public static Dimensions for_widget_allocation(Gtk.Widget widget) {
Gtk.Allocation allocation;
widget.get_allocation(out allocation);
+ var scale = widget.get_scale_factor();
- return Dimensions(allocation.width, allocation.height);
+ return Dimensions(allocation.width * scale, allocation.height * scale);
}
public static Dimensions for_rectangle(Gdk.Rectangle rect) {
@@ -283,6 +284,7 @@ public struct Scaling {
public static Scaling for_widget(Gtk.Widget widget, bool scale_up) {
Dimensions viewport = Dimensions.for_widget_allocation(widget);
+ print("****** Viewport size: %s\n", viewport.to_string());
// Because it seems that Gtk.Application realizes the main window and its
// attendant widgets lazily, it's possible to get here with the PhotoPage's
diff --git a/src/PhotoPage.vala b/src/PhotoPage.vala
index 4d21647d..23fa80d7 100644
--- a/src/PhotoPage.vala
+++ b/src/PhotoPage.vala
@@ -994,6 +994,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
}
+ print("Set_pixbuf on_pixbuf_fetched\n");
set_pixbuf(pixbuf, max_dim);
pixbuf_dirty = false;
@@ -1253,6 +1254,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
private void quick_update_pixbuf() {
Gdk.Pixbuf? pixbuf = cache.get_ready_pixbuf(get_photo());
if (pixbuf != null) {
+ print("Set_pixbuf quick_update_pixbuf\n");
set_pixbuf(pixbuf, get_photo().get_dimensions());
pixbuf_dirty = false;
@@ -1266,6 +1268,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
// throw a resized large thumbnail up to get an image on the screen quickly,
// and when ready decode and display the full image
try {
+ print("Set_pixbuf quick_update_pixbuf\n");
set_pixbuf(get_photo().get_preview_pixbuf(scaling), get_photo().get_dimensions());
} catch (Error err) {
warning("%s", err.message);
@@ -1313,6 +1316,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
if (!photo_missing && pixbuf != null) {
+ print("Set_pixbuf update_pixbuf\n");
set_pixbuf(pixbuf, max_dim);
pixbuf_dirty = false;
}
@@ -1422,11 +1426,13 @@ public abstract class EditingHostPage : SinglePhotoPage {
cancel_zoom();
}
+ print("Set_pixbuf swap_in_original\n");
set_pixbuf(original, get_photo().get_master_dimensions());
}
private void swap_out_original() {
if (swapped != null) {
+ print("Set_pixbuf swap_out_original\n");
set_pixbuf(swapped, get_photo().get_dimensions());
restore_zoom_state();
@@ -1470,8 +1476,10 @@ public abstract class EditingHostPage : SinglePhotoPage {
return;
}
- if (unscaled != null)
+ if (unscaled != null) {
+ print("Set_pixbuf activate_tool\n");
set_pixbuf(unscaled, max_dim);
+ }
// create the PhotoCanvas object for a two-way interface to the tool
EditingTools.PhotoCanvas photo_canvas = new EditingHostCanvas(this);
@@ -1532,8 +1540,10 @@ public abstract class EditingHostPage : SinglePhotoPage {
needs_improvement = true;
}
- if (replacement != null)
+ if (replacement != null) {
+ print("Set_pixbuf deactivate_tool\n");
set_pixbuf(replacement, new_max_dim);
+ }
cancel_editing_pixbuf = null;
// if this is a rough pixbuf, schedule an improvement
diff --git a/src/SinglePhotoPage.vala b/src/SinglePhotoPage.vala
index d87b891c..4f9966ed 100644
--- a/src/SinglePhotoPage.vala
+++ b/src/SinglePhotoPage.vala
@@ -215,6 +215,7 @@ public abstract class SinglePhotoPage : Page {
// is used when scale_up_to_viewport is set to true. Pass a Dimensions with no area if
// max_dim should be ignored (i.e. scale_up_to_viewport is false).
public void set_pixbuf(Gdk.Pixbuf unscaled, Dimensions max_dim, Direction? direction = null) {
+ print("New pixbuf: %s\n", max_dim.to_string());
static_zoom_state = ZoomState(max_dim, pixmap_dim,
static_zoom_state.get_interpolation_factor(),
static_zoom_state.get_viewport_center());
@@ -309,14 +310,20 @@ public abstract class SinglePhotoPage : Page {
private bool on_canvas_exposed(Cairo.Context exposed_ctx) {
// draw pixmap onto canvas unless it's not been instantiated, in which case draw black
// (so either old image or contents of another page is not left on screen)
- if (pixmap != null)
+ if (pixmap != null) {
+ pixmap.set_device_scale(Application.get_scale(), Application.get_scale());
exposed_ctx.set_source_surface(pixmap, 0, 0);
+ }
else
set_source_color_from_string(exposed_ctx, "#000");
exposed_ctx.rectangle(0, 0, get_allocated_width(), get_allocated_height());
exposed_ctx.paint();
+ if (pixmap != null) {
+ pixmap.set_device_scale(1.0, 1.0);
+ }
+
return true;
}
@@ -325,26 +332,32 @@ public abstract class SinglePhotoPage : Page {
protected virtual void updated_pixbuf(Gdk.Pixbuf pixbuf, UpdateReason reason, Dimensions old_dim) {
}
+ static int buffer_counter = 0;
protected virtual void paint(Cairo.Context ctx, Dimensions ctx_dim) {
if (is_zoom_supported() && (!static_zoom_state.is_default())) {
+ print("Render zoomed\n");
set_source_color_from_string(ctx, "#000");
ctx.rectangle(0, 0, pixmap_dim.width, pixmap_dim.height);
ctx.fill();
render_zoomed_to_pixmap(static_zoom_state);
} else if (!transition_clock.paint(ctx, ctx_dim.width, ctx_dim.height)) {
+ print("Paint with background\n");
// transition is not running, so paint the full image on a black background
set_source_color_from_string(ctx, "#000");
ctx.rectangle(0, 0, pixmap_dim.width, pixmap_dim.height);
ctx.fill();
+ //scaled.save("src%010d.png".printf(buffer_counter), "png");
paint_pixmap_with_background(ctx, scaled, scaled_pos.x, scaled_pos.y);
+ //pixmap.write_to_png("%010d.png".printf(buffer_counter++));
}
}
private void repaint_pixmap() {
+ print("Repainting pixmap\n");
if (pixmap_ctx == null)
return;
@@ -382,6 +395,9 @@ public abstract class SinglePhotoPage : Page {
// save if reporting an image being rescaled
Dimensions old_scaled_dim = Dimensions.for_rectangle(scaled_pos);
+ print("Old scaled dimensions %s\n", old_scaled_dim.to_string());
+ print("Pixmap dimensions %s\n", pixmap_dim.to_string());
+
Gdk.Rectangle old_scaled_pos = scaled_pos;
// attempt to reuse pixmap
@@ -391,12 +407,14 @@ public abstract class SinglePhotoPage : Page {
// if necessary, create a pixmap as large as the entire viewport
bool new_pixmap = false;
if (pixmap == null) {
- init_pixmap(width, height);
+ init_pixmap(width * Application.get_scale(), height * Application.get_scale());
new_pixmap = true;
}
if (new_pixbuf || new_pixmap) {
+ print("New pixbuf %s / new pixmap %s\n", new_pixbuf.to_string(), new_pixmap.to_string());
Dimensions unscaled_dim = Dimensions.for_pixbuf(unscaled);
+ print("Unscaled dimensions %s\n", unscaled_dim.to_string());
// determine scaled size of pixbuf ... if a max dimensions is set and not scaling up,
// respect it
@@ -406,12 +424,14 @@ public abstract class SinglePhotoPage : Page {
else
scaled_dim = unscaled_dim.get_scaled_proportional(pixmap_dim);
- assert(width >= scaled_dim.width);
- assert(height >= scaled_dim.height);
+ print("Scaled_dim: %s\n", scaled_dim.to_string());
+
+ //assert(width >= scaled_dim.width);
+ //assert(height >= scaled_dim.height);
// center pixbuf on the canvas
- scaled_pos.x = (width - scaled_dim.width) / 2;
- scaled_pos.y = (height - scaled_dim.height) / 2;
+ scaled_pos.x = ((width * Application.get_scale()) - scaled_dim.width) / 2;
+ scaled_pos.y = ((height * Application.get_scale()) - scaled_dim.height) / 2;
scaled_pos.width = scaled_dim.width;
scaled_pos.height = scaled_dim.height;
}
@@ -420,7 +440,9 @@ public abstract class SinglePhotoPage : Page {
// rescale if canvas rescaled or better quality is requested
if (scaled == null) {
+ print("Rescale...\n");
scaled = resize_pixbuf(unscaled, Dimensions.for_rectangle(scaled_pos), interp);
+ print("Rescale...%d %d\n", scaled.width, scaled.height);
UpdateReason reason = UpdateReason.RESIZED_CANVAS;
if (new_pixbuf)
@@ -454,6 +476,7 @@ public abstract class SinglePhotoPage : Page {
assert(canvas.get_window() != null);
// Cairo backing surface (manual double-buffering)
+ print("Init pixmap: Scale %d\n", Application.get_scale());
pixmap = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);
pixmap_dim = Dimensions(width, height);
diff --git a/src/main.vala b/src/main.vala
index 4afaf295..bc96a1a3 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -314,6 +314,7 @@ void editing_exec(string filename, bool fullscreen) {
DirectWindow direct_window = new DirectWindow(initial_file);
direct_window.show_all();
+ direct_window.maximize();
debug("%lf seconds to Gtk.main()", startup_timer.elapsed());
diff --git a/src/util/image.vala b/src/util/image.vala
index 2133364f..e7fcb079 100644
--- a/src/util/image.vala
+++ b/src/util/image.vala
@@ -343,7 +343,7 @@ private Cairo.Surface get_background_surface() {
string color_b;
var config = Config.Facade.get_instance();
- var type = config.get_transparent_background_type();
+ var type = "checkered"; //config.get_transparent_background_type();
switch (type) {
case "checkered":
color_a = "#808080";
@@ -377,6 +377,8 @@ public void invalidate_transparent_background() {
background_surface = null;
}
+static int buffer_br = 0;
+
public void paint_pixmap_with_background (Cairo.Context ctx, Gdk.Pixbuf pixbuf, int x, int y) {
if (pixbuf.get_has_alpha()) {
ctx.set_source_surface(get_background_surface(), 0, 0);
@@ -386,7 +388,8 @@ public void paint_pixmap_with_background (Cairo.Context ctx, Gdk.Pixbuf pixbuf,
}
Gdk.cairo_set_source_pixbuf(ctx, pixbuf, x, y);
- ctx.paint();
+ ctx.rectangle(x, y, pixbuf.width , pixbuf.height);
+ ctx.fill();
}
// Force an axially-aligned box to be inside a rotated rectangle.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]