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.
* \param iso The ISO string to convert.
* \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 *
draw_iso2utf8(const char *iso, size_t len)
bool
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 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");
if(!len || dont_need_convert)
return NULL;
return false;
if(iso2utf8 == (iconv_t) -1)
{
@ -66,20 +67,26 @@ draw_iso2utf8(const char *iso, size_t len)
else
warn("unable to convert text: %s", strerror(errno));
return NULL;
return false;
}
}
utf8len = 2 * len + 1;
utf8 = utf8p = p_new(char, utf8len);
size_t orig_utf8len, 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)
{
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 *

22
draw.h
View File

@ -141,18 +141,26 @@ draw_context_wipe(draw_context_t *ctx)
font_t *draw_font_new(const char *);
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
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((utf8 = draw_iso2utf8(str, len)))
{
*dest = utf8;
if(draw_iso2utf8(str, len, dest, dlen))
return true;
}
*dest = a_strdup(str);
if(dlen)
*dlen = len;
return false;
}

View File

@ -273,8 +273,9 @@ property_update_wm_name(client_t *c)
p_delete(&c->name);
if((utf8 = draw_iso2utf8(name, len)))
c->name = utf8;
/* if no conversion needed, just point to name */
if(draw_iso2utf8(name, len, &utf8, NULL))
p_delete(&name);
else
c->name = name;
@ -298,8 +299,8 @@ property_update_wm_icon_name(client_t *c)
p_delete(&c->icon_name);
if((utf8 = draw_iso2utf8(name, len)))
c->icon_name = utf8;
if(draw_iso2utf8(name, len, &utf8, NULL))
p_delete(&name);
else
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 = p_new(tag_t, 1);
a_iso2utf8(&tag->name, name, len);
a_iso2utf8(name, len, &tag->name, NULL);
/* to avoid error */
tag->screen = SCREEN_UNDEF;
@ -357,7 +357,7 @@ luaA_tag_newindex(lua_State *L)
{
const char *buf = luaL_checklstring(L, 3, &len);
p_delete(&(*tag)->name);
a_iso2utf8(&(*tag)->name, buf, len);
a_iso2utf8(buf, len, &(*tag)->name, NULL);
}
break;
case A_TK_SCREEN:

View File

@ -30,7 +30,7 @@ typedef struct
/** Textbox text */
char *text;
/** Textbox text length */
size_t len;
ssize_t len;
/** Textbox width */
int width;
/** Extents */
@ -244,15 +244,16 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
draw_parser_data_init(&d->pdata);
p_delete(&d->text);
/* re-init */
d->len = len;
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);
}
else
{
d->len = 0;
p_clear(&d->extents, 1);
}
}
break;
case A_TK_WIDTH: