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); 151