summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-12-19 21:19:15 -0500
committerMatthias Clasen <mclasen@redhat.com>2021-12-19 21:53:16 -0500
commit647dfda42af2fa8c940a1df84416b24bbfb2fb48 (patch)
tree54726a4cb623c8660f0dcfaea150d71d817783db
parent254a11aefbd00a95e7a7e938b3044d171afe98df (diff)
downloadpango-647dfda42af2fa8c940a1df84416b24bbfb2fb48.tar.gz
Add a matrix decompose api
This will be used to pull a slant ratio out of the font matrix in the following commits.
-rw-r--r--pango/pango-matrix.c86
-rw-r--r--pango/pango-matrix.h10
2 files changed, 95 insertions, 1 deletions
diff --git a/pango/pango-matrix.c b/pango/pango-matrix.c
index a066eb57..396cb095 100644
--- a/pango/pango-matrix.c
+++ b/pango/pango-matrix.c
@@ -262,6 +262,92 @@ pango_matrix_get_font_scale_factors (const PangoMatrix *matrix,
*yscale = minor;
}
+#define DEG_TO_RAD(x) ((x) / 180. * G_PI)
+#define RAD_TO_DEG(x) ((x) * 180. / G_PI)
+
+/**
+ * pango_matrix_decompose:
+ * @matrix: a `PangoMatrix`
+ * @skew_x: (out): Skew ratio in the X direction
+ * @skew_y: (out): Skew ratio in the Y direction
+ * @scale_x: (out): Scale factor in the X direction
+ * @scale_y: (out): Scale factor in the Y direction
+ * @angle: (out): Rotation angle in radians
+ * @dx: (out): Translation in the X direction
+ * @dy: (out): Translation in the Y direction
+ *
+ * Decompose a matrix into shear, scale, rotation and translation.
+ *
+ * Since: 1.50
+ */
+void
+pango_matrix_decompose (const PangoMatrix *matrix,
+ double *skew_x,
+ double *skew_y,
+ double *scale_x,
+ double *scale_y,
+ double *angle,
+ double *dx,
+ double *dy)
+{
+ PangoMatrix m = matrix ? *matrix : (PangoMatrix) PANGO_MATRIX_INIT;
+ double a = m.xx;
+ double b = m.xy;
+ double c = m.yx;
+ double d = m.yy;
+ double e = m.x0;
+ double f = m.y0;
+
+ *dx = e;
+ *dy = f;
+
+#define sign(x) ((x) < 0 ? -1 : 1)
+
+ double det = a*d - b*c;
+
+ if (det != 0)
+ {
+ /* prefer a decomposition without rotation */
+ if (b == 0)
+ goto ab;
+ else
+ goto cd;
+ }
+
+ if (a != 0 || b != 0)
+ {
+ab:
+ double r = sqrt (a*a + b*b);
+
+ *angle = sign (b) * acos (a / r);
+ *scale_x = r;
+ *scale_y = det / r;
+ *skew_x = (a*c + b*d) / (r*r);
+ *skew_y = 0;
+ }
+ else if (c != 0 || d != 0)
+ {
+cd:
+ double s = sqrt (c*c + d*d);
+
+ *angle = G_PI/2 - sign (d) * acos (-c / s);
+ *scale_x = det / s;
+ *scale_y = s;
+ *skew_x = 0;
+ *skew_y = (a*c + b*d) / (s*s);
+ }
+ else
+ {
+ *angle = 0;
+ *scale_x = 0;
+ *scale_y = 0;
+ *skew_x = 0;
+ *skew_y = 0;
+ }
+
+#undef sign
+}
+
/**
* pango_matrix_transform_distance:
* @matrix: (nullable): a `PangoMatrix`
diff --git a/pango/pango-matrix.h b/pango/pango-matrix.h
index d4277401..c1540586 100644
--- a/pango/pango-matrix.h
+++ b/pango/pango-matrix.h
@@ -121,7 +121,15 @@ double pango_matrix_get_font_scale_factor (const PangoMatrix *matrix) G_GNUC_PUR
PANGO_AVAILABLE_IN_1_38
void pango_matrix_get_font_scale_factors (const PangoMatrix *matrix,
double *xscale, double *yscale);
-
+PANGO_AVAILABLE_IN_1_50
+void pango_matrix_decompose (const PangoMatrix *matrix,
+ double *skew_x,
+ double *skew_y,
+ double *scale_x,
+ double *scale_y,
+ double *angle,
+ double *dx,
+ double *dy);
G_END_DECLS