Root/target/linux/xburst/patches-3.0/0030-fbcon-color-fonts.patch

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

Archive Download this file



interactive