From 02db4ec9027889ee1c0933740c6766a4b6e14b98 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Tue, 7 Mar 2023 13:21:12 +0300 Subject: video console: add support for fonts wider than 1 byte Devices with high ppi may benefit from wider fonts. Current width implementation is limited by 1 byte, i.e. 8 bits. New version iterates VIDEO_FONT_BYTE_WIDTH times, to process all width bytes, thus allowing fonts wider than 1 byte. Signed-off-by: Dzmitry Sankouski Reviewed-by: Simon Glass --- drivers/video/console_core.c | 84 ++++++++++++++++++++++++------------- drivers/video/console_normal.c | 2 +- drivers/video/console_rotate.c | 6 +-- drivers/video/vidconsole_internal.h | 1 + 4 files changed, 59 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 9c2e4cb4ea5..de004f585c4 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -45,7 +45,7 @@ inline void fill_pixel_and_goto_next(void **dstp, u32 value, int pbytes, int ste int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vid_priv, bool direction) { - int step, line_step, pbytes, ret; + int step, line_step, pbytes, bitcount, width_remainder, ret; void *dst; ret = check_bpix_support(vid_priv->bpix); @@ -61,23 +61,36 @@ int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vid_priv, line_step = vid_priv->line_length; } + width_remainder = VIDEO_FONT_WIDTH % 8; for (int row = 0; row < VIDEO_FONT_HEIGHT; row++) { + uchar bits; + + bitcount = 8; dst = *line; - uchar bits = pfont[row]; - - for (int i = 0; i < VIDEO_FONT_WIDTH; i++) { - u32 value = (bits & 0x80) ? - vid_priv->colour_fg : - vid_priv->colour_bg; - - fill_pixel_and_goto_next(&dst, - value, - pbytes, - step - ); - bits <<= 1; + for (int col = 0; col < VIDEO_FONT_BYTE_WIDTH; col++) { + if (width_remainder) { + bool is_last_iteration = (VIDEO_FONT_BYTE_WIDTH - col == 1); + + if (is_last_iteration) + bitcount = width_remainder; + } + bits = pfont[col]; + + for (int bit = 0; bit < bitcount; bit++) { + u32 value = (bits & 0x80) ? + vid_priv->colour_fg : + vid_priv->colour_bg; + + fill_pixel_and_goto_next(&dst, + value, + pbytes, + step + ); + bits <<= 1; + } } *line += line_step; + pfont += VIDEO_FONT_BYTE_WIDTH; } return ret; } @@ -85,9 +98,9 @@ int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vid_priv, int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_priv, bool direction) { - int step, line_step, pbytes, ret; + int step, line_step, pbytes, bitcount = 8, width_remainder, ret; void *dst; - u8 mask = 0x80; + u8 mask; ret = check_bpix_support(vid_priv->bpix); if (ret) @@ -101,21 +114,32 @@ int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_pri step = pbytes; line_step = -vid_priv->line_length; } - for (int col = 0; col < VIDEO_FONT_WIDTH; col++) { - dst = *line; - for (int row = 0; row < VIDEO_FONT_HEIGHT; row++) { - u32 value = (pfont[row * VIDEO_FONT_BYTE_WIDTH] & mask) ? - vid_priv->colour_fg : - vid_priv->colour_bg; - - fill_pixel_and_goto_next(&dst, - value, - pbytes, - step - ); + + width_remainder = VIDEO_FONT_WIDTH % 8; + for (int col = 0; col < VIDEO_FONT_BYTE_WIDTH; col++) { + mask = 0x80; + if (width_remainder) { + bool is_last_iteration = (VIDEO_FONT_BYTE_WIDTH - col == 1); + + if (is_last_iteration) + bitcount = width_remainder; + } + for (int bit = 0; bit < bitcount; bit++) { + dst = *line; + for (int row = 0; row < VIDEO_FONT_HEIGHT; row++) { + u32 value = (pfont[row * VIDEO_FONT_BYTE_WIDTH] & mask) ? + vid_priv->colour_fg : + vid_priv->colour_bg; + + fill_pixel_and_goto_next(&dst, + value, + pbytes, + step + ); + } + *line += line_step; + mask >>= 1; } - *line += line_step; - mask >>= 1; } return ret; } diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 57186bedd86..e499e64852b 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -67,7 +67,7 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, char ch) int pbytes = VNBYTES(vid_priv->bpix); int x, linenum, ret; void *start, *line; - uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_CHAR_PIXEL_BYTES; if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) return -EAGAIN; diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index 70cc62d1781..64e2f12c2fe 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -71,7 +71,7 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch) int pbytes = VNBYTES(vid_priv->bpix); int x, linenum, ret; void *start, *line; - uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_CHAR_PIXEL_BYTES; if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) return -EAGAIN; @@ -142,7 +142,7 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch) int pbytes = VNBYTES(vid_priv->bpix); int linenum, x, ret; void *start, *line; - uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_CHAR_PIXEL_BYTES; if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) return -EAGAIN; @@ -217,7 +217,7 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch) int pbytes = VNBYTES(vid_priv->bpix); int linenum, x, ret; void *start, *line; - uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_CHAR_PIXEL_BYTES; if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) return -EAGAIN; diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index 0dfcd402c54..c7bc3870352 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -9,6 +9,7 @@ #include /* Get font data, width and height */ #define VIDEO_FONT_BYTE_WIDTH ((VIDEO_FONT_WIDTH / 8) + (VIDEO_FONT_WIDTH % 8 > 0)) +#define VIDEO_FONT_CHAR_PIXEL_BYTES (VIDEO_FONT_HEIGHT * VIDEO_FONT_BYTE_WIDTH) #define FLIPPED_DIRECTION 1 #define NORMAL_DIRECTION 0 -- cgit v1.2.3