Factor out common math from ssd's get_scale_box() for use elsewhere.
#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 */
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;
+}
#include <assert.h>
#include "buffer.h"
+#include "common/box.h"
#include "common/list.h"
#include "common/mem.h"
#include "labwc.h"
}
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