Commit | Line | Data |
---|---|---|
ca09e989 WJ |
1 | /* Copyright (C) 1989, 1990 Aladdin Enterprises. All rights reserved. |
2 | Distributed by Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of Ghostscript. | |
5 | ||
6 | Ghostscript is distributed in the hope that it will be useful, but | |
7 | WITHOUT ANY WARRANTY. No author or distributor accepts responsibility | |
8 | to anyone for the consequences of using it or for whether it serves any | |
9 | particular purpose or works at all, unless he says so in writing. Refer | |
10 | to the Ghostscript General Public License for full details. | |
11 | ||
12 | Everyone is granted permission to copy, modify and redistribute | |
13 | Ghostscript, but only under the conditions described in the Ghostscript | |
14 | General Public License. A copy of this license is supposed to have been | |
15 | given to you along with Ghostscript so you can know your rights and | |
16 | responsibilities. It should be in a file named COPYING. Among other | |
17 | things, the copyright notice and this notice must be preserved on all | |
18 | copies. */ | |
19 | ||
20 | /* gxfixed.h */ | |
21 | /* Fixed-point arithmetic for GhostScript */ | |
22 | ||
23 | /* | |
24 | * Coordinates are generally represented internally by fixed-point | |
25 | * quantities: integers lose accuracy in crucial places, | |
26 | * and floating point arithmetic is slow. | |
27 | */ | |
28 | typedef long fixed; | |
29 | #define max_fixed 0x7fffffffL | |
30 | #define min_fixed (~max_fixed) | |
31 | /* | |
32 | * 12 bits of fraction provides both the necessary accuracy and | |
33 | * a sufficiently large range of coordinates. | |
34 | */ | |
35 | #define _fixed_shift 12 | |
36 | #define _fixed_scale (1<<_fixed_shift) | |
37 | #define _fixed_rshift(x) arith_rshift(x,_fixed_shift) | |
38 | #define _fixed_round_v (_fixed_scale>>1) | |
39 | #define _fixed_fraction_v (_fixed_scale-1) | |
40 | ||
41 | /* | |
42 | * Most operations can be done directly on fixed-point quantities: | |
43 | * addition, subtraction, shifting, multiplication or division by | |
44 | * (integer) constants; assignment, assignment with zero; | |
45 | * comparison, comparison against zero. | |
46 | * Multiplication and division by floats is OK if the result is | |
47 | * explicitly cast back to fixed. | |
48 | * Conversion to and from int and float types must be done explicitly. | |
49 | * Note that if we are casting a fixed to a float in a context where | |
50 | * only ratios and not actual values are involved, we don't need to take | |
51 | * the scale factor into account: we can simply cast to float directly. | |
52 | */ | |
53 | #define int2fixed(i) ((fixed)(i)<<_fixed_shift) | |
54 | /* Define some useful constants. */ | |
55 | #define fixed_0 int2fixed(0) | |
56 | #define fixed_1 int2fixed(1) | |
57 | /* | |
58 | * On 16-bit systems, we can convert fixed variables to ints more efficiently | |
59 | * than general fixed quantities. For this reason, we define two separate | |
60 | * sets of conversion macros. | |
61 | */ | |
62 | #define fixed2int(x) ((int)_fixed_rshift(x)) | |
63 | #define fixed2int_rounded(x) ((int)_fixed_rshift((x)+_fixed_round_v)) | |
64 | #define fixed2int_ceiling(x) ((int)_fixed_rshift((x)+_fixed_fraction_v)) | |
65 | #if arch_ints_are_short & !arch_is_big_endian | |
66 | /* Do some of the shifting and extraction ourselves. */ | |
67 | # define _fixed_hi(x) *((uint *)&(x)+1) | |
68 | # define _fixed_lo(x) *((uint *)&(x)) | |
69 | # define fixed2int_var(x)\ | |
70 | ((int)((_fixed_hi(x) << (16-_fixed_shift)) +\ | |
71 | (_fixed_lo(x) >> _fixed_shift))) | |
72 | # define fixed2int_var_rounded(x)\ | |
73 | ((int)((_fixed_hi(x) << (16-_fixed_shift)) +\ | |
74 | (((_fixed_lo(x) >> (_fixed_shift-1))+1)>>1))) | |
75 | # define fixed2int_var_ceiling(x)\ | |
76 | (fixed2int_var(x) -\ | |
77 | arith_rshift((int)-(_fixed_lo(x) & _fixed_fraction_v), _fixed_shift)) | |
78 | #else | |
79 | /* Use reasonable definitions. */ | |
80 | # define fixed2int_var(x) fixed2int(x) | |
81 | # define fixed2int_var_rounded(x) fixed2int_rounded(x) | |
82 | # define fixed2int_var_ceiling(x) fixed2int_ceiling(x) | |
83 | #endif | |
84 | #define fixed2long(x) ((long)_fixed_rshift(x)) | |
85 | #define fixed2long_rounded(x) ((long)_fixed_rshift((x)+_fixed_round_v)) | |
86 | #define fixed2long_ceiling(x) ((long)_fixed_rshift((x)+_fixed_fraction_v)) | |
87 | #define float2fixed(f) ((fixed)((f)*(float)_fixed_scale)) | |
88 | #define fixed2float(x) ((float)((x)*(1.0/_fixed_scale))) | |
89 | ||
90 | /* Rounding and truncation on fixeds */ | |
91 | #define fixed_truncated(x) ((x)&(-1L<<_fixed_shift)) | |
92 | #define fixed_rounded(x) (((x)+_fixed_round_v)&(-1L<<_fixed_shift)) | |
93 | #define fixed_ceiling(x) (((x)+_fixed_fraction_v)&(-1L<<_fixed_shift)) | |
94 | #define fixed_fraction(x) ((x)&_fixed_fraction_v) | |
95 | ||
96 | /* A point with fixed coordinates */ | |
97 | typedef struct gs_fixed_point_s { | |
98 | fixed x, y; | |
99 | } gs_fixed_point; | |
100 | ||
101 | /* A rectangle with fixed coordinates */ | |
102 | typedef struct gs_fixed_rect_s { | |
103 | gs_fixed_point p, q; | |
104 | } gs_fixed_rect; |