-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PATCH] fbcon: Console Rotation - Add support to rotate font bitmap
Add support to rotate the font bitmap. To save on processing time, the entire fontdata will be rotated on a console switch, then stored in a buffer private to fbcon. To further save on processing, the fontdata will only be rotated if the font has changed or if the angle of rotation has changed. Only a single copy of the rotated fontdata will be kept. Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
- Loading branch information
Antonino A. Daplas
authored and
Linus Torvalds
committed
Nov 9, 2005
1 parent
9c44e5f
commit 6cc50e1
Showing
4 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* linux/drivers/video/console/fbcon_rotate.c -- Software Rotation | ||
* | ||
* Copyright (C) 2005 Antonino Daplas <adaplas @pol.net> | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file COPYING in the main directory of this archive for | ||
* more details. | ||
*/ | ||
|
||
#include <linux/config.h> | ||
#include <linux/module.h> | ||
#include <linux/string.h> | ||
#include <linux/fb.h> | ||
#include <linux/vt_kern.h> | ||
#include <linux/console.h> | ||
#include <asm/types.h> | ||
#include "fbcon.h" | ||
#include "fbcon_rotate.h" | ||
|
||
static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc, | ||
struct display *p) | ||
{ | ||
struct fbcon_ops *ops = info->fbcon_par; | ||
int len, err = 0; | ||
int s_cellsize, d_cellsize, i; | ||
const u8 *src; | ||
u8 *dst; | ||
|
||
if (vc->vc_font.data == ops->fontdata && | ||
p->con_rotate == ops->cur_rotate) | ||
goto finished; | ||
|
||
src = ops->fontdata = vc->vc_font.data; | ||
ops->cur_rotate = p->con_rotate; | ||
len = (!p->userfont) ? 256 : FNTCHARCNT(src); | ||
s_cellsize = ((vc->vc_font.width + 7)/8) * | ||
vc->vc_font.height; | ||
d_cellsize = s_cellsize; | ||
|
||
if (ops->rotate == FB_ROTATE_CW || | ||
ops->rotate == FB_ROTATE_CCW) | ||
d_cellsize = ((vc->vc_font.height + 7)/8) * | ||
vc->vc_font.width; | ||
|
||
if (info->fbops->fb_sync) | ||
info->fbops->fb_sync(info); | ||
|
||
if (ops->fd_size < d_cellsize * len) { | ||
dst = kmalloc(d_cellsize * len, GFP_KERNEL); | ||
|
||
if (dst == NULL) { | ||
err = -ENOMEM; | ||
goto finished; | ||
} | ||
|
||
ops->fd_size = d_cellsize * len; | ||
kfree(ops->fontbuffer); | ||
ops->fontbuffer = dst; | ||
} | ||
|
||
dst = ops->fontbuffer; | ||
memset(dst, 0, ops->fd_size); | ||
|
||
switch (ops->rotate) { | ||
case FB_ROTATE_UD: | ||
for (i = len; i--; ) { | ||
rotate_ud(src, dst, vc->vc_font.width, | ||
vc->vc_font.height); | ||
|
||
src += s_cellsize; | ||
dst += d_cellsize; | ||
} | ||
break; | ||
case FB_ROTATE_CW: | ||
for (i = len; i--; ) { | ||
rotate_cw(src, dst, vc->vc_font.width, | ||
vc->vc_font.height); | ||
src += s_cellsize; | ||
dst += d_cellsize; | ||
} | ||
break; | ||
case FB_ROTATE_CCW: | ||
for (i = len; i--; ) { | ||
rotate_ccw(src, dst, vc->vc_font.width, | ||
vc->vc_font.height); | ||
src += s_cellsize; | ||
dst += d_cellsize; | ||
} | ||
break; | ||
} | ||
|
||
finished: | ||
return err; | ||
} | ||
|
||
void fbcon_set_rotate(struct fbcon_ops *ops) | ||
{ | ||
ops->rotate_font = fbcon_rotate_font; | ||
} | ||
EXPORT_SYMBOL(fbcon_set_rotate); | ||
|
||
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); | ||
MODULE_DESCRIPTION("Console Rotation Support"); | ||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation | ||
* | ||
* Copyright (C) 2005 Antonino Daplas <adaplas@pol.net> | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file COPYING in the main directory of this archive | ||
* for more details. | ||
*/ | ||
|
||
#ifndef _FBCON_ROTATE_H | ||
#define _FBCON_ROTATE_H | ||
|
||
#define FNTCHARCNT(fd) (((int *)(fd))[-3]) | ||
|
||
#define GETVYRES(s,i) ({ \ | ||
(s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \ | ||
(i)->var.yres : (i)->var.yres_virtual; }) | ||
|
||
#define GETVXRES(s,i) ({ \ | ||
(s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \ | ||
(i)->var.xres : (i)->var.xres_virtual; }) | ||
|
||
/* | ||
* The bitmap is always big endian | ||
*/ | ||
#if defined(__LITTLE_ENDIAN) | ||
#define FBCON_BIT(b) (7 - (b)) | ||
#else | ||
#define FBCON_BIT(b) (b) | ||
#endif | ||
|
||
static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat) | ||
{ | ||
u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; | ||
|
||
pat +=index; | ||
return (test_bit(FBCON_BIT(bit), (void *)pat)); | ||
} | ||
|
||
static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat) | ||
{ | ||
u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; | ||
|
||
pat += index; | ||
set_bit(FBCON_BIT(bit), (void *)pat); | ||
} | ||
|
||
static inline void rotate_ud(const char *in, char *out, u32 width, u32 height) | ||
{ | ||
int i, j; | ||
int shift = width % 8; | ||
|
||
width = (width + 7) & ~7; | ||
|
||
for (i = 0; i < height; i++) { | ||
for (j = 0; j < width; j++) { | ||
if (pattern_test_bit(j, i, width, in)) | ||
pattern_set_bit(width - (1 + j + shift), | ||
height - (1 + i), | ||
width, out); | ||
} | ||
|
||
} | ||
} | ||
|
||
static inline void rotate_cw(const char *in, char *out, u32 width, u32 height) | ||
{ | ||
int i, j, h = height, w = width; | ||
int shift = (8 - (height % 8)) & 7; | ||
|
||
width = (width + 7) & ~7; | ||
height = (height + 7) & ~7; | ||
|
||
for (i = 0; i < h; i++) { | ||
for (j = 0; j < w; j++) { | ||
if (pattern_test_bit(j, i, width, in)) | ||
pattern_set_bit(height - 1 - i - shift, j, | ||
height, out); | ||
|
||
} | ||
} | ||
} | ||
|
||
static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height) | ||
{ | ||
int i, j, h = height, w = width; | ||
int shift = width % 8; | ||
|
||
width = (width + 7) & ~7; | ||
height = (height + 7) & ~7; | ||
|
||
for (i = 0; i < h; i++) { | ||
for (j = 0; j < w; j++) { | ||
if (pattern_test_bit(j, i, width, in)) | ||
pattern_set_bit(i, width - 1 - j - shift, | ||
height, out); | ||
} | ||
} | ||
} | ||
|
||
#endif |