mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-30 17:40:16 +02:00
kernel-3.0: add fbcon color fonts patch
This commit is contained in:
parent
bfd462568f
commit
87387eb5b1
300
target/linux/xburst/patches-3.0/0030-fbcon-color-fonts.patch
Normal file
300
target/linux/xburst/patches-3.0/0030-fbcon-color-fonts.patch
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
--- a/drivers/tty/vt/vt.c
|
||||||
|
+++ b/drivers/tty/vt/vt.c
|
||||||
|
@@ -4034,6 +4034,7 @@ static int con_font_set(struct vc_data *
|
||||||
|
struct console_font font;
|
||||||
|
int rc = -EINVAL;
|
||||||
|
int size;
|
||||||
|
+ u8 std_font = *((u32*)op->data) != 0x6a127efd;
|
||||||
|
|
||||||
|
if (vc->vc_mode != KD_TEXT)
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -4063,7 +4064,7 @@ static int con_font_set(struct vc_data *
|
||||||
|
}
|
||||||
|
if (op->width <= 0 || op->width > 32 || op->height > 32)
|
||||||
|
return -EINVAL;
|
||||||
|
- size = (op->width+7)/8 * 32 * op->charcount;
|
||||||
|
+ size = ( std_font ? (op->width+7)/8 * 32 : 4 * op->width * op->height) * op->charcount;
|
||||||
|
if (size > max_font_size)
|
||||||
|
return -ENOSPC;
|
||||||
|
font.charcount = op->charcount;
|
||||||
|
--- a/drivers/video/console/bitblit.c
|
||||||
|
+++ b/drivers/video/console/bitblit.c
|
||||||
|
@@ -105,6 +105,12 @@ static inline void bit_putcs_aligned(str
|
||||||
|
info->fbops->fb_imageblit(info, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* info: details of the framebuffer
|
||||||
|
+ * image: the off-screen image in which the character (sub)string is being
|
||||||
|
+ * prepared
|
||||||
|
+ * dst: a pointer to the top-left pixel in the off-screen image where the
|
||||||
|
+ * character (sub)string should go
|
||||||
|
+ */
|
||||||
|
static inline void bit_putcs_unaligned(struct vc_data *vc,
|
||||||
|
struct fb_info *info, const u16 *s,
|
||||||
|
u32 attr, u32 cnt, u32 d_pitch,
|
||||||
|
@@ -140,12 +146,62 @@ static inline void bit_putcs_unaligned(s
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+void inline draw_glyph_row_inv( int pixels_across_glyph, u8 *src, u8 *target) {
|
||||||
|
+ u32 *pixel_on_glyph_sheet = (u32*) src;
|
||||||
|
+ u32 *pixel_on_screen = (u32*) target;
|
||||||
|
+
|
||||||
|
+ while( pixels_across_glyph--) {
|
||||||
|
+ *pixel_on_screen = ~(*pixel_on_glyph_sheet);
|
||||||
|
+ ++ pixel_on_glyph_sheet;
|
||||||
|
+ ++ pixel_on_screen;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void inline draw_glyph_row_75( int pixels_across_glyph, u8 *src, u8 *target) {
|
||||||
|
+ u32 pixel;
|
||||||
|
+ u32 *pixel_on_glyph_sheet = (u32*) src;
|
||||||
|
+ u32 *pixel_on_screen = (u32*) target;
|
||||||
|
+ /* Copy the pixels at 75% brightness */
|
||||||
|
+ while( pixels_across_glyph--) {
|
||||||
|
+ pixel = *pixel_on_glyph_sheet;
|
||||||
|
+ /* This is a cheeky way of multiplying by 0.75 */
|
||||||
|
+ pixel = ( pixel >> 1) & 0x7f7f7f7f;
|
||||||
|
+ pixel += ( pixel >> 1) & 0x7f7f7f7f;
|
||||||
|
+ *pixel_on_screen = pixel;
|
||||||
|
+ ++ pixel_on_glyph_sheet;
|
||||||
|
+ ++ pixel_on_screen;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * width: the number of bytes required to store a single row of pixels from
|
||||||
|
+ * a glyph
|
||||||
|
+ * cellsize: the number of bytes required to store the pixels for a single
|
||||||
|
+ * glyph
|
||||||
|
+ * maxcnt: the maximum number of characters that can be blasted to the screen
|
||||||
|
+ * at one time ( limited by the amount of video RAM available for a
|
||||||
|
+ * (sub)string of characters)
|
||||||
|
+ * The NanoNote has 32-bits per pixel arranged BGRA
|
||||||
|
+ * info->fix.line_length: the number of bytes to advance through the frame
|
||||||
|
+ * buffer in order to get from the address of a pixel to
|
||||||
|
+ * the address of the pixel directly below it
|
||||||
|
+ * screen_row_hop: the number of 32-bit words to advance through the frame
|
||||||
|
+ * buffer in order to get from the address of a pixel to the
|
||||||
|
+ * address of the pixel directly below it on the screen
|
||||||
|
+ * glyph_on_screen: the address of the pixel on screen where the top-left of
|
||||||
|
+ * the next glyph should go
|
||||||
|
+ * row_on_screen: the address of the pixel on screen where the next row of
|
||||||
|
+ * pixels from the glyph should go
|
||||||
|
+ * row_on_glyph_sheet: pointer within font.data ( the glyph sheet) of the
|
||||||
|
+ * left-most pixel from the next row to be drawn
|
||||||
|
+ */
|
||||||
|
static void bit_putcs(struct vc_data *vc, struct fb_info *info,
|
||||||
|
const unsigned short *s, int count, int yy, int xx,
|
||||||
|
int fg, int bg)
|
||||||
|
{
|
||||||
|
struct fb_image image;
|
||||||
|
- u32 width = DIV_ROUND_UP(vc->vc_font.width, 8);
|
||||||
|
+ u8 std_font = *((u32*)vc->vc_font.data) != 0x6a127efd;
|
||||||
|
+ u32 width = std_font ? DIV_ROUND_UP(vc->vc_font.width, 8) : 4 * 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;
|
||||||
|
@@ -153,6 +209,10 @@ static void bit_putcs(struct vc_data *vc
|
||||||
|
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
|
||||||
|
u32 attribute = get_attribute(info, scr_readw(s));
|
||||||
|
u8 *dst, *buf = NULL;
|
||||||
|
+ u32 screen_row_hop;
|
||||||
|
+ u16 charmask;
|
||||||
|
+ u8 *row_on_glyph_sheet, *glyph_on_screen, *row_on_screen;
|
||||||
|
+ u8 code_point, rows_left;
|
||||||
|
|
||||||
|
image.fg_color = fg;
|
||||||
|
image.bg_color = bg;
|
||||||
|
@@ -167,31 +227,73 @@ static void bit_putcs(struct vc_data *vc
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- while (count) {
|
||||||
|
- if (count > maxcnt)
|
||||||
|
- cnt = maxcnt;
|
||||||
|
- else
|
||||||
|
- cnt = count;
|
||||||
|
-
|
||||||
|
- image.width = vc->vc_font.width * cnt;
|
||||||
|
- pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
|
||||||
|
- pitch &= ~scan_align;
|
||||||
|
- size = pitch * image.height + buf_align;
|
||||||
|
- size &= ~buf_align;
|
||||||
|
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
|
||||||
|
- image.data = dst;
|
||||||
|
-
|
||||||
|
- if (!mod)
|
||||||
|
- bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
|
||||||
|
- width, cellsize, &image, buf, dst);
|
||||||
|
- else
|
||||||
|
- bit_putcs_unaligned(vc, info, s, attribute, cnt,
|
||||||
|
- pitch, width, cellsize, &image,
|
||||||
|
- buf, dst);
|
||||||
|
-
|
||||||
|
- image.dx += cnt * vc->vc_font.width;
|
||||||
|
- count -= cnt;
|
||||||
|
- s += cnt;
|
||||||
|
+ if ( std_font) {
|
||||||
|
+ while (count) {
|
||||||
|
+ if (count > maxcnt)
|
||||||
|
+ cnt = maxcnt;
|
||||||
|
+ else
|
||||||
|
+ cnt = count;
|
||||||
|
+
|
||||||
|
+ image.width = vc->vc_font.width * cnt;
|
||||||
|
+ pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
|
||||||
|
+ pitch &= ~scan_align;
|
||||||
|
+ size = pitch * image.height + buf_align;
|
||||||
|
+ size &= ~buf_align;
|
||||||
|
+ dst = fb_get_buffer_offset(info, &info->pixmap, size);
|
||||||
|
+ image.data = dst;
|
||||||
|
+
|
||||||
|
+ if (!mod)
|
||||||
|
+ bit_putcs_aligned(vc, info, s, attribute, cnt,
|
||||||
|
+ pitch, width, cellsize,
|
||||||
|
+ &image, buf, dst);
|
||||||
|
+ else
|
||||||
|
+ bit_putcs_unaligned(vc, info, s, attribute, cnt,
|
||||||
|
+ pitch, width, cellsize,
|
||||||
|
+ &image, buf, dst);
|
||||||
|
+
|
||||||
|
+ image.dx += cnt * vc->vc_font.width;
|
||||||
|
+ count -= cnt;
|
||||||
|
+ s += cnt;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else { /* The font is not a standard 1-bit font */
|
||||||
|
+ charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
|
||||||
|
+ screen_row_hop = info->fix.line_length;
|
||||||
|
+ glyph_on_screen = info->screen_base +
|
||||||
|
+ screen_row_hop * image.dy +
|
||||||
|
+ 4 * image.dx;
|
||||||
|
+ /* While there are still characters to draw.. */
|
||||||
|
+ while (count--) {
|
||||||
|
+ code_point = scr_readw(s++) & charmask;
|
||||||
|
+ row_on_glyph_sheet = vc->vc_font.data +
|
||||||
|
+ cellsize * code_point;
|
||||||
|
+ /* Draw every row of the glyph */
|
||||||
|
+ row_on_screen = glyph_on_screen;
|
||||||
|
+ rows_left = vc->vc_font.height;
|
||||||
|
+ while( rows_left--)
|
||||||
|
+ {
|
||||||
|
+ /* If the background color is NOT black then do
|
||||||
|
+ * reverse video */
|
||||||
|
+ if ( 0 < bg) {
|
||||||
|
+ draw_glyph_row_inv( vc->vc_font.width,
|
||||||
|
+ row_on_glyph_sheet,
|
||||||
|
+ row_on_screen);
|
||||||
|
+ }
|
||||||
|
+ /* If the foreground color is high-intensity */
|
||||||
|
+ else if ( 8 <= fg) {
|
||||||
|
+ memcpy( row_on_screen,
|
||||||
|
+ row_on_glyph_sheet, width);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ draw_glyph_row_75( vc->vc_font.width,
|
||||||
|
+ row_on_glyph_sheet,
|
||||||
|
+ row_on_screen);
|
||||||
|
+ }
|
||||||
|
+ row_on_glyph_sheet += width;
|
||||||
|
+ row_on_screen += screen_row_hop;
|
||||||
|
+ }
|
||||||
|
+ glyph_on_screen += width;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buf is always NULL except when in monochrome mode, so in this case
|
||||||
|
@@ -234,6 +336,29 @@ static void bit_clear_margins(struct vc_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void bgra_cursor( struct vc_data *vc, struct fb_info *info, short c,
|
||||||
|
+ struct fb_cursor *cursor)
|
||||||
|
+{
|
||||||
|
+ u32 x = cursor->image.dx;
|
||||||
|
+ u32 y = cursor->image.dy;
|
||||||
|
+ u32 gw = vc->vc_font.width;
|
||||||
|
+ u32 gh = vc->vc_font.height;
|
||||||
|
+ u32 *pixel;
|
||||||
|
+
|
||||||
|
+ /* Draw the glyph to the screen */
|
||||||
|
+ bit_putcs( vc, info, &c, 1, y/gh, x/gw, 0, 0);
|
||||||
|
+
|
||||||
|
+ if ( cursor->enable) {
|
||||||
|
+ /* Invert the last row of pixels */
|
||||||
|
+ pixel = (u32*) ( info->screen_base +
|
||||||
|
+ info->fix.line_length * ( y + gh - 1) + 4 * x);
|
||||||
|
+ while ( gw--) {
|
||||||
|
+ *pixel ^= 0xffffffff;
|
||||||
|
+ ++ pixel;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
|
||||||
|
int softback_lines, int fg, int bg)
|
||||||
|
{
|
||||||
|
@@ -245,6 +370,7 @@ static void bit_cursor(struct vc_data *v
|
||||||
|
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
|
||||||
|
int err = 1;
|
||||||
|
char *src;
|
||||||
|
+ u8 std_font = *((u32*)vc->vc_font.data) != 0x6a127efd;
|
||||||
|
|
||||||
|
cursor.set = 0;
|
||||||
|
|
||||||
|
@@ -383,8 +509,14 @@ static void bit_cursor(struct vc_data *v
|
||||||
|
if (info->fbops->fb_cursor)
|
||||||
|
err = info->fbops->fb_cursor(info, &cursor);
|
||||||
|
|
||||||
|
- if (err)
|
||||||
|
- soft_cursor(info, &cursor);
|
||||||
|
+ if (err) {
|
||||||
|
+ if ( std_font) {
|
||||||
|
+ soft_cursor(info, &cursor);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ bgra_cursor( vc, info, c, &cursor);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ops->cursor_reset = 0;
|
||||||
|
}
|
||||||
|
--- a/drivers/video/console/fbcon.c
|
||||||
|
+++ b/drivers/video/console/fbcon.c
|
||||||
|
@@ -2552,7 +2552,8 @@ static int fbcon_set_font(struct vc_data
|
||||||
|
int size;
|
||||||
|
int i, csum;
|
||||||
|
u8 *new_data, *data = font->data;
|
||||||
|
- int pitch = (font->width+7) >> 3;
|
||||||
|
+ u8 std_font = *((u32*)data) != 0x6a127efd;
|
||||||
|
+ int pitch = std_font ? (font->width+7) >> 3 : 4 * font->width;
|
||||||
|
|
||||||
|
/* Is there a reason why fbconsole couldn't handle any charcount >256?
|
||||||
|
* If not this check should be changed to charcount < 256 */
|
||||||
|
@@ -2571,6 +2572,7 @@ static int fbcon_set_font(struct vc_data
|
||||||
|
size = h * pitch * charcount;
|
||||||
|
|
||||||
|
new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
|
||||||
|
+ DPRINTK(KERN_INFO "fbcon_set_font size:%d\n", size);
|
||||||
|
|
||||||
|
if (!new_data)
|
||||||
|
return -ENOMEM;
|
||||||
|
@@ -2579,8 +2581,14 @@ static int fbcon_set_font(struct vc_data
|
||||||
|
FNTSIZE(new_data) = size;
|
||||||
|
FNTCHARCNT(new_data) = charcount;
|
||||||
|
REFCOUNT(new_data) = 0; /* usage counter */
|
||||||
|
- for (i=0; i< charcount; i++) {
|
||||||
|
- memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch);
|
||||||
|
+ if ( std_font) {
|
||||||
|
+ for (i=0; i< charcount; i++) {
|
||||||
|
+ memcpy(new_data + i*h*pitch, data + i*32*pitch,
|
||||||
|
+ h*pitch);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ memcpy( new_data, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Since linux has a nice crc32 function use it for counting font
|
Loading…
Reference in New Issue
Block a user