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:
parent
49260dc620
commit
e8ca12ee30
@ -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:
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user