From 4b40e8314b015f07618e88b7c5e7c00b55679a82 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 10 Jul 2011 17:18:26 +0000 Subject: Fix a few NXTEXT bugs git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3765 42af7a65-404d-4744-a932-0658087f49c3 --- apps/examples/README.txt | 6 +++ apps/examples/nxtext/nxtext_bkgd.c | 87 ++++++++++++++++++---------------- apps/examples/nxtext/nxtext_internal.h | 3 +- apps/examples/nxtext/nxtext_main.c | 44 ++++++++--------- apps/examples/nxtext/nxtext_putc.c | 71 +++++++++++++++++++++------ 5 files changed, 133 insertions(+), 78 deletions(-) (limited to 'apps/examples') diff --git a/apps/examples/README.txt b/apps/examples/README.txt index f21011829..d3306f3a9 100644 --- a/apps/examples/README.txt +++ b/apps/examples/README.txt @@ -312,6 +312,12 @@ examples/nxtest defined in include/nuttx/nx.h. This text focuses on text displays on the dispaly background combined with pop-up displays over the text. The text display will continue to update while the pop-up is visible. + + NOTE: This example will *only* work with FB drivers and with LCD + drivers that support reading the contents of the internal LCD memory. + If you notice garbage on the display or a failure at the point where + the display should scroll, it is probably because you have an LCD + driver that is write-only. The following configuration options can be selected: diff --git a/apps/examples/nxtext/nxtext_bkgd.c b/apps/examples/nxtext/nxtext_bkgd.c index 9c1ccf41f..6bc7a82cf 100644 --- a/apps/examples/nxtext/nxtext_bkgd.c +++ b/apps/examples/nxtext/nxtext_bkgd.c @@ -200,68 +200,73 @@ static void nxbg_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, * Name: nxbg_scroll ****************************************************************************/ -static void nxbg_scroll(NXWINDOW hwnd, int lineheight) +static inline void nxbg_scroll(NXWINDOW hwnd, int lineheight) { struct nxgl_rect_s rect; + struct nxgl_point_s offset; + int ret; int i; int j; - /* Scroll up until the next display position is in the window. We may need - * do this more than once (unlikely) - */ + /* Adjust the vertical position of each character */ - while (g_bgstate.fpos.y >= g_bgstate.wsize.h - lineheight) + for (i = 0; i < g_bgstate.nchars; ) { - /* Adjust the vertical position of each character */ + FAR struct nxtext_bitmap_s *bm = &g_bgstate.bm[i]; - for (i = 0; i < g_bgstate.nchars; ) - { - FAR struct nxtext_bitmap_s *bm = &g_bgstate.bm[i]; + /* Has any part of this character scrolled off the screen? */ - /* Has any part of this character scrolled off the screen? */ + if (bm->pos.y < lineheight) + { + /* Yes... Delete the character by moving all of the data */ - if (bm->pos.y < lineheight) + for (j = i; j < g_bgstate.nchars-1; j++) { - /* Yes... Delete the character by moving all of the data */ - - for (j = i; j < g_bgstate.nchars-1; j++) - { - memcpy(&g_bgstate.bm[j], &g_bgstate.bm[j+1], sizeof(struct nxtext_bitmap_s)); - } - - /* Decrement the number of cached characters (i is not incremented - * in this case because it already points to the next charactger) - */ - - g_bgstate.nchars--; + memcpy(&g_bgstate.bm[j], &g_bgstate.bm[j+1], sizeof(struct nxtext_bitmap_s)); } - /* No.. just decrement its vertical position (moving it "up" the - * display by one line. + /* Decrement the number of cached characters ('i' is not incremented + * in this case because it already points to the next character) */ - else - { - bm->pos.y -= lineheight; + g_bgstate.nchars--; + } - /* We are keeping this one so increment to the next character */ + /* No.. just decrement its vertical position (moving it "up" the + * display by one line). + */ + + else + { + bm->pos.y -= lineheight; + + /* We are keeping this one so increment to the next character */ - i++; - } + i++; } + } - /* And move the next display position up by one line as well */ + /* And move the next display position up by one line as well */ - g_bgstate.fpos.y -= lineheight; - } + g_bgstate.fpos.y -= lineheight; - /* Then re-draw the entire display */ + /* Move the display in the range of 0-height up one lineheight. The + * line at the bottom will be reset to the background color automatically. + */ rect.pt1.x = 0; - rect.pt1.y = 0; + rect.pt1.y = lineheight; rect.pt2.x = g_bgstate.wsize.w - 1; rect.pt2.y = g_bgstate.wsize.h - 1; - nxbg_redrawrect(hwnd, NULL); + + offset.x = 0; + offset.y = -lineheight; + + ret = nx_move(hwnd, &rect, &offset); + if (ret < 0) + { + message("nxbg_redrawrect: nx_move failed: %d\n", errno); + } } /**************************************************************************** @@ -318,7 +323,7 @@ FAR struct nxtext_state_s *nxbg_getstate(void) void nxbg_write(NXWINDOW hwnd, FAR const uint8_t *buffer, size_t buflen) { - int lineheight = (g_bgstate.fheight + 2); + int lineheight = (g_bgstate.fheight + LINE_SEPARATION); while (buflen-- > 0) { @@ -339,9 +344,11 @@ void nxbg_write(NXWINDOW hwnd, FAR const uint8_t *buffer, size_t buflen) } } - /* Check if we need to scroll up */ + /* Check if we need to scroll up (handling a corner case where + * there may be more than one newline). + */ - if (g_bgstate.fpos.y >= g_bgstate.wsize.h - lineheight) + while (g_bgstate.fpos.y >= g_bgstate.wsize.h - lineheight) { nxbg_scroll(hwnd, lineheight); } diff --git a/apps/examples/nxtext/nxtext_internal.h b/apps/examples/nxtext/nxtext_internal.h index fe3cf549f..af0cd0310 100644 --- a/apps/examples/nxtext/nxtext_internal.h +++ b/apps/examples/nxtext/nxtext_internal.h @@ -172,7 +172,8 @@ /* Sizes and maximums */ -#define MAX_USECNT 255 +#define MAX_USECNT 255 /* Limit to range of a uint8_t */ +#define LINE_SEPARATION 2 /* Space (in rows) between lines */ /**************************************************************************** * Public Types diff --git a/apps/examples/nxtext/nxtext_main.c b/apps/examples/nxtext/nxtext_main.c index e6d0eca39..ba898faf8 100644 --- a/apps/examples/nxtext/nxtext_main.c +++ b/apps/examples/nxtext/nxtext_main.c @@ -100,29 +100,29 @@ static const uint8_t g_pumsg[] = "Pop-Up!"; static const char *g_bgmsg[BGMSG_LINES] = { "\nJULIET\n", - "Wilt thou be gone? ", - "It is not yet near day:\n", - "It was the nightingale, ", - "and not the lark,\n", - "That pierced the fearful hollow ", - "of thine ear;\n", - "Nightly she sings ", - "on yon pomegranate-tree:\n", - "Believe me, love, " - "it was the nightingale.\n" + "Wilt thou be gone?\n", + " It is not yet near day:\n", + "It was the nightingale,\n", + " and not the lark,\n", + "That pierced the fearful hollow\n", + " of thine ear;\n", + "Nightly she sings\n", + " on yon pomegranate-tree:\n", + "Believe me, love,\n" + " it was the nightingale.\n" "\nROMEO\n" - "It was the lark, " - "the herald of the morn,\n" - "No nightingale: " - "look, love, what envious streaks\n" - "Do lace the severing clouds " - "in yonder east:\n" - "Night's candles are burnt out, " - "and jocund day\n" - "Stands tiptoe " - "on the misty mountain tops.\n" - "I must be gone and live, " - "or stay and die. \n" + "It was the lark,\n" + " the herald of the morn,\n" + "No nightingale:\n" + " look, love, what envious streaks\n" + "Do lace the severing clouds\n" + " in yonder east:\n" + "Night's candles are burnt out,\n" + " and jocund day\n" + "Stands tiptoe\n" + " on the misty mountain tops.\n" + "I must be gone and live,\n" + " or stay and die.\n" }; #endif diff --git a/apps/examples/nxtext/nxtext_putc.c b/apps/examples/nxtext/nxtext_putc.c index f1125f17d..37602bb43 100644 --- a/apps/examples/nxtext/nxtext_putc.c +++ b/apps/examples/nxtext/nxtext_putc.c @@ -220,7 +220,7 @@ nxtext_findglyph(FAR struct nxtext_state_s *st, uint8_t ch) static inline FAR struct nxtext_glyph_s * nxtext_renderglyph(FAR struct nxtext_state_s *st, - FAR const struct nx_fontbitmap_s *bm, uint8_t ch) + FAR const struct nx_fontbitmap_s *fbm, uint8_t ch) { FAR struct nxtext_glyph_s *glyph = NULL; FAR nxgl_mxpixel_t *ptr; @@ -234,7 +234,7 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, /* Make sure that there is room for another glyph */ - message("nxtext_renderglyph: ch=%02x\n", ch); + message("nxtext_renderglyph: ch=%c [%02x]\n", isprint(ch) ? ch : '.', ch); /* Allocate the glyph (always succeeds) */ @@ -243,8 +243,8 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, /* Get the dimensions of the glyph */ - glyph->width = bm->metric.width + bm->metric.xoffset; - glyph->height = bm->metric.height + bm->metric.yoffset; + glyph->width = fbm->metric.width + fbm->metric.xoffset; + glyph->height = fbm->metric.height + fbm->metric.yoffset; /* Allocate memory to hold the glyph with its offsets */ @@ -308,7 +308,7 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, ret = RENDERER((FAR nxgl_mxpixel_t*)glyph->bitmap, glyph->height, glyph->width, glyph->stride, - bm, st->fcolor[0]); + fbm, st->fcolor[0]); if (ret < 0) { /* Actually, the RENDERER never returns a failure */ @@ -322,6 +322,29 @@ nxtext_renderglyph(FAR struct nxtext_state_s *st, return glyph; } +/**************************************************************************** + * Name: nxtext_fontsize + ****************************************************************************/ + +static int nxtext_fontsize(uint8_t ch, FAR struct nxgl_size_s *size) +{ + FAR const struct nx_fontbitmap_s *fbm; + + /* No, it is not cached... Does the code map to a font? */ + + fbm = nxf_getbitmap(ch); + if (fbm) + { + /* Yes.. return the font size */ + + size->w = fbm->metric.width + fbm->metric.xoffset; + size->h = fbm->metric.height + fbm->metric.yoffset; + return OK; + } + + return ERROR; +} + /**************************************************************************** * Name: nxtext_getglyph ****************************************************************************/ @@ -424,9 +447,9 @@ void nxtext_home(FAR struct nxtext_state_s *st) st->fpos.x = st->spwidth; - /* And two lines from the top */ + /* And LINE_SEPARATION lines from the top */ - st->fpos.y = 2; + st->fpos.y = LINE_SEPARATION; } /**************************************************************************** @@ -443,9 +466,9 @@ void nxtext_newline(FAR struct nxtext_state_s *st) st->fpos.x = st->spwidth; - /* Linefeed: Down the max font height + 2 */ + /* Linefeed: Down the max font height + LINE_SEPARATION */ - st->fpos.y += (st->fheight + 2); + st->fpos.y += (st->fheight + LINE_SEPARATION); } /**************************************************************************** @@ -499,6 +522,7 @@ void nxtext_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, FAR struct nxtext_glyph_s *glyph; struct nxgl_rect_s bounds; struct nxgl_rect_s intersection; + struct nxgl_size_s fsize; int ret; /* Handle the special case of spaces which have no glyph bitmap */ @@ -508,12 +532,16 @@ void nxtext_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, return; } - /* Find (or create) the matching glyph */ + /* Get the size of the font glyph (which may not have been created yet) */ - glyph = nxtext_getglyph(st, bm->code); - if (!glyph) + ret = nxtext_fontsize(bm->code, &fsize); + if (ret < 0) { - /* This shouldn't happen */ + /* This would mean that there is no bitmap for the character code and + * that the font would be rendered as a space. But this case should + * never happen here because the BM_ISSPACE() should have already + * found all such cases. + */ return; } @@ -522,8 +550,8 @@ void nxtext_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, bounds.pt1.x = bm->pos.x; bounds.pt1.y = bm->pos.y; - bounds.pt2.x = bm->pos.x + glyph->width - 1; - bounds.pt2.y = bm->pos.y + glyph->height - 1; + bounds.pt2.x = bm->pos.x + fsize.w - 1; + bounds.pt2.y = bm->pos.y + fsize.h - 1; /* Should this also be clipped to a region in the window? */ @@ -546,6 +574,19 @@ void nxtext_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, { FAR const void *src = (FAR const void *)glyph->bitmap; + /* Find (or create) the glyph that goes with this font */ + + glyph = nxtext_getglyph(st, bm->code); + if (!glyph) + { + /* Shouldn't happen */ + + return; + } + + /* Blit the font bitmap into the window */ + + src = (FAR const void *)glyph->bitmap; ret = nx_bitmap((NXWINDOW)hwnd, &intersection, &src, &bm->pos, (unsigned int)glyph->stride); if (ret < 0) -- cgit v1.2.3