File Coverage

blib/lib/Termbox/PP/WCWidth.pm
Criterion Covered Total %
statement 17 46 36.9
branch 0 26 0.0
condition 0 39 0.0
subroutine 6 9 66.6
pod 2 2 100.0
total 25 122 20.4


line stmt bran cond sub pod time code
1             # ------------------------------------------------------------------------
2             #
3             # WCWidth - determine columns needed for a wide character
4             #
5             # Code based on Terminal::WCWidth (a Raku port), 2026
6             #
7             # Copyright (c) 2007 Markus Kuhn (Unicode 5.0)
8             # 2014 Jeff Quast
9             # 2015 bluebear94
10             # 2026 Elizabeth Mattijsen
11             #
12             # ------------------------------------------------------------------------
13             # Author: 2024-2026 J. Schneider
14             # ------------------------------------------------------------------------
15            
16             package Termbox::PP::WCWidth;
17            
18             # ------------------------------------------------------------------------
19             # Boilerplate ------------------------------------------------------------
20             # ------------------------------------------------------------------------
21            
22 1     1   110852 use 5.010;
  1         3  
23 1     1   8 use strict;
  1         2  
  1         34  
24 1     1   4 use warnings;
  1         1  
  1         42  
25            
26             # version '...'
27 1     1   322 use version;
  1         2018  
  1         11  
28             our $version = version->declare('v0.1.5');
29             our $VERSION = version->declare('v0.4.0');
30            
31             # authority '...'
32             our $authority = 'github:raku-community-modules';
33             our $AUTHORITY = 'github:brickpool';
34            
35             # ------------------------------------------------------------------------
36             # Imports ----------------------------------------------------------------
37             # ------------------------------------------------------------------------
38            
39 1     1   954 use Termbox::PP::WCWidth::Tables;
  1         3  
  1         112  
40            
41             # ------------------------------------------------------------------------
42             # Exports ----------------------------------------------------------------
43             # ------------------------------------------------------------------------
44            
45             =head1 EXPORTS
46            
47             Nothing per default, but can export the following per request:
48            
49             :all
50             wcwidth
51             wcswidth
52            
53             =cut
54            
55 1     1   8 use Exporter qw( import );
  1         2  
  1         721  
56            
57             our @EXPORT_OK = qw(
58             wcwidth
59             wcswidth
60             );
61            
62             our %EXPORT_TAGS = (
63             all => \@EXPORT_OK,
64             );
65            
66             # ------------------------------------------------------------------------
67             # Functions --------------------------------------------------------------
68             # ------------------------------------------------------------------------
69            
70             # Auxiliary function for binary search in interval table
71             sub _bisearch { # $result ($ucs, \@table)
72 0     0     my ($ucs, $table) = @_;
73 0           my $lower = 0;
74 0           my $upper = scalar(@$table) - 1;
75 0 0 0       return 0 if $ucs < $table->[0][0] || $ucs > $table->[$upper][1];
76 0           while ($upper >= $lower) {
77 0           my $mid = ($lower + $upper) >> 1;
78 0 0         if ($ucs > $table->[$mid][1]) {
    0          
79 0           $lower = $mid + 1;
80             } elsif ($ucs < $table->[$mid][0]) {
81 0           $upper = $mid - 1;
82             } else {
83 0           return 1;
84             }
85             }
86 0           return 0;
87             }
88            
89             my %cache = ();
90            
91             sub wcwidth { # $result ($ucs)
92 0     0 1   my ($ucs) = @_;
93            
94 0 0 0       return -1 unless defined $ucs && !ref $ucs;
95 0 0         return -1 unless $ucs =~ /\A[0-9]+\z/;
96            
97 0 0 0       return -1 if $ucs < 0 || $ucs > 0x10ffff;
98 0 0 0       return -1 if $ucs >= 0xD800 && $ucs <= 0xDFFF;
99            
100 0 0         return $cache{$ucs} if exists $cache{$ucs};
101            
102 0 0 0       return ($cache{$ucs} = 0)
      0        
      0        
      0        
      0        
      0        
      0        
103             if $ucs == 0
104             || $ucs == 0x034f
105             || (0x200b <= $ucs && $ucs <= 0x200f)
106             || (0x202a <= $ucs && $ucs <= 0x202e)
107             || (0x2060 <= $ucs && $ucs <= 0x2063);
108            
109 0 0 0       return ($cache{$ucs} = -1)
      0        
110             if $ucs < 32 || (0x07f <= $ucs && $ucs < 0x0a0);
111            
112 0 0         return ($cache{$ucs} = 0) if _bisearch($ucs, ZERO_WIDTH);
113 0 0         return ($cache{$ucs} = 2) if _bisearch($ucs, WIDE_EASTASIAN);
114            
115 0           return ($cache{$ucs} = 1);
116             }
117            
118             sub wcswidth { # $result ($str)
119 0     0 1   my ($str) = @_;
120            
121 0           my $res = 0;
122 0           for (split //, $str) {
123 0           my $w = wcwidth(ord $_);
124 0 0         return -1 if $w < 0;
125 0           $res += $w;
126             }
127 0           return $res;
128             }
129            
130             1;
131            
132             __END__