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