Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fbcon: Increase maximum font width x height to 64 x 128

By using bitmaps we actually support whatever size we would want, but
the console currently limits fonts to 64x128 (which gives 60x16 text on
4k screens), so we don't need more for now, and we can easily increase
later.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Helge Deller <deller@gmx.de>

authored by

Samuel Thibault and committed by
Helge Deller
15260979 bc87bb34

+89 -45
+1 -1
drivers/firmware/efi/earlycon.c
··· 252 252 if (si->lfb_depth != 32) 253 253 return -ENODEV; 254 254 255 - font = get_default_font(xres, yres, -1, -1); 255 + font = get_default_font(xres, yres, NULL, NULL); 256 256 if (!font) 257 257 return -ENODEV; 258 258
+11 -4
drivers/video/fbdev/arkfb.c
··· 622 622 info->tileops = NULL; 623 623 624 624 /* in 4bpp supports 8p wide tiles only, any tiles otherwise */ 625 - info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0); 626 - info->pixmap.blit_y = ~(u32)0; 625 + if (bpp == 4) { 626 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 627 + set_bit(8 - 1, info->pixmap.blit_x); 628 + } else { 629 + bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 630 + } 631 + bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 627 632 628 633 offset_value = (info->var.xres_virtual * bpp) / 64; 629 634 screen_size = info->var.yres_virtual * info->fix.line_length; ··· 640 635 info->tileops = &arkfb_tile_ops; 641 636 642 637 /* supports 8x16 tiles only */ 643 - info->pixmap.blit_x = 1 << (8 - 1); 644 - info->pixmap.blit_y = 1 << (16 - 1); 638 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 639 + set_bit(8 - 1, info->pixmap.blit_x); 640 + bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 641 + set_bit(16 - 1, info->pixmap.blit_y); 645 642 646 643 offset_value = info->var.xres_virtual / 16; 647 644 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
+9 -7
drivers/video/fbdev/core/fbcon.c
··· 2485 2485 h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres)) 2486 2486 return -EINVAL; 2487 2487 2488 - if (font->width > 32 || font->height > 32) 2488 + if (font->width > FB_MAX_BLIT_WIDTH || font->height > FB_MAX_BLIT_HEIGHT) 2489 2489 return -EINVAL; 2490 2490 2491 2491 /* Make sure drawing engine can handle the font */ 2492 - if (!(info->pixmap.blit_x & BIT(font->width - 1)) || 2493 - !(info->pixmap.blit_y & BIT(font->height - 1))) 2492 + if (!test_bit(font->width - 1, info->pixmap.blit_x) || 2493 + !test_bit(font->height - 1, info->pixmap.blit_y)) 2494 2494 return -EINVAL; 2495 2495 2496 2496 /* Make sure driver can handle the font length */ ··· 3084 3084 vc = vc_cons[i].d; 3085 3085 if (vc && vc->vc_mode == KD_TEXT && 3086 3086 info->node == con2fb_map[i]) { 3087 - caps->x |= 1 << (vc->vc_font.width - 1); 3088 - caps->y |= 1 << (vc->vc_font.height - 1); 3087 + set_bit(vc->vc_font.width - 1, caps->x); 3088 + set_bit(vc->vc_font.height - 1, caps->y); 3089 3089 charcnt = vc->vc_font.charcount; 3090 3090 if (caps->len < charcnt) 3091 3091 caps->len = charcnt; ··· 3096 3096 3097 3097 if (vc && vc->vc_mode == KD_TEXT && 3098 3098 info->node == con2fb_map[fg_console]) { 3099 - caps->x = 1 << (vc->vc_font.width - 1); 3100 - caps->y = 1 << (vc->vc_font.height - 1); 3099 + bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH); 3100 + set_bit(vc->vc_font.width - 1, caps->x); 3101 + bitmap_zero(caps->y, FB_MAX_BLIT_HEIGHT); 3102 + set_bit(vc->vc_font.height - 1, caps->y); 3101 3103 caps->len = vc->vc_font.charcount; 3102 3104 } 3103 3105 }
+6 -6
drivers/video/fbdev/core/fbmem.c
··· 212 212 fbcon_get_requirement(info, &caps); 213 213 info->fbops->fb_get_caps(info, &fbcaps, var); 214 214 215 - if (((fbcaps.x ^ caps.x) & caps.x) || 216 - ((fbcaps.y ^ caps.y) & caps.y) || 215 + if (!bitmap_subset(caps.x, fbcaps.x, FB_MAX_BLIT_WIDTH) || 216 + !bitmap_subset(caps.y, fbcaps.y, FB_MAX_BLIT_HEIGHT) || 217 217 (fbcaps.len < caps.len)) 218 218 err = -EINVAL; 219 219 ··· 420 420 } 421 421 fb_info->pixmap.offset = 0; 422 422 423 - if (!fb_info->pixmap.blit_x) 424 - fb_info->pixmap.blit_x = ~(u32)0; 423 + if (bitmap_empty(fb_info->pixmap.blit_x, FB_MAX_BLIT_WIDTH)) 424 + bitmap_fill(fb_info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 425 425 426 - if (!fb_info->pixmap.blit_y) 427 - fb_info->pixmap.blit_y = ~(u32)0; 426 + if (bitmap_empty(fb_info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT)) 427 + bitmap_fill(fb_info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 428 428 429 429 if (!fb_info->modelist.prev || !fb_info->modelist.next) 430 430 INIT_LIST_HEAD(&fb_info->modelist);
+11 -4
drivers/video/fbdev/core/svgalib.c
··· 354 354 { 355 355 if (var->bits_per_pixel == 0) { 356 356 /* can only support 256 8x16 bitmap */ 357 - caps->x = 1 << (8 - 1); 358 - caps->y = 1 << (16 - 1); 357 + bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH); 358 + set_bit(8 - 1, caps->x); 359 + bitmap_zero(caps->y, FB_MAX_BLIT_HEIGHT); 360 + set_bit(16 - 1, caps->y); 359 361 caps->len = 256; 360 362 } else { 361 - caps->x = (var->bits_per_pixel == 4) ? 1 << (8 - 1) : ~(u32)0; 362 - caps->y = ~(u32)0; 363 + if (var->bits_per_pixel == 4) { 364 + bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH); 365 + set_bit(8 - 1, caps->x); 366 + } else { 367 + bitmap_fill(caps->x, FB_MAX_BLIT_WIDTH); 368 + } 369 + bitmap_fill(caps->y, FB_MAX_BLIT_HEIGHT); 363 370 caps->len = ~(u32)0; 364 371 } 365 372 }
+11 -4
drivers/video/fbdev/s3fb.c
··· 617 617 info->tileops = NULL; 618 618 619 619 /* in 4bpp supports 8p wide tiles only, any tiles otherwise */ 620 - info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0); 621 - info->pixmap.blit_y = ~(u32)0; 620 + if (bpp == 4) { 621 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 622 + set_bit(8 - 1, info->pixmap.blit_x); 623 + } else { 624 + bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 625 + } 626 + bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 622 627 623 628 offset_value = (info->var.xres_virtual * bpp) / 64; 624 629 screen_size = info->var.yres_virtual * info->fix.line_length; ··· 635 630 info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops; 636 631 637 632 /* supports 8x16 tiles only */ 638 - info->pixmap.blit_x = 1 << (8 - 1); 639 - info->pixmap.blit_y = 1 << (16 - 1); 633 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 634 + set_bit(8 - 1, info->pixmap.blit_x); 635 + bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 636 + set_bit(16 - 1, info->pixmap.blit_y); 640 637 641 638 offset_value = info->var.xres_virtual / 16; 642 639 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
+5 -1
drivers/video/fbdev/vga16fb.c
··· 1353 1353 info->var = vga16fb_defined; 1354 1354 info->fix = vga16fb_fix; 1355 1355 /* supports rectangles with widths of multiples of 8 */ 1356 - info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31; 1356 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 1357 + set_bit(8 - 1, info->pixmap.blit_x); 1358 + set_bit(16 - 1, info->pixmap.blit_x); 1359 + set_bit(24 - 1, info->pixmap.blit_x); 1360 + set_bit(32 - 1, info->pixmap.blit_x); 1357 1361 info->flags = FBINFO_HWACCEL_YPAN; 1358 1362 1359 1363 i = (info->var.bits_per_pixel == 8) ? 256 : 16;
+11 -4
drivers/video/fbdev/vt8623fb.c
··· 390 390 info->tileops = NULL; 391 391 392 392 /* in 4bpp supports 8p wide tiles only, any tiles otherwise */ 393 - info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0); 394 - info->pixmap.blit_y = ~(u32)0; 393 + if (bpp == 4) { 394 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 395 + set_bit(8 - 1, info->pixmap.blit_x); 396 + } else { 397 + bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 398 + } 399 + bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 395 400 396 401 offset_value = (info->var.xres_virtual * bpp) / 64; 397 402 fetch_value = ((info->var.xres * bpp) / 128) + 4; ··· 413 408 info->tileops = &vt8623fb_tile_ops; 414 409 415 410 /* supports 8x16 tiles only */ 416 - info->pixmap.blit_x = 1 << (8 - 1); 417 - info->pixmap.blit_y = 1 << (16 - 1); 411 + bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH); 412 + set_bit(8 - 1, info->pixmap.blit_x); 413 + bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT); 414 + set_bit(16 - 1, info->pixmap.blit_y); 418 415 419 416 offset_value = info->var.xres_virtual / 16; 420 417 fetch_value = (info->var.xres / 8) + 8;
+1 -1
drivers/video/sticore.c
··· 529 529 if (fbfont_name && strlen(fbfont_name)) 530 530 fbfont = find_font(fbfont_name); 531 531 if (!fbfont) 532 - fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0); 532 + fbfont = get_default_font(1024, 768, NULL, NULL); 533 533 if (!fbfont) 534 534 return NULL; 535 535
+12 -6
include/linux/fb.h
··· 143 143 void *data; 144 144 }; 145 145 146 + /* Enough for the VT console needs, see its max_font_width/height */ 147 + #define FB_MAX_BLIT_WIDTH 64 148 + #define FB_MAX_BLIT_HEIGHT 128 149 + 146 150 struct fb_blit_caps { 147 - u32 x; 148 - u32 y; 151 + DECLARE_BITMAP(x, FB_MAX_BLIT_WIDTH); 152 + DECLARE_BITMAP(y, FB_MAX_BLIT_HEIGHT); 149 153 u32 len; 150 154 u32 flags; 151 155 }; ··· 196 192 u32 scan_align; /* alignment per scanline */ 197 193 u32 access_align; /* alignment per read/write (bits) */ 198 194 u32 flags; /* see FB_PIXMAP_* */ 199 - u32 blit_x; /* supported bit block dimensions (1-32)*/ 200 - u32 blit_y; /* Format: blit_x = 1 << (width - 1) */ 201 - /* blit_y = 1 << (height - 1) */ 202 - /* if 0, will be set to 0xffffffff (all)*/ 195 + /* supported bit block dimensions */ 196 + /* Format: test_bit(width - 1, blit_x) */ 197 + /* test_bit(height - 1, blit_y) */ 198 + /* if zero, will be set to full (all) */ 199 + DECLARE_BITMAP(blit_x, FB_MAX_BLIT_WIDTH); 200 + DECLARE_BITMAP(blit_y, FB_MAX_BLIT_HEIGHT); 203 201 /* access methods */ 204 202 void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size); 205 203 void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size);
+2 -1
include/linux/font.h
··· 57 57 /* Get the default font for a specific screen size */ 58 58 59 59 extern const struct font_desc *get_default_font(int xres, int yres, 60 - u32 font_w, u32 font_h); 60 + unsigned long *font_w, 61 + unsigned long *font_h); 61 62 62 63 /* Max. length for the name of a predefined font */ 63 64 #define MAX_FONT_NAME 32
+9 -6
lib/fonts/fonts.c
··· 96 96 * get_default_font - get default font 97 97 * @xres: screen size of X 98 98 * @yres: screen size of Y 99 - * @font_w: bit array of supported widths (1 - 32) 100 - * @font_h: bit array of supported heights (1 - 32) 99 + * @font_w: bit array of supported widths (1 - FB_MAX_BLIT_WIDTH) 100 + * @font_h: bit array of supported heights (1 - FB_MAX_BLIT_HEIGHT) 101 101 * 102 102 * Get the default font for a specified screen size. 103 103 * Dimensions are in pixels. 104 + * 105 + * font_w or font_h being NULL means all values are supported. 104 106 * 105 107 * Returns %NULL if no font is found, or a pointer to the 106 108 * chosen font. 107 109 * 108 110 */ 109 - const struct font_desc *get_default_font(int xres, int yres, u32 font_w, 110 - u32 font_h) 111 + const struct font_desc *get_default_font(int xres, int yres, 112 + unsigned long *font_w, 113 + unsigned long *font_h) 111 114 { 112 115 int i, c, cc, res; 113 116 const struct font_desc *f, *g; ··· 138 135 if (res > 20) 139 136 c += 20 - res; 140 137 141 - if ((font_w & (1U << (f->width - 1))) && 142 - (font_h & (1U << (f->height - 1)))) 138 + if ((!font_w || test_bit(f->width - 1, font_w)) && 139 + (!font_h || test_bit(f->height - 1, font_h))) 143 140 c += 1000; 144 141 145 142 if (c > cc) {