1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6# Copy from RenderBuffer.pm
7use constant {
8   LINE_SINGLE => 0x01,
9   LINE_DOUBLE => 0x02,
10   LINE_THICK  => 0x03,
11};
12
13# Bitmasks on Cell linemask
14use constant {
15   # Connections to the next cell upwards
16   NORTH        => 0x03,
17   NORTH_SINGLE => 0x01,
18   NORTH_DOUBLE => 0x02,
19   NORTH_THICK  => 0x03,
20   NORTH_SHIFT  => 0,
21
22   # Connections to the next cell to the right
23   EAST         => 0x0C,
24   EAST_SINGLE  => 0x04,
25   EAST_DOUBLE  => 0x08,
26   EAST_THICK   => 0x0C,
27   EAST_SHIFT   => 2,
28
29   # Connections to the next cell downwards
30   SOUTH        => 0x30,
31   SOUTH_SINGLE => 0x10,
32   SOUTH_DOUBLE => 0x20,
33   SOUTH_THICK  => 0x30,
34   SOUTH_SHIFT  => 4,
35
36   # Connections to the next cell to the left
37   WEST         => 0xC0,
38   WEST_SINGLE  => 0x40,
39   WEST_DOUBLE  => 0x80,
40   WEST_THICK   => 0xC0,
41   WEST_SHIFT   => 6,
42};
43my @linechars;
44
45while( <DATA> ) {
46   chomp;
47   my ( $char, $spec ) = split( m/\s+=>\s+/, $_, 2 );
48
49   my $mask = 0;
50   $mask |= __PACKAGE__->$_ for $spec =~ m/([A-Z_]+)/g;
51
52   $linechars[$mask] = ord $char;
53}
54
55close DATA;
56
57# Fill in the gaps
58foreach my $mask ( 1 .. 255 ) {
59   next if defined $linechars[$mask];
60
61   # Try with SINGLE instead of THICK, so mask away 0xAA
62   if( my $char = $linechars[$mask & 0xAA] ) {
63      $linechars[$mask] = $char;
64      next;
65   }
66
67   # The only ones left now are awkward mixes of single/double
68   # Turn DOUBLE into SINGLE
69   my $singlemask = $mask;
70   foreach my $dir (qw( NORTH EAST SOUTH WEST )) {
71      my $dirmask = __PACKAGE__->$dir;
72      my $dirshift = __PACKAGE__->${\"${dir}_SHIFT"};
73
74      my $dirsingle = LINE_SINGLE << $dirshift;
75      my $dirdouble = LINE_DOUBLE << $dirshift;
76
77      $singlemask = ( $singlemask & ~$dirmask ) | $dirsingle
78         if ( $singlemask & $dirmask ) == $dirdouble;
79   }
80
81   if( my $char = $linechars[$singlemask] ) {
82      $linechars[$mask] = $char;
83      next;
84   }
85
86   die sprintf "TODO: Couldn't find a linechar for %02x\n", $mask;
87}
88
89# Now output the mask
90
91open STDOUT, ">", ( $0 =~ m/^(.*)\.PL$/ )[0]
92   or die "Cannot write $1 - $!\n";
93
94print <<'EOF';
95static uint32_t linemask_to_char[] = {
96EOF
97
98foreach ( 0 .. $#linechars ) {
99   printf "  // 0x%02x\n  ", $_ if $_%16 == 0;
100   printf "0x%04x, ", $linechars[$_] // 0;
101   printf "\n" if $_%16 == 15;
102}
103
104print <<'EOF';
105};
106EOF
107
108use utf8;
109__DATA__
110─ => WEST_SINGLE | EAST_SINGLE
111━ => WEST_THICK | EAST_THICK
112│ => NORTH_SINGLE | SOUTH_SINGLE
113┃ => NORTH_THICK | SOUTH_THICK
114┌ => SOUTH_SINGLE | EAST_SINGLE
115┍ => SOUTH_SINGLE | EAST_THICK
116┎ => SOUTH_THICK | EAST_SINGLE
117┏ => SOUTH_THICK | EAST_THICK
118┐ => SOUTH_SINGLE | WEST_SINGLE
119┑ => SOUTH_SINGLE | WEST_THICK
120┒ => SOUTH_THICK | WEST_SINGLE
121┓ => SOUTH_THICK | WEST_THICK
122└ => NORTH_SINGLE | EAST_SINGLE
123┕ => NORTH_SINGLE | EAST_THICK
124┖ => NORTH_THICK | EAST_SINGLE
125┗ => NORTH_THICK | EAST_THICK
126┘ => NORTH_SINGLE | WEST_SINGLE
127┙ => NORTH_SINGLE | WEST_THICK
128┚ => NORTH_THICK | WEST_SINGLE
129┛ => NORTH_THICK | WEST_THICK
130├ => NORTH_SINGLE | EAST_SINGLE | SOUTH_SINGLE
131┝ => NORTH_SINGLE | SOUTH_SINGLE | EAST_THICK
132┞ => NORTH_THICK | EAST_SINGLE | SOUTH_SINGLE
133┟ => NORTH_SINGLE | EAST_SINGLE | SOUTH_THICK
134┠ => NORTH_THICK | EAST_SINGLE | SOUTH_THICK
135┡ => NORTH_THICK | EAST_THICK | SOUTH_SINGLE
136┢ => NORTH_SINGLE | EAST_THICK | SOUTH_THICK
137┣ => NORTH_THICK | EAST_THICK | SOUTH_THICK
138┤ => NORTH_SINGLE | WEST_SINGLE | SOUTH_SINGLE
139┥ => NORTH_SINGLE | SOUTH_SINGLE | WEST_THICK
140┦ => WEST_SINGLE | NORTH_THICK | SOUTH_SINGLE
141┧ => NORTH_SINGLE | WEST_SINGLE | SOUTH_THICK
142┨ => WEST_SINGLE | NORTH_THICK | SOUTH_THICK
143┩ => WEST_THICK | NORTH_THICK | SOUTH_SINGLE
144┪ => WEST_THICK | NORTH_SINGLE | SOUTH_THICK
145┫ => WEST_THICK | NORTH_THICK | SOUTH_THICK
146┬ => WEST_SINGLE | SOUTH_SINGLE | EAST_SINGLE
147┭ => WEST_THICK | SOUTH_SINGLE | EAST_SINGLE
148┮ => WEST_SINGLE | SOUTH_SINGLE | EAST_THICK
149┯ => WEST_THICK | SOUTH_SINGLE | EAST_THICK
150┰ => WEST_SINGLE | SOUTH_THICK | EAST_SINGLE
151┱ => WEST_THICK | SOUTH_THICK | EAST_SINGLE
152┲ => WEST_SINGLE | SOUTH_THICK | EAST_THICK
153┳ => WEST_THICK | SOUTH_THICK | EAST_THICK
154┴ => WEST_SINGLE | NORTH_SINGLE | EAST_SINGLE
155┵ => WEST_THICK | NORTH_SINGLE | EAST_SINGLE
156┶ => WEST_SINGLE | NORTH_SINGLE | EAST_THICK
157┷ => WEST_THICK | NORTH_SINGLE | EAST_THICK
158┸ => WEST_SINGLE | NORTH_THICK | EAST_SINGLE
159┹ => WEST_THICK | NORTH_THICK | EAST_SINGLE
160┺ => WEST_SINGLE | NORTH_THICK | EAST_THICK
161┻ => WEST_THICK | NORTH_THICK | EAST_THICK
162┼ => WEST_SINGLE | NORTH_SINGLE | EAST_SINGLE | SOUTH_SINGLE
163┽ => WEST_THICK | NORTH_SINGLE | EAST_SINGLE | SOUTH_SINGLE
164┾ => WEST_SINGLE | NORTH_SINGLE | EAST_THICK | SOUTH_SINGLE
165┿ => WEST_THICK | NORTH_SINGLE | EAST_THICK | SOUTH_SINGLE
166╀ => WEST_SINGLE | NORTH_THICK | EAST_SINGLE | SOUTH_SINGLE
167╁ => WEST_SINGLE | NORTH_SINGLE | EAST_SINGLE | SOUTH_THICK
168╂ => WEST_SINGLE | NORTH_THICK | EAST_SINGLE | SOUTH_THICK
169╃ => WEST_THICK | NORTH_THICK | EAST_SINGLE | SOUTH_SINGLE
170╄ => WEST_SINGLE | NORTH_THICK | EAST_THICK | SOUTH_SINGLE
171╅ => WEST_THICK | NORTH_SINGLE | EAST_SINGLE | SOUTH_THICK
172╆ => WEST_SINGLE | NORTH_SINGLE | EAST_THICK | SOUTH_THICK
173╇ => WEST_THICK | NORTH_THICK | EAST_THICK | SOUTH_SINGLE
174╈ => WEST_THICK | NORTH_SINGLE | EAST_THICK | SOUTH_THICK
175╉ => WEST_THICK | NORTH_THICK | EAST_SINGLE | SOUTH_THICK
176╊ => WEST_SINGLE | NORTH_THICK | EAST_THICK | SOUTH_THICK
177╋ => WEST_THICK | NORTH_THICK | EAST_THICK | SOUTH_THICK
178═ => WEST_DOUBLE | EAST_DOUBLE
179║ => NORTH_DOUBLE | SOUTH_DOUBLE
180╒ => EAST_DOUBLE | SOUTH_SINGLE
181╓ => EAST_SINGLE | SOUTH_DOUBLE
182╔ => SOUTH_DOUBLE | EAST_DOUBLE
183╕ => WEST_DOUBLE | SOUTH_SINGLE
184╖ => WEST_SINGLE | SOUTH_DOUBLE
185╗ => WEST_DOUBLE | SOUTH_DOUBLE
186╘ => NORTH_SINGLE | EAST_DOUBLE
187╙ => NORTH_DOUBLE | EAST_SINGLE
188╚ => NORTH_DOUBLE | EAST_DOUBLE
189╛ => WEST_DOUBLE | NORTH_SINGLE
190╜ => WEST_SINGLE | NORTH_DOUBLE
191╝ => WEST_DOUBLE | NORTH_DOUBLE
192╞ => NORTH_SINGLE | EAST_DOUBLE | SOUTH_SINGLE
193╟ => NORTH_DOUBLE | EAST_SINGLE | SOUTH_DOUBLE
194╠ => NORTH_DOUBLE | EAST_DOUBLE | SOUTH_DOUBLE
195╡ => WEST_DOUBLE | NORTH_SINGLE | SOUTH_SINGLE
196╢ => WEST_SINGLE | NORTH_DOUBLE | SOUTH_DOUBLE
197╣ => WEST_DOUBLE | NORTH_DOUBLE | SOUTH_DOUBLE
198╤ => WEST_DOUBLE | SOUTH_SINGLE | EAST_DOUBLE
199╥ => WEST_SINGLE | SOUTH_DOUBLE | EAST_SINGLE
200╦ => WEST_DOUBLE | SOUTH_DOUBLE | EAST_DOUBLE
201╧ => WEST_DOUBLE | NORTH_SINGLE | EAST_DOUBLE
202╨ => WEST_SINGLE | NORTH_DOUBLE | EAST_SINGLE
203╩ => WEST_DOUBLE | NORTH_DOUBLE | EAST_DOUBLE
204╪ => WEST_DOUBLE | NORTH_SINGLE | EAST_DOUBLE | SOUTH_SINGLE
205╫ => WEST_SINGLE | NORTH_DOUBLE | EAST_SINGLE | SOUTH_DOUBLE
206╬ => WEST_DOUBLE | NORTH_DOUBLE | EAST_DOUBLE | SOUTH_DOUBLE
207╴ => WEST_SINGLE
208╵ => NORTH_SINGLE
209╶ => EAST_SINGLE
210╷ => SOUTH_SINGLE
211╸ => WEST_THICK
212╹ => NORTH_THICK
213╺ => EAST_THICK
214╻ => SOUTH_THICK
215╼ => WEST_SINGLE | EAST_THICK
216╽ => NORTH_SINGLE | SOUTH_THICK
217╾ => WEST_THICK | EAST_SINGLE
218╿ => NORTH_THICK | SOUTH_SINGLE
219