Root/target/linux/xburst/patches-3.2/0024-fbcon-color-fonts.patch

1From 44cb778f4b2c6febb91631243c73f89a91c2f1ca Mon Sep 17 00:00:00 2001
2From: Xiangfu Liu <xiangfu@sharism.cc>
3Date: Tue, 18 Oct 2011 09:21:04 +0800
4Subject: [PATCH 24/28] fbcon-color-fonts
5
6---
7 drivers/tty/vt/vt.c | 3 +-
8 drivers/video/console/bitblit.c | 188 +++++++++++++++++++++++++++++++++------
9 drivers/video/console/fbcon.c | 14 +++-
10 3 files changed, 173 insertions(+), 32 deletions(-)
11
12diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
13index e716839..298f727 100644
14--- a/drivers/tty/vt/vt.c
15+++ b/drivers/tty/vt/vt.c
16@@ -4034,6 +4034,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
17     struct console_font font;
18     int rc = -EINVAL;
19     int size;
20+ u8 std_font = *((u32*)op->data) != 0x6a127efd;
21 
22     if (vc->vc_mode != KD_TEXT)
23         return -EINVAL;
24@@ -4063,7 +4064,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
25     }
26     if (op->width <= 0 || op->width > 32 || op->height > 32)
27         return -EINVAL;
28- size = (op->width+7)/8 * 32 * op->charcount;
29+ size = ( std_font ? (op->width+7)/8 * 32 : 4 * op->width * op->height) * op->charcount;
30     if (size > max_font_size)
31         return -ENOSPC;
32     font.charcount = op->charcount;
33diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
34index 28b1a83..8e559df 100644
35--- a/drivers/video/console/bitblit.c
36+++ b/drivers/video/console/bitblit.c
37@@ -105,6 +105,12 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
38     info->fbops->fb_imageblit(info, image);
39 }
40 
41+/* info: details of the framebuffer
42+ * image: the off-screen image in which the character (sub)string is being
43+ * prepared
44+ * dst: a pointer to the top-left pixel in the off-screen image where the
45+ * character (sub)string should go
46+ */
47 static inline void bit_putcs_unaligned(struct vc_data *vc,
48                        struct fb_info *info, const u16 *s,
49                        u32 attr, u32 cnt, u32 d_pitch,
50@@ -140,12 +146,62 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
51 
52 }
53 
54+void inline draw_glyph_row_inv( int pixels_across_glyph, u8 *src, u8 *target) {
55+ u32 *pixel_on_glyph_sheet = (u32*) src;
56+ u32 *pixel_on_screen = (u32*) target;
57+
58+ while( pixels_across_glyph--) {
59+ *pixel_on_screen = ~(*pixel_on_glyph_sheet);
60+ ++ pixel_on_glyph_sheet;
61+ ++ pixel_on_screen;
62+ }
63+}
64+
65+void inline draw_glyph_row_75( int pixels_across_glyph, u8 *src, u8 *target) {
66+ u32 pixel;
67+ u32 *pixel_on_glyph_sheet = (u32*) src;
68+ u32 *pixel_on_screen = (u32*) target;
69+ /* Copy the pixels at 75% brightness */
70+ while( pixels_across_glyph--) {
71+ pixel = *pixel_on_glyph_sheet;
72+ /* This is a cheeky way of multiplying by 0.75 */
73+ pixel = ( pixel >> 1) & 0x7f7f7f7f;
74+ pixel += ( pixel >> 1) & 0x7f7f7f7f;
75+ *pixel_on_screen = pixel;
76+ ++ pixel_on_glyph_sheet;
77+ ++ pixel_on_screen;
78+ }
79+}
80+
81+/*
82+ * width: the number of bytes required to store a single row of pixels from
83+ * a glyph
84+ * cellsize: the number of bytes required to store the pixels for a single
85+ * glyph
86+ * maxcnt: the maximum number of characters that can be blasted to the screen
87+ * at one time ( limited by the amount of video RAM available for a
88+ * (sub)string of characters)
89+ * The NanoNote has 32-bits per pixel arranged BGRA
90+ * info->fix.line_length: the number of bytes to advance through the frame
91+ * buffer in order to get from the address of a pixel to
92+ * the address of the pixel directly below it
93+ * screen_row_hop: the number of 32-bit words to advance through the frame
94+ * buffer in order to get from the address of a pixel to the
95+ * address of the pixel directly below it on the screen
96+ * glyph_on_screen: the address of the pixel on screen where the top-left of
97+ * the next glyph should go
98+ * row_on_screen: the address of the pixel on screen where the next row of
99+ * pixels from the glyph should go
100+ * row_on_glyph_sheet: pointer within font.data ( the glyph sheet) of the
101+ * left-most pixel from the next row to be drawn
102+ */
103 static void bit_putcs(struct vc_data *vc, struct fb_info *info,
104               const unsigned short *s, int count, int yy, int xx,
105               int fg, int bg)
106 {
107     struct fb_image image;
108- u32 width = DIV_ROUND_UP(vc->vc_font.width, 8);
109+ u8 std_font = *((u32*)vc->vc_font.data) != 0x6a127efd;
110+ u32 width = std_font ? DIV_ROUND_UP(vc->vc_font.width, 8) : 4 * vc->vc_font.width;
111     u32 cellsize = width * vc->vc_font.height;
112     u32 maxcnt = info->pixmap.size/cellsize;
113     u32 scan_align = info->pixmap.scan_align - 1;
114@@ -153,6 +209,10 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
115     u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
116     u32 attribute = get_attribute(info, scr_readw(s));
117     u8 *dst, *buf = NULL;
118+ u32 screen_row_hop;
119+ u16 charmask;
120+ u8 *row_on_glyph_sheet, *glyph_on_screen, *row_on_screen;
121+ u8 code_point, rows_left;
122 
123     image.fg_color = fg;
124     image.bg_color = bg;
125@@ -167,31 +227,73 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
126             return;
127     }
128 
129- while (count) {
130- if (count > maxcnt)
131- cnt = maxcnt;
132- else
133- cnt = count;
134-
135- image.width = vc->vc_font.width * cnt;
136- pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
137- pitch &= ~scan_align;
138- size = pitch * image.height + buf_align;
139- size &= ~buf_align;
140- dst = fb_get_buffer_offset(info, &info->pixmap, size);
141- image.data = dst;
142-
143- if (!mod)
144- bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
145- width, cellsize, &image, buf, dst);
146- else
147- bit_putcs_unaligned(vc, info, s, attribute, cnt,
148- pitch, width, cellsize, &image,
149- buf, dst);
150-
151- image.dx += cnt * vc->vc_font.width;
152- count -= cnt;
153- s += cnt;
154+ if ( std_font) {
155+ while (count) {
156+ if (count > maxcnt)
157+ cnt = maxcnt;
158+ else
159+ cnt = count;
160+
161+ image.width = vc->vc_font.width * cnt;
162+ pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
163+ pitch &= ~scan_align;
164+ size = pitch * image.height + buf_align;
165+ size &= ~buf_align;
166+ dst = fb_get_buffer_offset(info, &info->pixmap, size);
167+ image.data = dst;
168+
169+ if (!mod)
170+ bit_putcs_aligned(vc, info, s, attribute, cnt,
171+ pitch, width, cellsize,
172+ &image, buf, dst);
173+ else
174+ bit_putcs_unaligned(vc, info, s, attribute, cnt,
175+ pitch, width, cellsize,
176+ &image, buf, dst);
177+
178+ image.dx += cnt * vc->vc_font.width;
179+ count -= cnt;
180+ s += cnt;
181+ }
182+ }
183+ else { /* The font is not a standard 1-bit font */
184+ charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
185+ screen_row_hop = info->fix.line_length;
186+ glyph_on_screen = info->screen_base +
187+ screen_row_hop * image.dy +
188+ 4 * image.dx;
189+ /* While there are still characters to draw.. */
190+ while (count--) {
191+ code_point = scr_readw(s++) & charmask;
192+ row_on_glyph_sheet = vc->vc_font.data +
193+ cellsize * code_point;
194+ /* Draw every row of the glyph */
195+ row_on_screen = glyph_on_screen;
196+ rows_left = vc->vc_font.height;
197+ while( rows_left--)
198+ {
199+ /* If the background color is NOT black then do
200+ * reverse video */
201+ if ( 0 < bg) {
202+ draw_glyph_row_inv( vc->vc_font.width,
203+ row_on_glyph_sheet,
204+ row_on_screen);
205+ }
206+ /* If the foreground color is high-intensity */
207+ else if ( 8 <= fg) {
208+ memcpy( row_on_screen,
209+ row_on_glyph_sheet, width);
210+ }
211+ else {
212+ draw_glyph_row_75( vc->vc_font.width,
213+ row_on_glyph_sheet,
214+ row_on_screen);
215+ }
216+ row_on_glyph_sheet += width;
217+ row_on_screen += screen_row_hop;
218+ }
219+ glyph_on_screen += width;
220+ }
221     }
222 
223     /* buf is always NULL except when in monochrome mode, so in this case
224@@ -234,6 +336,29 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
225     }
226 }
227 
228+static void bgra_cursor( struct vc_data *vc, struct fb_info *info, short c,
229+ struct fb_cursor *cursor)
230+{
231+ u32 x = cursor->image.dx;
232+ u32 y = cursor->image.dy;
233+ u32 gw = vc->vc_font.width;
234+ u32 gh = vc->vc_font.height;
235+ u32 *pixel;
236+
237+ /* Draw the glyph to the screen */
238+ bit_putcs( vc, info, &c, 1, y/gh, x/gw, 0, 0);
239+
240+ if ( cursor->enable) {
241+ /* Invert the last row of pixels */
242+ pixel = (u32*) ( info->screen_base +
243+ info->fix.line_length * ( y + gh - 1) + 4 * x);
244+ while ( gw--) {
245+ *pixel ^= 0xffffffff;
246+ ++ pixel;
247+ }
248+ }
249+}
250+
251 static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
252                int softback_lines, int fg, int bg)
253 {
254@@ -245,6 +370,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
255     int attribute, use_sw = (vc->vc_cursor_type & 0x10);
256     int err = 1;
257     char *src;
258+ u8 std_font = *((u32*)vc->vc_font.data) != 0x6a127efd;
259 
260     cursor.set = 0;
261 
262@@ -383,8 +509,14 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
263     if (info->fbops->fb_cursor)
264         err = info->fbops->fb_cursor(info, &cursor);
265 
266- if (err)
267- soft_cursor(info, &cursor);
268+ if (err) {
269+ if ( std_font) {
270+ soft_cursor(info, &cursor);
271+ }
272+ else {
273+ bgra_cursor( vc, info, c, &cursor);
274+ }
275+ }
276 
277     ops->cursor_reset = 0;
278 }
279diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
280index 8745637..dea9d2c 100644
281--- a/drivers/video/console/fbcon.c
282+++ b/drivers/video/console/fbcon.c
283@@ -2552,7 +2552,8 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
284     int size;
285     int i, csum;
286     u8 *new_data, *data = font->data;
287- int pitch = (font->width+7) >> 3;
288+ u8 std_font = *((u32*)data) != 0x6a127efd;
289+ int pitch = std_font ? (font->width+7) >> 3 : 4 * font->width;
290 
291     /* Is there a reason why fbconsole couldn't handle any charcount >256?
292      * If not this check should be changed to charcount < 256 */
293@@ -2571,6 +2572,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
294     size = h * pitch * charcount;
295 
296     new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
297+ DPRINTK(KERN_INFO "fbcon_set_font size:%d\n", size);
298 
299     if (!new_data)
300         return -ENOMEM;
301@@ -2579,8 +2581,14 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
302     FNTSIZE(new_data) = size;
303     FNTCHARCNT(new_data) = charcount;
304     REFCOUNT(new_data) = 0; /* usage counter */
305- for (i=0; i< charcount; i++) {
306- memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch);
307+ if ( std_font) {
308+ for (i=0; i< charcount; i++) {
309+ memcpy(new_data + i*h*pitch, data + i*32*pitch,
310+ h*pitch);
311+ }
312+ }
313+ else {
314+ memcpy( new_data, data, size);
315     }
316 
317     /* Since linux has a nice crc32 function use it for counting font
318--
3191.7.5.4
320
321

Archive Download this file



interactive