| /* Copyright (C) 1989, 1990 Aladdin Enterprises. All rights reserved. |
| Distributed by Free Software Foundation, Inc. |
| |
| 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 */ |
| |
| /* |
| * 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 0x7fffffffL |
| #define min_fixed (~max_fixed) |
| /* |
| * 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) |
| /* |
| * Because of the way conversions from fixed to int are defined |
| * on MS-DOS systems, the argument of fixed2int must be a variable |
| * (or at least something that has an l-value). |
| */ |
| #ifdef __MSDOS__ |
| /* Assume 16-bit ints, little-endian machine. */ |
| # define _fixed_hi(x) *((uint *)&(x)+1) |
| # define _fixed_lo(x) *((uint *)&(x)) |
| # define fixed2int(x)\ |
| ((int)((_fixed_hi(x) << (16-_fixed_shift)) +\ |
| (_fixed_lo(x) >> _fixed_shift))) |
| # define fixed2int_rounded(x)\ |
| ((int)((_fixed_hi(x) << (16-_fixed_shift)) +\ |
| (((_fixed_lo(x) >> (_fixed_shift-1))+1)>>1))) |
| # define fixed2int_ceiling(x)\ |
| (fixed2int(x) -\ |
| arith_rshift((int)-(_fixed_lo(x) & _fixed_fraction_v), _fixed_shift)) |
| #else /* use reasonable definitions */ |
| # 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)) |
| #endif |
| /* The other definitions are more reasonable. */ |
| #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_truncated(x) ((x)&(-1L<<_fixed_shift)) |
| #define fixed_rounded(x) (((x)+_fixed_round_v)&(-1L<<_fixed_shift)) |
| #define fixed_fraction(x) ((x)&_fixed_fraction_v) |
| |
| /* 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; |