From 50186d826d63c0298353e8377b2f1a130b454958 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Mar 2010 19:55:09 +0100 Subject: [PATCH] Fix combining characters messing with width counter --- include/grub/unicode.h | 9 ++++----- kern/term.c | 3 ++- normal/charset.c | 10 ++++++++-- normal/menu_text.c | 3 ++- term/serial.c | 2 +- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/grub/unicode.h b/include/grub/unicode.h index e7f176d0f..2bc9753ed 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -84,6 +84,9 @@ struct grub_unicode_glyph grub_uint32_t code; enum grub_comb_type type; } *combining; + /* Hint by unicode subsystem how wide this character usually is. + Real width is determined by font. Set only in UTF-8 stream. */ + int estimated_width; }; #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 @@ -134,15 +137,11 @@ static inline struct grub_unicode_glyph * grub_unicode_glyph_from_code (grub_uint32_t code) { struct grub_unicode_glyph *ret; - ret = grub_malloc (sizeof (*ret)); + ret = grub_zalloc (sizeof (*ret)); if (!ret) return NULL; ret->base = code; - ret->variant = 0; - ret->attributes = 0; - ret->ncomb = 0; - ret->combining = 0; return ret; } diff --git a/kern/term.c b/kern/term.c index 8139e8118..a65d67196 100644 --- a/kern/term.c +++ b/kern/term.c @@ -41,7 +41,8 @@ grub_putcode_dumb (grub_uint32_t code, .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; if (code == '\t' && term->getxy) diff --git a/normal/charset.c b/normal/charset.c index 53b9578e5..af53b3134 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -538,6 +538,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, out->variant = 0; out->attributes = 0; out->ncomb = 0; + out->estimated_width = 1; out->combining = NULL; } return ptr - in; @@ -1075,7 +1076,8 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; if (c->base == '\t' && term->getxy) @@ -1096,6 +1098,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { int i; + c2.estimated_width = 1; for (i = -1; i < (int) c->ncomb; i++) { grub_uint8_t u8[20], *ptr; @@ -1112,8 +1115,10 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) { c2.base = *ptr; (term->putchar) (&c2); + c2.estimated_width = 0; } } + c2.estimated_width = 1; } else (term->putchar) (c); @@ -1133,7 +1138,8 @@ putcode_real (grub_uint32_t code, struct grub_term_output *term) .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; c.base = map_code (code, term); diff --git a/normal/menu_text.c b/normal/menu_text.c index 61ddd2490..2e2cf0e0c 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -273,7 +273,8 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, .variant = 0, .attributes = 0, .ncomb = 0, - .combining = 0 + .combining = 0, + .estimated_width = 1 }; x += grub_term_getcharwidth (term, &pseudo_glyph); } diff --git a/term/serial.c b/term/serial.c index 18978911f..666606fcc 100644 --- a/term/serial.c +++ b/term/serial.c @@ -356,7 +356,7 @@ grub_serial_putchar (const struct grub_unicode_glyph *c) serial_hw_put ('\r'); serial_hw_put ('\n'); } - xpos++; + xpos += c->estimated_width; break; } }