00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "konsole_wcwidth.h"
00011
00012 struct interval {
00013 unsigned short first;
00014 unsigned short last;
00015 };
00016
00017
00018 static int bisearch(quint16 ucs, const struct interval *table, int max) {
00019 int min = 0;
00020 int mid;
00021
00022 if (ucs < table[0].first || ucs > table[max].last)
00023 return 0;
00024 while (max >= min) {
00025 mid = (min + max) / 2;
00026 if (ucs > table[mid].last)
00027 min = mid + 1;
00028 else if (ucs < table[mid].first)
00029 max = mid - 1;
00030 else
00031 return 1;
00032 }
00033
00034 return 0;
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 int konsole_wcwidth(quint16 ucs)
00069 {
00070
00071 static const struct interval combining[] = {
00072 { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 },
00073 { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
00074 { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
00075 { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
00076 { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
00077 { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
00078 { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C },
00079 { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 },
00080 { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
00081 { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
00082 { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
00083 { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 },
00084 { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 },
00085 { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 },
00086 { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 },
00087 { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 },
00088 { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 },
00089 { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 },
00090 { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
00091 { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA },
00092 { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 },
00093 { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 },
00094 { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD },
00095 { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 },
00096 { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 },
00097 { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC },
00098 { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 },
00099 { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 },
00100 { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 },
00101 { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 },
00102 { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F },
00103 { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A },
00104 { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF },
00105 { 0xFFF9, 0xFFFB }
00106 };
00107
00108
00109 if (ucs == 0)
00110 return 0;
00111 if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
00112 return -1;
00113
00114
00115 if (bisearch(ucs, combining,
00116 sizeof(combining) / sizeof(struct interval) - 1))
00117 return 0;
00118
00119
00120
00121 return 1 +
00122 (ucs >= 0x1100 &&
00123 (ucs <= 0x115f ||
00124 (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
00125 ucs != 0x303f) ||
00126 (ucs >= 0xac00 && ucs <= 0xd7a3) ||
00127 (ucs >= 0xf900 && ucs <= 0xfaff) ||
00128 (ucs >= 0xfe30 && ucs <= 0xfe6f) ||
00129 (ucs >= 0xff00 && ucs <= 0xff5f) ||
00130 (ucs >= 0xffe0 && ucs <= 0xffe6)
00131 ));
00132 }
00133
00134 #if 0
00135
00136
00137
00138
00139
00140
00141
00142
00143 int konsole_wcwidth_cjk(quint16 ucs)
00144 {
00145
00146
00147 static const struct interval ambiguous[] = {
00148 { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
00149 { 0x00AA, 0x00AA }, { 0x00AD, 0x00AD }, { 0x00B0, 0x00B4 },
00150 { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
00151 { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
00152 { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
00153 { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
00154 { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
00155 { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
00156 { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
00157 { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
00158 { 0x0148, 0x014A }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
00159 { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
00160 { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
00161 { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
00162 { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
00163 { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, { 0x02CD, 0x02CD },
00164 { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, { 0x02DD, 0x02DD },
00165 { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 },
00166 { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, { 0x0410, 0x044F },
00167 { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, { 0x2013, 0x2016 },
00168 { 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2021 },
00169 { 0x2025, 0x2027 }, { 0x2030, 0x2030 }, { 0x2032, 0x2033 },
00170 { 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x2074, 0x2074 },
00171 { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
00172 { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
00173 { 0x2113, 0x2113 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 },
00174 { 0x212B, 0x212B }, { 0x2154, 0x2155 }, { 0x215B, 0x215B },
00175 { 0x215E, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
00176 { 0x2190, 0x2199 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 },
00177 { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, { 0x2207, 0x2208 },
00178 { 0x220B, 0x220B }, { 0x220F, 0x220F }, { 0x2211, 0x2211 },
00179 { 0x2215, 0x2215 }, { 0x221A, 0x221A }, { 0x221D, 0x2220 },
00180 { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, { 0x2227, 0x222C },
00181 { 0x222E, 0x222E }, { 0x2234, 0x2237 }, { 0x223C, 0x223D },
00182 { 0x2248, 0x2248 }, { 0x224C, 0x224C }, { 0x2252, 0x2252 },
00183 { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, { 0x226A, 0x226B },
00184 { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 },
00185 { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 },
00186 { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF },
00187 { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 },
00188 { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 },
00189 { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 },
00190 { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 },
00191 { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 },
00192 { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, { 0x2609, 0x2609 },
00193 { 0x260E, 0x260F }, { 0x261C, 0x261C }, { 0x261E, 0x261E },
00194 { 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2661 },
00195 { 0x2663, 0x2665 }, { 0x2667, 0x266A }, { 0x266C, 0x266D },
00196 { 0x266F, 0x266F }, { 0x300A, 0x300B }, { 0x301A, 0x301B },
00197 { 0xE000, 0xF8FF }, { 0xFFFD, 0xFFFD }
00198 };
00199
00200
00201 if (bisearch(ucs, ambiguous,
00202 sizeof(ambiguous) / sizeof(struct interval) - 1))
00203 return 2;
00204
00205 return konsole_wcwidth(ucs);
00206 }
00207 #endif
00208
00209
00210 int string_width( const QString &txt )
00211 {
00212 int w = 0;
00213 for ( int i = 0; i < txt.length(); ++i )
00214 w += konsole_wcwidth( txt[ i ].unicode() );
00215 return w;
00216 }