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

Configure Feed

Select the types of activity you want to include in your feed.

lib/fonts: Implement glyph rotation

Move the glyph rotation helpers from fbcon to the font library. Wrap them
behind clean interfaces. Also clear the output memory to zero. Previously,
the implementation relied on the caller to do that.

Go through the fbcon code and callers of the glyph-rotation helpers. In
addition to the font rotation, there's also the cursor code, which uses
the rotation helpers.

The font-rotation relied on a single memset to zero for the whole font.
This is now multiple memsets on each glyph. This will be sorted out when
the font library also implements font rotation.

Building glyph rotation in the font library still depends on
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y. If we get more users of the code,
we can still add a dedicated Kconfig symbol to the font library.

No changes have been made to the actual implementation of the rotate_*()
and pattern_*() functions. These will be refactored as separate changes.

v2:
- fix typos

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>

authored by

Thomas Zimmermann and committed by
Helge Deller
bdfd9432 de0b375b

+167 -83
+2 -2
drivers/video/fbdev/core/fbcon_ccw.c
··· 12 12 #include <linux/slab.h> 13 13 #include <linux/string.h> 14 14 #include <linux/fb.h> 15 + #include <linux/font.h> 15 16 #include <linux/vt_kern.h> 16 17 #include <linux/console.h> 17 18 #include <asm/types.h> ··· 345 344 size = cur_height * width; 346 345 while (size--) 347 346 tmp[i++] = 0xff; 348 - memset(mask, 0, w * vc->vc_font.width); 349 - rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height); 347 + font_glyph_rotate_270(tmp, vc->vc_font.width, vc->vc_font.height, mask); 350 348 kfree(tmp); 351 349 } 352 350
+2 -2
drivers/video/fbdev/core/fbcon_cw.c
··· 12 12 #include <linux/slab.h> 13 13 #include <linux/string.h> 14 14 #include <linux/fb.h> 15 + #include <linux/font.h> 15 16 #include <linux/vt_kern.h> 16 17 #include <linux/console.h> 17 18 #include <asm/types.h> ··· 328 327 size = cur_height * width; 329 328 while (size--) 330 329 tmp[i++] = 0xff; 331 - memset(mask, 0, w * vc->vc_font.width); 332 - rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height); 330 + font_glyph_rotate_90(tmp, vc->vc_font.width, vc->vc_font.height, mask); 333 331 kfree(tmp); 334 332 } 335 333
+4 -8
drivers/video/fbdev/core/fbcon_rotate.c
··· 12 12 #include <linux/slab.h> 13 13 #include <linux/string.h> 14 14 #include <linux/fb.h> 15 + #include <linux/font.h> 15 16 #include <linux/vt_kern.h> 16 17 #include <linux/console.h> 17 18 #include <asm/types.h> ··· 61 60 } 62 61 63 62 dst = par->fontbuffer; 64 - memset(dst, 0, par->fd_size); 65 63 66 64 switch (par->rotate) { 67 65 case FB_ROTATE_UD: 68 66 for (i = len; i--; ) { 69 - rotate_ud(src, dst, vc->vc_font.width, 70 - vc->vc_font.height); 71 - 67 + font_glyph_rotate_180(src, vc->vc_font.width, vc->vc_font.height, dst); 72 68 src += s_cellsize; 73 69 dst += d_cellsize; 74 70 } 75 71 break; 76 72 case FB_ROTATE_CW: 77 73 for (i = len; i--; ) { 78 - rotate_cw(src, dst, vc->vc_font.width, 79 - vc->vc_font.height); 74 + font_glyph_rotate_90(src, vc->vc_font.width, vc->vc_font.height, dst); 80 75 src += s_cellsize; 81 76 dst += d_cellsize; 82 77 } 83 78 break; 84 79 case FB_ROTATE_CCW: 85 80 for (i = len; i--; ) { 86 - rotate_ccw(src, dst, vc->vc_font.width, 87 - vc->vc_font.height); 81 + font_glyph_rotate_270(src, vc->vc_font.width, vc->vc_font.height, dst); 88 82 src += s_cellsize; 89 83 dst += d_cellsize; 90 84 }
-71
drivers/video/fbdev/core/fbcon_rotate.h
··· 19 19 (fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE || !(i)->fix.xpanstep) ? \ 20 20 (i)->var.xres : (i)->var.xres_virtual; }) 21 21 22 - 23 - static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat) 24 - { 25 - u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; 26 - 27 - pat +=index; 28 - return (*pat) & (0x80 >> bit); 29 - } 30 - 31 - static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat) 32 - { 33 - u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; 34 - 35 - pat += index; 36 - 37 - (*pat) |= 0x80 >> bit; 38 - } 39 - 40 - static inline void rotate_ud(const char *in, char *out, u32 width, u32 height) 41 - { 42 - int i, j; 43 - int shift = (8 - (width % 8)) & 7; 44 - 45 - width = (width + 7) & ~7; 46 - 47 - for (i = 0; i < height; i++) { 48 - for (j = 0; j < width - shift; j++) { 49 - if (pattern_test_bit(j, i, width, in)) 50 - pattern_set_bit(width - (1 + j + shift), 51 - height - (1 + i), 52 - width, out); 53 - } 54 - 55 - } 56 - } 57 - 58 - static inline void rotate_cw(const char *in, char *out, u32 width, u32 height) 59 - { 60 - int i, j, h = height, w = width; 61 - int shift = (8 - (height % 8)) & 7; 62 - 63 - width = (width + 7) & ~7; 64 - height = (height + 7) & ~7; 65 - 66 - for (i = 0; i < h; i++) { 67 - for (j = 0; j < w; j++) { 68 - if (pattern_test_bit(j, i, width, in)) 69 - pattern_set_bit(height - 1 - i - shift, j, 70 - height, out); 71 - 72 - } 73 - } 74 - } 75 - 76 - static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height) 77 - { 78 - int i, j, h = height, w = width; 79 - int shift = (8 - (width % 8)) & 7; 80 - 81 - width = (width + 7) & ~7; 82 - height = (height + 7) & ~7; 83 - 84 - for (i = 0; i < h; i++) { 85 - for (j = 0; j < w; j++) { 86 - if (pattern_test_bit(j, i, width, in)) 87 - pattern_set_bit(i, width - 1 - j - shift, 88 - height, out); 89 - } 90 - } 91 - } 92 - 93 22 int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc); 94 23 95 24 #if defined(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION)
+8
include/linux/font.h
··· 104 104 bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs); 105 105 int font_data_export(font_data_t *fd, struct console_font *font, unsigned int vpitch); 106 106 107 + /* font_rotate.c */ 108 + void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsigned int height, 109 + unsigned char *out); 110 + void font_glyph_rotate_180(const unsigned char *glyph, unsigned int width, unsigned int height, 111 + unsigned char *out); 112 + void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsigned int height, 113 + unsigned char *out); 114 + 107 115 /* 108 116 * Font description 109 117 */
+1
lib/fonts/Makefile
··· 2 2 # Font handling 3 3 4 4 font-y := fonts.o 5 + font-$(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION) += font_rotate.o 5 6 6 7 # Built-in fonts; sorted by Family-Size in ascending order 7 8 font-$(CONFIG_FONT_6x8) += font_6x8.o
+150
lib/fonts/font_rotate.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Font rotation 4 + * 5 + * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> 6 + * 7 + * This file is subject to the terms and conditions of the GNU General Public 8 + * License. See the file COPYING in the main directory of this archive for 9 + * more details. 10 + */ 11 + 12 + #include <linux/export.h> 13 + #include <linux/math.h> 14 + #include <linux/string.h> 15 + 16 + #include "font.h" 17 + 18 + static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat) 19 + { 20 + u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; 21 + 22 + pat += index; 23 + return (*pat) & (0x80 >> bit); 24 + } 25 + 26 + static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat) 27 + { 28 + u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; 29 + 30 + pat += index; 31 + 32 + (*pat) |= 0x80 >> bit; 33 + } 34 + 35 + static inline void rotate_cw(const char *in, char *out, u32 width, u32 height) 36 + { 37 + int i, j, h = height, w = width; 38 + int shift = (8 - (height % 8)) & 7; 39 + 40 + width = (width + 7) & ~7; 41 + height = (height + 7) & ~7; 42 + 43 + for (i = 0; i < h; i++) { 44 + for (j = 0; j < w; j++) { 45 + if (pattern_test_bit(j, i, width, in)) 46 + pattern_set_bit(height - 1 - i - shift, j, 47 + height, out); 48 + } 49 + } 50 + } 51 + 52 + /** 53 + * font_glyph_rotate_90 - Rotate a glyph pattern by 90° in clockwise direction 54 + * @glyph: The glyph to rotate 55 + * @width: The glyph width in bits per scanline 56 + * @height: The number of scanlines in the glyph 57 + * @out: The rotated glyph bitmap 58 + * 59 + * The parameters @width and @height refer to the input glyph given in @glyph. 60 + * The caller has to provide the output buffer @out of sufficient size to hold 61 + * the rotated glyph. Rotating by 90° flips the width and height for the output 62 + * glyph. Depending on the glyph pitch, the size of the output glyph can be 63 + * different than the size of the input. Callers have to take this into account 64 + * when allocating the output memory. 65 + */ 66 + void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsigned int height, 67 + unsigned char *out) 68 + { 69 + memset(out, 0, font_glyph_size(height, width)); /* flip width/height */ 70 + 71 + rotate_cw(glyph, out, width, height); 72 + } 73 + EXPORT_SYMBOL_GPL(font_glyph_rotate_90); 74 + 75 + static inline void rotate_ud(const char *in, char *out, u32 width, u32 height) 76 + { 77 + int i, j; 78 + int shift = (8 - (width % 8)) & 7; 79 + 80 + width = (width + 7) & ~7; 81 + 82 + for (i = 0; i < height; i++) { 83 + for (j = 0; j < width - shift; j++) { 84 + if (pattern_test_bit(j, i, width, in)) 85 + pattern_set_bit(width - (1 + j + shift), 86 + height - (1 + i), 87 + width, out); 88 + } 89 + } 90 + } 91 + 92 + /** 93 + * font_glyph_rotate_180 - Rotate a glyph pattern by 180° 94 + * @glyph: The glyph to rotate 95 + * @width: The glyph width in bits per scanline 96 + * @height: The number of scanlines in the glyph 97 + * @out: The rotated glyph bitmap 98 + * 99 + * The parameters @width and @height refer to the input glyph given in @glyph. 100 + * The caller has to provide the output buffer @out of sufficient size to hold 101 + * the rotated glyph. 102 + */ 103 + void font_glyph_rotate_180(const unsigned char *glyph, unsigned int width, unsigned int height, 104 + unsigned char *out) 105 + { 106 + memset(out, 0, font_glyph_size(width, height)); 107 + 108 + rotate_ud(glyph, out, width, height); 109 + } 110 + EXPORT_SYMBOL_GPL(font_glyph_rotate_180); 111 + 112 + static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height) 113 + { 114 + int i, j, h = height, w = width; 115 + int shift = (8 - (width % 8)) & 7; 116 + 117 + width = (width + 7) & ~7; 118 + height = (height + 7) & ~7; 119 + 120 + for (i = 0; i < h; i++) { 121 + for (j = 0; j < w; j++) { 122 + if (pattern_test_bit(j, i, width, in)) 123 + pattern_set_bit(i, width - 1 - j - shift, 124 + height, out); 125 + } 126 + } 127 + } 128 + 129 + /** 130 + * font_glyph_rotate_270 - Rotate a glyph pattern by 270° in clockwise direction 131 + * @glyph: The glyph to rotate 132 + * @width: The glyph width in bits per scanline 133 + * @height: The number of scanlines in the glyph 134 + * @out: The rotated glyph bitmap 135 + * 136 + * The parameters @width and @height refer to the input glyph given in @glyph. 137 + * The caller has to provide the output buffer @out of sufficient size to hold 138 + * the rotated glyph. Rotating by 270° flips the width and height for the output 139 + * glyph. Depending on the glyph pitch, the size of the output glyph can be 140 + * different than the size of the input. Callers have to take this into account 141 + * when allocating the output memory. 142 + */ 143 + void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsigned int height, 144 + unsigned char *out) 145 + { 146 + memset(out, 0, font_glyph_size(height, width)); /* flip width/height */ 147 + 148 + rotate_ccw(glyph, out, width, height); 149 + } 150 + EXPORT_SYMBOL_GPL(font_glyph_rotate_270);