Fix #30575: Text gets wrongly clipped when using accented letters

Clipping functions used for drawing weren't using stepping and always were assuming
letters are single byte encoded. Now they're using correct stepping.
This commit is contained in:
Sergey Sharybin 2012-03-22 09:20:22 +00:00
parent 9751653410
commit 762a8baf05

@ -41,6 +41,7 @@
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_rect.h" #include "BLI_rect.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
#include "BKE_context.h" #include "BKE_context.h"
@ -933,6 +934,22 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
static void ui_text_clip_give_prev_off(uiBut *but)
{
char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + but->ofs);
int bytes = but->drawstr + but->ofs - prev_utf8;
but->ofs -= bytes;
}
static void ui_text_clip_give_next_off(uiBut *but)
{
char *next_utf8 = BLI_str_find_next_char_utf8(but->drawstr + but->ofs, NULL);
int bytes = next_utf8 - (but->drawstr + but->ofs);
but->ofs += bytes;
}
/* sets but->ofs to make sure text is correctly visible */ /* sets but->ofs to make sure text is correctly visible */
static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect) static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
{ {
@ -967,23 +984,26 @@ static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
char buf[UI_MAX_DRAW_STR]; char buf[UI_MAX_DRAW_STR];
/* copy draw string */ /* copy draw string */
BLI_strncpy(buf, but->drawstr, sizeof(buf)); BLI_strncpy_utf8(buf, but->drawstr, sizeof(buf));
/* string position of cursor */ /* string position of cursor */
buf[but->pos]= 0; buf[but->pos]= 0;
width= BLF_width(fstyle->uifont_id, buf+but->ofs); width= BLF_width(fstyle->uifont_id, buf+but->ofs);
/* if cursor is at 20 pixels of right side button we clip left */ /* if cursor is at 20 pixels of right side button we clip left */
if(width > okwidth-20) if(width > okwidth-20)
but->ofs++; ui_text_clip_give_next_off(but);
else { else {
int len, bytes;
/* shift string to the left */ /* shift string to the left */
if(width < 20 && but->ofs > 0) if(width < 20 && but->ofs > 0)
but->ofs--; ui_text_clip_give_prev_off(but);
but->drawstr[ strlen(but->drawstr)-1 ]= 0; len= strlen(but->drawstr);
bytes= BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + len));
but->drawstr[ len-bytes ]= 0;
} }
} }
else else
but->ofs++; ui_text_clip_give_next_off(but);
but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs);
@ -1018,9 +1038,13 @@ static void ui_text_label_rightclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
/* chop off the leading text, starting from the right */ /* chop off the leading text, starting from the right */
while (but->strwidth > okwidth && cp2 > but->drawstr) { while (but->strwidth > okwidth && cp2 > but->drawstr) {
int bytes = BLI_str_utf8_size(cp2);
if (bytes < 0)
bytes = 1;
/* shift the text after and including cp2 back by 1 char, +1 to include null terminator */ /* shift the text after and including cp2 back by 1 char, +1 to include null terminator */
memmove(cp2-1, cp2, strlen(cp2)+1); memmove(cp2-bytes, cp2, strlen(cp2)+1);
cp2--; cp2-=bytes;
but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs);
if(but->strwidth < 10) break; if(but->strwidth < 10) break;
@ -1030,7 +1054,7 @@ static void ui_text_label_rightclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
/* after the leading text is gone, chop off the : and following space, with ofs */ /* after the leading text is gone, chop off the : and following space, with ofs */
while ((but->strwidth > okwidth) && (but->ofs < 2)) while ((but->strwidth > okwidth) && (but->ofs < 2))
{ {
but->ofs++; ui_text_clip_give_next_off(but);
but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs);
if(but->strwidth < 10) break; if(but->strwidth < 10) break;
} }
@ -1039,10 +1063,12 @@ static void ui_text_label_rightclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
/* once the label's gone, chop off the least significant digits */ /* once the label's gone, chop off the least significant digits */
while(but->strwidth > okwidth ) { while(but->strwidth > okwidth ) {
int pos= strlen(but->drawstr); int len= strlen(but->drawstr);
int bytes= BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + len));
if (bytes < 0)
bytes = 1;
but->drawstr[ pos-1 ] = 0; but->drawstr[ len-bytes ]= 0;
pos--;
but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs);
if(but->strwidth < 10) break; if(but->strwidth < 10) break;