diff --git a/FL/fl_utf8.h b/FL/fl_utf8.h index 27499de12a949d28a2738d57018624a79c2ba5be..bc35ab4b65aa263fdc5eb31bcb04eeb9be17f616 100644 --- a/FL/fl_utf8.h +++ b/FL/fl_utf8.h @@ -142,6 +142,15 @@ FL_EXPORT int fl_utf8locale(); * type of the src text. */ FL_EXPORT int fl_utf8test(const char *src, unsigned len); +/* XX: return width of "raw" ucs character in columns. + * for internal use only */ +FL_EXPORT int fl_wcwidth_(unsigned int ucs); + +/* XX: return width of utf-8 character string in columns. + * NOTE: this may also do C1 control character (0x80 to 0x9f) to CP1252 mapping, + * depending on original build options */ +FL_EXPORT int fl_wcwidth(const char *src); + /* OD: Return true if the character is non-spacing */ FL_EXPORT unsigned int fl_nonspacing(unsigned int ucs); diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx index 7ba7a76e611d41dc1308c2c1aa7b399ee7bd7875..5c87340b651011027161948d1c4a87821aef78f1 100644 --- a/src/Fl_Text_Buffer.cxx +++ b/src/Fl_Text_Buffer.cxx @@ -1025,8 +1025,8 @@ int Fl_Text_Buffer::character_width(const char *src, int indent, int tabDist) int len = fl_utf8len(c); int ret = 0; unsigned int ucs = fl_utf8decode(src, src+len, &ret); - int width = 1; // mk_wcwidth((wchar_t)ucs); // FIXME - // fprintf(stderr, "mk_wcwidth(%x) -> %d (%d, %d, %s)\n", ucs, width, len, ret, s); + int width = fl_wcwidth_(ucs); // FIXME + // fprintf(stderr, "mk_wcwidth(%x) -> %d (%d, %d, %s)\n", ucs, width, len, ret, src); return width; } if ((c & 0x80) && !(c & 0x40)) { // other byte of UTF-8 sequence diff --git a/src/fl_utf.c b/src/fl_utf.c index b5b2a53ac267430f60266a0516a9a5c731866850..3240c88ba7e70a473bd108daef191267fc14081d 100644 --- a/src/fl_utf.c +++ b/src/fl_utf.c @@ -856,6 +856,51 @@ int fl_utf8test(const char* src, unsigned srclen) { return ret; } +/* forward declare mk_wcwidth() as static so the name is not visible. + */ + static int mk_wcwidth(unsigned int ucs); + + /* include the c source directly so it's contents are only visible here + */ +#include "xutf8/mk_wcwidth.c" + +/** wrapper to adapt Markus Kuhn's implementation of wcwidth() for FLTK + \param [in] ucs Unicode character value + \returns width of character in columns + + This is an implementation of wcwidth() and wcswidth() + (defined in IEEE Std 1002.1-2001) for Unicode. + See http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + + WARNING: this function returns widths for "raw" Unicode characters. + It does not even try to map C1 control characters (0x80 to 0x9F) to + CP1252, and C0/C1 control characters and DEL will return -1. + */ +int fl_wcwidth_(unsigned int ucs) { + return mk_wcwidth(ucs); +} + +/** extended wrapper around fl_wcwidth_(unsigned int ucs) function. + \param[in] src pointer to start of UTF-8 byte sequence + \returns width of character in columns + + Depending on build options, this function may map C1 control + characters (0x80 to 0x9f) to CP1252, and return the width of + that character instead. This is not the same behaviour as + fl_wcwidth_(unsigned int ucs) . + + Note that other control characters and DEL will still return -1, + so if you want different behaviour, you need to test for those + characters before calling fl_wcwidth(), and handle them separately. + */ +int fl_wcwidth(const char* src) { + int len = fl_utf8len(*src); + int ret = 0; + unsigned int ucs = fl_utf8decode(src, src+len, &ret); + int width = fl_wcwidth_(ucs); + return width; +} + /** @} */ /*