draw: fix UTF-8 string len computation upon conversion

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-12-03 14:37:35 +01:00
parent 9adf3fd869
commit a4d914f0e4
5 changed files with 45 additions and 28 deletions

29
draw.c
View File

@ -39,13 +39,14 @@ extern awesome_t globalconf;
/** Convert text from any charset to UTF-8 using iconv. /** Convert text from any charset to UTF-8 using iconv.
* \param iso The ISO string to convert. * \param iso The ISO string to convert.
* \param len The string size. * \param len The string size.
* \return NULL if error, otherwise pointer to the new converted string. * \param dest The destination pointer. Memory will be allocated, up to you to
* free, like any char *.
* \param dlen The destination length, can be NULL.
* \return True if conversion was done.
*/ */
char * bool
draw_iso2utf8(const char *iso, size_t len) draw_iso2utf8(const char *iso, size_t len, char **dest, ssize_t *dlen)
{ {
size_t utf8len;
char *utf8, *utf8p;
static iconv_t iso2utf8 = (iconv_t) -1; static iconv_t iso2utf8 = (iconv_t) -1;
static int8_t dont_need_convert = -1; static int8_t dont_need_convert = -1;
@ -53,7 +54,7 @@ draw_iso2utf8(const char *iso, size_t len)
dont_need_convert = !a_strcmp(nl_langinfo(CODESET), "UTF-8"); dont_need_convert = !a_strcmp(nl_langinfo(CODESET), "UTF-8");
if(!len || dont_need_convert) if(!len || dont_need_convert)
return NULL; return false;
if(iso2utf8 == (iconv_t) -1) if(iso2utf8 == (iconv_t) -1)
{ {
@ -66,20 +67,26 @@ draw_iso2utf8(const char *iso, size_t len)
else else
warn("unable to convert text: %s", strerror(errno)); warn("unable to convert text: %s", strerror(errno));
return NULL; return false;
} }
} }
utf8len = 2 * len + 1; size_t orig_utf8len, utf8len;
utf8 = utf8p = p_new(char, utf8len); char *utf8;
orig_utf8len = utf8len = 2 * len + 1;
utf8 = *dest = p_new(char, utf8len);
if(iconv(iso2utf8, (char **) &iso, &len, &utf8, &utf8len) == (size_t) -1) if(iconv(iso2utf8, (char **) &iso, &len, &utf8, &utf8len) == (size_t) -1)
{ {
warn("text conversion failed: %s", strerror(errno)); warn("text conversion failed: %s", strerror(errno));
p_delete(&utf8p); p_delete(dest);
} }
return utf8p; if(dlen)
*dlen = orig_utf8len - utf8len;
return true;
} }
static xcb_visualtype_t * static xcb_visualtype_t *

22
draw.h
View File

@ -141,18 +141,26 @@ draw_context_wipe(draw_context_t *ctx)
font_t *draw_font_new(const char *); font_t *draw_font_new(const char *);
void draw_font_delete(font_t **); void draw_font_delete(font_t **);
char * draw_iso2utf8(const char *, size_t); bool draw_iso2utf8(const char *, size_t, char **, ssize_t *);
/** Convert a string to UTF-8.
* \param str The string to convert.
* \param len The string length.
* \param dest The destination string that will be allocated.
* \param dlen The destination string length allocated, can be NULL.
* \return True if the conversion happened, false otherwise. In both case, dest
* and dlen will have value and dest have to be free().
*/
static inline bool static inline bool
a_iso2utf8(char **dest, const char *str, ssize_t len) a_iso2utf8(const char *str, ssize_t len, char **dest, ssize_t *dlen)
{ {
char *utf8; if(draw_iso2utf8(str, len, dest, dlen))
if((utf8 = draw_iso2utf8(str, len)))
{
*dest = utf8;
return true; return true;
}
*dest = a_strdup(str); *dest = a_strdup(str);
if(dlen)
*dlen = len;
return false; return false;
} }

View File

@ -273,8 +273,9 @@ property_update_wm_name(client_t *c)
p_delete(&c->name); p_delete(&c->name);
if((utf8 = draw_iso2utf8(name, len))) /* if no conversion needed, just point to name */
c->name = utf8; if(draw_iso2utf8(name, len, &utf8, NULL))
p_delete(&name);
else else
c->name = name; c->name = name;
@ -298,8 +299,8 @@ property_update_wm_icon_name(client_t *c)
p_delete(&c->icon_name); p_delete(&c->icon_name);
if((utf8 = draw_iso2utf8(name, len))) if(draw_iso2utf8(name, len, &utf8, NULL))
c->icon_name = utf8; p_delete(&name);
else else
c->icon_name = name; c->icon_name = name;

4
tag.c
View File

@ -54,7 +54,7 @@ tag_new(const char *name, ssize_t len)
tag_t *tag; tag_t *tag;
tag = p_new(tag_t, 1); tag = p_new(tag_t, 1);
a_iso2utf8(&tag->name, name, len); a_iso2utf8(name, len, &tag->name, NULL);
/* to avoid error */ /* to avoid error */
tag->screen = SCREEN_UNDEF; tag->screen = SCREEN_UNDEF;
@ -357,7 +357,7 @@ luaA_tag_newindex(lua_State *L)
{ {
const char *buf = luaL_checklstring(L, 3, &len); const char *buf = luaL_checklstring(L, 3, &len);
p_delete(&(*tag)->name); p_delete(&(*tag)->name);
a_iso2utf8(&(*tag)->name, buf, len); a_iso2utf8(buf, len, &(*tag)->name, NULL);
} }
break; break;
case A_TK_SCREEN: case A_TK_SCREEN:

View File

@ -30,7 +30,7 @@ typedef struct
/** Textbox text */ /** Textbox text */
char *text; char *text;
/** Textbox text length */ /** Textbox text length */
size_t len; ssize_t len;
/** Textbox width */ /** Textbox width */
int width; int width;
/** Extents */ /** Extents */
@ -244,16 +244,17 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
draw_parser_data_init(&d->pdata); draw_parser_data_init(&d->pdata);
p_delete(&d->text); p_delete(&d->text);
/* re-init */
d->len = len;
if(buf) if(buf)
{ {
a_iso2utf8(&d->text, buf, len); a_iso2utf8(buf, len, &d->text, &d->len);
d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata); d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata);
} }
else else
{
d->len = 0;
p_clear(&d->extents, 1); p_clear(&d->extents, 1);
} }
}
break; break;
case A_TK_WIDTH: case A_TK_WIDTH:
d->width = luaL_checknumber(L, 3); d->width = luaL_checknumber(L, 3);