5 #define R(a,b,w) { (b), (w)/2, (b)-(a) }
7 static const struct range {
100 R(0x1100, 0x115F, 2),
101 R(0x1160, 0x11FF, 0),
102 R(0x135F, 0x135F, 0),
103 R(0x1712, 0x1714, 0),
104 R(0x1732, 0x1734, 0),
105 R(0x1752, 0x1753, 0),
106 R(0x1772, 0x1773, 0),
107 R(0x17B4, 0x17B5, 0),
108 R(0x17B7, 0x17BD, 0),
109 R(0x17C6, 0x17C6, 0),
110 R(0x17C9, 0x17D3, 0),
111 R(0x17DD, 0x17DD, 0),
112 R(0x180B, 0x180D, 0),
113 R(0x18A9, 0x18A9, 0),
114 R(0x1920, 0x1922, 0),
115 R(0x1927, 0x1928, 0),
116 R(0x1932, 0x1932, 0),
117 R(0x1939, 0x193B, 0),
118 R(0x1A17, 0x1A18, 0),
119 R(0x1B00, 0x1B03, 0),
120 R(0x1B34, 0x1B34, 0),
121 R(0x1B36, 0x1B3A, 0),
122 R(0x1B3C, 0x1B3C, 0),
123 R(0x1B42, 0x1B42, 0),
124 R(0x1B6B, 0x1B73, 0),
125 R(0x1DC0, 0x1DCA, 0),
126 R(0x1DFE, 0x1DFF, 0),
127 R(0x200B, 0x200F, 0),
128 R(0x202A, 0x202E, 0),
129 R(0x2060, 0x2063, 0),
130 R(0x206A, 0x206F, 0),
131 R(0x20D0, 0x20EF, 0),
132 R(0x2329, 0x232A, 2),
133 R(0x2E80, 0x3029, 2),
134 R(0x302A, 0x302F, 0),
135 R(0x3030, 0x303E, 2),
136 R(0x3099, 0x309A, 0),
137 R(0xA806, 0xA806, 0),
138 R(0xA80B, 0xA80B, 0),
139 R(0xA825, 0xA826, 0),
140 R(0xF900, 0xFAFF, 2),
141 R(0xFB1E, 0xFB1E, 0),
142 R(0xFE00, 0xFE0F, 0),
143 R(0xFE20, 0xFE23, 0),
144 R(0xFE30, 0xFE6F, 2),
145 R(0xFEFF, 0xFEFF, 0),
146 R(0xFF00, 0xFF60, 2),
147 R(0xFFE0, 0xFFE6, 2),
148 R(0x10A01, 0x10A03, 0),
149 R(0x10A05, 0x10A06, 0),
150 R(0x10A0C, 0x10A0F, 0),
151 R(0x10A38, 0x10A3A, 0),
152 R(0x10A3F, 0x10A3F, 0),
153 R(0x1D167, 0x1D169, 0),
154 R(0x1D173, 0x1D182, 0),
155 R(0x1D185, 0x1D18B, 0),
156 R(0x1D1AA, 0x1D1AD, 0),
157 R(0x1D242, 0x1D244, 0),
158 R(0xE0001, 0xE0001, 0),
159 R(0xE0020, 0xE007F, 0),
160 R(0xE0100, 0xE01EF, 0),
163 /* Note: because the len field is only 10 bits, we must special-case
164 * the two huge ranges of full width characters and exclude them
165 * from the binary search table. */
167 int wcwidth(wchar_t wc)
172 if (c-0x20 < 0x5f) return 1;
173 if (!iswprint(c)) return wc ? -1 : 0;
174 if (c-0x20000 < 0x20000) return 2;
176 /* The following code is a branchless binary search. */
178 n = sizeof ranges / sizeof ranges[0];
181 a += n+1 & (signed)(ranges[a+n].base-c)>>31;
183 if (ranges[a].base-c <= ranges[a].len)
184 return 2*ranges[a].width;
185 return 1 + (c-0x3040 < 0xd800-0x3040);