[PATCH] font: fbconsole: add custom font support

Du Huanpeng u74147 at gmail.com
Thu Nov 12 02:13:25 PST 2015


add custom font and charset support. useful for
non ascii chars, e.g. Chinese and others.

Signed-off-by: Du Huanpeng <u74147 at gmail.com>
---
 drivers/video/fbconsole.c   |  5 +++--
 include/linux/font.h        | 11 ++++++++++-
 lib/fonts/Kconfig           |  5 +++++
 lib/fonts/Makefile          |  1 +
 lib/fonts/font_7x14.c       |  1 +
 lib/fonts/font_8x16.c       |  1 +
 lib/fonts/font_custom_16x.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 lib/fonts/font_mini_4x6.c   |  1 +
 lib/fonts/fonts.c           | 32 ++++++++++++++++++++++++++++++++
 9 files changed, 98 insertions(+), 3 deletions(-)
 create mode 100644 lib/fonts/font_custom_16x.c

diff --git a/drivers/video/fbconsole.c b/drivers/video/fbconsole.c
index 60f3c48..7fd4047 100644
--- a/drivers/video/fbconsole.c
+++ b/drivers/video/fbconsole.c
@@ -84,7 +84,7 @@ static struct rgb colors[] = {
 	{ 255, 255, 255 },
 };
 
-static void drawchar(struct fbc_priv *priv, int x, int y, char c)
+static void drawchar(struct fbc_priv *priv, int x, int y, int c)
 {
 	void *buf;
 	int bpp = priv->fb->bits_per_pixel >> 3;
@@ -97,7 +97,8 @@ static void drawchar(struct fbc_priv *priv, int x, int y, char c)
 
 	buf = gui_screen_render_buffer(priv->sc);
 
-	inbuf = &priv->font->data[c * priv->font->height];
+	i = find_font_index(priv->font, c);
+	inbuf = priv->font->data + i;
 
 	line_length = priv->fb->line_length;
 
diff --git a/include/linux/font.h b/include/linux/font.h
index 62b1879..d7fb415 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -12,20 +12,29 @@
 #define _VIDEO_FONT_H
 
 #include <param.h>
+#include <wchar.h>
 
+struct font_index {
+	wchar_t wc;	/* code of the char. */
+	short index;	/* offset of the char in the bitmap. */
+};
 struct font_desc {
 	const char *name;
 	int width, height;
+	struct font_index *index;
 	const void *data;
+	int num_chars;
 };
 
 extern const struct font_desc	font_vga_8x16,
 			font_7x14,
-			font_mini_4x6;
+			font_mini_4x6,
+			font_custom_16x;
 
 /* Max. length for the name of a predefined font */
 #define MAX_FONT_NAME	32
 
+extern int find_font_index(const struct font_desc *font, int ch);
 extern const struct font_desc *find_font_enum(int n);
 extern struct param_d *add_param_font(struct device_d *dev,
 		int (*set)(struct param_d *p, void *priv),
diff --git a/lib/fonts/Kconfig b/lib/fonts/Kconfig
index 715d5e5..d23b283 100644
--- a/lib/fonts/Kconfig
+++ b/lib/fonts/Kconfig
@@ -20,6 +20,11 @@ config FONT_7x14
 config FONT_MINI_4x6
 	bool "Mini 4x6 font"
 
+config FONT_CUSTOM_16X
+	bool "Custom 16x16 font"
+	help
+	  This font is useful for Chinese and other non ascii chars.
+
 config FONT_AUTOSELECT
 	def_bool y
 	depends on !FONT_MINI_4x6
diff --git a/lib/fonts/Makefile b/lib/fonts/Makefile
index b7d4765..98245b3 100644
--- a/lib/fonts/Makefile
+++ b/lib/fonts/Makefile
@@ -5,6 +5,7 @@ font-objs := fonts.o
 font-objs-$(CONFIG_FONT_8x16)      += font_8x16.o
 font-objs-$(CONFIG_FONT_7x14)      += font_7x14.o
 font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
+font-objs-$(CONFIG_FONT_CUSTOM_16X)+= font_custom_16x.o
 
 font-objs += $(font-objs-y)
 
diff --git a/lib/fonts/font_7x14.c b/lib/fonts/font_7x14.c
index fe99871..60cb57e 100644
--- a/lib/fonts/font_7x14.c
+++ b/lib/fonts/font_7x14.c
@@ -4113,4 +4113,5 @@ const struct font_desc font_7x14 = {
 	.width	= 7,
 	.height	= 14,
 	.data	= fontdata_7x14,
+	.index	= NULL,
 };
diff --git a/lib/fonts/font_8x16.c b/lib/fonts/font_8x16.c
index 4717ead..0ba2921 100644
--- a/lib/fonts/font_8x16.c
+++ b/lib/fonts/font_8x16.c
@@ -4626,5 +4626,6 @@ const struct font_desc font_vga_8x16 = {
 	.width	= 8,
 	.height	= 16,
 	.data	= fontdata_8x16,
+	.index	= NULL,
 };
 EXPORT_SYMBOL(font_vga_8x16);
diff --git a/lib/fonts/font_custom_16x.c b/lib/fonts/font_custom_16x.c
new file mode 100644
index 0000000..103dbe8
--- /dev/null
+++ b/lib/fonts/font_custom_16x.c
@@ -0,0 +1,44 @@
+/*
+ * by Du Huanpeng <u74147 at gmail.com>
+ */
+
+#include <linux/font.h>
+#include <common.h>
+
+/* place real font data here or set fontdata_custom_16x points to
+ * the address of font data and also setup the index.
+ */
+
+static const unsigned char fontdata_custom_16x[] = {
+	0xFF, 0xFF,	/*OOOOOOOOOOOOOOOO*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0x80, 0x01,	/*O______________O*/
+	0xFF, 0xFF,	/*OOOOOOOOOOOOOOOO*/
+};
+
+static struct font_index fontdata_custom_16x_index[] = {
+	{ 0x0000, 0x0000 },
+};
+
+const struct font_desc font_custom_16x = {
+	.name	= "CUSTOM-16x",
+	.width	= 16,
+	.height	= 16,
+	.data	= fontdata_custom_16x,
+	.index	= fontdata_custom_16x_index,
+	.num_chars = ARRAY_SIZE(fontdata_custom_16x_index),
+
+};
+
diff --git a/lib/fonts/font_mini_4x6.c b/lib/fonts/font_mini_4x6.c
index 3ecb4fb..733d20a 100644
--- a/lib/fonts/font_mini_4x6.c
+++ b/lib/fonts/font_mini_4x6.c
@@ -2152,4 +2152,5 @@ const struct font_desc font_mini_4x6 = {
 	.width	= 4,
 	.height	= 6,
 	.data	= fontdata_mini_4x6,
+	.index	= NULL,
 };
diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c
index 39efb61..6bc2af1 100644
--- a/lib/fonts/fonts.c
+++ b/lib/fonts/fonts.c
@@ -7,6 +7,10 @@
  *	2001 - Documented with DocBook
  *	- Brad Douglas <brad at neruo.com>
  *
+ *	2015 - Add custom font supports
+ *	- Du Huanpeng <u74147 at gmail.com>
+ *
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
@@ -33,6 +37,10 @@ static const struct font_desc *fonts[] = {
 #undef NO_FONTS
 	&font_mini_4x6,
 #endif
+#ifdef CONFIG_FONT_CUSTOM_16X
+#undef NO_FONTS
+	&font_custom_16x,
+#endif
 };
 
 #define num_fonts ARRAY_SIZE(fonts)
@@ -51,6 +59,30 @@ const struct font_desc *find_font_enum(int n)
 	return fonts[n];
 }
 
+int find_font_index(const struct font_desc *font, int ch)
+{
+	int index;
+	if (font->index == NULL) {
+		index  = font->width + 7;
+		index /= 8;
+		index *= font->height;
+		index *= ch;
+	} else {
+		/*
+		* FIXME: use binary search instead!
+		*/
+		index = font->num_chars - 1;
+
+		while (index && font->index[index].wc != ch)
+			index--;
+
+		/* return 0 if not found. */
+		index = font->index->index;
+	}
+
+	return index;
+}
+
 struct param_d *add_param_font(struct device_d *dev,
 		int (*set)(struct param_d *p, void *priv),
 		int (*get)(struct param_d *p, void *priv),
-- 
1.9.1




More information about the barebox mailing list