[mutter] region-utils: Add API to scale an integer region with a double



commit 9c77e52ad38b314eeef3c8a239d751ad49fa5b9a
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Sep 14 18:51:10 2018 +0200

    region-utils: Add API to scale an integer region with a double
    
    The added API lets the caller decide whether to shrink or grow the
    rectangles if there are rounding issues.
    
    Related: https://gitlab.gnome.org/GNOME/mutter/issues/300

 src/compositor/region-utils.c | 45 +++++++++++++++++++++++++++++++++++++++++++
 src/compositor/region-utils.h | 10 ++++++++++
 2 files changed, 55 insertions(+)
---
diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c
index 1b970ba27..bcae441f4 100644
--- a/src/compositor/region-utils.c
+++ b/src/compositor/region-utils.c
@@ -172,6 +172,51 @@ meta_region_iterator_next (MetaRegionIterator *iter)
     }
 }
 
+cairo_region_t *
+meta_region_scale_double (cairo_region_t       *region,
+                          double                scale,
+                          MetaRoundingStrategy  rounding_strategy)
+{
+  int n_rects, i;
+  cairo_rectangle_int_t *rects;
+  cairo_region_t *scaled_region;
+
+  g_return_val_if_fail (scale > 0.0, NULL);
+
+  if (scale == 1.0)
+    return cairo_region_copy (region);
+
+  n_rects = cairo_region_num_rectangles (region);
+
+  rects = g_malloc (sizeof(cairo_rectangle_int_t) * n_rects);
+  for (i = 0; i < n_rects; i++)
+    {
+      cairo_region_get_rectangle (region, i, &rects[i]);
+
+      switch (rounding_strategy)
+        {
+        case META_ROUNDING_STRATEGY_SHRINK:
+          rects[i].x = (int) ceil (rects[i].x * scale);
+          rects[i].y = (int) ceil (rects[i].y * scale);
+          rects[i].width = (int) floor (rects[i].width * scale);
+          rects[i].height = (int) floor (rects[i].height * scale);
+          break;
+        case META_ROUNDING_STRATEGY_GROW:
+          rects[i].x = (int) floor (rects[i].x * scale);
+          rects[i].y = (int) floor (rects[i].y * scale);
+          rects[i].width = (int) ceil (rects[i].width * scale);
+          rects[i].height = (int) ceil (rects[i].height * scale);
+          break;
+        }
+    }
+
+  scaled_region = cairo_region_create_rectangles (rects, n_rects);
+
+  g_free (rects);
+
+  return scaled_region;
+}
+
 cairo_region_t *
 meta_region_scale (cairo_region_t *region, int scale)
 {
diff --git a/src/compositor/region-utils.h b/src/compositor/region-utils.h
index c9270c327..99a7112e1 100644
--- a/src/compositor/region-utils.h
+++ b/src/compositor/region-utils.h
@@ -26,6 +26,12 @@
 #include <cairo.h>
 #include <glib.h>
 
+typedef enum _MetaRoundingStrategy
+{
+  META_ROUNDING_STRATEGY_SHRINK,
+  META_ROUNDING_STRATEGY_GROW,
+} MetaRoundingStrategy;
+
 /**
  * MetaRegionIterator:
  * @region: region being iterated
@@ -95,6 +101,10 @@ void     meta_region_iterator_next      (MetaRegionIterator *iter);
 cairo_region_t * meta_region_scale (cairo_region_t *region,
                                     int             scale);
 
+cairo_region_t * meta_region_scale_double (cairo_region_t       *region,
+                                           double                scale,
+                                           MetaRoundingStrategy  rounding_strategy);
+
 cairo_region_t * meta_make_border_region (cairo_region_t *region,
                                           int             x_amount,
                                           int             y_amount,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]