diff --git a/docs/releases.txt b/docs/releases.txt index 37c2c397..517539c1 100644 --- a/docs/releases.txt +++ b/docs/releases.txt @@ -21,6 +21,7 @@ FEATURE: Added a dual circle with the same center drawing routine to GDISP FIX: Fixed an issue in the filled polygon drawing function which caused irregularities FEATURE: Added high-level functions to modify image color palettes FIX: Improving gdispDrawThickLine() +FEATURE: Added gdispAddFont() for adding a dynamic font to the permanent font list *** Release 2.6 *** diff --git a/src/gdisp/gdisp.h b/src/gdisp/gdisp.h index 98a1363b..7878233e 100644 --- a/src/gdisp/gdisp.h +++ b/src/gdisp/gdisp.h @@ -1053,6 +1053,8 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co * @details Allocates memory for new font metadata using gfxAlloc, remember to close font after use! * @return A new font or NULL if out of memory. * @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h + * @note A scaled font should probably not be added to the font list as it will prevent the + * unscaled font of the same name being found as it will be the scaled version that will be found. * * @param[in] font The base font to use. * @param[in] scale_x The scale factor in horizontal direction. @@ -1070,6 +1072,17 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co * @api */ const char *gdispGetFontName(font_t font); + + /** + * @brief Add a font permanently to the font list. + * @returns TRUE on success. Reasons it may fail: out of memory, if it is already on the list, it is not a font loaded in RAM. + * @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h + * + * @param[in] font The font to add to the font list. + * + * @api + */ + bool_t gdispAddFont(font_t font); #endif /* Extra Arc Functions */ diff --git a/src/gdisp/gdisp_fonts.c b/src/gdisp/gdisp_fonts.c index f1ef9e5d..36e8f73f 100644 --- a/src/gdisp/gdisp_fonts.c +++ b/src/gdisp/gdisp_fonts.c @@ -11,8 +11,10 @@ #include "mcufont/mcufont.h" -/* Custom flag to indicate dynamically allocated font */ -#define FONT_FLAG_DYNAMIC 0x80 +#define FONT_FLAG_DYNAMIC 0x80 // Custom flag to indicate dynamically allocated font +#define FONT_FLAG_UNLISTED 0x40 // Custom flag to indicate font is not currently listed + +static const struct mf_font_list_s *fontList; /** * Match a pattern against the font name. @@ -43,40 +45,44 @@ static bool_t matchfont(const char *pattern, const char *name) { font_t gdispOpenFont(const char *name) { const struct mf_font_list_s *fp; - + if (!fontList) + fontList = mf_get_font_list(); + // Try the long names first - for(fp = mf_get_font_list(); fp; fp = fp->next) { + for(fp = fontList; fp; fp = fp->next) { if (matchfont(name, fp->font->full_name)) return fp->font; } // Try the short names if no long names match - for(fp = mf_get_font_list(); fp; fp = fp->next) { + for(fp = fontList; fp; fp = fp->next) { if (matchfont(name, fp->font->short_name)) return fp->font; } - /* Return default font.. better than nothing. */ + /* Return default builtin font.. better than nothing. */ return mf_get_font_list()->font; } void gdispCloseFont(font_t font) { - if (font->flags & FONT_FLAG_DYNAMIC) - { - struct mf_font_s *dfont = (struct mf_font_s *)font; - + if ((font->flags & (FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED)) == (FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED)) { /* Make sure that no-one can successfully use font after closing */ - dfont->render_character = 0; + ((struct mf_font_s *)font)->render_character = 0; /* Release the allocated memory */ - gfxFree(dfont); + gfxFree((void *)font); } } font_t gdispScaleFont(font_t font, uint8_t scale_x, uint8_t scale_y) { - struct mf_scaledfont_s *newfont = gfxAlloc(sizeof(struct mf_scaledfont_s)); + struct mf_scaledfont_s *newfont; + + if (!(newfont = gfxAlloc(sizeof(struct mf_scaledfont_s)))) + return 0; + mf_scale_font(newfont, font, scale_x, scale_y); + ((struct mf_font_s *)newfont)->flags |= FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED; return (font_t)newfont; } @@ -84,4 +90,22 @@ const char *gdispGetFontName(font_t font) { return font->short_name; } +bool_t gdispAddFont(font_t font) { + struct mf_font_list_s *hdr; + + if ((font->flags & (FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED)) != (FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED)) + return FALSE; + + if (!(hdr = gfxAlloc(sizeof(struct mf_font_list_s)))) + return FALSE; + + if (!fontList) + fontList = mf_get_font_list(); + hdr->font = (const struct mf_font_s *)font; + hdr->next = fontList; + ((struct mf_font_s *)font)->flags &= ~FONT_FLAG_UNLISTED; + fontList = hdr; + return TRUE; +} + #endif /* GFX_USE_GDISP && GDISP_NEED_TEXT */