Coverage Report

Created: 2026-07-15 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gettext/gettext-tools/libgettextpo/uniwidth/width.c
Line
Count
Source
1
/* Determine display width of Unicode character.
2
   Copyright (C) 2001-2002, 2006-2026 Free Software Foundation, Inc.
3
   Written by Bruno Haible <bruno@clisp.org>, 2002.
4
5
   This file is free software: you can redistribute it and/or modify
6
   it under the terms of the GNU Lesser General Public License as
7
   published by the Free Software Foundation; either version 2.1 of the
8
   License, or (at your option) any later version.
9
10
   This file is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public License
16
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17
18
#include <config.h>
19
20
/* Specification.  */
21
#include "uniwidth.h"
22
23
#include <stdcountof.h>
24
25
#include "cjk.h"
26
27
/* The non-spacing attribute table consists of:
28
   * Non-spacing characters; generated from PropList.txt or
29
     "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt"
30
   * Format control characters; generated from
31
     "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt"
32
   * Zero width characters; generated from
33
     "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt"
34
   * Hangul Jamo characters that have conjoining behaviour:
35
       - jungseong = syllable-middle vowels
36
       - jongseong = syllable-final consonants
37
     Rationale:
38
     1) These characters act like combining characters. They have no
39
     equivalent in legacy character sets. Therefore the EastAsianWidth.txt
40
     file does not really matter for them; UAX #11 East Asian Width
41
     <https://www.unicode.org/reports/tr11/> makes it clear that it focus
42
     is on compatibility with traditional Japanese layout.
43
     By contrast, the same glyphs without conjoining behaviour are available
44
     in the U+3130..U+318F block, and these characters are mapped to legacy
45
     character sets, and traditional Japanese layout matters for them.
46
     2) glibc does the same thing, see
47
     <https://sourceware.org/PR21750>
48
     <https://sourceware.org/PR26120>
49
 */
50
#include "uniwidth/width0.h"
51
52
#include "uniwidth/width2.h"
53
#include "unictype/bitmap.h"
54
55
56
/* Determine number of column positions required for UC.  */
57
int
58
uc_width (ucs4_t uc, const char *encoding)
59
59.1M
{
60
  /* Test for non-spacing or control character.  */
61
59.1M
  if ((uc >> 9) < countof (nonspacing_table_ind))
62
59.1M
    {
63
59.1M
      int ind = nonspacing_table_ind[uc >> 9];
64
59.1M
      if (ind >= 0)
65
44.9M
        if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1)
66
22.5M
          {
67
22.5M
            if (uc > 0 && uc < 0xa0)
68
4.88M
              return -1;
69
17.6M
            else
70
17.6M
              return 0;
71
22.5M
          }
72
59.1M
    }
73
12.0k
  else if ((uc >> 9) == (0xe0000 >> 9))
74
581
    {
75
581
      if (uc >= 0xe0100)
76
76
        {
77
76
          if (uc <= 0xe01ef)
78
76
            return 0;
79
76
        }
80
505
      else
81
505
        {
82
505
          if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001)
83
49
            return 0;
84
505
        }
85
581
    }
86
  /* Test for double-width character.  */
87
36.6M
  if (bitmap_lookup (&u_width2, uc))
88
13.4M
    return 2;
89
  /* In ancient CJK encodings, Cyrillic and most other characters are
90
     double-width as well.  */
91
23.1M
  if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9
92
1.14M
      && is_cjk_encoding (encoding))
93
139k
    return 2;
94
23.0M
  return 1;
95
23.1M
}