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 <dsankou...@gmail.com> --- Charges for v2: - replace TAIL_BIT_COUNT macro with c code - rename refactoring Charges for v3: none drivers/video/console_simple.c | 93 +++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/drivers/video/console_simple.c b/drivers/video/console_simple.c index 1eb47be449..cdc26cac30 100644 --- a/drivers/video/console_simple.c +++ b/drivers/video/console_simple.c @@ -13,6 +13,7 @@ #include <video_font.h> /* 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 @@ -95,9 +96,9 @@ static inline void fill_pixel_and_goto_next(void **dstp, u32 value, int pbytes, static 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) @@ -111,21 +112,32 @@ static int fill_char_horizontally(uchar *pfont, void **line, struct video_priv * 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; } @@ -158,7 +170,7 @@ static int fill_char_horizontally(uchar *pfont, void **line, struct video_priv * static 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); @@ -174,23 +186,36 @@ static int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vi 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; } @@ -249,7 +274,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; @@ -358,7 +383,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; @@ -429,7 +454,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; @@ -504,7 +529,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; -- 2.30.2