[PATCH 1/1] Add cairo_shear and family.
James Cloos
cloos at jhcloos.com
Sat Jan 10 11:28:33 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 | 55 +++++++++++++++++++++++++++++++++
src/cairo.c | 32 +++++++++++++++++++
src/cairo.h | 5 ++-
src/cairoint.h | 5 +++
8 files changed, 152 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..f96b131 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -219,6 +219,61 @@ 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 0
+ * sy 1 0
+ * 0 0 1
+ *
+ **/
+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 0
+ * sy 1 0
+ * 0 0 1
+ *
+ **/
+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..4321661 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -1218,6 +1218,38 @@ 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 0
+ * sy 1 0
+ * 0 0 1
+ *
+ **/
+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