Fix a few NXTEXT bugs

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3765 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-07-10 17:18:26 +00:00
parent 49260dc620
commit e8ca12ee30
5 changed files with 134 additions and 79 deletions

View File

@ -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:

View File

@ -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; )
/* Has any part of this character scrolled off the screen? */
if (bm->pos.y < lineheight)
{
FAR struct nxtext_bitmap_s *bm = &g_bgstate.bm[i];
/* Yes... Delete the character by moving all of the data */
/* Has any part of this character scrolled off the screen? */
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;
/* We are keeping this one so increment to the next character */
i++;
}
g_bgstate.nchars--;
}
/* And move the next display position up by one line as well */
/* No.. just decrement its vertical position (moving it "up" the
* display by one line).
*/
g_bgstate.fpos.y -= lineheight;
else
{
bm->pos.y -= lineheight;
/* We are keeping this one so increment to the next character */
i++;
}
}
/* Then re-draw the entire display */
/* And move the next display position up by one line as well */
g_bgstate.fpos.y -= lineheight;
/* 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);
}

View File

@ -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

View File

@ -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

View File

@ -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)