Author: cazfi Date: Sat Jan 10 22:06:25 2015 New Revision: 27608 URL: http://svn.gna.org/viewcvs/freeciv?rev=27608&view=rev Log: Made sdl2-client edit widgets to handle UTF-8 correctly internally. They still are not handled outside the edit widget code.
See patch #5677 Modified: trunk/client/gui-sdl2/widget_edit.c Modified: trunk/client/gui-sdl2/widget_edit.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-sdl2/widget_edit.c?rev=27608&r1=27607&r2=27608&view=diff ============================================================================== --- trunk/client/gui-sdl2/widget_edit.c (original) +++ trunk/client/gui-sdl2/widget_edit.c Sat Jan 10 22:06:25 2015 @@ -31,17 +31,18 @@ #include "widget.h" #include "widget_p.h" -struct UniChar { - struct UniChar *next; - struct UniChar *prev; - Uint16 chr[2]; +struct Utf8Char { + struct Utf8Char *next; + struct Utf8Char *prev; + int bytes; + char chr[7]; SDL_Surface *pTsurf; }; struct EDIT { - struct UniChar *pBeginTextChain; - struct UniChar *pEndTextChain; - struct UniChar *pInputChain; + struct Utf8Char *pBeginTextChain; + struct Utf8Char *pEndTextChain; + struct Utf8Char *pInputChain; SDL_Surface *pBg; struct widget *pWidget; int ChainLen; @@ -50,10 +51,10 @@ int InputChain_X; }; -static size_t chainlen(const struct UniChar *pChain); -static void del_chain(struct UniChar *pChain); -static struct UniChar * text2chain(const Uint16 *pInText); -static Uint16 * chain2text(const struct UniChar *pInChain, size_t len); +static size_t chainlen(const struct Utf8Char *pChain); +static void del_chain(struct Utf8Char *pChain); +static struct Utf8Char *text2chain(const Uint16 *pInText); +static Uint16 *chain2text(const struct Utf8Char *pInChain, size_t len); static int (*baseclass_redraw)(struct widget *pwidget); @@ -62,7 +63,7 @@ **************************************************************************/ static int redraw_edit_chain(struct EDIT *pEdt) { - struct UniChar *pInputChain_TMP; + struct Utf8Char *pInputChain_TMP; SDL_Rect Dest, Dest_Copy = {0, 0, 0, 0}; int iStart_Mod_X; int ret; @@ -212,11 +213,11 @@ } /************************************************************************** - Return length of UniChar chain. - WARRNING: if struct UniChar has 1 member and UniChar->chr == 0 then + Return length of Utf8Char chain. + WARRNING: if struct Utf8Char has 1 member and Utf8Char->chr == 0 then this function return 1 ( not 0 like in strlen ) **************************************************************************/ -static size_t chainlen(const struct UniChar *pChain) +static size_t chainlen(const struct Utf8Char *pChain) { size_t length = 0; @@ -234,9 +235,9 @@ } /************************************************************************** - Delete UniChar structure. -**************************************************************************/ -static void del_chain(struct UniChar *pChain) + Delete Utf8Char structure. +**************************************************************************/ +static void del_chain(struct Utf8Char *pChain) { int i, len = 0; @@ -259,14 +260,14 @@ } /************************************************************************** - Convert Unistring ( Uint16[] ) to UniChar structure. + Convert Unistring ( Uint16[] ) to Utf8Char structure. Memmory alocation -> after all use need call del_chain(...) ! **************************************************************************/ -static struct UniChar *text2chain(const Uint16 *pInText) +static struct Utf8Char *text2chain(const Uint16 *pInText) { int i, len; - struct UniChar *pOutChain = NULL; - struct UniChar *chr_tmp = NULL; + struct Utf8Char *pOutChain = NULL; + struct Utf8Char *chr_tmp = NULL; len = unistrlen(pInText); @@ -274,15 +275,17 @@ return pOutChain; } - pOutChain = fc_calloc(1, sizeof(struct UniChar)); + pOutChain = fc_calloc(1, sizeof(struct Utf8Char)); pOutChain->chr[0] = pInText[0]; pOutChain->chr[1] = 0; + pOutChain->bytes = 1; chr_tmp = pOutChain; for (i = 1; i < len; i++) { - chr_tmp->next = fc_calloc(1, sizeof(struct UniChar)); + chr_tmp->next = fc_calloc(1, sizeof(struct Utf8Char)); chr_tmp->next->chr[0] = pInText[i]; chr_tmp->next->chr[1] = 0; + chr_tmp->next->bytes = 1; chr_tmp->next->prev = chr_tmp; chr_tmp = chr_tmp->next; } @@ -291,10 +294,10 @@ } /************************************************************************** - Convert UniChar structure to Unistring ( Uint16[] ). - WARRING: Do not free UniChar structure but allocate new Unistring. -**************************************************************************/ -static Uint16 *chain2text(const struct UniChar *pInChain, size_t len) + Convert Utf8Char structure to Unistring ( Uint16[] ). + WARRING: Do not free Utf8Char structure but allocate new Unistring. +**************************************************************************/ +static Uint16 *chain2text(const struct Utf8Char *pInChain, size_t len) { int i; Uint16 *pOutText = NULL; @@ -304,8 +307,17 @@ } pOutText = fc_calloc(len + 1, sizeof(Uint16)); - for (i = 0; i < len; i++) { - pOutText[i] = pInChain->chr[0]; + for (i = 0; i < len;) { + pOutText[i++] = pInChain->chr[0]; + +#if 0 + int j; + + for (j = 0; j < pInChain->bytes && i < len; j++) { + pOutText[i++] = pInChain->chr[j]; + } +#endif + pInChain = pInChain->next; } @@ -403,7 +415,7 @@ static Uint16 edit_key_down(SDL_Keysym key, void *pData) { struct EDIT *pEdt = (struct EDIT *)pData; - struct UniChar *pInputChain_TMP; + struct Utf8Char *pInputChain_TMP; bool Redraw = FALSE; /* find which key is pressed */ @@ -569,25 +581,37 @@ static Uint16 edit_textinput(char *text, void *pData) { struct EDIT *pEdt = (struct EDIT *)pData; - struct UniChar *pInputChain_TMP; + struct Utf8Char *pInputChain_TMP; int i; - for (i = 0; text[i] != '\0'; i++) { + for (i = 0; text[i] != '\0';) { + int charlen = 1; + unsigned char leading = text[i++]; + int sum = 128 + 64; + int addition = 32; + /* add new element of chain (and move cursor right) */ if (pEdt->pInputChain != pEdt->pBeginTextChain) { pInputChain_TMP = pEdt->pInputChain->prev; - pEdt->pInputChain->prev = fc_calloc(1, sizeof(struct UniChar)); + pEdt->pInputChain->prev = fc_calloc(1, sizeof(struct Utf8Char)); pEdt->pInputChain->prev->next = pEdt->pInputChain; pEdt->pInputChain->prev->prev = pInputChain_TMP; pInputChain_TMP->next = pEdt->pInputChain->prev; } else { - pEdt->pInputChain->prev = fc_calloc(1, sizeof(struct UniChar)); + pEdt->pInputChain->prev = fc_calloc(1, sizeof(struct Utf8Char)); pEdt->pInputChain->prev->next = pEdt->pInputChain; pEdt->pBeginTextChain = pEdt->pInputChain->prev; } - pEdt->pInputChain->prev->chr[0] = text[i]; - pEdt->pInputChain->prev->chr[1] = '\0'; + pEdt->pInputChain->prev->chr[0] = leading; + /* UTF-8 multibyte handling */ + while (leading >= sum) { + pEdt->pInputChain->prev->chr[charlen++] = text[i++]; + sum += addition; + addition /= 2; + } + pEdt->pInputChain->prev->chr[charlen] = '\0'; + pEdt->pInputChain->prev->bytes = charlen; if (pEdt->pInputChain->prev->chr) { if (get_wflags(pEdt->pWidget) & WF_PASSWD_EDIT) { @@ -599,9 +623,9 @@ pEdt->pWidget->string16->fgcol); } else { pEdt->pInputChain->prev->pTsurf = - TTF_RenderUNICODE_Blended(pEdt->pWidget->string16->font, - pEdt->pInputChain->prev->chr, - pEdt->pWidget->string16->fgcol); + TTF_RenderUTF8_Blended(pEdt->pWidget->string16->font, + pEdt->pInputChain->prev->chr, + pEdt->pWidget->string16->fgcol); } pEdt->Truelength += pEdt->pInputChain->prev->pTsurf->w; } @@ -643,8 +667,8 @@ enum Edit_Return_Codes edit_field(struct widget *pEdit_Widget) { struct EDIT pEdt; - struct UniChar ___last; - struct UniChar *pInputChain_TMP = NULL; + struct Utf8Char ___last; + struct Utf8Char *pInputChain_TMP = NULL; enum Edit_Return_Codes ret; void *backup = pEdit_Widget->data.ptr; @@ -682,9 +706,9 @@ } pEdt.pEndTextChain->pTsurf = - TTF_RenderUNICODE_Blended(pEdit_Widget->string16->font, - pEdt.pEndTextChain->chr, - pEdit_Widget->string16->fgcol); + TTF_RenderUTF8_Blended(pEdit_Widget->string16->font, + pEdt.pEndTextChain->chr, + pEdit_Widget->string16->fgcol); /* create surface for each font in chain and find chain length */ if (pEdt.pBeginTextChain) { @@ -702,9 +726,9 @@ pEdit_Widget->string16->fgcol); } else { pInputChain_TMP->pTsurf = - TTF_RenderUNICODE_Blended(pEdit_Widget->string16->font, - pInputChain_TMP->chr, - pEdit_Widget->string16->fgcol); + TTF_RenderUTF8_Blended(pEdit_Widget->string16->font, + pInputChain_TMP->chr, + pEdit_Widget->string16->fgcol); } pEdt.Truelength += pInputChain_TMP->pTsurf->w; _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits