From 7f79b89eda65e2529128710168a5b1de431ff7f0 Mon Sep 17 00:00:00 2001
From: inmarket <inmarket@ugfx.org>
Date: Mon, 14 Nov 2016 09:15:51 +1000
Subject: Add support for adding fonts to the font list

---
 docs/releases.txt       |  1 +
 src/gdisp/gdisp.h       | 13 +++++++++++++
 src/gdisp/gdisp_fonts.c | 50 ++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 51 insertions(+), 13 deletions(-)

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 */
-- 
cgit v1.2.3