home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1990, 1993 Aladdin Enterprises. All rights reserved.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* gxfixed.h */
- /* Fixed-point arithmetic for Ghostscript */
-
- #ifndef gxfixed_INCLUDED
- # define gxfixed_INCLUDED
-
- /*
- * Coordinates are generally represented internally by fixed-point
- * quantities: integers lose accuracy in crucial places,
- * and floating point arithmetic is slow.
- */
- typedef long fixed;
- #define max_fixed max_long
- #define min_fixed min_long
- /*
- * 12 bits of fraction provides both the necessary accuracy and
- * a sufficiently large range of coordinates.
- */
- #define _fixed_shift 12
- #define _fixed_scale (1<<_fixed_shift)
- #define _fixed_rshift(x) arith_rshift(x,_fixed_shift)
- #define _fixed_round_v (_fixed_scale>>1)
- #define _fixed_fraction_v (_fixed_scale-1)
-
- /*
- * Most operations can be done directly on fixed-point quantities:
- * addition, subtraction, shifting, multiplication or division by
- * (integer) constants; assignment, assignment with zero;
- * comparison, comparison against zero.
- * Multiplication and division by floats is OK if the result is
- * explicitly cast back to fixed.
- * Conversion to and from int and float types must be done explicitly.
- * Note that if we are casting a fixed to a float in a context where
- * only ratios and not actual values are involved, we don't need to take
- * the scale factor into account: we can simply cast to float directly.
- */
- #define int2fixed(i) ((fixed)(i)<<_fixed_shift)
- /* Define some useful constants. */
- #define fixed_0 int2fixed(0)
- #define fixed_1 int2fixed(1)
- #define fixed_half (fixed_1 >> 1)
- /*
- * On 16-bit systems, we can convert fixed variables to ints more efficiently
- * than general fixed quantities. For this reason, we define two separate
- * sets of conversion macros.
- */
- #define fixed2int(x) ((int)_fixed_rshift(x))
- #define fixed2int_rounded(x) ((int)_fixed_rshift((x)+_fixed_round_v))
- #define fixed2int_ceiling(x) ((int)_fixed_rshift((x)+_fixed_fraction_v))
- #if arch_ints_are_short & !arch_is_big_endian
- /* Do some of the shifting and extraction ourselves. */
- # define _fixed_hi(x) *((uint *)&(x)+1)
- # define _fixed_lo(x) *((uint *)&(x))
- # define fixed2int_var(x)\
- ((int)((_fixed_hi(x) << (16-_fixed_shift)) +\
- (_fixed_lo(x) >> _fixed_shift)))
- # define fixed2int_var_rounded(x)\
- ((int)((_fixed_hi(x) << (16-_fixed_shift)) +\
- (((_fixed_lo(x) >> (_fixed_shift-1))+1)>>1)))
- # define fixed2int_var_ceiling(x)\
- (fixed2int_var(x) -\
- arith_rshift((int)-(_fixed_lo(x) & _fixed_fraction_v), _fixed_shift))
- #else
- /* Use reasonable definitions. */
- # define fixed2int_var(x) fixed2int(x)
- # define fixed2int_var_rounded(x) fixed2int_rounded(x)
- # define fixed2int_var_ceiling(x) fixed2int_ceiling(x)
- #endif
- #define fixed2long(x) ((long)_fixed_rshift(x))
- #define fixed2long_rounded(x) ((long)_fixed_rshift((x)+_fixed_round_v))
- #define fixed2long_ceiling(x) ((long)_fixed_rshift((x)+_fixed_fraction_v))
- #define float2fixed(f) ((fixed)((f)*(float)_fixed_scale))
- #define fixed2float(x) ((float)((x)*(1.0/_fixed_scale)))
-
- /* Rounding and truncation on fixeds */
- #define fixed_floor(x) ((x)&(-1L<<_fixed_shift))
- #define fixed_rounded(x) (((x)+_fixed_round_v)&(-1L<<_fixed_shift))
- #define fixed_ceiling(x) (((x)+_fixed_fraction_v)&(-1L<<_fixed_shift))
- #define fixed_fraction(x) ((int)(x)&_fixed_fraction_v)
- /* I don't see how to do truncation towards 0 so easily.... */
- #define fixed_truncated(x) ((x) < 0 ? fixed_ceiling(x) : fixed_floor(x))
-
- /* A point with fixed coordinates */
- typedef struct gs_fixed_point_s {
- fixed x, y;
- } gs_fixed_point;
-
- /* A rectangle with fixed coordinates */
- typedef struct gs_fixed_rect_s {
- gs_fixed_point p, q;
- } gs_fixed_rect;
-
- #endif /* gxfixed_INCLUDED */
-