Date:2011-04-30 09:37:40 (8 years 7 months ago)
Author:kyak
Commit:bd76150ebb81cdf4f15b61e3b34e1b5ec7696b06
Message:add kernel patch for setfont2

Files: target/linux/xburst/patches-2.6.37/450-fbcon-color-fonts.patch (1 diff)

Change Details

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

Archive Download the corresponding diff file



interactive