[shotwell/wip/phako/hidpi: 617/617] Fix device scale interpretation with HiDPI




commit ed9c1fd20c205ad6a4927b4101914bcc9667188e
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..3d2c019e 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]