Coverage Report

Created: 2026-08-14 08:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cairo/src/cairo-matrix.c
Line
Count
Source
1
/* cairo - a vector graphics library with display and print output
2
 *
3
 * Copyright © 2002 University of Southern California
4
 *
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.
12
 *
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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16
 * You should have received a copy of the MPL along with this library
17
 * in the file COPYING-MPL-1.1
18
 *
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/
23
 *
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.
27
 *
28
 * The Original Code is the cairo graphics library.
29
 *
30
 * The Initial Developer of the Original Code is University of Southern
31
 * California.
32
 *
33
 * Contributor(s):
34
 *  Carl D. Worth <cworth@cworth.org>
35
 */
36
37
#include "cairoint.h"
38
#include "cairo-error-private.h"
39
#include <float.h>
40
41
16.7k
#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
42
43
/**
44
 * SECTION:cairo-matrix
45
 * @Title: cairo_matrix_t
46
 * @Short_Description: Generic matrix operations
47
 * @See_Also: #cairo_t
48
 *
49
 * #cairo_matrix_t is used throughout cairo to convert between different
50
 * coordinate spaces.  A #cairo_matrix_t holds an affine transformation,
51
 * such as a scale, rotation, shear, or a combination of these.
52
 * The transformation of a point (<literal>x</literal>,<literal>y</literal>)
53
 * is given by:
54
 *
55
 * <programlisting>
56
 * x_new = xx * x + xy * y + x0;
57
 * y_new = yx * x + yy * y + y0;
58
 * </programlisting>
59
 *
60
 * The current transformation matrix of a #cairo_t, represented as a
61
 * #cairo_matrix_t, defines the transformation from user-space
62
 * coordinates to device-space coordinates. See cairo_get_matrix() and
63
 * cairo_set_matrix().
64
 **/
65
66
static void
67
_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar);
68
69
static void
70
_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix);
71
72
/**
73
 * cairo_matrix_init_identity:
74
 * @matrix: a #cairo_matrix_t
75
 *
76
 * Modifies @matrix to be an identity transformation.
77
 *
78
 * Since: 1.0
79
 **/
80
void
81
cairo_matrix_init_identity (cairo_matrix_t *matrix)
82
3.67M
{
83
3.67M
    cairo_matrix_init (matrix,
84
3.67M
           1, 0,
85
3.67M
           0, 1,
86
3.67M
           0, 0);
87
3.67M
}
88
89
/**
90
 * cairo_matrix_init:
91
 * @matrix: a #cairo_matrix_t
92
 * @xx: xx component of the affine transformation
93
 * @yx: yx component of the affine transformation
94
 * @xy: xy component of the affine transformation
95
 * @yy: yy component of the affine transformation
96
 * @x0: X translation component of the affine transformation
97
 * @y0: Y translation component of the affine transformation
98
 *
99
 * Sets @matrix to be the affine transformation given by
100
 * @xx, @yx, @xy, @yy, @x0, @y0. The transformation is given
101
 * by:
102
 * <programlisting>
103
 *  x_new = xx * x + xy * y + x0;
104
 *  y_new = yx * x + yy * y + y0;
105
 * </programlisting>
106
 *
107
 * Since: 1.0
108
 **/
109
void
110
cairo_matrix_init (cairo_matrix_t *matrix,
111
       double xx, double yx,
112
113
       double xy, double yy,
114
       double x0, double y0)
115
7.85M
{
116
7.85M
    matrix->xx = xx; matrix->yx = yx;
117
7.85M
    matrix->xy = xy; matrix->yy = yy;
118
7.85M
    matrix->x0 = x0; matrix->y0 = y0;
119
7.85M
}
120
121
/**
122
 * _cairo_matrix_get_affine:
123
 * @matrix: a #cairo_matrix_t
124
 * @xx: location to store xx component of matrix
125
 * @yx: location to store yx component of matrix
126
 * @xy: location to store xy component of matrix
127
 * @yy: location to store yy component of matrix
128
 * @x0: location to store x0 (X-translation component) of matrix, or %NULL
129
 * @y0: location to store y0 (Y-translation component) of matrix, or %NULL
130
 *
131
 * Gets the matrix values for the affine transformation that @matrix represents.
132
 * See cairo_matrix_init().
133
 *
134
 *
135
 * This function is a leftover from the old public API, but is still
136
 * mildly useful as an internal means for getting at the matrix
137
 * members in a positional way. For example, when reassigning to some
138
 * external matrix type, or when renaming members to more meaningful
139
 * names (such as a,b,c,d,e,f) for particular manipulations.
140
 **/
141
void
142
_cairo_matrix_get_affine (const cairo_matrix_t *matrix,
143
        double *xx, double *yx,
144
        double *xy, double *yy,
145
        double *x0, double *y0)
146
727k
{
147
727k
    *xx  = matrix->xx;
148
727k
    *yx  = matrix->yx;
149
150
727k
    *xy  = matrix->xy;
151
727k
    *yy  = matrix->yy;
152
153
727k
    if (x0)
154
13.6k
  *x0 = matrix->x0;
155
727k
    if (y0)
156
13.6k
  *y0 = matrix->y0;
157
727k
}
158
159
/**
160
 * cairo_matrix_init_translate:
161
 * @matrix: a #cairo_matrix_t
162
 * @tx: amount to translate in the X direction
163
 * @ty: amount to translate in the Y direction
164
 *
165
 * Initializes @matrix to a transformation that translates by @tx and
166
 * @ty in the X and Y dimensions, respectively.
167
 *
168
 * Since: 1.0
169
 **/
170
void
171
cairo_matrix_init_translate (cairo_matrix_t *matrix,
172
           double tx, double ty)
173
1.27M
{
174
1.27M
    cairo_matrix_init (matrix,
175
1.27M
           1, 0,
176
1.27M
           0, 1,
177
1.27M
           tx, ty);
178
1.27M
}
179
180
/**
181
 * cairo_matrix_translate:
182
 * @matrix: a #cairo_matrix_t
183
 * @tx: amount to translate in the X direction
184
 * @ty: amount to translate in the Y direction
185
 *
186
 * Applies a translation by @tx, @ty to the transformation in
187
 * @matrix. The effect of the new transformation is to first translate
188
 * the coordinates by @tx and @ty, then apply the original transformation
189
 * to the coordinates.
190
 *
191
 * Since: 1.0
192
 **/
193
void
194
cairo_matrix_translate (cairo_matrix_t *matrix, double tx, double ty)
195
23.3k
{
196
23.3k
    cairo_matrix_t tmp;
197
198
23.3k
    cairo_matrix_init_translate (&tmp, tx, ty);
199
200
23.3k
    cairo_matrix_multiply (matrix, &tmp, matrix);
201
23.3k
}
202
203
/**
204
 * cairo_matrix_init_scale:
205
 * @matrix: a #cairo_matrix_t
206
 * @sx: scale factor in the X direction
207
 * @sy: scale factor in the Y direction
208
 *
209
 * Initializes @matrix to a transformation that scales by @sx and @sy
210
 * in the X and Y dimensions, respectively.
211
 *
212
 * Since: 1.0
213
 **/
214
void
215
cairo_matrix_init_scale (cairo_matrix_t *matrix,
216
       double sx, double sy)
217
2.24M
{
218
2.24M
    cairo_matrix_init (matrix,
219
2.24M
           sx,  0,
220
2.24M
           0, sy,
221
2.24M
           0, 0);
222
2.24M
}
223
224
/**
225
 * cairo_matrix_scale:
226
 * @matrix: a #cairo_matrix_t
227
 * @sx: scale factor in the X direction
228
 * @sy: scale factor in the Y direction
229
 *
230
 * Applies scaling by @sx, @sy to the transformation in @matrix. The
231
 * effect of the new transformation is to first scale the coordinates
232
 * by @sx and @sy, then apply the original transformation to the coordinates.
233
 *
234
 * Since: 1.0
235
 **/
236
void
237
cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy)
238
724k
{
239
724k
    cairo_matrix_t tmp;
240
241
724k
    cairo_matrix_init_scale (&tmp, sx, sy);
242
243
724k
    cairo_matrix_multiply (matrix, &tmp, matrix);
244
724k
}
245
246
/**
247
 * cairo_matrix_init_rotate:
248
 * @matrix: a #cairo_matrix_t
249
 * @radians: angle of rotation, in radians. The direction of rotation
250
 * is defined such that positive angles rotate in the direction from
251
 * the positive X axis toward the positive Y axis. With the default
252
 * axis orientation of cairo, positive angles rotate in a clockwise
253
 * direction.
254
 *
255
 * Initialized @matrix to a transformation that rotates by @radians.
256
 *
257
 * Since: 1.0
258
 **/
259
void
260
cairo_matrix_init_rotate (cairo_matrix_t *matrix,
261
        double radians)
262
0
{
263
0
    double  s;
264
0
    double  c;
265
266
0
    s = sin (radians);
267
0
    c = cos (radians);
268
269
0
    cairo_matrix_init (matrix,
270
0
           c, s,
271
0
           -s, c,
272
0
           0, 0);
273
0
}
274
275
/**
276
 * cairo_matrix_rotate:
277
 * @matrix: a #cairo_matrix_t
278
 * @radians: angle of rotation, in radians. The direction of rotation
279
 * is defined such that positive angles rotate in the direction from
280
 * the positive X axis toward the positive Y axis. With the default
281
 * axis orientation of cairo, positive angles rotate in a clockwise
282
 * direction.
283
 *
284
 * Applies rotation by @radians to the transformation in
285
 * @matrix. The effect of the new transformation is to first rotate the
286
 * coordinates by @radians, then apply the original transformation
287
 * to the coordinates.
288
 *
289
 * Since: 1.0
290
 **/
291
void
292
cairo_matrix_rotate (cairo_matrix_t *matrix, double radians)
293
0
{
294
0
    cairo_matrix_t tmp;
295
296
0
    cairo_matrix_init_rotate (&tmp, radians);
297
298
0
    cairo_matrix_multiply (matrix, &tmp, matrix);
299
0
}
300
301
/**
302
 * cairo_matrix_multiply:
303
 * @result: a #cairo_matrix_t in which to store the result
304
 * @a: a #cairo_matrix_t
305
 * @b: a #cairo_matrix_t
306
 *
307
 * Multiplies the affine transformations in @a and @b together
308
 * and stores the result in @result. The effect of the resulting
309
 * transformation is to first apply the transformation in @a to the
310
 * coordinates and then apply the transformation in @b to the
311
 * coordinates.
312
 *
313
 * It is allowable for @result to be identical to either @a or @b.
314
 *
315
 * Since: 1.0
316
 **/
317
/*
318
 * XXX: The ordering of the arguments to this function corresponds
319
 *      to [row_vector]*A*B. If we want to use column vectors instead,
320
 *      then we need to switch the two arguments and fix up all
321
 *      uses.
322
 */
323
void
324
cairo_matrix_multiply (cairo_matrix_t *result, const cairo_matrix_t *a, const cairo_matrix_t *b)
325
7.01M
{
326
7.01M
    cairo_matrix_t r;
327
328
7.01M
    r.xx = a->xx * b->xx + a->yx * b->xy;
329
7.01M
    r.yx = a->xx * b->yx + a->yx * b->yy;
330
331
7.01M
    r.xy = a->xy * b->xx + a->yy * b->xy;
332
7.01M
    r.yy = a->xy * b->yx + a->yy * b->yy;
333
334
7.01M
    r.x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0;
335
7.01M
    r.y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0;
336
337
7.01M
    *result = r;
338
7.01M
}
339
340
void
341
_cairo_matrix_multiply (cairo_matrix_t *r,
342
      const cairo_matrix_t *a,
343
      const cairo_matrix_t *b)
344
18
{
345
18
    r->xx = a->xx * b->xx + a->yx * b->xy;
346
18
    r->yx = a->xx * b->yx + a->yx * b->yy;
347
348
18
    r->xy = a->xy * b->xx + a->yy * b->xy;
349
18
    r->yy = a->xy * b->yx + a->yy * b->yy;
350
351
18
    r->x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0;
352
18
    r->y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0;
353
18
}
354
355
/**
356
 * cairo_matrix_transform_distance:
357
 * @matrix: a #cairo_matrix_t
358
 * @dx: X component of a distance vector. An in/out parameter
359
 * @dy: Y component of a distance vector. An in/out parameter
360
 *
361
 * Transforms the distance vector (@dx,@dy) by @matrix. This is
362
 * similar to cairo_matrix_transform_point() except that the translation
363
 * components of the transformation are ignored. The calculation of
364
 * the returned vector is as follows:
365
 *
366
 * <programlisting>
367
 * dx_new = xx * dx + xy * dy;
368
 * dy_new = yx * dx + yy * dy;
369
 * </programlisting>
370
 *
371
 * Since: 1.0
372
 **/
373
void
374
cairo_matrix_transform_distance (const cairo_matrix_t *matrix, double *dx, double *dy)
375
24.6M
{
376
24.6M
    double new_x, new_y;
377
378
24.6M
    new_x = (matrix->xx * *dx + matrix->xy * *dy);
379
24.6M
    new_y = (matrix->yx * *dx + matrix->yy * *dy);
380
381
24.6M
    *dx = new_x;
382
24.6M
    *dy = new_y;
383
24.6M
}
384
385
/**
386
 * cairo_matrix_transform_point:
387
 * @matrix: a #cairo_matrix_t
388
 * @x: X position. An in/out parameter
389
 * @y: Y position. An in/out parameter
390
 *
391
 * Transforms the point (@x, @y) by @matrix.
392
 *
393
 * Since: 1.0
394
 **/
395
void
396
cairo_matrix_transform_point (const cairo_matrix_t *matrix, double *x, double *y)
397
14.8M
{
398
14.8M
    cairo_matrix_transform_distance (matrix, x, y);
399
400
14.8M
    *x += matrix->x0;
401
14.8M
    *y += matrix->y0;
402
14.8M
}
403
404
void
405
_cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
406
              double *x1, double *y1,
407
              double *x2, double *y2,
408
              cairo_bool_t *is_tight)
409
128k
{
410
128k
    int i;
411
128k
    double quad_x[4], quad_y[4];
412
128k
    double min_x, max_x;
413
128k
    double min_y, max_y;
414
415
128k
    if (matrix->xy == 0. && matrix->yx == 0.) {
416
  /* non-rotation/skew matrix, just map the two extreme points */
417
418
127k
  if (matrix->xx != 1.) {
419
109k
      quad_x[0] = *x1 * matrix->xx;
420
109k
      quad_x[1] = *x2 * matrix->xx;
421
109k
      if (quad_x[0] < quad_x[1]) {
422
97.5k
    *x1 = quad_x[0];
423
97.5k
    *x2 = quad_x[1];
424
97.5k
      } else {
425
12.3k
    *x1 = quad_x[1];
426
12.3k
    *x2 = quad_x[0];
427
12.3k
      }
428
109k
  }
429
127k
  if (matrix->x0 != 0.) {
430
101k
      *x1 += matrix->x0;
431
101k
      *x2 += matrix->x0;
432
101k
  }
433
434
127k
  if (matrix->yy != 1.) {
435
111k
      quad_y[0] = *y1 * matrix->yy;
436
111k
      quad_y[1] = *y2 * matrix->yy;
437
111k
      if (quad_y[0] < quad_y[1]) {
438
84.1k
    *y1 = quad_y[0];
439
84.1k
    *y2 = quad_y[1];
440
84.1k
      } else {
441
27.1k
    *y1 = quad_y[1];
442
27.1k
    *y2 = quad_y[0];
443
27.1k
      }
444
111k
  }
445
127k
  if (matrix->y0 != 0.) {
446
115k
      *y1 += matrix->y0;
447
115k
      *y2 += matrix->y0;
448
115k
  }
449
450
127k
  if (is_tight)
451
0
      *is_tight = TRUE;
452
453
127k
  return;
454
127k
    }
455
456
    /* general matrix */
457
969
    quad_x[0] = *x1;
458
969
    quad_y[0] = *y1;
459
969
    cairo_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]);
460
461
969
    quad_x[1] = *x2;
462
969
    quad_y[1] = *y1;
463
969
    cairo_matrix_transform_point (matrix, &quad_x[1], &quad_y[1]);
464
465
969
    quad_x[2] = *x1;
466
969
    quad_y[2] = *y2;
467
969
    cairo_matrix_transform_point (matrix, &quad_x[2], &quad_y[2]);
468
469
969
    quad_x[3] = *x2;
470
969
    quad_y[3] = *y2;
471
969
    cairo_matrix_transform_point (matrix, &quad_x[3], &quad_y[3]);
472
473
969
    min_x = max_x = quad_x[0];
474
969
    min_y = max_y = quad_y[0];
475
476
3.87k
    for (i=1; i < 4; i++) {
477
2.90k
  if (quad_x[i] < min_x)
478
716
      min_x = quad_x[i];
479
2.90k
  if (quad_x[i] > max_x)
480
942
      max_x = quad_x[i];
481
482
2.90k
  if (quad_y[i] < min_y)
483
710
      min_y = quad_y[i];
484
2.90k
  if (quad_y[i] > max_y)
485
691
      max_y = quad_y[i];
486
2.90k
    }
487
488
969
    *x1 = min_x;
489
969
    *y1 = min_y;
490
969
    *x2 = max_x;
491
969
    *y2 = max_y;
492
493
969
    if (is_tight) {
494
        /* it's tight if and only if the four corner points form an axis-aligned
495
           rectangle.
496
           And that's true if and only if we can derive corners 0 and 3 from
497
           corners 1 and 2 in one of two straightforward ways...
498
           We could use a tolerance here but for now we'll fall back to FALSE in the case
499
           of floating point error.
500
        */
501
0
        *is_tight =
502
0
            (quad_x[1] == quad_x[0] && quad_y[1] == quad_y[3] &&
503
0
             quad_x[2] == quad_x[3] && quad_y[2] == quad_y[0]) ||
504
0
            (quad_x[1] == quad_x[3] && quad_y[1] == quad_y[0] &&
505
0
             quad_x[2] == quad_x[0] && quad_y[2] == quad_y[3]);
506
0
    }
507
969
}
508
509
cairo_private void
510
_cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix,
511
              cairo_box_t          *bbox,
512
              cairo_bool_t *is_tight)
513
23.2k
{
514
23.2k
    double x1, y1, x2, y2;
515
516
23.2k
    _cairo_box_to_doubles (bbox, &x1, &y1, &x2, &y2);
517
23.2k
    _cairo_matrix_transform_bounding_box (matrix, &x1, &y1, &x2, &y2, is_tight);
518
23.2k
    _cairo_box_from_doubles (bbox, &x1, &y1, &x2, &y2);
519
23.2k
}
520
521
static void
522
_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar)
523
13.6k
{
524
13.6k
    matrix->xx *= scalar;
525
13.6k
    matrix->yx *= scalar;
526
527
13.6k
    matrix->xy *= scalar;
528
13.6k
    matrix->yy *= scalar;
529
530
13.6k
    matrix->x0 *= scalar;
531
13.6k
    matrix->y0 *= scalar;
532
13.6k
}
533
534
/* This function isn't a correct adjoint in that the implicit 1 in the
535
   homogeneous result should actually be ad-bc instead. But, since this
536
   adjoint is only used in the computation of the inverse, which
537
   divides by det (A)=ad-bc anyway, everything works out in the end. */
538
static void
539
_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix)
540
13.6k
{
541
    /* adj (A) = transpose (C:cofactor (A,i,j)) */
542
13.6k
    double a, b, c, d, tx, ty;
543
544
13.6k
    _cairo_matrix_get_affine (matrix,
545
13.6k
            &a,  &b,
546
13.6k
            &c,  &d,
547
13.6k
            &tx, &ty);
548
549
13.6k
    cairo_matrix_init (matrix,
550
13.6k
           d, -b,
551
13.6k
           -c, a,
552
13.6k
           c*ty - d*tx, b*tx - a*ty);
553
13.6k
}
554
555
/**
556
 * cairo_matrix_invert:
557
 * @matrix: a #cairo_matrix_t
558
 *
559
 * Changes @matrix to be the inverse of its original value. Not
560
 * all transformation matrices have inverses; if the matrix
561
 * collapses points together (it is <firstterm>degenerate</firstterm>),
562
 * then it has no inverse and this function will fail.
563
 *
564
 * Returns: If @matrix has an inverse, modifies @matrix to
565
 *  be the inverse matrix and returns %CAIRO_STATUS_SUCCESS. Otherwise,
566
 *  returns %CAIRO_STATUS_INVALID_MATRIX.
567
 *
568
 * Since: 1.0
569
 **/
570
cairo_status_t
571
cairo_matrix_invert (cairo_matrix_t *matrix)
572
2.35M
{
573
2.35M
    double det;
574
575
    /* Simple scaling|translation matrices are quite common... */
576
2.35M
    if (matrix->xy == 0. && matrix->yx == 0.) {
577
2.34M
  matrix->x0 = -matrix->x0;
578
2.34M
  matrix->y0 = -matrix->y0;
579
580
2.34M
  if (matrix->xx != 1.) {
581
1.89M
      if (matrix->xx == 0.)
582
72
    return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
583
584
1.89M
      matrix->xx = 1. / matrix->xx;
585
1.89M
      matrix->x0 *= matrix->xx;
586
1.89M
  }
587
588
2.34M
  if (matrix->yy != 1.) {
589
1.93M
      if (matrix->yy == 0.)
590
232
    return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
591
592
1.93M
      matrix->yy = 1. / matrix->yy;
593
1.93M
      matrix->y0 *= matrix->yy;
594
1.93M
  }
595
596
2.34M
  return CAIRO_STATUS_SUCCESS;
597
2.34M
    }
598
599
    /* inv (A) = 1/det (A) * adj (A) */
600
15.6k
    det = _cairo_matrix_compute_determinant (matrix);
601
602
15.6k
    if (! ISFINITE (det))
603
0
  return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
604
605
15.6k
    if (det == 0)
606
2.06k
  return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
607
608
13.6k
    _cairo_matrix_compute_adjoint (matrix);
609
13.6k
    _cairo_matrix_scalar_multiply (matrix, 1 / det);
610
611
13.6k
    return CAIRO_STATUS_SUCCESS;
612
15.6k
}
613
614
cairo_bool_t
615
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix)
616
445k
{
617
445k
    double det;
618
619
445k
    det = _cairo_matrix_compute_determinant (matrix);
620
621
445k
    return ISFINITE (det) && det != 0.;
622
445k
}
623
624
cairo_bool_t
625
_cairo_matrix_is_scale_0 (const cairo_matrix_t *matrix)
626
19.8k
{
627
19.8k
    return matrix->xx == 0. &&
628
0
           matrix->xy == 0. &&
629
0
           matrix->yx == 0. &&
630
0
           matrix->yy == 0.;
631
19.8k
}
632
633
double
634
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix)
635
2.11M
{
636
2.11M
    double a, b, c, d;
637
638
2.11M
    a = matrix->xx; b = matrix->yx;
639
2.11M
    c = matrix->xy; d = matrix->yy;
640
641
2.11M
    return a*d - b*c;
642
2.11M
}
643
644
/**
645
 * _cairo_matrix_compute_basis_scale_factors:
646
 * @matrix: a matrix
647
 * @basis_scale: the scale factor in the direction of basis
648
 * @normal_scale: the scale factor in the direction normal to the basis
649
 * @x_basis: basis to use.  X basis if true, Y basis otherwise.
650
 *
651
 * Computes |Mv| and det(M)/|Mv| for v=[1,0] if x_basis is true, and v=[0,1]
652
 * otherwise, and M is @matrix.
653
 *
654
 * Return value: the scale factor of @matrix on the height of the font,
655
 * or 1.0 if @matrix is %NULL.
656
 **/
657
cairo_status_t
658
_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
659
             double *basis_scale, double *normal_scale,
660
             cairo_bool_t x_basis)
661
658k
{
662
658k
    double det;
663
664
658k
    det = _cairo_matrix_compute_determinant (matrix);
665
666
658k
    if (! ISFINITE (det))
667
0
  return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
668
669
658k
    if (det == 0)
670
0
    {
671
0
  *basis_scale = *normal_scale = 0;
672
0
    }
673
658k
    else
674
658k
    {
675
658k
  double x = x_basis != 0;
676
658k
  double y = x == 0;
677
658k
  double major, minor;
678
679
658k
  cairo_matrix_transform_distance (matrix, &x, &y);
680
658k
  major = hypot (x, y);
681
  /*
682
   * ignore mirroring
683
   */
684
658k
  if (det < 0)
685
16.5k
      det = -det;
686
658k
  if (major)
687
658k
      minor = det / major;
688
0
  else
689
0
      minor = 0.0;
690
658k
  if (x_basis)
691
658k
  {
692
658k
      *basis_scale = major;
693
658k
      *normal_scale = minor;
694
658k
  }
695
0
  else
696
0
  {
697
0
      *basis_scale = minor;
698
0
      *normal_scale = major;
699
0
  }
700
658k
    }
701
702
658k
    return CAIRO_STATUS_SUCCESS;
703
658k
}
704
705
cairo_bool_t
706
_cairo_matrix_is_integer_translation (const cairo_matrix_t *matrix,
707
              int *itx, int *ity)
708
5.47k
{
709
5.47k
    if (_cairo_matrix_is_translation (matrix))
710
4.36k
    {
711
4.36k
        cairo_fixed_t x0_fixed = _cairo_fixed_from_double (matrix->x0);
712
4.36k
        cairo_fixed_t y0_fixed = _cairo_fixed_from_double (matrix->y0);
713
714
4.36k
        if (_cairo_fixed_is_integer (x0_fixed) &&
715
4.36k
            _cairo_fixed_is_integer (y0_fixed))
716
4.36k
        {
717
4.36k
            if (itx)
718
4.36k
                *itx = _cairo_fixed_integer_part (x0_fixed);
719
4.36k
            if (ity)
720
4.36k
                *ity = _cairo_fixed_integer_part (y0_fixed);
721
722
4.36k
            return TRUE;
723
4.36k
        }
724
4.36k
    }
725
726
1.10k
    return FALSE;
727
5.47k
}
728
729
4.29M
#define SCALING_EPSILON _cairo_fixed_to_double(1)
730
731
static cairo_bool_t
732
4.29M
within_scaling_epsilon(double a, double b) {
733
4.29M
    return fabs(a - b) < SCALING_EPSILON;
734
4.29M
}
735
736
/* This only returns true if the matrix is 90 degree rotations or
737
 * flips. It appears calling code is relying on this. It will return
738
 * false for other rotations even if the scale is one. Approximations
739
 * are allowed to handle matricies filled in using trig functions
740
 * such as sin(M_PI_2).
741
 */
742
cairo_bool_t
743
_cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix)
744
1.10M
{
745
1.10M
    if (within_scaling_epsilon(matrix->xy, 0.0) && within_scaling_epsilon(matrix->yx, 0.0)) {
746
1.10M
  return within_scaling_epsilon(fabs(matrix->xx), 1.0) &&
747
976k
         within_scaling_epsilon(fabs(matrix->yy), 1.0);
748
1.10M
    } else if (within_scaling_epsilon(matrix->xx, 0.0) && within_scaling_epsilon(matrix->yy, 0.0)) {
749
1.09k
  return within_scaling_epsilon(fabs(matrix->xy), 1.0) &&
750
655
         within_scaling_epsilon(fabs(matrix->yx), 1.0);
751
1.09k
    } else {
752
1.03k
  return FALSE;
753
1.03k
    }
754
1.10M
}
755
756
/* By pixel exact here, we mean a matrix that is composed only of
757
 * 90 degree rotations, flips, and integer translations and produces a 1:1
758
 * mapping between source and destination pixels. If we transform an image
759
 * with a pixel-exact matrix, filtering is not useful.
760
 */
761
cairo_bool_t
762
_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix)
763
23.8k
{
764
23.8k
    cairo_fixed_t x0_fixed, y0_fixed;
765
766
23.8k
    if (! _cairo_matrix_has_unity_scale (matrix))
767
15.4k
  return FALSE;
768
769
8.38k
    x0_fixed = _cairo_fixed_from_double (matrix->x0);
770
8.38k
    y0_fixed = _cairo_fixed_from_double (matrix->y0);
771
772
8.38k
    return _cairo_fixed_is_integer (x0_fixed) && _cairo_fixed_is_integer (y0_fixed);
773
23.8k
}
774
775
/*
776
  A circle in user space is transformed into an ellipse in device space.
777
778
  The following is a derivation of a formula to calculate the length of the
779
  major axis for this ellipse; this is useful for error bounds calculations.
780
781
  Thanks to Walter Brisken <wbrisken@aoc.nrao.edu> for this derivation:
782
783
  1.  First some notation:
784
785
  All capital letters represent vectors in two dimensions.  A prime '
786
  represents a transformed coordinate.  Matrices are written in underlined
787
  form, ie _R_.  Lowercase letters represent scalar real values.
788
789
  2.  The question has been posed:  What is the maximum expansion factor
790
  achieved by the linear transformation
791
792
  X' = X _R_
793
794
  where _R_ is a real-valued 2x2 matrix with entries:
795
796
  _R_ = [a b]
797
        [c d]  .
798
799
  In other words, what is the maximum radius, MAX[ |X'| ], reached for any
800
  X on the unit circle ( |X| = 1 ) ?
801
802
  3.  Some useful formulae
803
804
  (A) through (C) below are standard double-angle formulae.  (D) is a lesser
805
  known result and is derived below:
806
807
  (A)  sin²(θ) = (1 - cos(2*θ))/2
808
  (B)  cos²(θ) = (1 + cos(2*θ))/2
809
  (C)  sin(θ)*cos(θ) = sin(2*θ)/2
810
  (D)  MAX[a*cos(θ) + b*sin(θ)] = sqrt(a² + b²)
811
812
  Proof of (D):
813
814
  find the maximum of the function by setting the derivative to zero:
815
816
       -a*sin(θ)+b*cos(θ) = 0
817
818
  From this it follows that
819
820
       tan(θ) = b/a
821
822
  and hence
823
824
       sin(θ) = b/sqrt(a² + b²)
825
826
  and
827
828
       cos(θ) = a/sqrt(a² + b²)
829
830
  Thus the maximum value is
831
832
       MAX[a*cos(θ) + b*sin(θ)] = (a² + b²)/sqrt(a² + b²)
833
                                   = sqrt(a² + b²)
834
835
  4.  Derivation of maximum expansion
836
837
  To find MAX[ |X'| ] we search brute force method using calculus.  The unit
838
  circle on which X is constrained is to be parameterized by t:
839
840
       X(θ) = (cos(θ), sin(θ))
841
842
  Thus
843
844
       X'(θ) = X(θ) * _R_ = (cos(θ), sin(θ)) * [a b]
845
                                               [c d]
846
             = (a*cos(θ) + c*sin(θ), b*cos(θ) + d*sin(θ)).
847
848
  Define
849
850
       r(θ) = |X'(θ)|
851
852
  Thus
853
854
       r²(θ) = (a*cos(θ) + c*sin(θ))² + (b*cos(θ) + d*sin(θ))²
855
             = (a² + b²)*cos²(θ) + (c² + d²)*sin²(θ)
856
                 + 2*(a*c + b*d)*cos(θ)*sin(θ)
857
858
  Now apply the double angle formulae (A) to (C) from above:
859
860
       r²(θ) = (a² + b² + c² + d²)/2
861
       + (a² + b² - c² - d²)*cos(2*θ)/2
862
         + (a*c + b*d)*sin(2*θ)
863
             = f + g*cos(φ) + h*sin(φ)
864
865
  Where
866
867
       f = (a² + b² + c² + d²)/2
868
       g = (a² + b² - c² - d²)/2
869
       h = (a*c + d*d)
870
       φ = 2*θ
871
872
  It is clear that MAX[ |X'| ] = sqrt(MAX[ r² ]).  Here we determine MAX[ r² ]
873
  using (D) from above:
874
875
       MAX[ r² ] = f + sqrt(g² + h²)
876
877
  And finally
878
879
       MAX[ |X'| ] = sqrt( f + sqrt(g² + h²) )
880
881
  Which is the solution to this problem.
882
883
  Walter Brisken
884
  2004/10/08
885
886
  (Note that the minor axis length is at the minimum of the above solution,
887
  which is just sqrt ( f - sqrt(g² + h²) ) given the symmetry of (D)).
888
889
890
  For another derivation of the same result, using Singular Value Decomposition,
891
  see doc/tutorial/src/singular.c.
892
*/
893
894
/* determine the length of the major axis of a circle of the given radius
895
   after applying the transformation matrix. */
896
double
897
_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
898
               double radius)
899
669k
{
900
669k
    double  a, b, c, d, f, g, h, i, j;
901
902
669k
    if (_cairo_matrix_has_unity_scale (matrix))
903
596k
  return radius;
904
905
72.6k
    _cairo_matrix_get_affine (matrix,
906
72.6k
                              &a, &b,
907
72.6k
                              &c, &d,
908
72.6k
                              NULL, NULL);
909
910
72.6k
    i = a*a + b*b;
911
72.6k
    j = c*c + d*d;
912
913
72.6k
    f = 0.5 * (i + j);
914
72.6k
    g = 0.5 * (i - j);
915
72.6k
    h = a*c + b*d;
916
917
72.6k
    return radius * sqrt (f + hypot (g, h));
918
919
    /*
920
     * we don't need the minor axis length, which is
921
     * double min = radius * sqrt (f - sqrt (g*g+h*h));
922
     */
923
669k
}
924
925
static const pixman_transform_t pixman_identity_transform = {{
926
        {1 << 16,        0,       0},
927
        {       0, 1 << 16,       0},
928
        {       0,       0, 1 << 16}
929
    }};
930
931
static cairo_status_t
932
_cairo_matrix_to_pixman_matrix (const cairo_matrix_t  *matrix,
933
        pixman_transform_t  *pixman_transform,
934
        double xc,
935
        double yc)
936
3.66k
{
937
3.66k
    cairo_matrix_t inv;
938
3.66k
    unsigned max_iterations;
939
940
3.66k
    pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
941
3.66k
    pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
942
3.66k
    pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
943
944
3.66k
    pixman_transform->matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
945
3.66k
    pixman_transform->matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
946
3.66k
    pixman_transform->matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
947
948
3.66k
    pixman_transform->matrix[2][0] = 0;
949
3.66k
    pixman_transform->matrix[2][1] = 0;
950
3.66k
    pixman_transform->matrix[2][2] = 1 << 16;
951
952
    /* The conversion above breaks cairo's translation invariance:
953
     * a translation of (a, b) in device space translates to
954
     * a translation of (xx * a + xy * b, yx * a + yy * b)
955
     * for cairo, while pixman uses rounded versions of xx ... yy.
956
     * This error increases as a and b get larger.
957
     *
958
     * To compensate for this, we fix the point (xc, yc) in pattern
959
     * space and adjust pixman's transform to agree with cairo's at
960
     * that point.
961
     */
962
963
3.66k
    if (_cairo_matrix_has_unity_scale (matrix))
964
0
  return CAIRO_STATUS_SUCCESS;
965
966
3.66k
    if (unlikely (fabs (matrix->xx) > PIXMAN_MAX_INT ||
967
3.66k
      fabs (matrix->xy) > PIXMAN_MAX_INT ||
968
3.66k
      fabs (matrix->x0) > PIXMAN_MAX_INT ||
969
3.66k
      fabs (matrix->yx) > PIXMAN_MAX_INT ||
970
3.66k
      fabs (matrix->yy) > PIXMAN_MAX_INT ||
971
3.66k
      fabs (matrix->y0) > PIXMAN_MAX_INT))
972
2
    {
973
2
  return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
974
2
    }
975
976
    /* Note: If we can't invert the transformation, skip the adjustment. */
977
3.65k
    inv = *matrix;
978
3.65k
    if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
979
0
  return CAIRO_STATUS_SUCCESS;
980
981
    /* find the pattern space coordinate that maps to (xc, yc) */
982
3.65k
    max_iterations = 5;
983
6.74k
    do {
984
6.74k
  double x,y;
985
6.74k
  pixman_vector_t vector;
986
6.74k
  cairo_fixed_16_16_t dx, dy;
987
988
6.74k
  vector.vector[0] = _cairo_fixed_16_16_from_double (xc);
989
6.74k
  vector.vector[1] = _cairo_fixed_16_16_from_double (yc);
990
6.74k
  vector.vector[2] = 1 << 16;
991
992
  /* If we can't transform the reference point, skip the adjustment. */
993
6.74k
  if (! pixman_transform_point_3d (pixman_transform, &vector))
994
0
      return CAIRO_STATUS_SUCCESS;
995
996
6.74k
  x = pixman_fixed_to_double (vector.vector[0]);
997
6.74k
  y = pixman_fixed_to_double (vector.vector[1]);
998
6.74k
  cairo_matrix_transform_point (&inv, &x, &y);
999
1000
  /* Ideally, the vector should now be (xc, yc).
1001
   * We can now compensate for the resulting error.
1002
   */
1003
6.74k
  x -= xc;
1004
6.74k
  y -= yc;
1005
6.74k
  cairo_matrix_transform_distance (matrix, &x, &y);
1006
6.74k
  dx = _cairo_fixed_16_16_from_double (x);
1007
6.74k
  dy = _cairo_fixed_16_16_from_double (y);
1008
6.74k
  pixman_transform->matrix[0][2] -= dx;
1009
6.74k
  pixman_transform->matrix[1][2] -= dy;
1010
1011
6.74k
  if (dx == 0 && dy == 0)
1012
3.65k
      return CAIRO_STATUS_SUCCESS;
1013
6.74k
    } while (--max_iterations);
1014
1015
    /* We didn't find an exact match between cairo and pixman, but
1016
     * the matrix should be mostly correct */
1017
0
    return CAIRO_STATUS_SUCCESS;
1018
3.65k
}
1019
1020
static inline double
1021
_pixman_nearest_sample (double d)
1022
11.1k
{
1023
11.1k
    return ceil (d - .5);
1024
11.1k
}
1025
1026
/**
1027
 * _cairo_matrix_is_pixman_translation:
1028
 * @matrix: a matrix
1029
 * @filter: the filter to be used on the pattern transformed by @matrix
1030
 * @x_offset: the translation in the X direction
1031
 * @y_offset: the translation in the Y direction
1032
 *
1033
 * Checks if @matrix translated by (x_offset, y_offset) can be
1034
 * represented using just an offset (within the range pixman can
1035
 * accept) and an identity matrix.
1036
 *
1037
 * Passing a non-zero value in x_offset/y_offset has the same effect
1038
 * as applying cairo_matrix_translate(matrix, x_offset, y_offset) and
1039
 * setting x_offset and y_offset to 0.
1040
 *
1041
 * Upon return x_offset and y_offset contain the translation vector if
1042
 * the return value is %TRUE. If the return value is %FALSE, they will
1043
 * not be modified.
1044
 *
1045
 * Return value: %TRUE if @matrix can be represented as a pixman
1046
 * translation, %FALSE otherwise.
1047
 **/
1048
cairo_bool_t
1049
_cairo_matrix_is_pixman_translation (const cairo_matrix_t     *matrix,
1050
             cairo_filter_t            filter,
1051
             int                      *x_offset,
1052
             int                      *y_offset)
1053
56.5k
{
1054
56.5k
    double tx, ty;
1055
1056
56.5k
    if (!_cairo_matrix_is_translation (matrix))
1057
48.8k
  return FALSE;
1058
1059
7.70k
    if (matrix->x0 == 0. && matrix->y0 == 0.)
1060
1.56k
  return TRUE;
1061
1062
6.14k
    tx = matrix->x0 + *x_offset;
1063
6.14k
    ty = matrix->y0 + *y_offset;
1064
1065
6.14k
    if (filter == CAIRO_FILTER_FAST || filter == CAIRO_FILTER_NEAREST) {
1066
5.57k
  tx = _pixman_nearest_sample (tx);
1067
5.57k
  ty = _pixman_nearest_sample (ty);
1068
5.57k
    } else if (tx != floor (tx) || ty != floor (ty)) {
1069
570
  return FALSE;
1070
570
    }
1071
1072
5.57k
    if (fabs (tx) > PIXMAN_MAX_INT || fabs (ty) > PIXMAN_MAX_INT)
1073
38
  return FALSE;
1074
1075
5.53k
    *x_offset = _cairo_lround (tx);
1076
5.53k
    *y_offset = _cairo_lround (ty);
1077
5.53k
    return TRUE;
1078
5.57k
}
1079
1080
/**
1081
 * _cairo_matrix_to_pixman_matrix_offset:
1082
 * @matrix: a matrix
1083
 * @filter: the filter to be used on the pattern transformed by @matrix
1084
 * @xc: the X coordinate of the point to fix in pattern space
1085
 * @yc: the Y coordinate of the point to fix in pattern space
1086
 * @out_transform: the transformation which best approximates @matrix
1087
 * @x_offset: the translation in the X direction
1088
 * @y_offset: the translation in the Y direction
1089
 *
1090
 * This function tries to represent @matrix translated by (x_offset,
1091
 * y_offset) as a %pixman_transform_t and an translation.
1092
 *
1093
 * Passing a non-zero value in x_offset/y_offset has the same effect
1094
 * as applying cairo_matrix_translate(matrix, x_offset, y_offset) and
1095
 * setting x_offset and y_offset to 0.
1096
 *
1097
 * If it is possible to represent the matrix with an identity
1098
 * %pixman_transform_t and a translation within the valid range for
1099
 * pixman, this function will set @out_transform to be the identity,
1100
 * @x_offset and @y_offset to be the translation vector and will
1101
 * return %CAIRO_INT_STATUS_NOTHING_TO_DO. Otherwise it will try to
1102
 * evenly divide the translational component of @matrix between
1103
 * @out_transform and (@x_offset, @y_offset).
1104
 *
1105
 * Upon return x_offset and y_offset contain the translation vector.
1106
 *
1107
 * Return value: %CAIRO_INT_STATUS_NOTHING_TO_DO if the out_transform
1108
 * is the identity, %CAIRO_STATUS_INVALID_MATRIX if it was not
1109
 * possible to represent @matrix as a pixman_transform_t without
1110
 * overflows, %CAIRO_STATUS_SUCCESS otherwise.
1111
 **/
1112
cairo_status_t
1113
_cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t *matrix,
1114
               cairo_filter_t            filter,
1115
               double                    xc,
1116
               double                    yc,
1117
               pixman_transform_t *out_transform,
1118
               int                      *x_offset,
1119
               int                      *y_offset)
1120
3.67k
{
1121
3.67k
    cairo_bool_t is_pixman_translation;
1122
1123
3.67k
    is_pixman_translation = _cairo_matrix_is_pixman_translation (matrix,
1124
3.67k
                 filter,
1125
3.67k
                 x_offset,
1126
3.67k
                 y_offset);
1127
1128
3.67k
    if (is_pixman_translation) {
1129
12
  *out_transform = pixman_identity_transform;
1130
12
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
1131
3.66k
    } else {
1132
3.66k
  cairo_matrix_t m;
1133
1134
3.66k
  m = *matrix;
1135
3.66k
  cairo_matrix_translate (&m, *x_offset, *y_offset);
1136
3.66k
  if (m.x0 != 0.0 || m.y0 != 0.0) {
1137
3.65k
      double tx, ty, norm;
1138
3.65k
      int i, j;
1139
1140
      /* pixman also limits the [xy]_offset to 16 bits so evenly
1141
       * spread the bits between the two.
1142
       *
1143
       * To do this, find the solutions of:
1144
       *   |x| = |x*m.xx + y*m.xy + m.x0|
1145
       *   |y| = |x*m.yx + y*m.yy + m.y0|
1146
       *
1147
       * and select the one whose maximum norm is smallest.
1148
       */
1149
3.65k
      tx = m.x0;
1150
3.65k
      ty = m.y0;
1151
3.65k
      norm = MAX (fabs (tx), fabs (ty));
1152
1153
10.9k
      for (i = -1; i < 2; i+=2) {
1154
21.9k
    for (j = -1; j < 2; j+=2) {
1155
14.6k
        double x, y, den, new_norm;
1156
1157
14.6k
        den = (m.xx + i) * (m.yy + j) - m.xy * m.yx;
1158
14.6k
        if (fabs (den) < DBL_EPSILON)
1159
0
      continue;
1160
1161
14.6k
        x = m.y0 * m.xy - m.x0 * (m.yy + j);
1162
14.6k
        y = m.x0 * m.yx - m.y0 * (m.xx + i);
1163
1164
14.6k
        den = 1 / den;
1165
14.6k
        x *= den;
1166
14.6k
        y *= den;
1167
1168
14.6k
        new_norm = MAX (fabs (x), fabs (y));
1169
14.6k
        if (norm > new_norm) {
1170
8.32k
      norm = new_norm;
1171
8.32k
      tx = x;
1172
8.32k
      ty = y;
1173
8.32k
        }
1174
14.6k
    }
1175
7.30k
      }
1176
1177
3.65k
      tx = floor (tx);
1178
3.65k
      ty = floor (ty);
1179
3.65k
      *x_offset = -tx;
1180
3.65k
      *y_offset = -ty;
1181
3.65k
      cairo_matrix_translate (&m, tx, ty);
1182
3.65k
  } else {
1183
8
      *x_offset = 0;
1184
8
      *y_offset = 0;
1185
8
  }
1186
1187
3.66k
  return _cairo_matrix_to_pixman_matrix (&m, out_transform, xc, yc);
1188
3.66k
    }
1189
3.67k
}