]> mj.ucw.cz Git - libucw.git/blob - charset/misc/gen-ligatures
Merge with git+ssh://git.ucw.cz/projects/sherlock/GIT/sherlock.git#v3.10
[libucw.git] / charset / misc / gen-ligatures
1 #!/usr/bin/perl
2 #
3 #  Generate Expansion Table of Compatibility Ligatures
4 #  (c) 2003 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
5 #
6
7 use strict;
8 use warnings;
9
10 print STDERR "Reading ligature list\n";
11 open(L, "misc/u-ligatures") || die "lig file open";
12 my %ligs = ();
13 while (<L>) {
14         chomp;
15         $ligs{$_} = 1;
16 }
17 close L;
18
19 print STDERR "Reading decompositions\n";
20 open(I, "unidata/UnicodeData.txt") || die "Unable to open UniCode data file";
21 my %decs = ();
22 while (<I>) {
23         chomp;
24         (/^$/ || /^#/) && next;
25         my ($code,$name,$cat,$comb,$bidir,$decomp,$d0,$d1,$n0,$mirr,$cmt1,$cmt2,$upper,$lower,$title) = split /;/;
26         $code =~ /^....$/ || next;
27         if (my ($d) = ($decomp =~ /^<compat> (.*)/)) {
28                 $decs{$code} = $d;
29         }
30 }
31 close I;
32
33 sub expand($) {
34         my ($c) = @_;
35         if (defined $decs{$c}) {
36                 return join (" ", map { expand($_) } split(/\s+/, $decs{$c}));
37         } else {
38                 return $c;
39         }
40 }
41
42 print STDERR "Searching for a perfect hash function\n";
43 my $n = keys %ligs;
44 my $div = $n-1;
45 DIV: while (++$div) {
46         #print STDERR "Trying $div... ";
47         my @c = ();
48         foreach my $l (keys %ligs) {
49                 my $i = (hex $l) % $div;
50                 if (defined $c[$i]) {
51                         #print STDERR "collision\n";
52                         next DIV;
53                 }
54                 $c[$i] = 1;
55         }
56         #print STDERR "FOUND\n";
57         last;
58 }
59
60 print STDERR "Filling hash table with $div entries for $n ligatures\n";
61 my @ht = map { "NULL" } 1..$div;
62 foreach my $l (keys %ligs) {
63         my $i = (hex $l) % $div;
64         my $w = join(", ", map { "0x$_" } split(/ /, expand($l)));
65         $ht[$i] = "/* $l */ (const u16 []) { $w, 0 }";
66 }
67
68 print "#define LIG_HASH_SIZE $div\n\n";
69 print "static const u16 *_U_lig_hash[] = {\n";
70 for (my $i=0; $i<$div; $i++) {
71         print "\t", $ht[$i], ",\n";
72 }
73 print "};\n";