| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package App::optex::pingu::Picture; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
10
|
use v5.24; |
|
|
1
|
|
|
|
|
3
|
|
|
4
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
57
|
|
|
5
|
1
|
|
|
1
|
|
3
|
use utf8; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
28
|
use Exporter 'import'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
53
|
|
|
8
|
|
|
|
|
|
|
our @EXPORT_OK = qw(&load); |
|
9
|
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
4
|
use Data::Dumper; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
78
|
|
|
11
|
1
|
|
|
1
|
|
12
|
use List::Util qw(pairs zip reduce all any); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
225
|
|
|
12
|
1
|
|
|
1
|
|
535
|
use Term::ANSIColor::Concise qw(ansi_color); |
|
|
1
|
|
|
|
|
56913
|
|
|
|
1
|
|
|
|
|
104
|
|
|
13
|
|
|
|
|
|
|
$Term::ANSIColor::Concise::NO_RESET_EL = 1; |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use constant { |
|
16
|
1
|
|
|
1
|
|
799
|
FB => "\N{FULL BLOCK}", |
|
|
1
|
|
|
|
|
7974
|
|
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
2089
|
|
|
17
|
|
|
|
|
|
|
THB => "\N{UPPER HALF BLOCK}", |
|
18
|
|
|
|
|
|
|
BHB => "\N{LOWER HALF BLOCK}", |
|
19
|
|
|
|
|
|
|
LHB => "\N{LEFT HALF BLOCK}", |
|
20
|
|
|
|
|
|
|
RHB => "\N{RIGHT HALF BLOCK}", |
|
21
|
|
|
|
|
|
|
QUL => "\N{QUADRANT UPPER LEFT}", |
|
22
|
|
|
|
|
|
|
QUR => "\N{QUADRANT UPPER RIGHT}", |
|
23
|
|
|
|
|
|
|
QLL => "\N{QUADRANT LOWER LEFT}", |
|
24
|
|
|
|
|
|
|
QLR => "\N{QUADRANT LOWER RIGHT}", |
|
25
|
|
|
|
|
|
|
QULLR => "\N{QUADRANT UPPER LEFT AND LOWER RIGHT}", |
|
26
|
|
|
|
|
|
|
QURLL => "\N{QUADRANT UPPER RIGHT AND LOWER LEFT}", |
|
27
|
|
|
|
|
|
|
Q____ => "\N{SPACE}", |
|
28
|
|
|
|
|
|
|
Qxx__ => "\N{UPPER HALF BLOCK}", |
|
29
|
|
|
|
|
|
|
Q__xx => "\N{LOWER HALF BLOCK}", |
|
30
|
|
|
|
|
|
|
Qx_x_ => "\N{LEFT HALF BLOCK}", |
|
31
|
|
|
|
|
|
|
Q_x_x => "\N{RIGHT HALF BLOCK}", |
|
32
|
|
|
|
|
|
|
Qx___ => "\N{QUADRANT UPPER LEFT}", |
|
33
|
|
|
|
|
|
|
Q_x__ => "\N{QUADRANT UPPER RIGHT}", |
|
34
|
|
|
|
|
|
|
Q__x_ => "\N{QUADRANT LOWER LEFT}", |
|
35
|
|
|
|
|
|
|
Q___x => "\N{QUADRANT LOWER RIGHT}", |
|
36
|
|
|
|
|
|
|
Qx__x => "\N{QUADRANT UPPER LEFT AND LOWER RIGHT}", |
|
37
|
|
|
|
|
|
|
Q_xx_ => "\N{QUADRANT UPPER RIGHT AND LOWER LEFT}", |
|
38
|
|
|
|
|
|
|
Q_xxx => "\N{QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT}", |
|
39
|
|
|
|
|
|
|
Qx_xx => "\N{QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT}", |
|
40
|
|
|
|
|
|
|
Qxx_x => "\N{QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT}", |
|
41
|
|
|
|
|
|
|
Qxxx_ => "\N{QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT}", |
|
42
|
|
|
|
|
|
|
Qxxxx => "\N{FULL BLOCK}", |
|
43
|
1
|
|
|
1
|
|
35764
|
}; |
|
|
1
|
|
|
|
|
2
|
|
|
44
|
|
|
|
|
|
|
my $color_re = qr/[RGBCMYKW]/i; |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
my %loader = ( |
|
47
|
|
|
|
|
|
|
asc => \&read_asc, |
|
48
|
|
|
|
|
|
|
asc2 => sub { read_asc({ y => 2}, @_) }, |
|
49
|
|
|
|
|
|
|
asc4 => sub { read_asc({ x => 2, y => 2}, @_) }, |
|
50
|
|
|
|
|
|
|
); |
|
51
|
|
|
|
|
|
|
$loader{default} //= $loader{asc}; |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub load { |
|
54
|
0
|
|
|
0
|
0
|
|
my $file = shift; |
|
55
|
0
|
|
|
|
|
|
my %opt = @_; |
|
56
|
0
|
0
|
|
|
|
|
open my $fh, '<', $file or die "$file: $!\n"; |
|
57
|
0
|
|
|
|
|
|
my $data = do { local $/; <$fh> }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
58
|
0
|
0
|
|
|
|
|
if ($file =~ /\.(\w+)$/) { |
|
59
|
0
|
|
0
|
|
|
|
$opt{format} ||= $1; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
0
|
|
|
|
|
|
load_data($data, %opt); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub load_data { |
|
65
|
0
|
|
|
0
|
0
|
|
my $data = shift; |
|
66
|
0
|
|
|
|
|
|
my %opt = @_; |
|
67
|
0
|
|
|
|
|
|
for ($data) { |
|
68
|
0
|
|
|
|
|
|
s/.*^__DATA__\n//ms; |
|
69
|
0
|
|
|
|
|
|
s/^#.*\n//mg; |
|
70
|
|
|
|
|
|
|
} |
|
71
|
0
|
|
0
|
|
|
|
$opt{format} ||= 'default'; |
|
72
|
0
|
|
0
|
|
|
|
my $loader = $loader{$opt{format}} // die "$opt{format}: unknown format.\n"; |
|
73
|
0
|
|
|
|
|
|
$loader->($data); |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub squash { |
|
77
|
|
|
|
|
|
|
map @$_, reduce { |
|
78
|
0
|
|
|
0
|
|
|
my $x = $a->[-1]; |
|
79
|
0
|
0
|
0
|
|
|
|
if ($x && all { $x->[$_] eq $b->[$_] } keys @$b) { |
|
|
0
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
|
$x->[-1]++; |
|
81
|
|
|
|
|
|
|
} else { |
|
82
|
0
|
|
|
|
|
|
push @$a, [ @$b, 1 ]; |
|
83
|
|
|
|
|
|
|
} |
|
84
|
0
|
|
|
|
|
|
$a; |
|
85
|
0
|
|
|
0
|
0
|
|
} [], @_; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
my %element = ( |
|
89
|
|
|
|
|
|
|
"0" => Q____ , # |
|
90
|
|
|
|
|
|
|
"1" => Qxxxx , # █ |
|
91
|
|
|
|
|
|
|
"00" => Q____ , # |
|
92
|
|
|
|
|
|
|
"10" => Qxx__ , # ▀ |
|
93
|
|
|
|
|
|
|
"01" => Q__xx , # ▄ |
|
94
|
|
|
|
|
|
|
"11" => Qxxxx , # █ |
|
95
|
|
|
|
|
|
|
"0000" => Q____ , # |
|
96
|
|
|
|
|
|
|
"0001" => Q___x , # ▗ |
|
97
|
|
|
|
|
|
|
"0010" => Q__x_ , # ▖ |
|
98
|
|
|
|
|
|
|
"0011" => Q__xx , # ▄ |
|
99
|
|
|
|
|
|
|
"0100" => Q_x__ , # ▝ |
|
100
|
|
|
|
|
|
|
"0101" => Q_x_x , # ▐ |
|
101
|
|
|
|
|
|
|
"0110" => Q_xx_ , # ▞ |
|
102
|
|
|
|
|
|
|
"0111" => Q_xxx , # ▟ |
|
103
|
|
|
|
|
|
|
"1000" => Qx___ , # ▘ |
|
104
|
|
|
|
|
|
|
"1001" => Qx__x , # ▚ |
|
105
|
|
|
|
|
|
|
"1010" => Qx_x_ , # ▄ |
|
106
|
|
|
|
|
|
|
"1011" => Qx_xx , # ▙ |
|
107
|
|
|
|
|
|
|
"1100" => Qxx__ , # ▀ |
|
108
|
|
|
|
|
|
|
"1101" => Qxx_x , # ▜ |
|
109
|
|
|
|
|
|
|
"1110" => Qxxx_ , # ▛ |
|
110
|
|
|
|
|
|
|
"1111" => Qxxxx , # █ |
|
111
|
|
|
|
|
|
|
); |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub stringify { |
|
114
|
0
|
|
|
0
|
0
|
|
my $vec = shift; |
|
115
|
0
|
|
|
|
|
|
my $n = pop @$vec; |
|
116
|
0
|
|
|
|
|
|
my $spec = join '', @$vec; |
|
117
|
0
|
|
0
|
|
|
|
my $c1 = ($spec =~ /($color_re)/)[0] // ''; |
|
118
|
0
|
|
0
|
|
|
|
my $c2 = ($spec =~ /((?!$c1)$color_re)/)[0] // ''; |
|
119
|
0
|
|
0
|
|
|
|
my $ch = (state $cache = {})->{$spec} //= do { |
|
120
|
0
|
0
|
|
|
|
|
if ($c1) { |
|
121
|
0
|
|
|
|
|
|
my $bit = $spec =~ s/(.)/int($1 eq $c1)/ger; |
|
|
0
|
|
|
|
|
|
|
|
122
|
0
|
|
0
|
|
|
|
$element{$bit} // die "$spec -> $bit"; |
|
123
|
|
|
|
|
|
|
} else { |
|
124
|
0
|
|
|
|
|
|
substr $spec, 0, 1; |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
}; |
|
127
|
0
|
|
0
|
|
|
|
my $s = $ch x $n || 1; |
|
128
|
0
|
0
|
|
|
|
|
$c1 ? ansi_color("$c1/$c2", $s) : $s; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub read_asc { |
|
132
|
0
|
0
|
|
0
|
0
|
|
my $opt = ref $_[0] eq 'HASH' ? shift : {}; |
|
133
|
0
|
|
0
|
|
|
|
my $x = $opt->{x} // 1; |
|
134
|
0
|
|
0
|
|
|
|
my $y = $opt->{y} // 1; |
|
135
|
0
|
|
|
|
|
|
my $data = shift; |
|
136
|
0
|
|
|
|
|
|
my @data = $data =~ /.+/g; |
|
137
|
0
|
0
|
|
|
|
|
@data % $y and die "data format error."; |
|
138
|
0
|
0
|
|
0
|
|
|
any { (length) % $x } @data and die "data format error."; |
|
|
0
|
|
|
|
|
|
|
|
139
|
0
|
|
|
|
|
|
my @image; |
|
140
|
0
|
|
|
|
|
|
while (my @y = splice @data, 0, $y) { |
|
141
|
0
|
|
|
|
|
|
my @sequence = squash zip map [ /\X{$x}/g ], @y; |
|
142
|
0
|
|
|
|
|
|
my $line = join '', map stringify($_), @sequence; |
|
143
|
0
|
|
|
|
|
|
push @image, $line; |
|
144
|
|
|
|
|
|
|
} |
|
145
|
0
|
0
|
|
|
|
|
wantarray ? @image : join('', map "$_\n", @image); |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
###################################################################### |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub read_asc_1 { |
|
151
|
0
|
|
|
0
|
0
|
|
local $_ = shift; |
|
152
|
0
|
|
|
|
|
|
s/^#.*\n//mg; |
|
153
|
0
|
|
|
|
|
|
s{ (?(?$color_re)\g{col}*) }{ |
|
154
|
0
|
|
|
|
|
|
ansi_color($+{col}, FB x length($+{str})) |
|
155
|
|
|
|
|
|
|
}xge; |
|
156
|
0
|
|
|
|
|
|
my @image = /.+/g; |
|
157
|
0
|
0
|
|
|
|
|
wantarray ? @image : join('', map "$_\n", @image); |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
my $use_FB = 0; # use FULL BLOCK when upper/lower are same |
|
161
|
|
|
|
|
|
|
my $use_BHB = 0; # use LOWER HALF BLOCK to show lower part |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub stringify_2 { |
|
164
|
0
|
|
|
0
|
0
|
|
my($hi, $lo, $c) = @{+shift}; |
|
|
0
|
|
|
|
|
|
|
|
165
|
0
|
|
0
|
|
|
|
$c //= 1; |
|
166
|
0
|
0
|
|
|
|
|
if ($hi =~ $color_re) { |
|
|
|
0
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
|
my $color = $hi; |
|
168
|
0
|
0
|
0
|
|
|
|
if ($use_FB and $lo eq $hi) { |
|
169
|
0
|
|
|
|
|
|
ansi_color($color, FB x $c); |
|
170
|
|
|
|
|
|
|
} else { |
|
171
|
0
|
0
|
|
|
|
|
$color .= "/$lo" if $lo =~ $color_re; |
|
172
|
0
|
|
|
|
|
|
ansi_color($color, THB x $c); |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
elsif ($lo =~ $color_re) { |
|
176
|
0
|
0
|
|
|
|
|
if ($use_BHB) { |
|
177
|
0
|
|
|
|
|
|
ansi_color($lo, BHB x $c); |
|
178
|
|
|
|
|
|
|
} else { |
|
179
|
0
|
|
|
|
|
|
ansi_color("S$lo", THB x $c); |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
else { |
|
183
|
0
|
|
|
|
|
|
$hi x $c; |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub read_asc_2 { |
|
188
|
0
|
|
|
0
|
0
|
|
my $data = shift; |
|
189
|
0
|
|
|
|
|
|
my @data = grep !/^\s*#/, $data =~ /.+/g; |
|
190
|
0
|
0
|
|
|
|
|
@data % 2 and die "Data format error.\n"; |
|
191
|
0
|
|
|
|
|
|
my @image; |
|
192
|
0
|
|
|
|
|
|
for (pairs @data) { |
|
193
|
0
|
|
|
|
|
|
my($hi, $lo) = @$_; |
|
194
|
0
|
|
|
|
|
|
my @data = squash zip [ $hi =~ /\X/g ], [ $lo =~ /\X/g ]; |
|
195
|
0
|
|
|
|
|
|
my $line = join '', map stringify_2($_), @data; |
|
196
|
0
|
|
|
|
|
|
push @image, $line; |
|
197
|
|
|
|
|
|
|
} |
|
198
|
0
|
0
|
|
|
|
|
wantarray ? @image : join('', map "$_\n", @image); |
|
199
|
|
|
|
|
|
|
} |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
###################################################################### |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
if (__FILE__ eq $0) { |
|
204
|
1
|
|
|
1
|
|
8
|
use open IO => ':utf8', ':std'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
9
|
|
|
205
|
|
|
|
|
|
|
local $/; |
|
206
|
|
|
|
|
|
|
while (<>) { |
|
207
|
|
|
|
|
|
|
my $suffix = ($ARGV =~ /\.(\w+)$/)[0] // 'default'; |
|
208
|
|
|
|
|
|
|
print scalar load_data($_, format => $suffix); |
|
209
|
|
|
|
|
|
|
} |
|
210
|
|
|
|
|
|
|
} |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
1; |