This commit is contained in:
kraus 2021-08-20 00:10:41 +02:00
parent 60385b089f
commit e3068fe145
5 changed files with 148 additions and 33 deletions

View File

@ -257,6 +257,7 @@ https://github.com/olikraus/u8g2 ChangeLog
* Added support for ST7567_HEM6432 (issue 1159)
* U8g2 16 Bit Mode enabled by default for ARM and ESP Systems (issue 1222)
2021-xx-xx v2.29.xx olikraus@gmail.com
* Update for getStrWidth/getUTF8Width: The new value might be little bit larger (issue 1561)
* Added vertical mirror option for u8g2 (mattnutsch@gmail.com).
* Added support for UC1638 based 196x96 display (issue 371)
* Added support for HD44102 and T7932 displays (issue 1492)

View File

@ -150,6 +150,19 @@
#define U8G2_WITH_UNICODE
/*
See issue https://github.com/olikraus/u8g2/issues/1561
The old behaviour of the StrWidth and UTF8Width functions returned an unbalanced string width, where
a small space was added to the left but not to the right of the string in some cases.
The new "balanced" procedure will assume the same gap on the left and the right side of the string
Example: The string width of "C" with font u8g2_font_helvR08_tr was returned as 7.
A frame of width 9 would place the C a little bit more to the right (width of that "C" are 6 pixel).
If U8G2_BALANCED_STR_WIDTH_CALCULATION is defined, the width of "C" is returned as 8.
Not defining U8G2_BALANCED_STR_WIDTH_CALCULATION would fall back to the old bahavior.
*/
#define U8G2_BALANCED_STR_WIDTH_CALCULATION
/*==========================================*/
@ -1451,7 +1464,7 @@ uint8_t u8g2_IsAllValidUTF8(u8g2_t *u8g2, const char *str); // checks whether al
u8g2_uint_t u8g2_GetStrWidth(u8g2_t *u8g2, const char *s);
u8g2_uint_t u8g2_GetUTF8Width(u8g2_t *u8g2, const char *str);
u8g2_uint_t u8g2_GetExactStrWidth(u8g2_t *u8g2, const char *s);
/*u8g2_uint_t u8g2_GetExactStrWidth(u8g2_t *u8g2, const char *s);*/ /*obsolete, see also https://github.com/olikraus/u8g2/issues/1561 */
void u8g2_SetFontPosBaseline(u8g2_t *u8g2);

View File

@ -1118,6 +1118,9 @@ static u8g2_uint_t u8g2_string_width(u8g2_t *u8g2, const char *str)
{
uint16_t e;
u8g2_uint_t w, dx;
#ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
int8_t initial_x_offset = -64;
#endif
u8g2->font_decode.glyph_width = 0;
u8x8_utf8_init(u8g2_GetU8x8(u8g2));
@ -1137,10 +1140,15 @@ static u8g2_uint_t u8g2_string_width(u8g2_t *u8g2, const char *str)
if ( e != 0x0fffe )
{
dx = u8g2_GetGlyphWidth(u8g2, e); /* delta x value of the glyph */
//printf("'%c' x=%d dx=%d ", e, u8g2->glyph_x_offset, dx);
#ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
if ( initial_x_offset == -64 )
initial_x_offset = u8g2->glyph_x_offset;
#endif
//printf("'%c' x=%d dx=%d w=%d io=%d ", e, u8g2->glyph_x_offset, dx, u8g2->font_decode.glyph_width, initial_x_offset);
w += dx;
}
}
//printf("\n");
/* adjust the last glyph, check for issue #16: do not adjust if width is 0 */
if ( u8g2->font_decode.glyph_width != 0 )
@ -1150,6 +1158,11 @@ static u8g2_uint_t u8g2_string_width(u8g2_t *u8g2, const char *str)
w += u8g2->font_decode.glyph_width; /* the real pixel width of the glyph, sideeffect of GetGlyphWidth */
/* issue #46: we have to add the x offset also */
w += u8g2->glyph_x_offset; /* this value is set as a side effect of u8g2_GetGlyphWidth() */
#ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
/* https://github.com/olikraus/u8g2/issues/1561 */
if ( initial_x_offset > 0 )
w+=initial_x_offset;
#endif
}
// printf("w=%d \n", w);
@ -1186,12 +1199,17 @@ offset is removed
Idea: for the user interface it probably would be better to add the xoffset of the first char to the end, so that the overall word looks better.
Maybe then the procedure should be called differently, maybe balanced width instead of exact width
u8g2_calculate_exact_string_width is now OBSOLETE, instead the above str width calculation has been updated:
https://github.com/olikraus/u8g2/issues/1561
*/
#ifdef OBSOLETE
static u8g2_uint_t u8g2_calculate_exact_string_width(u8g2_t *u8g2, const char *str)
{
u8g2_uint_t w;
const char *s = str;
uint16_t enc;
u8g2_uint_t w;
uint8_t cnt;
uint8_t gw;
int8_t ox, dx;
@ -1200,22 +1218,32 @@ static u8g2_uint_t u8g2_calculate_exact_string_width(u8g2_t *u8g2, const char *s
/* check for empty string, width is already 0 */
do
cnt = 0;
for(;;)
{
enc = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
str++;
} while( enc == 0x0fffe );
enc = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*s);
if ( enc == 0x0ffff )
break;
s++;
if ( enc != 0x0fffe )
{
if ( cnt == 0 )
{
/* get glyph properties of the first char */
u8g2_GetGlyphHorizontalProperties(u8g2, enc, &gw, &ox, &dx);
}
cnt++;
if ( cnt > 2 )
break;
}
}
if ( enc== 0x0ffff )
return w;
/* 19 Aug 2021: WARNING: "str" needs to be reseted here, i think */
/* get the glyph information of the first char. This must be valid, because we already checked for the empty string */
/* if *s is not inside the font, then the cached parameters of the glyph are all zero */
/* 19 Aug 2021: WARNING: I think enc is the last char, not the first char as it should be */
u8g2_GetGlyphHorizontalProperties(u8g2, enc, &gw, &ox, &dx);
if ( cnt == 0 )
return 0;
if ( cnt == 1 )
return gw;
/* strlen(s) == 1: width = width(s[0]) */
/* strlen(s) == 2: width = - offx(s[0]) + deltax(s[0]) + offx(s[1]) + width(s[1]) */
@ -1226,39 +1254,37 @@ static u8g2_uint_t u8g2_calculate_exact_string_width(u8g2_t *u8g2, const char *s
w = -ox;
for(;;)
{
/* check and stop if the end of the string is reached */
do
{
enc = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
str++;
} while( enc == 0x0fffe );
enc = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
if ( enc== 0x0ffff )
break;
u8g2_GetGlyphHorizontalProperties(u8g2, enc, &gw, &ox, &dx);
/* if there are still more characters, add the delta to the next glyph */
w += dx;
str++;
if ( enc != 0x0fffe )
{
u8g2_GetGlyphHorizontalProperties(u8g2, enc, &gw, &ox, &dx);
/* if there are still more characters, add the delta to the next glyph */
w += dx;
}
}
/* finally calculate the width of the last char */
/* here is another exception, if the last char is a blank, use the dx value instead */
if ( enc != ' ' )
if ( gw != 0 )
{
w -= dx; /* remove the last dx */
/* if g was not updated in the for loop (strlen() == 1), then the initial offset x gets removed */
w += gw;
w += ox;
}
else
{
w += dx;
//w += dx;
}
return w;
}
#endif
@ -1270,11 +1296,13 @@ u8g2_uint_t u8g2_GetStrWidth(u8g2_t *u8g2, const char *s)
return u8g2_string_width(u8g2, s);
}
/* OBSOLETE
u8g2_uint_t u8g2_GetExactStrWidth(u8g2_t *u8g2, const char *s)
{
u8g2->u8x8.next_cb = u8x8_ascii_next;
return u8g2_calculate_exact_string_width(u8g2, s);
}
*/
/*
source: https://en.wikipedia.org/wiki/UTF-8

View File

@ -177,7 +177,7 @@ int main(void)
u8g2_SetFont(&u8g2, u8g2_font_inb16_mf );
u8g2_SetFont(&u8g2, u8g2_font_courB12_tr);
u8g2_SetFont(&u8g2, u8g2_font_timR08_tr);
u8g2_SetFont(&u8g2, u8g2_font_helvR08_tr);
u8g2_SetFont(&u8g2, u8g2_font_helvR08_tr);
u8g2_SetFontMode(&u8g2, 1);
//u8g2_SetFontPosTop(&u8g2);
//u8g2_SetFontPosBottom(&u8g2);
@ -199,6 +199,31 @@ int main(void)
nu8g2_DrawButtonUTF8(&u8g2, 64, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 126, /*ph*/ 0, /*pv*/0, "Center W128 Inv");
}
if ( ui.current_form_fds[1] == 13 )
{
u8g2_uint_t w = u8g2_GetStrWidth(&u8g2, "C");
u8g2_uint_t h = u8g2_GetAscent(&u8g2)-u8g2_GetDescent(&u8g2);
u8g2_uint_t x = 5;
u8g2_uint_t y = 9;
u8g2_DrawStr(&u8g2, x, y, "C");
u8g2_DrawFrame(&u8g2, x-1,y-u8g2_GetAscent(&u8g2)-1, w+2, h+2);
nu8g2_DrawButtonUTF8(&u8g2, 64, 9, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Center W0");
nu8g2_DrawButtonUTF8(&u8g2, 64, 22, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Center W0 Inv");
nu8g2_DrawButtonUTF8(&u8g2, 10, 35, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "v");
nu8g2_DrawButtonUTF8(&u8g2, 10, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "v");
nu8g2_DrawButtonUTF8(&u8g2, 24, 35, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "vd");
nu8g2_DrawButtonUTF8(&u8g2, 24, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "vd");
nu8g2_DrawButtonUTF8(&u8g2, 40, 35, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "B");
nu8g2_DrawButtonUTF8(&u8g2, 40, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "B");
nu8g2_DrawButtonUTF8(&u8g2, 60, 35, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "A");
nu8g2_DrawButtonUTF8(&u8g2, 60, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "A");
nu8g2_DrawButtonUTF8(&u8g2, 80, 35, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Ab");
nu8g2_DrawButtonUTF8(&u8g2, 80, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Ab");
nu8g2_DrawButtonUTF8(&u8g2, 100, 35, /*flags*/U8G2_BTN_HCENTER|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Abg");
nu8g2_DrawButtonUTF8(&u8g2, 100, 48, /*flags*/U8G2_BTN_HCENTER|U8G2_BTN_INV|1, /*w*/ 0, /*ph*/ 0, /*pv*/0, "Abg");
}
//u8g2_DrawBox(&u8g2, 10, 10+y, 20, x);
//u8g2_DrawFrame(&u8g2, 34, 10+y, 20, x);

View File

@ -473,6 +473,54 @@ int main(void)
tga_save_png("u8g2_frame.png");
/*=========================================*/
/* u8g2_c_frame.png */
u8x8_ClearDisplay(u8g2_GetU8x8(&desc));
u8g2_SetFont(&u8g2, u8g2_font_helvR08_tr);
{
char *s = "Cage";
u8g2_uint_t w = u8g2_GetStrWidth(&u8g2, s);
u8g2_uint_t h = u8g2_GetAscent(&u8g2)-u8g2_GetDescent(&u8g2);
u8g2_uint_t x = 5;
u8g2_uint_t y = 11;
u8g2_SetFontPosBaseline(&u8g2);
u8g2_FirstPage(&u8g2);
do
{
u8g2_DrawStr(&u8g2, x, y, s);
u8g2_DrawFrame(&u8g2, x-1,y-u8g2_GetAscent(&u8g2)-1, w+2, h+2);
} while( u8g2_NextPage(&u8g2) );
tga_is_transparent = 1;
u8g2_FirstPage(&desc);
do
{
u8g2_SetFont(&desc, u8g2_font_helvB18_tf);
ra(x,y, "x=5, y=11");
u8g2_SetFont(&u8g2, u8g2_font_ncenB18_tf);
/* descent usually is negative */
vm(x-1+w+2+2,y-9+h+2-1, h+2);
hm(x-1, y-8+h+2+1+10, w+2);
hm(x, y-8+h+2+1, w);
//ra(60,40, "x=60, y=40");
//vm(60+16+2,40+9-1, 9);
//hm(60, 40+9+1, 16);
//vm(62,19-u8g2_GetDescent(&u8g2), -u8g2_GetDescent(&u8g2));
} while( u8g2_NextPage(&desc) );
}
tga_is_transparent = 0;
u8g2_SetFontPosBaseline(&u8g2);
tga_save_png("u8g2_c_frame.png");
/*=========================================*/
/* u8g2_ellipse.png */