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