]> git.mdlowis.com Git - proto/labwc.git/commitdiff
common/box: add box_fit_within()
authorJohn Lindgren <john@jlindgren.net>
Sat, 5 Oct 2024 13:45:48 +0000 (09:45 -0400)
committerJohn Lindgren <john@jlindgren.net>
Mon, 7 Oct 2024 01:30:33 +0000 (21:30 -0400)
Factor out common math from ssd's get_scale_box() for use elsewhere.

include/common/box.h
src/common/box.c
src/ssd/ssd-part.c

index 105ff2974237c71228b50c984f3e2e65bc60b0de..651fcff0ac3452b8d083e1682f87eac592dcd360 100644 (file)
@@ -4,14 +4,23 @@
 
 #include <wlr/util/box.h>
 
-bool
-box_contains(struct wlr_box *box_super, struct wlr_box *box_sub);
+bool box_contains(struct wlr_box *box_super, struct wlr_box *box_sub);
 
-bool
-box_intersects(struct wlr_box *box_a, struct wlr_box *box_b);
+bool box_intersects(struct wlr_box *box_a, struct wlr_box *box_b);
 
 /* Returns the bounding box of 2 boxes */
-void
-box_union(struct wlr_box *box_dest, struct wlr_box *box_a, struct wlr_box *box_b);
+void box_union(struct wlr_box *box_dest, struct wlr_box *box_a,
+       struct wlr_box *box_b);
+
+/*
+ * Fits and centers a content box (width & height) within a bounding box
+ * (max_width & max_height). The content box is downscaled if necessary
+ * (preserving aspect ratio) but not upscaled.
+ *
+ * The returned x & y coordinates are the centered content position
+ * relative to the top-left corner of the bounding box.
+ */
+struct wlr_box box_fit_within(int width, int height, int max_width,
+       int max_height);
 
 #endif /* LABWC_BOX_H */
index 1a56cfe23c79a4a26672135268ba2ef1776bf1f4..eefa535cdc4f23eb3cdc2ff8db3964289b6027e9 100644 (file)
@@ -47,3 +47,29 @@ box_union(struct wlr_box *box_dest, struct wlr_box *box_a, struct wlr_box *box_b
        box_dest->width = x2 - x1;
        box_dest->height = y2 - y1;
 }
+
+struct wlr_box
+box_fit_within(int width, int height, int max_width, int max_height)
+{
+       struct wlr_box box;
+
+       if (width <= max_width && height <= max_height) {
+               /* No downscaling needed */
+               box.width = width;
+               box.height = height;
+       } else if (width * max_height > height * max_width) {
+               /* Wider content, fit width */
+               box.width = max_width;
+               box.height = (height * max_width + (width / 2)) / width;
+       } else {
+               /* Taller content, fit height */
+               box.width = (width * max_height + (height / 2)) / height;
+               box.height = max_height;
+       }
+
+       /* Compute centered position */
+       box.x = (max_width - box.width) / 2;
+       box.y = (max_height - box.height) / 2;
+
+       return box;
+}
index 2e572966744f389d6e78cadab3ac51f86b00dc37..58305e0c3d95048796305a77329fb15bbddb0db4 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <assert.h>
 #include "buffer.h"
+#include "common/box.h"
 #include "common/list.h"
 #include "common/mem.h"
 #include "labwc.h"
@@ -80,29 +81,11 @@ add_scene_buffer(struct wl_list *list, enum ssd_part_type type,
 }
 
 static struct wlr_box
-get_scale_box(struct lab_data_buffer *buffer, double container_width,
-               double container_height)
+get_scale_box(struct lab_data_buffer *buffer, int container_width,
+               int container_height)
 {
-       struct wlr_box icon_geo = {
-               .width = buffer->logical_width,
-               .height = buffer->logical_height
-       };
-
-       /* Scale down buffer if required */
-       if (icon_geo.width && icon_geo.height) {
-               double scale = MIN(container_width / icon_geo.width,
-                       container_height / icon_geo.height);
-               if (scale < 1.0f) {
-                       icon_geo.width = (double)icon_geo.width * scale;
-                       icon_geo.height = (double)icon_geo.height * scale;
-               }
-       }
-
-       /* Center buffer on both axis */
-       icon_geo.x = (container_width - icon_geo.width) / 2;
-       icon_geo.y = (container_height - icon_geo.height) / 2;
-
-       return icon_geo;
+       return box_fit_within(buffer->logical_width, buffer->logical_height,
+               container_width, container_height);
 }
 
 void