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