1 (*******************************************************************
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 ******************************************************************)
28 (* These types are used as a way to garantee the size of some *)
29 (* specific integers. *)
31 (* Of course, they are equivalent to Short, UShort, Long, etc .. *)
32 (* but parts of this unit could be used by different programs. *)
35 (* Define the 16-bit type *)
36 {$IFDEF BORLANDPASCAL}
38 Word16
= Word; (* 16-bits unsigned *)
42 Word16
= Word; (* 16-bits unsigned *)
46 Word16
= Word; (* 16-bits unsigned *)
49 Word16
= SmallWord
; (* 16-bits unsigned *)
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 "" *)
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;
83 procedure Neg64( var x
: Int64 );
84 procedure DivMod64by32( var X
: Int64; Y
: Int32
; var Q
, R
: Int32
);
89 (* add support for Virtual Pascal inline assembly *)
90 {$IFDEF VIRTUALPASCAL}
94 (* add support for Delphi 2 and 3 inline assembly *)
99 (* add support for Borland Pascal and Turbo Pascal inline assembly *)
100 {$IFDEF BORLANDPASCAL}
104 (* Delphi 16 uses the same inline assembly than Borland Pascal *)
109 (* add support for Free Pascal inline assembly *)
114 (*****************************************************************)
116 (* MulDiv : computes A*B/C with an intermediate 64 bits *)
119 (*****************************************************************)
121 function MulDiv( a
, b
, c
: Int32
) : Int32
;
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
;
138 (*****************************************************************)
140 (* MulDiv : computes A*B/C with an intermediate 64 bits *)
141 (* _Round precision and rounding. *)
143 (*****************************************************************)
145 function MulDiv_Round( a
, b
, c
: Int32
) : Int32
;
152 s
:= s
xor b
; b
:= abs(b
);
153 s
:= s
xor c
; c
:= abs(c
);
155 MulTo64( a
, b
, temp
);
160 Add64( temp
, temp2
, temp
);
162 c
:= Div64by32( temp
, c
);
164 if s
< 0 then c
:= -c
;
170 (**********************************************************)
173 procedure Neg64( var x
: Int64 );
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;
185 if x
.hi
= $80000000 then (* check -MaxInt32-1 *)
187 dec( x
.lo
); (* we return $7FFFFFFF *)
194 (**********************************************************)
195 (* MSB index ( return -1 for 0 ) *)
197 function Order64( var Z
: Int64 ) : integer;
199 if Z
.Hi
<> 0 then Order64
:= 32 + Order32( Z
.Hi
)
200 else Order64
:= Order32( Z
.Lo
);
204 (**********************************************************)
205 (* MSB index ( return -1 for 0 ) *)
207 function Order32( Z
: Int32
) : integer;
211 while Z
<> 0 do begin Z
:= Z
shr 1; inc( b
); end;
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,
235 (**************************************************)
236 (* Integer Square Root *)
238 function Sqrt32( L
: Int32
): LongInt;
242 if L
<=0 then Sqrt32
:=0 else
243 if L
=1 then Sqrt32
:=1 else
245 R
:=Roots
[ Order32(L
) ];
249 R
:=( R
+ L
div R
) shr 1;
250 until ( R
<= S
) and ( R
*R
<= L
);
257 (**************************************************)
258 (* Integer Square Root *)
260 function Sqrt64( L
: Int64 ): LongInt;
265 if L
.Hi
< 0 then Sqrt64
:=0 else
268 if S
= 0 then Sqrt64
:=1 else
275 R
:= ( R
+Div64by32(L
,R
) ) shr 1;
277 if ( R
> S
) then continue
;
282 until ( L2
.Hi
>= 0 );