]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
lib/fonts: Provide helpers for calculating glyph pitch and size
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 7 Apr 2026 09:23:14 +0000 (11:23 +0200)
committerHelge Deller <deller@gmx.de>
Tue, 7 Apr 2026 15:38:07 +0000 (17:38 +0200)
Implement pitch and size calculation for a single font glyph in the
new helpers font_glyph_pitch() and font_glyph_size(). Replace the
instances where the calculations are open-coded.

Note that in the case of fbcon console rotation, the parameters for
a glyph's width and height might be reversed. This is intentional.

v2:
- fix typos in commit message

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
drivers/tty/vt/vt.c
drivers/video/fbdev/core/fbcon_ccw.c
drivers/video/fbdev/core/fbcon_cw.c
drivers/video/fbdev/core/fbcon_rotate.c
drivers/video/fbdev/core/fbcon_ud.c
include/linux/font.h
lib/fonts/fonts.c

index 3c90856488cdcce82b8bc86fae9eb65aaf54dceb..5c9fec4f99a0a37682ddcb0b0707a48067a94325 100644 (file)
@@ -71,7 +71,6 @@
  * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
  */
 
-#include <linux/math.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/sched/signal.h>
@@ -244,7 +243,7 @@ enum {
  */
 unsigned int vc_font_pitch(const struct vc_font *font)
 {
-       return DIV_ROUND_UP(font->width, 8);
+       return font_glyph_pitch(font->width);
 }
 EXPORT_SYMBOL_GPL(vc_font_pitch);
 
@@ -261,7 +260,7 @@ EXPORT_SYMBOL_GPL(vc_font_pitch);
  */
 unsigned int vc_font_size(const struct vc_font *font)
 {
-       return font->height * vc_font_pitch(font) * font->charcount;
+       return font_glyph_size(font->width, font->height) * font->charcount;
 }
 EXPORT_SYMBOL_GPL(vc_font_size);
 
index 2f394b5a17f79610f18746f45d093ef5ea2775c6..96ef449ee6ac8b929f79ddc1312991736417d1ca 100644 (file)
@@ -26,7 +26,7 @@ static void ccw_update_attr(u8 *dst, u8 *src, int attribute,
                                  struct vc_data *vc)
 {
        int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
-       int width = (vc->vc_font.height + 7) >> 3;
+       int width = font_glyph_pitch(vc->vc_font.height);
        int mod = vc->vc_font.height % 8;
        u8 c, msk = ~(0xff << offset), msk1 = 0;
 
@@ -101,7 +101,7 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
 {
        struct fbcon_par *par = info->fbcon_par;
        u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-       u32 idx = (vc->vc_font.height + 7) >> 3;
+       u32 idx = font_glyph_pitch(vc->vc_font.height);
        u8 *src;
 
        while (cnt--) {
@@ -131,7 +131,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
 {
        struct fb_image image;
        struct fbcon_par *par = info->fbcon_par;
-       u32 width = (vc->vc_font.height + 7)/8;
+       u32 width = font_glyph_pitch(vc->vc_font.height);
        u32 cellsize = width * vc->vc_font.width;
        u32 maxcnt = info->pixmap.size/cellsize;
        u32 scan_align = info->pixmap.scan_align - 1;
@@ -223,7 +223,8 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
        struct fb_cursor cursor;
        struct fbcon_par *par = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-       int w = (vc->vc_font.height + 7) >> 3, c;
+       int w = font_glyph_pitch(vc->vc_font.height);
+       int c;
        int y = real_y(par->p, vc->state.y);
        int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
        int err = 1, dx, dy;
@@ -297,7 +298,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
                char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
                                                 GFP_ATOMIC);
                int cur_height, size, i = 0;
-               int width = (vc->vc_font.width + 7)/8;
+               int width = font_glyph_pitch(vc->vc_font.width);
 
                if (!mask)
                        return;
index 3c3ad3471ec4b7092457807d816566559c89e217..ea712654edae31952307e2efc442014c62a7122d 100644 (file)
@@ -26,7 +26,7 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute,
                                  struct vc_data *vc)
 {
        int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
-       int width = (vc->vc_font.height + 7) >> 3;
+       int width = font_glyph_pitch(vc->vc_font.height);
        u8 c, msk = ~(0xff >> offset);
 
        for (i = 0; i < vc->vc_font.width; i++) {
@@ -86,7 +86,7 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
 {
        struct fbcon_par *par = info->fbcon_par;
        u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-       u32 idx = (vc->vc_font.height + 7) >> 3;
+       u32 idx = font_glyph_pitch(vc->vc_font.height);
        u8 *src;
 
        while (cnt--) {
@@ -116,7 +116,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
 {
        struct fb_image image;
        struct fbcon_par *par = info->fbcon_par;
-       u32 width = (vc->vc_font.height + 7)/8;
+       u32 width = font_glyph_pitch(vc->vc_font.height);
        u32 cellsize = width * vc->vc_font.width;
        u32 maxcnt = info->pixmap.size/cellsize;
        u32 scan_align = info->pixmap.scan_align - 1;
@@ -206,7 +206,8 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
        struct fb_cursor cursor;
        struct fbcon_par *par = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-       int w = (vc->vc_font.height + 7) >> 3, c;
+       int w = font_glyph_pitch(vc->vc_font.height);
+       int c;
        int y = real_y(par->p, vc->state.y);
        int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
        int err = 1, dx, dy;
@@ -280,7 +281,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
                char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
                                                 GFP_ATOMIC);
                int cur_height, size, i = 0;
-               int width = (vc->vc_font.width + 7)/8;
+               int width = font_glyph_pitch(vc->vc_font.width);
 
                if (!mask)
                        return;
index 5348f6c6f57c7c3fbeee344d5b2410c54a3bf968..18575c5182db33078131366c5ab6e557df9ca2ba 100644 (file)
@@ -33,14 +33,12 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
        src = par->fontdata = vc->vc_font.data;
        par->cur_rotate = par->p->con_rotate;
        len = vc->vc_font.charcount;
-       s_cellsize = ((vc->vc_font.width + 7)/8) *
-               vc->vc_font.height;
+       s_cellsize = font_glyph_size(vc->vc_font.width, vc->vc_font.height);
        d_cellsize = s_cellsize;
 
        if (par->rotate == FB_ROTATE_CW ||
            par->rotate == FB_ROTATE_CCW)
-               d_cellsize = ((vc->vc_font.height + 7)/8) *
-                       vc->vc_font.width;
+               d_cellsize = font_glyph_size(vc->vc_font.height, vc->vc_font.width);
 
        if (info->fbops->fb_sync)
                info->fbops->fb_sync(info);
index 6fc30cad5b19b23c9cf479eb98775d7244b57fb7..f7cd89c42b01c58afc2444bffa05f8ae122f638a 100644 (file)
@@ -26,7 +26,7 @@ static void ud_update_attr(u8 *dst, u8 *src, int attribute,
                                  struct vc_data *vc)
 {
        int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
-       int width = (vc->vc_font.width + 7) >> 3;
+       int width = font_glyph_pitch(vc->vc_font.width);
        unsigned int cellsize = vc->vc_font.height * width;
        u8 c;
 
@@ -153,7 +153,7 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
 {
        struct fb_image image;
        struct fbcon_par *par = info->fbcon_par;
-       u32 width = (vc->vc_font.width + 7)/8;
+       u32 width = font_glyph_pitch(vc->vc_font.width);
        u32 cellsize = width * vc->vc_font.height;
        u32 maxcnt = info->pixmap.size/cellsize;
        u32 scan_align = info->pixmap.scan_align - 1;
@@ -253,7 +253,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
        struct fb_cursor cursor;
        struct fbcon_par *par = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-       int w = (vc->vc_font.width + 7) >> 3, c;
+       int w = font_glyph_pitch(vc->vc_font.width);
+       int c;
        int y = real_y(par->p, vc->state.y);
        int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
        int err = 1, dx, dy;
index 5401f07dd6ce82760b3ec749dfb8dc91c44b593a..3bd49d914b22f0bc83cc5656a74a64ad56ae053a 100644 (file)
 #ifndef _VIDEO_FONT_H
 #define _VIDEO_FONT_H
 
+#include <linux/math.h>
 #include <linux/types.h>
 
 struct console_font;
 
+/*
+ * Glyphs
+ */
+
+/**
+ * font_glyph_pitch - Calculates the number of bytes per scanline
+ * @width: The glyph width in bits per scanline
+ *
+ * A glyph's pitch is the number of bytes in a single scanline, rounded
+ * up to the next full byte. The parameter @width receives the number
+ * of visible bits per scanline. For example, if width is 14 bytes per
+ * scanline, the pitch is 2 bytes per scanline. If width is 8 bits per
+ * scanline, the pitch is 1 byte per scanline.
+ *
+ * Returns:
+ * The number of bytes in a single scanline of the glyph
+ */
+static inline unsigned int font_glyph_pitch(unsigned int width)
+{
+       return DIV_ROUND_UP(width, 8);
+}
+
+/**
+ * font_glyph_size - Calculates the number of bytes per glyph
+ * @width: The glyph width in bits per scanline
+ * @vpitch: The number of scanlines in the glyph
+ *
+ * The number of bytes in a glyph depends on the pitch and the number
+ * of scanlines. font_glyph_size automatically calculates the pitch
+ * from the given width. The parameter @vpitch gives the number of
+ * scanlines, which is usually the glyph's height in scanlines. Fonts
+ * coming from user space can sometimes have a different vertical pitch
+ * with empty scanlines between two adjacent glyphs.
+ */
+static inline unsigned int font_glyph_size(unsigned int width, unsigned int vpitch)
+{
+       return font_glyph_pitch(width) * vpitch;
+}
+
 /*
  * font_data_t and helpers
  */
index 5938f542906b00448e80db288cb7fda4741a7f36..f5d5333450a028a231684c1bf661de8f903b33da 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "font.h"
 
-#define console_font_pitch(font) DIV_ROUND_UP((font)->width, 8)
+#define console_font_pitch(font) font_glyph_pitch((font)->width)
 
 /*
  * Helpers for font_data_t