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