From 6b7e073c580b905325d5a068e143900223b5ac04 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Fri, 1 Aug 2014 09:50:31 +0100 Subject: Add support for double-size rendering of internal font for headings. --- framebuffer/font_internal.c | 99 ++++++++++++++++++++++++++++++++++++++++----- framebuffer/font_internal.h | 3 +- framebuffer/framebuffer.c | 16 +++++--- 3 files changed, 102 insertions(+), 16 deletions(-) (limited to 'framebuffer') diff --git a/framebuffer/font_internal.c b/framebuffer/font_internal.c index 678be1247..23ef42191 100644 --- a/framebuffer/font_internal.c +++ b/framebuffer/font_internal.c @@ -36,6 +36,7 @@ #define GLYPH_LEN 16 uint8_t code_point[GLYPH_LEN]; +uint8_t glyph_x2[GLYPH_LEN * 4]; #define SEVEN_SET ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | \ (1 << 4) | (1 << 5) | (1 << 6)) @@ -213,9 +214,68 @@ fb_get_font_style(const plot_font_style_t *fstyle) } } +int +fb_get_font_size(const plot_font_style_t *fstyle) +{ + int size = fstyle->size * 10 / + (((nsoption_int(font_min_size) * 3 + + nsoption_int(font_size)) / 4) * FONT_SIZE_SCALE); + if (size > 2) + size = 2; + else if (size <= 0) + size = 1; + + return size; +} + +static const uint8_t * +glyph_scale_2(const uint8_t *glyph_data) +{ + int y, x; + uint8_t *pos = glyph_x2; + + for (y = 0; y < 16; y++) { + *pos = 0; + for (x = 0; x < 4; x++) { + if (glyph_data[y] & (1 << (7 - x))) { + *pos |= 1 << ((3 - x) * 2); + *pos |= 1 << ((3 - x) * 2 + 1); + } + } + pos++; + *pos = 0; + for (x = 4; x < 8; x++) { + if (glyph_data[y] & (1 << (7 - x))) { + *pos |= 1 << ((7 - x) * 2); + *pos |= 1 << ((7 - x) * 2 + 1); + } + } + pos++; + *pos = 0; + for (x = 0; x < 4; x++) { + if (glyph_data[y] & (1 << (7 - x))) { + *pos |= 1 << ((3 - x) * 2); + *pos |= 1 << ((3 - x) * 2 + 1); + } + } + pos++; + *pos = 0; + for (x = 4; x < 8; x++) { + if (glyph_data[y] & (1 << (7 - x))) { + *pos |= 1 << ((7 - x) * 2); + *pos |= 1 << ((7 - x) * 2 + 1); + } + } + pos++; + } + + return glyph_x2; +} + const uint8_t * -fb_get_glyph(uint32_t ucs4, enum fb_font_style style) +fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale) { + const uint8_t *glyph_data; unsigned int section; unsigned int offset; uint16_t g_offset; @@ -233,7 +293,8 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style) offset = section * 256 + (ucs4 & 0xff); g_offset = fb_bold_italic_sections[offset] * 16; if (g_offset != 0) { - return &font_glyph_data[g_offset]; + glyph_data = &font_glyph_data[g_offset]; + break; } } case FB_BOLD: @@ -242,7 +303,8 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style) offset = section * 256 + (ucs4 & 0xff); g_offset = fb_bold_sections[offset] * 16; if (g_offset != 0) { - return &font_glyph_data[g_offset]; + glyph_data = &font_glyph_data[g_offset]; + break; } } case FB_ITALIC: @@ -251,7 +313,8 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style) offset = section * 256 + (ucs4 & 0xff); g_offset = fb_italic_sections[offset] * 16; if (g_offset != 0) { - return &font_glyph_data[g_offset]; + glyph_data = &font_glyph_data[g_offset]; + break; } } case FB_REGULAR: @@ -260,12 +323,27 @@ fb_get_glyph(uint32_t ucs4, enum fb_font_style style) offset = section * 256 + (ucs4 & 0xff); g_offset = fb_regular_sections[offset] * 16; if (g_offset != 0) { - return &font_glyph_data[g_offset]; + glyph_data = &font_glyph_data[g_offset]; + break; } } + default: + glyph_data = get_codepoint(ucs4, style & FB_ITALIC); + break; + } + + switch (scale) { + case 1: + break; + case 2: + glyph_data = glyph_scale_2(glyph_data); + break; + default: + assert(scale >= 1 && scale <= 2); + break; } - return get_codepoint(ucs4, style & FB_ITALIC); + return glyph_data; } static nserror utf8_to_local(const char *string, @@ -310,6 +388,7 @@ static bool nsfont_width(const plot_font_style_t *fstyle, nxtchr = utf8_next(string, length, nxtchr); } + *width *= fb_get_font_size(fstyle); return true; } @@ -329,17 +408,18 @@ static bool nsfont_position_in_string(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { + const int width = fb_get_font_size(fstyle) * FB_FONT_WIDTH; size_t nxtchr = 0; int x_pos = 0; while (nxtchr < length) { uint32_t ucs4; - if (abs(x_pos - x) <= (FB_FONT_WIDTH / 2)) + if (abs(x_pos - x) <= (width / 2)) break; ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); if (codepoint_displayable(ucs4)) { - x_pos += FB_FONT_WIDTH; + x_pos += width; } nxtchr = utf8_next(string, length, nxtchr); @@ -380,6 +460,7 @@ static bool nsfont_split(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { + const int width = fb_get_font_size(fstyle) * FB_FONT_WIDTH; size_t nxtchr = 0; int last_space_x = 0; int last_space_idx = 0; @@ -395,7 +476,7 @@ static bool nsfont_split(const plot_font_style_t *fstyle, ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); if (codepoint_displayable(ucs4)) { - *actual_x += FB_FONT_WIDTH; + *actual_x += width; } if (*actual_x > x && last_space_idx != 0) { diff --git a/framebuffer/font_internal.h b/framebuffer/font_internal.h index ead179c99..d066f6bf4 100644 --- a/framebuffer/font_internal.h +++ b/framebuffer/font_internal.h @@ -38,8 +38,9 @@ enum fb_font_style { }; enum fb_font_style fb_get_font_style(const plot_font_style_t *fstyle); +int fb_get_font_size(const plot_font_style_t *fstyle); -const uint8_t * fb_get_glyph(uint32_t ucs4, enum fb_font_style style); +const uint8_t *fb_get_glyph(uint32_t ucs4, enum fb_font_style style, int scale); #define codepoint_displayable(u) \ (!(u >= 0x200b && u <= 0x200f)) diff --git a/framebuffer/framebuffer.c b/framebuffer/framebuffer.c index 1b0c34b54..a0f39707c 100644 --- a/framebuffer/framebuffer.c +++ b/framebuffer/framebuffer.c @@ -126,12 +126,16 @@ static bool framebuffer_plot_text(int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle) { enum fb_font_style style = fb_get_font_style(fstyle); + int size = fb_get_font_size(fstyle); const uint8_t *chrp; size_t nxtchr = 0; nsfb_bbox_t loc; uint32_t ucs4; + int p = FB_FONT_PITCH * size; + int w = FB_FONT_WIDTH * size; + int h = FB_FONT_HEIGHT * size; - y -= ((FB_FONT_HEIGHT * 3) / 4); + y -= ((h * 3) / 4); /* the coord is the bottom-left of the pixels offset by 1 to make * it work since fb coords are the top-left of pixels */ y += 1; @@ -145,13 +149,13 @@ static bool framebuffer_plot_text(int x, int y, const char *text, size_t length, loc.x0 = x; loc.y0 = y; - loc.x1 = loc.x0 + FB_FONT_WIDTH; - loc.y1 = loc.y0 + FB_FONT_HEIGHT; + loc.x1 = loc.x0 + w; + loc.y1 = loc.y0 + h; - chrp = fb_get_glyph(ucs4, style); - nsfb_plot_glyph1(nsfb, &loc, chrp, FB_FONT_PITCH, fstyle->foreground); + chrp = fb_get_glyph(ucs4, style, size); + nsfb_plot_glyph1(nsfb, &loc, chrp, p, fstyle->foreground); - x += FB_FONT_WIDTH; + x += w; } -- cgit v1.2.3