contrib/OWB: add correct SDL dependency, fix compilers used
[AROS-Contrib.git] / freetype1 / pascal / lib / ttcalc.pas
blob2d08741e3c49f2214aa8a9fdaccbfb2a31e8e697
1 (*******************************************************************
3 * TTCalc.Pas 1.2
5 * Arithmetic and Vectorial Computations (specification)
7 * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg
9 * This file is part of the FreeType project, and may only be used
10 * modified and distributed under the terms of the FreeType project
11 * license, LICENSE.TXT. By continuing to use, modify or distribute
12 * this file you indicate that you have read the license and
13 * understand and accept it fully.
15 * NOTES : All vector operations were moved to the interpreter
17 ******************************************************************)
19 unit TTCalc;
21 interface
23 {$I TTCONFIG.INC}
25 type
26 (* IntN types : *)
27 (* *)
28 (* These types are used as a way to garantee the size of some *)
29 (* specific integers. *)
30 (* *)
31 (* Of course, they are equivalent to Short, UShort, Long, etc .. *)
32 (* but parts of this unit could be used by different programs. *)
33 (* *)
35 (* Define the 16-bit type *)
36 {$IFDEF BORLANDPASCAL}
37 Int16 = Integer;
38 Word16 = Word; (* 16-bits unsigned *)
39 {$ELSE}
40 {$IFDEF DELPHI16}
41 Int16 = Integer;
42 Word16 = Word; (* 16-bits unsigned *)
43 {$ELSE}
44 {$IFDEF DELPHI32}
45 Int16 = SmallInt;
46 Word16 = Word; (* 16-bits unsigned *)
47 {$ELSE}
48 Int16 = SmallInt;
49 Word16 = SmallWord; (* 16-bits unsigned *)
50 {$ENDIF}
51 {$ENDIF}
52 {$ENDIF}
54 Int32 = LongInt; (* 32 bits integer *)
56 Word32 = LongInt; (* 32 bits 'unsigned'. Note that there's *)
57 (* no unsigned long in Pascal.. *)
58 (* As cardinals are only 31 bits !! *)
60 Int64 = record (* 64 "" *)
61 Lo,
62 Hi : LongInt;
63 end;
65 function MulDiv( A, B, C : Int32 ): Int32;
67 function MulDiv_Round( A, B, C : Int32 ): Int32;
69 procedure Add64( var X, Y, Z : Int64 );
70 procedure Sub64( var X, Y, Z : Int64 );
72 procedure MulTo64( X, Y : Int32; var Z : Int64 );
74 function Div64by32( var X : Int64; Y : Int32 ) : Int32;
76 function Order64( var Z : Int64 ) : integer;
77 function Order32( Z : Int32 ) : integer;
79 function Sqrt32( L : Int32 ): LongInt;
80 function Sqrt64( L : Int64 ): LongInt;
82 {$IFDEF TEST}
83 procedure Neg64( var x : Int64 );
84 procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 );
85 {$ENDIF}
87 implementation
89 (* add support for Virtual Pascal inline assembly *)
90 {$IFDEF VIRTUALPASCAL}
91 {$I TTCALC2.INC}
92 {$ENDIF}
94 (* add support for Delphi 2 and 3 inline assembly *)
95 {$IFDEF DELPHI32}
96 {$I TTCALC3.INC}
97 {$ENDIF}
99 (* add support for Borland Pascal and Turbo Pascal inline assembly *)
100 {$IFDEF BORLANDPASCAL}
101 {$I TTCALC1.INC}
102 {$ENDIF}
104 (* Delphi 16 uses the same inline assembly than Borland Pascal *)
105 {$IFDEF DELPHI16}
106 {$I TTCALC1.INC}
107 {$ENDIF}
109 (* add support for Free Pascal inline assembly *)
110 {$IFDEF FPK}
111 {$I TTCALC4.INC}
112 {$ENDIF}
114 (*****************************************************************)
115 (* *)
116 (* MulDiv : computes A*B/C with an intermediate 64 bits *)
117 (* precision. *)
118 (* *)
119 (*****************************************************************)
121 function MulDiv( a, b, c : Int32 ) : Int32;
123 s : Int32;
124 temp : Int64;
125 begin
126 s := a; a := abs(a);
127 s := s xor b; b := abs(b);
128 s := s xor c; c := abs(c);
130 MulTo64( a, b, temp );
131 c := Div64by32( temp, c );
133 if s < 0 then c := -c;
135 MulDiv := c;
136 end;
138 (*****************************************************************)
139 (* *)
140 (* MulDiv : computes A*B/C with an intermediate 64 bits *)
141 (* _Round precision and rounding. *)
142 (* *)
143 (*****************************************************************)
145 function MulDiv_Round( a, b, c : Int32 ) : Int32;
147 s : Int32;
149 temp, temp2 : Int64;
150 begin
151 s := a; a := abs(a);
152 s := s xor b; b := abs(b);
153 s := s xor c; c := abs(c);
155 MulTo64( a, b, temp );
157 temp2.hi := 0;
158 temp2.lo := c div 2;
160 Add64( temp, temp2, temp );
162 c := Div64by32( temp, c );
164 if s < 0 then c := -c;
166 MulDiv_Round := c;
167 end;
170 (**********************************************************)
171 (* Negation *)
173 procedure Neg64( var x : Int64 );
174 begin
175 (* Remember that -(0x80000000) == 0x80000000 with 2-complement! *)
176 (* We take care of that here. *)
178 x.hi := x.hi xor $FFFFFFFF;
179 x.lo := x.lo xor $FFFFFFFF;
180 inc( x.lo );
182 if x.lo = 0 then
183 begin
184 inc( x.hi );
185 if x.hi = $80000000 then (* check -MaxInt32-1 *)
186 begin
187 dec( x.lo ); (* we return $7FFFFFFF *)
188 dec( x.hi );
189 end;
190 end;
191 end;
194 (**********************************************************)
195 (* MSB index ( return -1 for 0 ) *)
197 function Order64( var Z : Int64 ) : integer;
198 begin
199 if Z.Hi <> 0 then Order64 := 32 + Order32( Z.Hi )
200 else Order64 := Order32( Z.Lo );
201 end;
204 (**********************************************************)
205 (* MSB index ( return -1 for 0 ) *)
207 function Order32( Z : Int32 ) : integer;
208 var b : integer;
209 begin
210 b := 0;
211 while Z <> 0 do begin Z := Z shr 1; inc( b ); end;
212 Order32 := b-1;
213 end;
216 const
217 Roots : array[0..62] of LongInt
219 1, 1, 2, 3, 4, 5, 8, 11,
220 16, 22, 32, 45, 64, 90, 128, 181,
221 256, 362, 512, 724, 1024, 1448, 2048, 2896,
222 4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340,
224 65536, 92681, 131072, 185363, 262144, 370727,
225 524288, 741455, 1048576, 1482910, 2097152, 2965820,
226 4194304, 5931641, 8388608, 11863283, 16777216, 23726566,
228 33554432, 47453132, 67108864, 94906265,
229 134217728, 189812531, 268435456, 379625062,
230 536870912, 759250125, 1073741824, 1518500250,
231 2147483647
235 (**************************************************)
236 (* Integer Square Root *)
238 function Sqrt32( L : Int32 ): LongInt;
240 R, S : LongInt;
241 begin
242 if L<=0 then Sqrt32:=0 else
243 if L=1 then Sqrt32:=1 else
244 begin
245 R:=Roots[ Order32(L) ];
247 Repeat
248 S:=R;
249 R:=( R+ L div R ) shr 1;
250 until ( R <= S ) and ( R*R <= L );
252 Sqrt32:=R;
253 end;
254 end;
257 (**************************************************)
258 (* Integer Square Root *)
260 function Sqrt64( L : Int64 ): LongInt;
262 L2 : Int64;
263 R, S : LongInt;
264 begin
265 if L.Hi < 0 then Sqrt64:=0 else
266 begin
267 S := Order64(L);
268 if S = 0 then Sqrt64:=1 else
269 begin
270 R := Roots[S];
272 Repeat
274 S := R;
275 R := ( R+Div64by32(L,R) ) shr 1;
277 if ( R > S ) then continue;
279 MulTo64( R, R, L2 );
280 Sub64 ( L, L2, L2 );
282 until ( L2.Hi >= 0 );
284 Sqrt64 := R;
287 end;
289 end.