summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2022-01-27 08:14:34 +0000
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2022-01-27 08:14:34 +0000
commit62850589ee36ccae52e87173e21a1eff510ecac5 (patch)
treec15656c263856e8110c489025af73a2537731e6e
parent393cd568894d1f07858ed9945022b7964635f9f8 (diff)
parente6343ede2f0b9d9663fd25c8fc156cd03a033fdf (diff)
Merge branch 'device-scale' into 'master'
Wrapping surface device scale functions See merge request cairo/cairomm!22
-rw-r--r--cairomm/surface.cc18
-rw-r--r--cairomm/surface.h31
-rw-r--r--tests/test-surface.cc16
3 files changed, 65 insertions, 0 deletions
diff --git a/cairomm/surface.cc b/cairomm/surface.cc
index d7b9708..9982625 100644
--- a/cairomm/surface.cc
+++ b/cairomm/surface.cc
@@ -162,6 +162,24 @@ void Surface::get_device_offset(double& x_offset, double& y_offset) const
cairo_surface_get_device_offset(const_cast<cobject*>(cobj()), &x_offset, &y_offset);
}
+void Surface::set_device_scale(double x_scale, double y_scale)
+{
+ cairo_surface_set_device_scale(cobj(), x_scale, y_scale);
+ check_object_status_and_throw_exception(*this);
+}
+
+void Surface::get_device_scale(double& x_scale, double& y_scale) const
+{
+ cairo_surface_get_device_scale(const_cast<cobject*>(cobj()), &x_scale, &y_scale);
+}
+
+double Surface::get_device_scale() const
+{
+ double x_scale = 1, y_scale = 1;
+ get_device_scale(x_scale, y_scale);
+ return (x_scale + y_scale) / 2;
+}
+
void Surface::set_fallback_resolution(double x_pixels_per_inch, double y_pixels_per_inch)
{
cairo_surface_set_fallback_resolution(cobj(), x_pixels_per_inch, y_pixels_per_inch);
diff --git a/cairomm/surface.h b/cairomm/surface.h
index 663bd57..65d7cea 100644
--- a/cairomm/surface.h
+++ b/cairomm/surface.h
@@ -431,6 +431,37 @@ public:
*/
void get_device_offset(double& x_offset, double& y_offset) const;
+ /** Sets a scale that is multiplied to the device coordinates determined by
+ * the CTM when drawing to surface. One common use for this is to render to
+ * very high resolution display devices at a scale factor, so that code that
+ * assumes 1 pixel will be a certain size will still work. Setting a
+ * transformation via cairo_translate() isn't sufficient to do this, since
+ * functions like Cairo::Context::device_to_user() will expose the hidden scale.
+ *
+ * Note that the scale affects drawing to the surface as well as using the
+ * surface in a source pattern.
+ *
+ * @param x_scale a scale factor in the X direction
+ * @param y_scale a scale factor in the Y direction
+ */
+ void set_device_scale(double x_scale, double y_scale);
+
+ /** Sets x and y scale to the same value.
+ * See set_device_scale(double, double) for details.
+ *
+ * @param scale a scale factor in the X and Y direction
+ */
+ inline void set_device_scale(double scale) { set_device_scale(scale, scale); }
+
+ /** Returns a previous device scale set by set_device_scale().
+ */
+ void get_device_scale(double& x_scale, double& y_scale) const;
+
+ /** Returns the x and y average of a previous device scale set by
+ * set_device_scale().
+ */
+ double get_device_scale() const;
+
/**
* Set the horizontal and vertical resolution for image fallbacks.
*
diff --git a/tests/test-surface.cc b/tests/test-surface.cc
index 50069c8..152787c 100644
--- a/tests/test-surface.cc
+++ b/tests/test-surface.cc
@@ -89,6 +89,22 @@ BOOST_AUTO_TEST_CASE(test_content)
BOOST_CHECK_EQUAL(similar->get_content(), CONTENT_ALPHA);
}
+BOOST_AUTO_TEST_CASE(test_device_scale)
+{
+ auto surface = ImageSurface::create(Surface::Format::ARGB32, 1, 1);
+ const double new_x = 3, new_y = 5;
+ double x, y;
+ surface->set_device_scale(new_x, new_y);
+ surface->get_device_scale(x, y);
+ BOOST_CHECK_EQUAL(x, new_x);
+ BOOST_CHECK_EQUAL(y, new_y);
+ // average x/y scaling
+ BOOST_CHECK_EQUAL(4.0, surface->get_device_scale());
+ // uniform scaling
+ surface->set_device_scale(2);
+ BOOST_CHECK_EQUAL(2.0, surface->get_device_scale());
+}
+
BOOST_AUTO_TEST_CASE(test_fallback_resolution)
{
auto surface = ImageSurface::create(Surface::Format::ARGB32, 1, 1);