From cd159b6775b16cc8c2449422a4ed0d0e9f66df57 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 18 Jun 2014 13:12:08 +0100 Subject: Don't display certain invisible characters. Fixes display of U+200E code points all over Google search results. --- framebuffer/font_internal.c | 29 ++++++++++++++++++++++++++--- framebuffer/font_internal.h | 5 +++++ framebuffer/framebuffer.c | 3 +++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/framebuffer/font_internal.c b/framebuffer/font_internal.c index 5aada8f11..e514b12d9 100644 --- a/framebuffer/font_internal.c +++ b/framebuffer/font_internal.c @@ -287,11 +287,24 @@ static nserror utf8_from_local(const char *string, return NSERROR_OK; } + static bool nsfont_width(const plot_font_style_t *fstyle, const char *string, size_t length, int *width) { - *width = FB_FONT_WIDTH * utf8_bounded_length(string, length); + size_t nxtchr = 0; + + *width = 0; + while (nxtchr < length) { + uint32_t ucs4; + ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); + if (codepoint_displayable(ucs4)) { + *width += FB_FONT_WIDTH; + } + + nxtchr = utf8_next(string, length, nxtchr); + } + return true; } @@ -315,10 +328,15 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle, int x_pos = 0; while (nxtchr < length) { + uint32_t ucs4; if (abs(x_pos - x) <= (FB_FONT_WIDTH / 2)) break; - x_pos += FB_FONT_WIDTH; + ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); + if (codepoint_displayable(ucs4)) { + x_pos += FB_FONT_WIDTH; + } + nxtchr = utf8_next(string, length, nxtchr); } @@ -363,13 +381,18 @@ static bool nsfont_split(const plot_font_style_t *fstyle, *actual_x = 0; while (nxtchr < length) { + uint32_t ucs4; if (string[nxtchr] == ' ') { last_space_x = *actual_x; last_space_idx = nxtchr; } - *actual_x += FB_FONT_WIDTH; + ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); + if (codepoint_displayable(ucs4)) { + *actual_x += FB_FONT_WIDTH; + } + if (*actual_x > x && last_space_idx != 0) { /* string has exceeded available width and we've * found a space; return previous space */ diff --git a/framebuffer/font_internal.h b/framebuffer/font_internal.h index 236183ace..ead179c99 100644 --- a/framebuffer/font_internal.h +++ b/framebuffer/font_internal.h @@ -19,6 +19,8 @@ #ifndef NETSURF_FB_FONT_INTERNAL_H #define NETSURF_FB_FONT_INTERNAL_H +#include + struct fb_font_desc { const char *name; int width, height, pitch; @@ -39,5 +41,8 @@ enum fb_font_style fb_get_font_style(const plot_font_style_t *fstyle); const uint8_t * fb_get_glyph(uint32_t ucs4, enum fb_font_style style); +#define codepoint_displayable(u) \ + (!(u >= 0x200b && u <= 0x200f)) + #endif /* NETSURF_FB_FONT_INTERNAL_H */ diff --git a/framebuffer/framebuffer.c b/framebuffer/framebuffer.c index 0115d838c..4cd064c34 100644 --- a/framebuffer/framebuffer.c +++ b/framebuffer/framebuffer.c @@ -140,6 +140,9 @@ static bool framebuffer_plot_text(int x, int y, const char *text, size_t length, ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); nxtchr = utf8_next(text, length, nxtchr); + if (!codepoint_displayable(ucs4)) + continue; + loc.x0 = x; loc.y0 = y; loc.x1 = loc.x0 + FB_FONT_WIDTH; -- cgit v1.2.3