Allocate smaller buffers for glyphs

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1422 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2008-12-06 13:45:05 +00:00
parent 0f9ebcf159
commit 9a7d905289
5 changed files with 145 additions and 66 deletions
+4 -2
View File
@@ -208,8 +208,9 @@ enum exitcode_e
struct nxeg_glyph_s struct nxeg_glyph_s
{ {
ubyte code; /* Character code */ ubyte code; /* Character code */
ubyte width; /* Visible width of this glyph */ ubyte height; /* Height of this glyph (in rows) */
ubyte stride; /* Width of the glyph row in bytes */ ubyte width; /* Width of this glyph (in pixels) */
ubyte stride; /* Width of the glyph row (in bytes) */
FAR ubyte *bitmap; /* Allocated bitmap memory */ FAR ubyte *bitmap; /* Allocated bitmap memory */
}; };
@@ -231,6 +232,7 @@ struct nxeg_state_s
#ifdef CONFIG_NX_KBD #ifdef CONFIG_NX_KBD
ubyte height; /* Max height of a font in pixels */ ubyte height; /* Max height of a font in pixels */
ubyte width; /* Max width of a font in pixels */ ubyte width; /* Max width of a font in pixels */
ubyte spwidth; /* The width of a space */
ubyte nchars; /* Number of KBD chars received */ ubyte nchars; /* Number of KBD chars received */
ubyte nglyphs; /* Number of glyphs cached */ ubyte nglyphs; /* Number of glyphs cached */
+120 -39
View File
@@ -41,6 +41,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <ctype.h> #include <ctype.h>
#include <debug.h> #include <debug.h>
#include <errno.h> #include <errno.h>
@@ -98,32 +99,37 @@
static void nxeg_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, static void nxeg_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
FAR const struct nxeg_bitmap_s *bm) FAR const struct nxeg_bitmap_s *bm)
{ {
FAR void *src = (FAR void *)bm->glyph->bitmap;
struct nxgl_rect_s intersection; struct nxgl_rect_s intersection;
int ret; int ret;
/* Get the intersection of the redraw region and the characer bitmap */ /* Handle the special case of spaces which have no glyph bitmap */
nxgl_rectintersect(&intersection, rect, &bm->bounds); if (src)
if (!nxgl_nullrect(&intersection))
{ {
FAR void *src = (FAR void *)bm->glyph->bitmap; /* Get the intersection of the redraw region and the characer bitmap */
nxgl_rectintersect(&intersection, rect, &bm->bounds);
if (!nxgl_nullrect(&intersection))
{
#ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS #ifndef CONFIG_EXAMPLES_NX_RAWWINDOWS
ret = nxtk_bitmapwindow((NXTKWINDOW)hwnd, &intersection, &src, ret = nxtk_bitmapwindow((NXTKWINDOW)hwnd, &intersection, &src,
&bm->bounds.pt1, &bm->bounds.pt1,
(unsigned int)bm->glyph->stride); (unsigned int)bm->glyph->stride);
if (ret < 0) if (ret < 0)
{ {
message("nxeg_fillchar: nxtk_bitmapwindow failed: %d\n", errno); message("nxeg_fillchar: nxtk_bitmapwindow failed: %d\n", errno);
} }
#else #else
ret = nx_bitmap((NXWINDOW)hwnd, &intersection, &src, ret = nx_bitmap((NXWINDOW)hwnd, &intersection, &src,
&bm->bounds.pt1, &bm->bounds.pt1,
(unsigned int)bm->glyph->stride); (unsigned int)bm->glyph->stride);
if (ret < 0) if (ret < 0)
{ {
message("nxeg_fillchar: nx_bitmapwindow failed: %d\n", errno); message("nxeg_fillchar: nx_bitmapwindow failed: %d\n", errno);
} }
#endif #endif
}
} }
} }
@@ -132,13 +138,14 @@ static void nxeg_fillchar(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
****************************************************************************/ ****************************************************************************/
static inline FAR const struct nxeg_glyph_s * static inline FAR const struct nxeg_glyph_s *
nxeg_renderglyph(FAR struct nxeg_state_s *st, ubyte ch) nxeg_renderglyph(FAR struct nxeg_state_s *st, FAR const struct nx_fontbitmap_s *bm, ubyte ch)
{ {
FAR struct nxeg_glyph_s *glyph = NULL; FAR struct nxeg_glyph_s *glyph = NULL;
FAR nxgl_mxpixel_t *ptr; FAR nxgl_mxpixel_t *ptr;
int bmsize; int bmsize;
int row; int row;
int col; int col;
int ret;
/* Make sure that there is room for another glyph */ /* Make sure that there is room for another glyph */
@@ -150,10 +157,15 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, ubyte ch)
glyph = &st->glyph[st->nglyphs]; glyph = &st->glyph[st->nglyphs];
glyph->code = ch; glyph->code = ch;
/* Allocate the maximum size for the bitmap */ /* Get the dimensions of the glyph */
glyph->stride = (st->width * CONFIG_EXAMPLES_NX_BPP + 4) / 8; glyph->width = bm->metric.width + bm->metric.xoffset;
bmsize = glyph->stride * st->height; glyph->height = bm->metric.height + bm->metric.yoffset;
/* Allocate memory to hold the glyph with its offsets */
glyph->stride = (glyph->width * CONFIG_EXAMPLES_NX_BPP + 7) / 8;
bmsize = glyph->stride * glyph->height;
glyph->bitmap = (FAR ubyte *)malloc(bmsize); glyph->bitmap = (FAR ubyte *)malloc(bmsize);
if (glyph->bitmap) if (glyph->bitmap)
@@ -164,9 +176,9 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, ubyte ch)
# error "Additional logic is needed here" # error "Additional logic is needed here"
#else #else
ptr = (FAR nxgl_mxpixel_t *)glyph->bitmap; ptr = (FAR nxgl_mxpixel_t *)glyph->bitmap;
for (row = 0; row < st->height; row++) for (row = 0; row < glyph->height; row++)
{ {
for (col = 0; col < st->width; col++) for (col = 0; col < glyph->width; col++)
{ {
*ptr++ = st->color[0]; *ptr++ = st->color[0];
} }
@@ -174,12 +186,14 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, ubyte ch)
#endif #endif
/* Then render the glyph into the allocated memory */ /* Then render the glyph into the allocated memory */
glyph->width = RENDERER((FAR nxgl_mxpixel_t*)glyph->bitmap, ret = RENDERER((FAR nxgl_mxpixel_t*)glyph->bitmap,
st->height, st->width, glyph->stride, glyph->height, glyph->width, glyph->stride,
ch, CONFIG_EXAMPLES_NX_FONTCOLOR); bm, CONFIG_EXAMPLES_NX_FONTCOLOR);
if (glyph->width <= 0) if (ret < 0)
{ {
message("nxeg_renderglyph: RENDERER returned width=%d\n", glyph->width); /* Actually, the RENDERER never returns a failure */
message("nxeg_renderglyph: RENDERER failed\n");
free(glyph->bitmap); free(glyph->bitmap);
glyph->bitmap = NULL; glyph->bitmap = NULL;
glyph = NULL; glyph = NULL;
@@ -197,11 +211,37 @@ nxeg_renderglyph(FAR struct nxeg_state_s *st, ubyte ch)
} }
/**************************************************************************** /****************************************************************************
* Name: nxeg_getglyph * Name: nxeg_addspace
****************************************************************************/
static inline FAR const struct nxeg_glyph_s *
nxeg_addspace(FAR struct nxeg_state_s *st, ubyte ch)
{
FAR struct nxeg_glyph_s *glyph = NULL;
/* Make sure that there is room for another glyph */
if (st->nglyphs < NXTK_MAXKBDCHARS)
{
/* Allocate the NULL glyph */
glyph = &st->glyph[st->nglyphs];
memset(glyph, 0, sizeof(struct nxeg_glyph_s));
glyph->code = ' ';
glyph->width = st->spwidth;
st->nglyphs++;
}
return glyph;
}
/****************************************************************************
* Name: nxeg_findglyph
****************************************************************************/ ****************************************************************************/
static FAR const struct nxeg_glyph_s * static FAR const struct nxeg_glyph_s *
nxeg_getglyph(FAR struct nxeg_state_s *st, ubyte ch) nxeg_findglyph(FAR struct nxeg_state_s *st, ubyte ch)
{ {
int i; int i;
@@ -214,10 +254,45 @@ nxeg_getglyph(FAR struct nxeg_state_s *st, ubyte ch)
return &st->glyph[i]; return &st->glyph[i];
} }
} }
return NULL;
}
/* No, it is not cached... render it now and add it to the cache */ /****************************************************************************
* Name: nxeg_getglyph
****************************************************************************/
return nxeg_renderglyph(st, ch); static FAR const struct nxeg_glyph_s *
nxeg_getglyph(FAR struct nxeg_state_s *st, ubyte ch)
{
FAR const struct nxeg_glyph_s *glyph;
FAR const struct nx_fontbitmap_s *bm;
/* First, try to find the glyph in the cache of pre-rendered glyphs */
glyph = nxeg_findglyph(st, ch);
if (!glyph)
{
/* No, it is not cached... Does the code map to a glyph? */
bm = nxf_getbitmap(ch);
if (!bm)
{
/* No, there is no glyph for this code. Use space */
glyph = nxeg_findglyph(st, ' ');
if (!glyph)
{
/* There isn't fake glyph for ' ' yet... create one */
glyph = nxeg_addspace(st, ' ');
}
}
else
{
glyph = nxeg_renderglyph(st, bm, ch);
}
}
return glyph;
} }
/**************************************************************************** /****************************************************************************
@@ -229,7 +304,6 @@ nxeg_addchar(FAR struct nxeg_state_s *st, ubyte ch)
{ {
FAR struct nxeg_bitmap_s *bm = NULL; FAR struct nxeg_bitmap_s *bm = NULL;
FAR struct nxeg_bitmap_s *bmleft; FAR struct nxeg_bitmap_s *bmleft;
FAR const struct nx_font_s *fontset;
nxgl_coord_t leftx; nxgl_coord_t leftx;
/* Is there space for another character on the display? */ /* Is there space for another character on the display? */
@@ -238,7 +312,7 @@ nxeg_addchar(FAR struct nxeg_state_s *st, ubyte ch)
{ {
/* Yes, setup the bitmap */ /* Yes, setup the bitmap */
bm = &st->bm[st->nchars]; bm = &st->bm[st->nchars];
/* Find the matching glyph */ /* Find the matching glyph */
@@ -254,8 +328,7 @@ nxeg_addchar(FAR struct nxeg_state_s *st, ubyte ch)
{ {
/* The first character is one space from the left */ /* The first character is one space from the left */
fontset = nxf_getfontset(); leftx = st->spwidth;
leftx = fontset->spwidth;
} }
else else
{ {
@@ -268,7 +341,7 @@ nxeg_addchar(FAR struct nxeg_state_s *st, ubyte ch)
bm->bounds.pt1.x = leftx; bm->bounds.pt1.x = leftx;
bm->bounds.pt1.y = 2; bm->bounds.pt1.y = 2;
bm->bounds.pt2.x = leftx + bm->glyph->width - 1; bm->bounds.pt2.x = leftx + bm->glyph->width - 1;
bm->bounds.pt2.y = 2 + st->height - 1; bm->bounds.pt2.y = 2 + bm->glyph->height - 1;
st->nchars++; st->nchars++;
} }
@@ -287,7 +360,10 @@ static inline void nxeg_addchars(NXWINDOW hwnd, FAR struct nxeg_state_s *st,
while (nch--) while (nch--)
{ {
bm = nxeg_addchar(st, *ch++); bm = nxeg_addchar(st, *ch++);
nxeg_fillchar(hwnd, &bm->bounds, bm); if (bm)
{
nxeg_fillchar(hwnd, &bm->bounds, bm);
}
} }
} }
@@ -327,6 +403,11 @@ void nxeg_filltext(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
FAR struct nxeg_state_s *st) FAR struct nxeg_state_s *st)
{ {
int i; int i;
/* Fill each character on the display (Only the characters within rect
* will actually be redrawn).
*/
for (i = 0; i < st->nchars; i++) for (i = 0; i < st->nchars; i++)
{ {
nxeg_fillchar(hwnd, rect, &st->bm[i]); nxeg_fillchar(hwnd, rect, &st->bm[i]);
+1
View File
@@ -164,6 +164,7 @@ static void nxeg_initstate(FAR struct nxeg_state_s *st, int wnum,
st->nglyphs = 0; st->nglyphs = 0;
st->height = fontset->mxheight; st->height = fontset->mxheight;
st->width = fontset->mxwidth; st->width = fontset->mxwidth;
st->spwidth = fontset->spwidth;
#endif #endif
} }
+5 -16
View File
@@ -126,21 +126,20 @@
* height - The max height of the returned char in rows * height - The max height of the returned char in rows
* width - The max width of the returned char in pixels * width - The max width of the returned char in pixels
* stride - The width of the destination buffer in bytes * stride - The width of the destination buffer in bytes
* ch - The character code to convert * bm - Describes the character glyph to convert
* color - The color to use for '1' bits in the font bitmap * color - The color to use for '1' bits in the font bitmap
* (0 bits are transparent) * (0 bits are transparent)
* *
* Returned Value: * Returned Value:
* On Success, this function returns the actual width of the font in bytes. * OK on Success, ERROR: on failure with errno set appropriately.
* on failed, a negated errno is retured. * (never fails)
* *
****************************************************************************/ ****************************************************************************/
int NXF_FUNCNAME(nxf_convert,NXFONTS_SUFFIX) int NXF_FUNCNAME(nxf_convert,NXFONTS_SUFFIX)
(FAR NXF_PIXEL_T *dest, uint16 height, uint16 width, uint16 stride, (FAR NXF_PIXEL_T *dest, uint16 height, uint16 width, uint16 stride,
uint16 ch, nxgl_mxpixel_t color) FAR const struct nx_fontbitmap_s *bm, nxgl_mxpixel_t color)
{ {
FAR const struct nx_fontbitmap_s *bm;
FAR ubyte *line; FAR ubyte *line;
FAR NXF_PIXEL_T *dptr; FAR NXF_PIXEL_T *dptr;
FAR const ubyte *sptr; FAR const ubyte *sptr;
@@ -157,16 +156,6 @@ int NXF_FUNCNAME(nxf_convert,NXFONTS_SUFFIX)
int nbits; int nbits;
#endif #endif
/* Map the character code to a bitmap font */
bm = nxf_getbitmap(ch);
if (!bm)
{
/* No character? Nothing to rend, return the width of a space */
return g_fonts.spwidth;
}
/* Get the starting position */ /* Get the starting position */
line = (ubyte*)dest + bm->metric.yoffset * stride + NXF_SCALEX(bm->metric.xoffset); line = (ubyte*)dest + bm->metric.yoffset * stride + NXF_SCALEX(bm->metric.xoffset);
@@ -276,5 +265,5 @@ int NXF_FUNCNAME(nxf_convert,NXFONTS_SUFFIX)
} }
} }
#endif #endif
return bm->metric.width + bm->metric.xoffset; return OK;
} }
+15 -9
View File
@@ -150,33 +150,39 @@ EXTERN FAR const struct nx_fontbitmap_s *nxf_getbitmap(uint16 ch);
* height - The max height of the returned char in rows * height - The max height of the returned char in rows
* width - The max width of the returned char in pixels * width - The max width of the returned char in pixels
* stride - The width of the destination buffer in bytes * stride - The width of the destination buffer in bytes
* ch - The character code to convert * bm - Describes the character glyph to convert
* color - The color to use for '1' bits in the font bitmap * color - The color to use for '1' bits in the font bitmap
* (0 bits are transparent) * (0 bits are transparent)
* *
* Returned Value: * Returned Value:
* On Success, this function returns the actual width of the font in bytes. * OK on Success, ERROR: on failure with errno set appropriately.
* on failed, a negated errno is retured. * (never fails)
* *
****************************************************************************/ ****************************************************************************/
EXTERN int nxf_convert_2bpp(FAR ubyte *dest, uint16 height, EXTERN int nxf_convert_2bpp(FAR ubyte *dest, uint16 height,
uint16 width, uint16 stride, uint16 ch, uint16 width, uint16 stride,
FAR const struct nx_fontbitmap_s *bm,
nxgl_mxpixel_t color); nxgl_mxpixel_t color);
EXTERN int nxf_convert_4bpp(FAR ubyte *dest, uint16 height, EXTERN int nxf_convert_4bpp(FAR ubyte *dest, uint16 height,
uint16 width, uint16 stride, uint16 ch, uint16 width, uint16 stride,
FAR const struct nx_fontbitmap_s *bm,
nxgl_mxpixel_t color); nxgl_mxpixel_t color);
EXTERN int nxf_convert_8bpp(FAR ubyte *dest, uint16 height, EXTERN int nxf_convert_8bpp(FAR ubyte *dest, uint16 height,
uint16 width, uint16 stride, uint16 ch, uint16 width, uint16 stride,
FAR const struct nx_fontbitmap_s *bm,
nxgl_mxpixel_t color); nxgl_mxpixel_t color);
EXTERN int nxf_convert_16bpp(FAR uint16 *dest, uint16 height, EXTERN int nxf_convert_16bpp(FAR uint16 *dest, uint16 height,
uint16 width, uint16 stride, uint16 ch, uint16 width, uint16 stride,
FAR const struct nx_fontbitmap_s *bm,
nxgl_mxpixel_t color); nxgl_mxpixel_t color);
EXTERN int nxf_convert_24bpp(FAR uint32 *dest, uint16 height, EXTERN int nxf_convert_24bpp(FAR uint32 *dest, uint16 height,
uint16 width, uint16 stride, uint16 ch, uint16 width, uint16 stride,
FAR const struct nx_fontbitmap_s *bm,
nxgl_mxpixel_t color); nxgl_mxpixel_t color);
EXTERN int nxf_convert_32bpp(FAR uint32 *dest, uint16 height, EXTERN int nxf_convert_32bpp(FAR uint32 *dest, uint16 height,
uint16 width, uint16 stride, uint16 ch, uint16 width, uint16 stride,
FAR const struct nx_fontbitmap_s *bm,
nxgl_mxpixel_t color); nxgl_mxpixel_t color);
#undef EXTERN #undef EXTERN