1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2002 University of Southern California
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is University of Southern
34 * Carl D. Worth <cworth@cworth.org>
41 #if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
42 #define ISFINITE(x) isfinite (x)
44 #define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
48 _cairo_matrix_scalar_multiply (cairo_matrix_t
*matrix
, double scalar
);
51 _cairo_matrix_compute_adjoint (cairo_matrix_t
*matrix
);
54 * cairo_matrix_init_identity:
55 * @matrix: a #cairo_matrix_t
57 * Modifies @matrix to be an identity transformation.
60 cairo_matrix_init_identity (cairo_matrix_t
*matrix
)
62 cairo_matrix_init (matrix
,
67 slim_hidden_def(cairo_matrix_init_identity
);
71 * @matrix: a #cairo_matrix_t
72 * @xx: xx component of the affine transformation
73 * @yx: yx component of the affine transformation
74 * @xy: xy component of the affine transformation
75 * @yy: yy component of the affine transformation
76 * @x0: X translation component of the affine transformation
77 * @y0: Y translation component of the affine transformation
79 * Sets @matrix to be the affine transformation given by
80 * @xx, @yx, @xy, @yy, @x0, @y0. The transformation is given
83 * x_new = xx * x + xy * y + x0;
84 * y_new = yx * x + yy * y + y0;
88 cairo_matrix_init (cairo_matrix_t
*matrix
,
94 matrix
->xx
= xx
; matrix
->yx
= yx
;
95 matrix
->xy
= xy
; matrix
->yy
= yy
;
96 matrix
->x0
= x0
; matrix
->y0
= y0
;
98 slim_hidden_def(cairo_matrix_init
);
101 * _cairo_matrix_get_affine:
102 * @matrix: a #cairo_matrix_t
103 * @xx: location to store xx component of matrix
104 * @yx: location to store yx component of matrix
105 * @xy: location to store xy component of matrix
106 * @yy: location to store yy component of matrix
107 * @x0: location to store x0 (X-translation component) of matrix, or %NULL
108 * @y0: location to store y0 (Y-translation component) of matrix, or %NULL
110 * Gets the matrix values for the affine transformation that @matrix represents.
111 * See cairo_matrix_init().
114 * This function is a leftover from the old public API, but is still
115 * mildly useful as an internal means for getting at the matrix
116 * members in a positional way. For example, when reassigning to some
117 * external matrix type, or when renaming members to more meaningful
118 * names (such as a,b,c,d,e,f) for particular manipulations.
121 _cairo_matrix_get_affine (const cairo_matrix_t
*matrix
,
122 double *xx
, double *yx
,
123 double *xy
, double *yy
,
124 double *x0
, double *y0
)
139 * cairo_matrix_init_translate:
140 * @matrix: a #cairo_matrix_t
141 * @tx: amount to translate in the X direction
142 * @ty: amount to translate in the Y direction
144 * Initializes @matrix to a transformation that translates by @tx and
145 * @ty in the X and Y dimensions, respectively.
148 cairo_matrix_init_translate (cairo_matrix_t
*matrix
,
149 double tx
, double ty
)
151 cairo_matrix_init (matrix
,
156 slim_hidden_def(cairo_matrix_init_translate
);
159 * cairo_matrix_translate:
160 * @matrix: a #cairo_matrix_t
161 * @tx: amount to translate in the X direction
162 * @ty: amount to translate in the Y direction
164 * Applies a translation by @tx, @ty to the transformation in
165 * @matrix. The effect of the new transformation is to first translate
166 * the coordinates by @tx and @ty, then apply the original transformation
167 * to the coordinates.
170 cairo_matrix_translate (cairo_matrix_t
*matrix
, double tx
, double ty
)
174 cairo_matrix_init_translate (&tmp
, tx
, ty
);
176 cairo_matrix_multiply (matrix
, &tmp
, matrix
);
178 slim_hidden_def (cairo_matrix_translate
);
181 * cairo_matrix_init_scale:
182 * @matrix: a #cairo_matrix_t
183 * @sx: scale factor in the X direction
184 * @sy: scale factor in the Y direction
186 * Initializes @matrix to a transformation that scales by @sx and @sy
187 * in the X and Y dimensions, respectively.
190 cairo_matrix_init_scale (cairo_matrix_t
*matrix
,
191 double sx
, double sy
)
193 cairo_matrix_init (matrix
,
198 slim_hidden_def(cairo_matrix_init_scale
);
201 * cairo_matrix_scale:
202 * @matrix: a #cairo_matrix_t
203 * @sx: scale factor in the X direction
204 * @sy: scale factor in the Y direction
206 * Applies scaling by @sx, @sy to the transformation in @matrix. The
207 * effect of the new transformation is to first scale the coordinates
208 * by @sx and @sy, then apply the original transformation to the coordinates.
211 cairo_matrix_scale (cairo_matrix_t
*matrix
, double sx
, double sy
)
215 cairo_matrix_init_scale (&tmp
, sx
, sy
);
217 cairo_matrix_multiply (matrix
, &tmp
, matrix
);
219 slim_hidden_def(cairo_matrix_scale
);
222 * cairo_matrix_init_rotate:
223 * @matrix: a #cairo_matrix_t
224 * @radians: angle of rotation, in radians. The direction of rotation
225 * is defined such that positive angles rotate in the direction from
226 * the positive X axis toward the positive Y axis. With the default
227 * axis orientation of cairo, positive angles rotate in a clockwise
230 * Initialized @matrix to a transformation that rotates by @radians.
233 cairo_matrix_init_rotate (cairo_matrix_t
*matrix
,
242 cairo_matrix_init (matrix
,
247 slim_hidden_def(cairo_matrix_init_rotate
);
250 * cairo_matrix_rotate:
251 * @matrix: a #cairo_matrix_t
252 * @radians: angle of rotation, in radians. The direction of rotation
253 * is defined such that positive angles rotate in the direction from
254 * the positive X axis toward the positive Y axis. With the default
255 * axis orientation of cairo, positive angles rotate in a clockwise
258 * Applies rotation by @radians to the transformation in
259 * @matrix. The effect of the new transformation is to first rotate the
260 * coordinates by @radians, then apply the original transformation
261 * to the coordinates.
264 cairo_matrix_rotate (cairo_matrix_t
*matrix
, double radians
)
268 cairo_matrix_init_rotate (&tmp
, radians
);
270 cairo_matrix_multiply (matrix
, &tmp
, matrix
);
274 * cairo_matrix_multiply:
275 * @result: a #cairo_matrix_t in which to store the result
276 * @a: a #cairo_matrix_t
277 * @b: a #cairo_matrix_t
279 * Multiplies the affine transformations in @a and @b together
280 * and stores the result in @result. The effect of the resulting
281 * transformation is to first apply the transformation in @a to the
282 * coordinates and then apply the transformation in @b to the
285 * It is allowable for @result to be identical to either @a or @b.
288 * XXX: The ordering of the arguments to this function corresponds
289 * to [row_vector]*A*B. If we want to use column vectors instead,
290 * then we need to switch the two arguments and fix up all
294 cairo_matrix_multiply (cairo_matrix_t
*result
, const cairo_matrix_t
*a
, const cairo_matrix_t
*b
)
298 r
.xx
= a
->xx
* b
->xx
+ a
->yx
* b
->xy
;
299 r
.yx
= a
->xx
* b
->yx
+ a
->yx
* b
->yy
;
301 r
.xy
= a
->xy
* b
->xx
+ a
->yy
* b
->xy
;
302 r
.yy
= a
->xy
* b
->yx
+ a
->yy
* b
->yy
;
304 r
.x0
= a
->x0
* b
->xx
+ a
->y0
* b
->xy
+ b
->x0
;
305 r
.y0
= a
->x0
* b
->yx
+ a
->y0
* b
->yy
+ b
->y0
;
309 slim_hidden_def(cairo_matrix_multiply
);
312 * cairo_matrix_transform_distance:
313 * @matrix: a #cairo_matrix_t
314 * @dx: X component of a distance vector. An in/out parameter
315 * @dy: Y component of a distance vector. An in/out parameter
317 * Transforms the distance vector (@dx,@dy) by @matrix. This is
318 * similar to cairo_matrix_transform_point() except that the translation
319 * components of the transformation are ignored. The calculation of
320 * the returned vector is as follows:
323 * dx2 = dx1 * a + dy1 * c;
324 * dy2 = dx1 * b + dy1 * d;
327 * Affine transformations are position invariant, so the same vector
328 * always transforms to the same vector. If (@x1,@y1) transforms
329 * to (@x2,@y2) then (@x1+@dx1,@y1+@dy1) will transform to
330 * (@x1+@dx2,@y1+@dy2) for all values of @x1 and @x2.
333 cairo_matrix_transform_distance (const cairo_matrix_t
*matrix
, double *dx
, double *dy
)
337 new_x
= (matrix
->xx
* *dx
+ matrix
->xy
* *dy
);
338 new_y
= (matrix
->yx
* *dx
+ matrix
->yy
* *dy
);
343 slim_hidden_def(cairo_matrix_transform_distance
);
346 * cairo_matrix_transform_point:
347 * @matrix: a #cairo_matrix_t
348 * @x: X position. An in/out parameter
349 * @y: Y position. An in/out parameter
351 * Transforms the point (@x, @y) by @matrix.
354 cairo_matrix_transform_point (const cairo_matrix_t
*matrix
, double *x
, double *y
)
356 cairo_matrix_transform_distance (matrix
, x
, y
);
361 slim_hidden_def(cairo_matrix_transform_point
);
364 _cairo_matrix_transform_bounding_box (const cairo_matrix_t
*matrix
,
365 double *x1
, double *y1
,
366 double *x2
, double *y2
,
367 cairo_bool_t
*is_tight
)
370 double quad_x
[4], quad_y
[4];
374 if (_cairo_matrix_is_identity (matrix
)) {
381 if (matrix
->xy
== 0. && matrix
->yx
== 0.) {
382 /* non-rotation/skew matrix, just map the two extreme points */
385 cairo_matrix_transform_distance (matrix
, &quad_x
[0], &quad_y
[0]);
389 cairo_matrix_transform_distance (matrix
, &quad_x
[1], &quad_y
[1]);
391 if (quad_x
[0] < quad_x
[1]) {
392 *x1
= quad_x
[0] + matrix
->x0
;
393 *x2
= quad_x
[1] + matrix
->x0
;
395 *x1
= quad_x
[1] + matrix
->x0
;
396 *x2
= quad_x
[0] + matrix
->x0
;
399 if (quad_y
[0] < quad_y
[1]) {
400 *y1
= quad_y
[0] + matrix
->y0
;
401 *y2
= quad_y
[1] + matrix
->y0
;
403 *y1
= quad_y
[1] + matrix
->y0
;
404 *y2
= quad_y
[0] + matrix
->y0
;
416 cairo_matrix_transform_point (matrix
, &quad_x
[0], &quad_y
[0]);
420 cairo_matrix_transform_point (matrix
, &quad_x
[1], &quad_y
[1]);
424 cairo_matrix_transform_point (matrix
, &quad_x
[2], &quad_y
[2]);
428 cairo_matrix_transform_point (matrix
, &quad_x
[3], &quad_y
[3]);
430 min_x
= max_x
= quad_x
[0];
431 min_y
= max_y
= quad_y
[0];
433 for (i
=1; i
< 4; i
++) {
434 if (quad_x
[i
] < min_x
)
436 if (quad_x
[i
] > max_x
)
439 if (quad_y
[i
] < min_y
)
441 if (quad_y
[i
] > max_y
)
451 /* it's tight if and only if the four corner points form an axis-aligned
453 And that's true if and only if we can derive corners 0 and 3 from
454 corners 1 and 2 in one of two straightforward ways...
455 We could use a tolerance here but for now we'll fall back to FALSE in the case
456 of floating point error.
459 (quad_x
[1] == quad_x
[0] && quad_y
[1] == quad_y
[3] &&
460 quad_x
[2] == quad_x
[3] && quad_y
[2] == quad_y
[0]) ||
461 (quad_x
[1] == quad_x
[3] && quad_y
[1] == quad_y
[0] &&
462 quad_x
[2] == quad_x
[0] && quad_y
[2] == quad_y
[3]);
467 _cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t
*matrix
,
469 cairo_bool_t
*is_tight
)
471 double x1
, y1
, x2
, y2
;
473 _cairo_box_to_doubles (bbox
, &x1
, &y1
, &x2
, &y2
);
474 _cairo_matrix_transform_bounding_box (matrix
, &x1
, &y1
, &x2
, &y2
, is_tight
);
475 _cairo_box_from_doubles (bbox
, &x1
, &y1
, &x2
, &y2
);
479 _cairo_matrix_scalar_multiply (cairo_matrix_t
*matrix
, double scalar
)
481 matrix
->xx
*= scalar
;
482 matrix
->yx
*= scalar
;
484 matrix
->xy
*= scalar
;
485 matrix
->yy
*= scalar
;
487 matrix
->x0
*= scalar
;
488 matrix
->y0
*= scalar
;
491 /* This function isn't a correct adjoint in that the implicit 1 in the
492 homogeneous result should actually be ad-bc instead. But, since this
493 adjoint is only used in the computation of the inverse, which
494 divides by det (A)=ad-bc anyway, everything works out in the end. */
496 _cairo_matrix_compute_adjoint (cairo_matrix_t
*matrix
)
498 /* adj (A) = transpose (C:cofactor (A,i,j)) */
499 double a
, b
, c
, d
, tx
, ty
;
501 _cairo_matrix_get_affine (matrix
,
506 cairo_matrix_init (matrix
,
509 c
*ty
- d
*tx
, b
*tx
- a
*ty
);
513 * cairo_matrix_invert:
514 * @matrix: a #cairo_matrix_t
516 * Changes @matrix to be the inverse of its original value. Not
517 * all transformation matrices have inverses; if the matrix
518 * collapses points together (it is <firstterm>degenerate</firstterm>),
519 * then it has no inverse and this function will fail.
521 * Returns: If @matrix has an inverse, modifies @matrix to
522 * be the inverse matrix and returns %CAIRO_STATUS_SUCCESS. Otherwise,
523 * returns %CAIRO_STATUS_INVALID_MATRIX.
526 cairo_matrix_invert (cairo_matrix_t
*matrix
)
530 /* Simple scaling|translation matrices are quite common... */
531 if (matrix
->xy
== 0. && matrix
->yx
== 0.) {
532 matrix
->x0
= -matrix
->x0
;
533 matrix
->y0
= -matrix
->y0
;
535 if (matrix
->xx
!= 1.) {
536 if (matrix
->xx
== 0.)
537 return _cairo_error (CAIRO_STATUS_INVALID_MATRIX
);
539 matrix
->xx
= 1. / matrix
->xx
;
540 matrix
->x0
*= matrix
->xx
;
543 if (matrix
->yy
!= 1.) {
544 if (matrix
->yy
== 0.)
545 return _cairo_error (CAIRO_STATUS_INVALID_MATRIX
);
547 matrix
->yy
= 1. / matrix
->yy
;
548 matrix
->y0
*= matrix
->yy
;
551 return CAIRO_STATUS_SUCCESS
;
554 /* inv (A) = 1/det (A) * adj (A) */
555 det
= _cairo_matrix_compute_determinant (matrix
);
557 if (! ISFINITE (det
))
558 return _cairo_error (CAIRO_STATUS_INVALID_MATRIX
);
561 return _cairo_error (CAIRO_STATUS_INVALID_MATRIX
);
563 _cairo_matrix_compute_adjoint (matrix
);
564 _cairo_matrix_scalar_multiply (matrix
, 1 / det
);
566 return CAIRO_STATUS_SUCCESS
;
568 slim_hidden_def(cairo_matrix_invert
);
571 _cairo_matrix_is_invertible (const cairo_matrix_t
*matrix
)
575 det
= _cairo_matrix_compute_determinant (matrix
);
577 return ISFINITE (det
) && det
!= 0.;
581 _cairo_matrix_compute_determinant (const cairo_matrix_t
*matrix
)
585 a
= matrix
->xx
; b
= matrix
->yx
;
586 c
= matrix
->xy
; d
= matrix
->yy
;
592 * _cairo_matrix_compute_basis_scale_factors:
594 * @basis_scale: the scale factor in the direction of basis
595 * @normal_scale: the scale factor in the direction normal to the basis
596 * @x_basis: basis to use. X basis if true, Y basis otherwise.
598 * Computes |Mv| and det(M)/|Mv| for v=[1,0] if x_basis is true, and v=[0,1]
599 * otherwise, and M is @matrix.
601 * Return value: the scale factor of @matrix on the height of the font,
602 * or 1.0 if @matrix is %NULL.
605 _cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t
*matrix
,
606 double *basis_scale
, double *normal_scale
,
607 cairo_bool_t x_basis
)
611 det
= _cairo_matrix_compute_determinant (matrix
);
613 if (! ISFINITE (det
))
614 return _cairo_error (CAIRO_STATUS_INVALID_MATRIX
);
618 *basis_scale
= *normal_scale
= 0;
622 double x
= x_basis
!= 0;
626 cairo_matrix_transform_distance (matrix
, &x
, &y
);
627 major
= sqrt(x
*x
+ y
*y
);
639 *basis_scale
= major
;
640 *normal_scale
= minor
;
644 *basis_scale
= minor
;
645 *normal_scale
= major
;
649 return CAIRO_STATUS_SUCCESS
;
653 _cairo_matrix_is_identity (const cairo_matrix_t
*matrix
)
655 return (matrix
->xx
== 1.0 && matrix
->yx
== 0.0 &&
656 matrix
->xy
== 0.0 && matrix
->yy
== 1.0 &&
657 matrix
->x0
== 0.0 && matrix
->y0
== 0.0);
661 _cairo_matrix_is_translation (const cairo_matrix_t
*matrix
)
663 return (matrix
->xx
== 1.0 && matrix
->yx
== 0.0 &&
664 matrix
->xy
== 0.0 && matrix
->yy
== 1.0);
668 _cairo_matrix_is_integer_translation (const cairo_matrix_t
*matrix
,
671 if (_cairo_matrix_is_translation (matrix
))
673 cairo_fixed_t x0_fixed
= _cairo_fixed_from_double (matrix
->x0
);
674 cairo_fixed_t y0_fixed
= _cairo_fixed_from_double (matrix
->y0
);
676 if (_cairo_fixed_is_integer (x0_fixed
) &&
677 _cairo_fixed_is_integer (y0_fixed
))
680 *itx
= _cairo_fixed_integer_part (x0_fixed
);
682 *ity
= _cairo_fixed_integer_part (y0_fixed
);
691 /* By pixel exact here, we mean a matrix that is composed only of
692 * 90 degree rotations, flips, and integer translations and produces a 1:1
693 * mapping between source and destination pixels. If we transform an image
694 * with a pixel-exact matrix, filtering is not useful.
696 cairo_private cairo_bool_t
697 _cairo_matrix_is_pixel_exact (const cairo_matrix_t
*matrix
)
699 cairo_fixed_t x0_fixed
, y0_fixed
;
701 if (matrix
->xy
== 0.0 && matrix
->yx
== 0.0) {
702 if (! (matrix
->xx
== 1.0 || matrix
->xx
== -1.0))
704 if (! (matrix
->yy
== 1.0 || matrix
->yy
== -1.0))
706 } else if (matrix
->xx
== 0.0 && matrix
->yy
== 0.0) {
707 if (! (matrix
->xy
== 1.0 || matrix
->xy
== -1.0))
709 if (! (matrix
->yx
== 1.0 || matrix
->yx
== -1.0))
714 x0_fixed
= _cairo_fixed_from_double (matrix
->x0
);
715 y0_fixed
= _cairo_fixed_from_double (matrix
->y0
);
717 return _cairo_fixed_is_integer (x0_fixed
) && _cairo_fixed_is_integer (y0_fixed
);
721 A circle in user space is transformed into an ellipse in device space.
723 The following is a derivation of a formula to calculate the length of the
724 major axis for this ellipse; this is useful for error bounds calculations.
726 Thanks to Walter Brisken <wbrisken@aoc.nrao.edu> for this derivation:
728 1. First some notation:
730 All capital letters represent vectors in two dimensions. A prime '
731 represents a transformed coordinate. Matrices are written in underlined
732 form, ie _R_. Lowercase letters represent scalar real values.
734 2. The question has been posed: What is the maximum expansion factor
735 achieved by the linear transformation
739 where _R_ is a real-valued 2x2 matrix with entries:
744 In other words, what is the maximum radius, MAX[ |X'| ], reached for any
745 X on the unit circle ( |X| = 1 ) ?
747 3. Some useful formulae
749 (A) through (C) below are standard double-angle formulae. (D) is a lesser
750 known result and is derived below:
752 (A) sin²(θ) = (1 - cos(2*θ))/2
753 (B) cos²(θ) = (1 + cos(2*θ))/2
754 (C) sin(θ)*cos(θ) = sin(2*θ)/2
755 (D) MAX[a*cos(θ) + b*sin(θ)] = sqrt(a² + b²)
759 find the maximum of the function by setting the derivative to zero:
761 -a*sin(θ)+b*cos(θ) = 0
763 From this it follows that
769 sin(θ) = b/sqrt(a² + b²)
773 cos(θ) = a/sqrt(a² + b²)
775 Thus the maximum value is
777 MAX[a*cos(θ) + b*sin(θ)] = (a² + b²)/sqrt(a² + b²)
780 4. Derivation of maximum expansion
782 To find MAX[ |X'| ] we search brute force method using calculus. The unit
783 circle on which X is constrained is to be parameterized by t:
785 X(θ) = (cos(θ), sin(θ))
789 X'(θ) = X(θ) * _R_ = (cos(θ), sin(θ)) * [a b]
791 = (a*cos(θ) + c*sin(θ), b*cos(θ) + d*sin(θ)).
799 r²(θ) = (a*cos(θ) + c*sin(θ))² + (b*cos(θ) + d*sin(θ))²
800 = (a² + b²)*cos²(θ) + (c² + d²)*sin²(θ)
801 + 2*(a*c + b*d)*cos(θ)*sin(θ)
803 Now apply the double angle formulae (A) to (C) from above:
805 r²(θ) = (a² + b² + c² + d²)/2
806 + (a² + b² - c² - d²)*cos(2*θ)/2
807 + (a*c + b*d)*sin(2*θ)
808 = f + g*cos(φ) + h*sin(φ)
812 f = (a² + b² + c² + d²)/2
813 g = (a² + b² - c² - d²)/2
817 It is clear that MAX[ |X'| ] = sqrt(MAX[ r² ]). Here we determine MAX[ r² ]
818 using (D) from above:
820 MAX[ r² ] = f + sqrt(g² + h²)
824 MAX[ |X'| ] = sqrt( f + sqrt(g² + h²) )
826 Which is the solution to this problem.
831 (Note that the minor axis length is at the minimum of the above solution,
832 which is just sqrt ( f - sqrt(g² + h²) ) given the symmetry of (D)).
835 For another derivation of the same result, using Singular Value Decomposition,
836 see doc/tutorial/src/singular.c.
839 /* determine the length of the major axis of a circle of the given radius
840 after applying the transformation matrix. */
842 _cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t
*matrix
,
845 double a
, b
, c
, d
, f
, g
, h
, i
, j
;
847 _cairo_matrix_get_affine (matrix
,
859 return radius
* sqrt (f
+ sqrt (g
*g
+h
*h
));
862 * we don't need the minor axis length, which is
863 * double min = radius * sqrt (f - sqrt (g*g+h*h));
868 _cairo_matrix_to_pixman_matrix (const cairo_matrix_t
*matrix
,
869 pixman_transform_t
*pixman_transform
,
873 static const pixman_transform_t pixman_identity_transform
= {{
879 if (_cairo_matrix_is_identity (matrix
)) {
880 *pixman_transform
= pixman_identity_transform
;
883 unsigned max_iterations
;
885 pixman_transform
->matrix
[0][0] = _cairo_fixed_16_16_from_double (matrix
->xx
);
886 pixman_transform
->matrix
[0][1] = _cairo_fixed_16_16_from_double (matrix
->xy
);
887 pixman_transform
->matrix
[0][2] = _cairo_fixed_16_16_from_double (matrix
->x0
);
889 pixman_transform
->matrix
[1][0] = _cairo_fixed_16_16_from_double (matrix
->yx
);
890 pixman_transform
->matrix
[1][1] = _cairo_fixed_16_16_from_double (matrix
->yy
);
891 pixman_transform
->matrix
[1][2] = _cairo_fixed_16_16_from_double (matrix
->y0
);
893 pixman_transform
->matrix
[2][0] = 0;
894 pixman_transform
->matrix
[2][1] = 0;
895 pixman_transform
->matrix
[2][2] = 1 << 16;
897 /* The conversion above breaks cairo's translation invariance:
898 * a translation of (a, b) in device space translates to
899 * a translation of (xx * a + xy * b, yx * a + yy * b)
900 * for cairo, while pixman uses rounded versions of xx ... yy.
901 * This error increases as a and b get larger.
903 * To compensate for this, we fix the point (xc, yc) in pattern
904 * space and adjust pixman's transform to agree with cairo's at
908 if (_cairo_matrix_is_translation (matrix
))
911 /* Note: If we can't invert the transformation, skip the adjustment. */
913 if (cairo_matrix_invert (&inv
) != CAIRO_STATUS_SUCCESS
)
916 /* find the pattern space coordinate that maps to (xc, yc) */
917 xc
+= .5; yc
+= .5; /* offset for the pixel centre */
921 pixman_vector_t vector
;
922 cairo_fixed_16_16_t dx
, dy
;
924 vector
.vector
[0] = _cairo_fixed_16_16_from_double (xc
);
925 vector
.vector
[1] = _cairo_fixed_16_16_from_double (yc
);
926 vector
.vector
[2] = 1 << 16;
928 if (! pixman_transform_point_3d (pixman_transform
, &vector
))
931 x
= pixman_fixed_to_double (vector
.vector
[0]);
932 y
= pixman_fixed_to_double (vector
.vector
[1]);
933 cairo_matrix_transform_point (&inv
, &x
, &y
);
935 /* Ideally, the vector should now be (xc, yc).
936 * We can now compensate for the resulting error.
940 cairo_matrix_transform_distance (matrix
, &x
, &y
);
941 dx
= _cairo_fixed_16_16_from_double (x
);
942 dy
= _cairo_fixed_16_16_from_double (y
);
943 pixman_transform
->matrix
[0][2] -= dx
;
944 pixman_transform
->matrix
[1][2] -= dy
;
946 if (dx
== 0 && dy
== 0)
948 } while (--max_iterations
);