1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Internal matrix routines for Ghostscript library */
18 
19 #ifndef gxmatrix_INCLUDED
20 #  define gxmatrix_INCLUDED
21 
22 #include "gsmatrix.h"
23 
24 /* The following switch is for developmenty purpose only.
25    PRECISE_CURRENTPOINT 0 must not go to production due to no clamping. */
26 #define PRECISE_CURRENTPOINT 1 /* Old code compatible with dropped clamping = 0, new code = 1 */
27 
28 /*
29  * Define a matrix with a cached fixed-point copy of the translation.
30  * This is only used by a few routines in gscoord.c; they are responsible
31  * for ensuring the validity of the cache.  Note that the floating point
32  * tx/ty values may be too large to fit in a fixed values; txy_fixed_valid
33  * is false if this is the case, and true otherwise.
34  */
35 struct gs_matrix_fixed_s {
36     _matrix_body;
37     fixed tx_fixed, ty_fixed;
38     bool txy_fixed_valid;
39 };
40 
41 #ifndef gs_matrix_fixed_DEFINED
42 #define gs_matrix_fixed_DEFINED
43 typedef struct gs_matrix_fixed_s gs_matrix_fixed;
44 #endif
45 
46 /* Make a gs_matrix_fixed from a gs_matrix. */
47 int gs_matrix_fixed_from_matrix(gs_matrix_fixed *, const gs_matrix *);
48 
49 /* Coordinate transformations to fixed point. */
50 int gs_point_transform2fixed(const gs_matrix_fixed *, floatp, floatp,
51                              gs_fixed_point *);
52 int gs_distance_transform2fixed(const gs_matrix_fixed *, floatp, floatp,
53                                 gs_fixed_point *);
54 #if PRECISE_CURRENTPOINT
55 int gs_point_transform2fixed_rounding(const gs_matrix_fixed * pmat,
56                          floatp x, floatp y, gs_fixed_point * ppt);
57 #endif
58 
59 /*
60  * Define the fixed-point coefficient structure for avoiding
61  * floating point in coordinate transformations.
62  * Currently this is used only by the Type 1 font interpreter.
63  * The setup is in gscoord.c.
64  */
65 typedef struct {
66     long xx, xy, yx, yy;
67     int skewed;
68     int shift;			/* see m_fixed */
69     int max_bits;		/* max bits of coefficient */
70     fixed round;		/* ditto */
71 } fixed_coeff;
72 
73 /*
74  * Multiply a fixed point value by a coefficient.  The coefficient has two
75  * parts: a value (long) and a shift factor (int), The result is (fixed *
76  * coef_value + round_value) >> (shift + _fixed_shift)) where the shift
77  * factor and the round value are picked from the fixed_coeff structure, and
78  * the coefficient value (from one of the coeff1 members) is passed
79  * explicitly.  The last parameter specifies the number of bits available to
80  * prevent overflow for integer arithmetic.  (This is a very custom
81  * routine.)  The intermediate value may exceed the size of a long integer.
82  */
83 fixed fixed_coeff_mult(fixed, long, const fixed_coeff *, int);
84 
85 /*
86  * Multiply a fixed whose integer part usually does not exceed max_bits
87  * in magnitude by a coefficient from a fixed_coeff.
88  * We can use a faster algorithm if the fixed is an integer within
89  * a range that doesn't cause the multiplication to overflow an int.
90  */
91 #define m_fixed(v, c, fc, maxb)\
92   (((v) + (fixed_1 << (maxb - 1))) &\
93     ((-fixed_1 << maxb) | _fixed_fraction_v) ?	/* out of range, or has fraction */\
94     fixed_coeff_mult((v), (fc).c, &(fc), maxb) : \
95    arith_rshift(fixed2int_var(v) * (fc).c + (fc).round, (fc).shift))
96 
97 #endif /* gxmatrix_INCLUDED */
98