From: Thomas Zimmermann <tzimmermann@suse.de>
To: deller@gmx.de, simona@ffwll.ch
Cc: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org,
sashiko-reviews@lists.linux.dev,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: [PATCH 6/6] fbcon: Handle characters with no glyph defined in a consistent way
Date: Tue, 27 Oct 2026 14:27:21 +0100 [thread overview]
Message-ID: <20261027133646.297856-7-tzimmermann@suse.de> (raw)
In-Reply-To: <20261027133646.297856-1-tzimmermann@suse.de>
Check the result of font_data_glyph_buf() for NULL when drawing the
screen. Fall back to a default value of '\0' for undefined glpyhs. Skip
the character if no fallback exists.
Error checking for fonts has been inconsistent or absent from fbcon.
Most of the drawing code relies on earlier validation in the font-import
code. Some code implements the glyph test by itself. At least all of
fbcon should be consistent in how it handles undefined glyphs.
Calls to font_data_glyph_buf() returning NULL for undefined glyphs make
it easy to handle this special case consistently across fbcon.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/video/fbdev/core/bitblit.c | 27 +++++++++++++++++----------
drivers/video/fbdev/core/fbcon_ccw.c | 12 +++++++++++-
drivers/video/fbdev/core/fbcon_cw.c | 13 +++++++++++--
drivers/video/fbdev/core/fbcon_ud.c | 18 +++++++++++++++++-
4 files changed, 56 insertions(+), 14 deletions(-)
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index b1c90bc29648..e108cd50cb1d 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -80,7 +80,6 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
unsigned char *buf, u8 *dst)
{
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- unsigned int charcnt = vc->vc_font.charcount;
u32 idx = vc->vc_font.width >> 3;
struct fbcon_par *par = info->fbcon_par;
u32 s_pitch = font_glyph_pitch(s_width);
@@ -89,9 +88,12 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
while (cnt--) {
u16 ch = scr_readw(s++) & charmask;
- if (ch >= charcnt)
- ch = 0;
src = font_data_glyph_buf(par->p->fontdata, s_width, s_vpitch, ch);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch, '\0');
+ if (!src)
+ goto next_char;
+ }
if (attr) {
update_attr(buf, src, attr, vc);
@@ -104,7 +106,7 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
image->height);
-
+next_char:
dst += s_pitch;
}
@@ -119,7 +121,6 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
unsigned char *buf, u8 *dst)
{
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- unsigned int charcnt = vc->vc_font.charcount;
u32 shift_low = 0, mod = vc->vc_font.width % 8;
u32 shift_high = 8;
u32 idx = vc->vc_font.width >> 3;
@@ -130,9 +131,12 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
while (cnt--) {
u16 ch = scr_readw(s++) & charmask;
- if (ch >= charcnt)
- ch = 0;
src = font_data_glyph_buf(par->p->fontdata, s_width, s_vpitch, ch);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch, '\0');
+ if (!src)
+ goto next_char;
+ }
if (attr) {
update_attr(buf, src, attr, vc);
@@ -142,6 +146,7 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
image->height, shift_high,
shift_low, mod);
+next_char:
shift_low += mod;
dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
shift_low &= 7;
@@ -271,10 +276,12 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
attribute = get_attribute(info, c);
c &= charmask;
- /* Clamp to font size, same as bit_putcs_aligned() */
- if (c >= vc->vc_font.charcount)
- c = 0;
src = font_data_glyph_buf(par->p->fontdata, width, vpitch, c);
+ if (!src) {
+ src = font_data_glyph_buf(par->p->fontdata, width, vpitch, '\0');
+ if (!src)
+ return;
+ }
if (par->cursor_state.image.data != (const char *)src ||
par->cursor_reset) {
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 9da6c0e41e7a..cbaa75fc1cc1 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -109,6 +109,11 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
while (cnt--) {
src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch,
scr_readw(s--) & charmask);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch, '\0');
+ if (!src)
+ goto next_char;
+ }
if (attr) {
ccw_update_attr(buf, src, attr, vc);
@@ -121,7 +126,7 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
vc->vc_font.width);
-
+next_char:
dst += d_pitch * vc->vc_font.width;
}
@@ -246,6 +251,11 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = font_data_glyph_buf(par->rotated.buf, width, vpitch, c & charmask);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, width, vpitch, c & charmask);
+ if (!src)
+ return;
+ }
if (par->cursor_state.image.data != (const char *)src ||
par->cursor_reset) {
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index 354f40f77bb4..7606ad38c269 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -94,7 +94,11 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
while (cnt--) {
src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch,
scr_readw(s++) & charmask);
-
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch, '\0');
+ if (!src)
+ goto next_char;
+ }
if (attr) {
cw_update_attr(buf, src, attr, vc);
src = buf;
@@ -106,7 +110,7 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
vc->vc_font.width);
-
+next_char:
dst += d_pitch * vc->vc_font.width;
}
@@ -229,6 +233,11 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = font_data_glyph_buf(par->rotated.buf, width, vpitch, c & charmask);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, width, vpitch, '\0');
+ if (!src)
+ return;
+ }
if (par->cursor_state.image.data != (const char *)src ||
par->cursor_reset) {
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index 01f45eaa2013..bdba3a959d1e 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -96,6 +96,11 @@ static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
while (cnt--) {
src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch,
scr_readw(s--) & charmask);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch, '\0');
+ if (!src)
+ goto next_char;
+ }
if (attr) {
ud_update_attr(buf, src, attr, vc);
@@ -108,7 +113,7 @@ static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
else
fb_pad_aligned_buffer(dst, d_pitch, src, idx,
image->height);
-
+next_char:
dst += s_pitch;
}
@@ -133,6 +138,11 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,
while (cnt--) {
src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch,
scr_readw(s--) & charmask);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, s_width, s_vpitch, '\0');
+ if (!src)
+ goto next_char;
+ }
if (attr) {
ud_update_attr(buf, src, attr, vc);
@@ -142,6 +152,7 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,
fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
image->height, shift_high,
shift_low, mod);
+next_char:
shift_low += mod;
dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
shift_low &= 7;
@@ -279,6 +290,11 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = font_data_glyph_buf(par->rotated.buf, width, vpitch, c & charmask);
+ if (!src) {
+ src = font_data_glyph_buf(par->rotated.buf, width, vpitch, '\0');
+ if (!src)
+ return;
+ }
if (par->cursor_state.image.data != (const char *)src ||
par->cursor_reset) {
--
2.56.0
prev parent reply other threads:[~2026-10-27 13:36 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 13:27 [PATCH 0/6] fbcon: Clean up glyph handling on redraws Thomas Zimmermann
2026-10-27 13:27 ` [PATCH 1/6] fbcon: Use unsigned char for glyph data Thomas Zimmermann
2026-10-27 13:27 ` [PATCH 2/6] lib/fonts: Provide internal helpers for allocating font_data_t Thomas Zimmermann
2026-10-27 13:27 ` [PATCH 3/6] lib/fonts, fbcon: Use font_data_t for rotated fonts Thomas Zimmermann
2026-10-27 13:27 ` [PATCH 4/6] fbcon: Refactor size calculation for cursor buffers Thomas Zimmermann
2026-10-27 13:27 ` [PATCH 5/6] fbcon: Look up glyphs using the font interface Thomas Zimmermann
2026-10-27 13:27 ` Thomas Zimmermann [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261027133646.297856-7-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=deller@gmx.de \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=simona@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox