[PATCH 1/1] Add cairo_shear and family.

James Cloos cloos at jhcloos.com
Sat Jan 10 11:27:45 PST 2009


Shearing multiplies the matrix by [1 sx sy 1 0 0].

With the addition of the shear operation, any matrix can be built
using the provided operations (translate, rotate, scale, shear), while
currently one has to resort to a full-matrix transform for some matrices.

Signed-off-by: James Cloos <cloos at jhcloos.com>
---
 doc/public/cairo-sections.txt         |    3 ++
 doc/public/tmpl/cairo-matrix.sgml     |   20 +++++++++++++
 doc/public/tmpl/cairo-transforms.sgml |   10 ++++++
 src/cairo-gstate.c                    |   23 +++++++++++++++
 src/cairo-matrix.c                    |   51 +++++++++++++++++++++++++++++++++
 src/cairo.c                           |   30 +++++++++++++++++++
 src/cairo.h                           |    5 ++-
 src/cairoint.h                        |    5 +++
 8 files changed, 146 insertions(+), 1 deletions(-)

diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt
index bb64cd6..a1c8841 100644
--- a/doc/public/cairo-sections.txt
+++ b/doc/public/cairo-sections.txt
@@ -262,9 +262,11 @@ cairo_matrix_init
 cairo_matrix_init_identity
 cairo_matrix_init_translate
 cairo_matrix_init_scale
+cairo_matrix_init_shear
 cairo_matrix_init_rotate
 cairo_matrix_translate
 cairo_matrix_scale
+cairo_matrix_shear
 cairo_matrix_rotate
 cairo_matrix_invert
 cairo_matrix_multiply
@@ -356,6 +358,7 @@ cairo_destroy_func_t
 <TITLE>transformations</TITLE>
 cairo_translate
 cairo_scale
+cairo_shear
 cairo_rotate
 cairo_transform
 cairo_set_matrix
diff --git a/doc/public/tmpl/cairo-matrix.sgml b/doc/public/tmpl/cairo-matrix.sgml
index 720cdac..7b61e35 100644
--- a/doc/public/tmpl/cairo-matrix.sgml
+++ b/doc/public/tmpl/cairo-matrix.sgml
@@ -87,6 +87,16 @@ Generic matrix operations
 @sy: 
 
 
+<!-- ##### FUNCTION cairo_matrix_init_shear ##### -->
+<para>
+
+</para>
+
+ at matrix: 
+ at sx: 
+ at sy: 
+
+
 <!-- ##### FUNCTION cairo_matrix_init_rotate ##### -->
 <para>
 
@@ -116,6 +126,16 @@ Generic matrix operations
 @sy: 
 
 
+<!-- ##### FUNCTION cairo_matrix_shear ##### -->
+<para>
+
+</para>
+
+ at matrix: 
+ at sx: 
+ at sy: 
+
+
 <!-- ##### FUNCTION cairo_matrix_rotate ##### -->
 <para>
 
diff --git a/doc/public/tmpl/cairo-transforms.sgml b/doc/public/tmpl/cairo-transforms.sgml
index 60c8ad9..798bd71 100644
--- a/doc/public/tmpl/cairo-transforms.sgml
+++ b/doc/public/tmpl/cairo-transforms.sgml
@@ -43,6 +43,16 @@ space</firstterm>.
 @sy: 
 
 
+<!-- ##### FUNCTION cairo_shear ##### -->
+<para>
+
+</para>
+
+ at cr: 
+ at sx: 
+ at sy: 
+
+
 <!-- ##### FUNCTION cairo_rotate ##### -->
 <para>
 
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index c79e799..5b58ce9 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -635,6 +635,29 @@ _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy)
 }
 
 cairo_status_t
+_cairo_gstate_shear (cairo_gstate_t *gstate, double sx, double sy)
+{
+    cairo_matrix_t tmp;
+
+    if (! ISFINITE (sx) || ! ISFINITE (sy))
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+
+    _cairo_gstate_unset_scaled_font (gstate);
+
+    cairo_matrix_init_shear (&tmp, sx, sy);
+    cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
+
+    /* paranoid check against gradual numerical instability */
+    if (! _cairo_matrix_is_invertible (&gstate->ctm))
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+
+    cairo_matrix_init_shear (&tmp, 1/sx, 1/sy);
+    cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
 _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle)
 {
     cairo_matrix_t tmp;
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 6dfe537..d61cf58 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -219,6 +219,57 @@ cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy)
 slim_hidden_def(cairo_matrix_scale);
 
 /**
+ * cairo_matrix_init_shear:
+ * @matrix: a #cairo_matrix_t
+ * @sx: shear factor in the X direction
+ * @sy: shear factor in the Y direction
+ *
+ * Initializes @matrix to a transformation that shears by @sx and @sy
+ * in the X and Y dimensions, respectively.
+ *
+ * Shearing multiplies the current transformation by the matrix
+ * [1 sx sy 1 0 0].
+ *
+ * Since: 1.10
+ **/
+void
+cairo_matrix_init_shear (cairo_matrix_t *matrix,
+			 double sx, double sy)
+{
+    cairo_matrix_init (matrix,
+		       1,  sx,
+		       sy, 1,
+		       0, 0);
+}
+slim_hidden_def(cairo_matrix_init_scale);
+
+/**
+ * cairo_matrix_shear:
+ * @matrix: a #cairo_matrix_t
+ * @sx: shear factor in the X direction
+ * @sy: shear factor in the Y direction
+ *
+ * Applies shearing by @sx, @sy to the transformation in @matrix. The
+ * effect of the new transformation is to first shear the coordinates
+ * by @sx and @sy, then apply the original transformation to the coordinates.
+ *
+ * Shearing multiplies the current transformation by the matrix
+ * [1 sx sy 1 0 0].
+ *
+ * Since 1.10
+ **/
+void
+cairo_matrix_shear (cairo_matrix_t *matrix, double sx, double sy)
+{
+    cairo_matrix_t tmp;
+
+    cairo_matrix_init_shear (&tmp, sx, sy);
+
+    cairo_matrix_multiply (matrix, &tmp, matrix);
+}
+slim_hidden_def(cairo_matrix_scale);
+
+/**
  * cairo_matrix_init_rotate:
  * @matrix: a #cairo_matrix_t
  * @radians: angle of rotation, in radians. The direction of rotation
diff --git a/src/cairo.c b/src/cairo.c
index 4cdf685..79784be 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -1218,6 +1218,36 @@ cairo_scale (cairo_t *cr, double sx, double sy)
 slim_hidden_def (cairo_scale);
 
 /**
+ * cairo_shear:
+ * @cr: a cairo context
+ * @sx: shear factor for the X dimension
+ * @sy: shear factor for the Y dimension
+ *
+ * Modifies the current transformation matrix (CTM) by shearing the X
+ * and Y user-space axes by @sx and @sy respectively. The shearing of
+ * the axes takes place after any existing transformation of user
+ * space.
+ *
+ * Shearing multiplies the current transformation by the matrix
+ * [1 sx sy 1 0 0].
+ *
+ * Since: 1.10
+ **/
+void
+cairo_shear (cairo_t *cr, double sx, double sy)
+{
+    cairo_status_t status;
+
+    if (cr->status)
+	return;
+
+    status = _cairo_gstate_shear (cr->gstate, sx, sy);
+    if (unlikely (status))
+	_cairo_set_error (cr, status);
+}
+slim_hidden_def (cairo_scale);
+
+/**
  * cairo_rotate:
  * @cr: a cairo context
  * @angle: angle (in radians) by which the user-space axes will be
diff --git a/src/cairo.h b/src/cairo.h
index 8f57ae0..be86d5f 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -590,6 +590,9 @@ cairo_public void
 cairo_scale (cairo_t *cr, double sx, double sy);
 
 cairo_public void
+cairo_shear (cairo_t *cr, double sx, double sy);
+
+cairo_public void
 cairo_rotate (cairo_t *cr, double angle);
 
 cairo_public void
@@ -815,7 +818,7 @@ typedef struct _cairo_scaled_font cairo_scaled_font_t;
  *
  * A #cairo_font_face_t specifies all aspects of a font other
  * than the size or font matrix (a font matrix is used to distort
- * a font by sheering it or scaling it unequally in the two
+ * a font by shearing it or scaling it unequally in the two
  * directions) . A font face can be set on a #cairo_t by using
  * cairo_set_font_face(); the size and font matrix are set with
  * cairo_set_font_size() and cairo_set_font_matrix().
diff --git a/src/cairoint.h b/src/cairoint.h
index a67dff5..38a39fc 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1120,6 +1120,9 @@ cairo_private cairo_status_t
 _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy);
 
 cairo_private cairo_status_t
+_cairo_gstate_shear (cairo_gstate_t *gstate, double sx, double sy);
+
+cairo_private cairo_status_t
 _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle);
 
 cairo_private cairo_status_t
@@ -2579,10 +2582,12 @@ slim_hidden_proto (cairo_matrix_init);
 slim_hidden_proto (cairo_matrix_init_identity);
 slim_hidden_proto (cairo_matrix_init_rotate);
 slim_hidden_proto (cairo_matrix_init_scale);
+slim_hidden_proto (cairo_matrix_init_shear);
 slim_hidden_proto (cairo_matrix_init_translate);
 slim_hidden_proto (cairo_matrix_invert);
 slim_hidden_proto (cairo_matrix_multiply);
 slim_hidden_proto (cairo_matrix_scale);
+slim_hidden_proto (cairo_matrix_shear);
 slim_hidden_proto (cairo_matrix_transform_distance);
 slim_hidden_proto (cairo_matrix_transform_point);
 slim_hidden_proto (cairo_matrix_translate);
-- 
1.6.0.3.613.g9f8f13.dirty


--=-=-=


-- 
James Cloos <cloos at jhcloos.com>         OpenPGP: 1024D/ED7DAEA6

--=-=-=--


More information about the cairo mailing list