1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
(***********************************************************************)
(* *)
(* Active-DVI *)
(* *)
(* Projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 2002 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the GNU Lesser General Public License. *)
(* *)
(* Jun Furuse, Didier Rmy and Pierre Weis. *)
(* Contributions by Roberto Di Cosmo, Didier Le Botlan, *)
(* Xavier Leroy, and Alan Schmitt. *)
(* *)
(* Based on Mldvi by Alexandre Miquel. *)
(***********************************************************************)
(* $Id: adviUnits.ml,v 1.1 2009/01/23 16:28:48 maranget Exp $ *)
type units =
| PT
| PC
| IN
| BP
| CM
| MM
| DD
| CC
| SP ;;
(*** Rational arithmetic ***)
let rec unsafe_gcd big small =
if small = 0 then big else
unsafe_gcd small (big mod small) ;;
let gcd a b =
if a > b then unsafe_gcd a b else
if a < b then unsafe_gcd b a else a ;;
let simplify (num, den) =
let d = gcd num den in
(num/d, den/d) ;;
let rec mag n =
if n = 0 then 0 else
1 + mag (n/2) ;;
let mul (n1, d1) (n2, d2) =
simplify (n1 * n2, d1 * d2) ;;
let div r (n, d) =
mul r (d, n) ;;
let conv_list = ref [PT, (1, 1)] ;;
let set k1 u1 (* = *) k2 u2 =
assert (not (List.mem_assoc u1 !conv_list)) ;
let r2 = List.assoc u2 !conv_list in
let r1 = mul r2 (k2, k1) in
conv_list := (u1, r1) :: !conv_list ;;
(* Convertion ratios (source: D. Knuth, The TeXbook 1986, Addisson-Wesley) *)
set 1 PC (* = *) 12 PT ;;
set 100 IN (* = *) 7227 PT ;;
set 72 BP (* = *) 1 IN ;;
set 254 CM (* = *) 100 IN ;;
set 10 MM (* = *) 1 CM ;;
set 1157 DD (* = *) 1238 PT ;;
set 1 CC (* = *) 12 DD ;;
set 65536 SP (* = *) 1 PT ;;
let int_of_units = function
| PT -> 0 | PC -> 1 | IN -> 2
| BP -> 3 | CM -> 4 | MM -> 5
| DD -> 6 | CC -> 7 | SP -> 8 ;;
let units_of_int = function
| 0 -> PT | 1 -> PC | 2 -> IN
| 3 -> BP | 4 -> CM | 5 -> MM
| 6 -> DD | 7 -> CC | 8 -> SP
| _ -> assert false ;;
let matrix = Array.create_matrix 9 9 (0, 0) ;;
for i = 0 to 8 do
for j = 0 to 8 do
let ri = List.assoc (units_of_int i) !conv_list
and rj = List.assoc (units_of_int j) !conv_list in
matrix.(i).(j) <- div rj ri
done
done ;;
let ratio u1 u2 =
matrix.(int_of_units u1).(int_of_units u2) ;;
let from_to u1 u2 =
let (n1, n2) = ratio u1 u2 in
let f = float n2 /. float n1 in
function x -> f *. x ;;
|