Release: 2000/12/12                !!注意!! このパッチは未完成です。一応動くことは動きますが、一般利用には向いていませ ん。ご意見・ご要望がありましたら、下記アドレスまでお送り下さい。 このパッチは、Linuxのカーネル(2.2.16+)にフレームバッファコンソール上での 日本語表示機能を追加するものです。現在、vesafbドライバでしかテストしていま せん(いくつかのドライバでは不具合が発生すると思います)。パッチを当てた後、 CONFIG_FONT_KANJI16を有効にして再コンパイルを行い、再起動する時にカーネル コマンドラインで「video=vesa:font:kanji16」を指定して下さい。 現時点では、下記のバグ・問題があります。 ・起動時のテキストは、漢字フォントに切替える時に化ける。 ・全角文字が行をまたがった場合、それ以降の文字(次の半角文字まで)が化ける。 ・フォントを変更すると、あとで漢字フォントに戻しても全角文字が表示できなく  なる。また、他のコンソールでも全角文字が表示できなくなることがある。 ・ESC [ 10 m のエスケープシーケンスを使うと、半角文字が化ける(VT100グラフ  ィック文字として表示される)。ESC ( B で直すと、以降の ESC [ 10 m は問題  を起こさない。 ・全角文字は、1番目のバイトのみredrawに渡した場合には再描画されない。 ・カーソルは、全角文字の上にあっても幅が半角文字と同じ。 ・半角カタカナ(ESC ( K)はサポートされていない。 パッチ作成者:アンドリュー・チャーチ(achurch@achurch.org) =========================================================================== *** WARNING *** This patch is still under development. It works to an extent, but is not recommended for general use. Please send comments to the address below. This patches the Linux kernel (2.2.16+) to support Japanese text on the framebuffer console. Tested with vesafb only (will probably break on some hardware drivers). To use, enable CONFIG_FONT_KANJI16 and give as a kernel command-line parameter "video=vesa:font:kanji16" (change "vesa" to something else for another driver). Known bugs: - Bootup screen is corrupted on initial switch to kanji16 font. - If a full-width character wraps over a line, all subsequent full-width characters (up to the first half-width character) will be corrupted. - Changing the font causes full-width characters to no longer be displayed correctly, even if the font is later changed back to kanji16. - ESC [ 10 m causes corruption (switches to VT100 graphics). ESC ( B to restore original character set. (After this, ESC [ 10 m works fine.) - Full-width characters are not redrawn if only the first byte is given to redraw. - Cursor is only half-width even on full-width characters. - Half-width katakana (ESC ( K) are not supported. --Andrew Church =========================================================================== --- linux-2.2.18-orig/drivers/char/console.c Mon Dec 11 09:49:41 2000 +++ linux-2.2.18/drivers/char/console.c Tue Dec 12 14:17:45 2000 @@ -1042,12 +1042,19 @@ * control chars if defined, don't set * bit 8 on output. */ - translate = set_translate(charset == 0 - ? G0_charset - : G1_charset,currcons); + { + int set; + if (widechars) + set = (charset ? wide1_charset + : wide0_charset); + else + set = (charset ? G1_charset + : G0_charset); + translate = set_translate(set, currcons); disp_ctrl = 0; toggle_meta = 0; break; + } case 11: /* ANSI X3.64-1979 (SCO-ish?) * Select first alternate font, lets * chars < 32 be displayed as ROM chars. @@ -1329,30 +1336,42 @@ s_blink = blink; s_reverse = reverse; s_charset = charset; + s_widechars = widechars; s_color = color; saved_G0 = G0_charset; saved_G1 = G1_charset; + saved_wide0 = wide0_charset; + saved_wide1 = wide1_charset; } static void restore_cur(int currcons) { + int set; + gotoxy(currcons,saved_x,saved_y); intensity = s_intensity; underline = s_underline; blink = s_blink; reverse = s_reverse; charset = s_charset; + widechars = s_widechars; color = s_color; G0_charset = saved_G0; G1_charset = saved_G1; - translate = set_translate(charset ? G1_charset : G0_charset,currcons); + wide0_charset = saved_wide0; + wide1_charset = saved_wide1; + if (widechars) + set = (charset ? wide1_charset : wide0_charset); + else + set = (charset ? G1_charset : G0_charset); + translate = set_translate(set, currcons); update_attr(currcons); need_wrap = 0; } enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd, - ESpalette }; + ESpalette, ESsetwide }; static void reset_terminal(int currcons, int do_clear) { @@ -1360,10 +1379,16 @@ bottom = video_num_lines; vc_state = ESnormal; ques = 0; - translate = set_translate(LAT1_MAP,currcons); +//FIXME +// translate = set_translate(LAT1_MAP,currcons); + translate = set_translate(widechars?WIDE_LAT1_MAP:LAT1_MAP,currcons); G0_charset = LAT1_MAP; G1_charset = GRAF_MAP; + wide0_charset = WIDE_LAT1_MAP; + wide1_charset = WIDE_GRAF_MAP; charset = 0; +//FIXME +// widechars = 0; need_wrap = 0; report_mouse = 0; utf = 0; @@ -1443,12 +1468,12 @@ return; case 14: charset = 1; - translate = set_translate(G1_charset,currcons); + translate = set_translate(widechars ? wide1_charset : G1_charset,currcons); disp_ctrl = 1; return; case 15: charset = 0; - translate = set_translate(G0_charset,currcons); + translate = set_translate(widechars ? wide0_charset : G0_charset,currcons); disp_ctrl = 0; return; case 24: case 26: @@ -1505,6 +1530,9 @@ case ')': vc_state = ESsetG1; return; + case '$': + vc_state = ESsetwide; + return; case '#': vc_state = EShash; return; @@ -1746,29 +1774,51 @@ } return; case ESsetG0: - if (c == '0') + if (c == '0') { G0_charset = GRAF_MAP; - else if (c == 'B') + wide0_charset = WIDE_GRAF_MAP; + } else if (c == 'B') { G0_charset = LAT1_MAP; - else if (c == 'U') + wide0_charset = WIDE_LAT1_MAP; + } else if (c == 'U') { G0_charset = IBMPC_MAP; - else if (c == 'K') + wide0_charset = IBMPC_MAP; + } else if (c == 'K') { G0_charset = USER_MAP; + wide0_charset = WIDE_USER_MAP; + } + if (widechars) + toggle_meta = 0; if (charset == 0) - translate = set_translate(G0_charset,currcons); + translate = set_translate(widechars ? wide0_charset : G0_charset, currcons); vc_state = ESnormal; return; case ESsetG1: - if (c == '0') + if (c == '0') { G1_charset = GRAF_MAP; - else if (c == 'B') + wide1_charset = WIDE_GRAF_MAP; + } else if (c == 'B') { G1_charset = LAT1_MAP; - else if (c == 'U') + wide1_charset = WIDE_LAT1_MAP; + } else if (c == 'U') { G1_charset = IBMPC_MAP; - else if (c == 'K') + wide1_charset = IBMPC_MAP; + } else if (c == 'K') { G1_charset = USER_MAP; + wide1_charset = WIDE_USER_MAP; + } + if (widechars) + toggle_meta = 0; if (charset == 1) - translate = set_translate(G1_charset,currcons); + translate = set_translate(widechars ? wide1_charset : G1_charset, currcons); + vc_state = ESnormal; + return; + case ESsetwide: + /* FIXME: this takes parameters like setG0 but what do they do? + * All I know is ESC $ B for switching to JIS [achurch] */ + /* MORE FIXME: this probably interferes with ESC [ {10,11,12} m */ + if (widechars) + toggle_meta = 1; vc_state = ESnormal; return; default: @@ -2387,11 +2437,11 @@ #ifndef VT_SINGLE_DRIVER -static void clear_buffer_attributes(int currcons) +static void clear_buffer_attributes(int currcons, int fontmask) { unsigned short *p = (unsigned short *) origin; int count = screenbuf_size/2; - int mask = hi_font_mask | 0xff; + int mask = fontmask | 0xff; for (; count > 0; count--, p++) { scr_writew((scr_readw(p)&mask) | (video_erase_char&~mask), p); @@ -2415,7 +2465,7 @@ conswitchp = csw; for (i = first; i <= last; i++) { - int old_was_color; + int old_was_color, old_hi_font_mask; int currcons = i; con_driver_map[i] = csw; @@ -2427,6 +2477,7 @@ if (IS_VISIBLE) save_screen(i); old_was_color = vc_cons[i].d->vc_can_do_color; + old_hi_font_mask = vc_cons[i].d->vc_hi_font_mask; vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d); visual_init(i, 0); update_attr(i); @@ -2435,8 +2486,16 @@ * the attributes in the screenbuf will be wrong. The * following resets all attributes to something sane. */ - if (old_was_color != vc_cons[i].d->vc_can_do_color) - clear_buffer_attributes(i); + /* ++achurch: Same applies to hi_font_mask. Note that in + * this case, we may also need to mask some bits that are + * now font bits because they used to be attribute bits. + */ + if (old_was_color != vc_cons[i].d->vc_can_do_color + || old_hi_font_mask != vc_cons[i].d->vc_hi_font_mask) { + int fontmask = old_hi_font_mask + & vc_cons[i].d->vc_hi_font_mask; + clear_buffer_attributes(i, fontmask); + } if (IS_VISIBLE) update_screen(i); --- linux-2.2.18-orig/drivers/char/console_macros.h Fri Sep 18 01:35:03 1998 +++ linux-2.2.18/drivers/char/console_macros.h Tue Dec 12 14:17:46 2000 @@ -21,8 +21,12 @@ #define translate (vc_cons[currcons].d->vc_translate) #define G0_charset (vc_cons[currcons].d->vc_G0_charset) #define G1_charset (vc_cons[currcons].d->vc_G1_charset) +#define wide0_charset (vc_cons[currcons].d->vc_wide0_charset) +#define wide1_charset (vc_cons[currcons].d->vc_wide1_charset) #define saved_G0 (vc_cons[currcons].d->vc_saved_G0) #define saved_G1 (vc_cons[currcons].d->vc_saved_G1) +#define saved_wide0 (vc_cons[currcons].d->vc_saved_wide0) +#define saved_wide1 (vc_cons[currcons].d->vc_saved_wide1) #define utf (vc_cons[currcons].d->vc_utf) #define utf_count (vc_cons[currcons].d->vc_utf_count) #define utf_char (vc_cons[currcons].d->vc_utf_char) @@ -45,6 +49,8 @@ #define background (color & 0xf0) #define charset (vc_cons[currcons].d->vc_charset) #define s_charset (vc_cons[currcons].d->vc_s_charset) +#define widechars (vc_cons[currcons].d->vc_widechars) +#define s_widechars (vc_cons[currcons].d->vc_s_widechars) #define intensity (vc_cons[currcons].d->vc_intensity) #define underline (vc_cons[currcons].d->vc_underline) #define blink (vc_cons[currcons].d->vc_blink) --- linux-2.2.18-orig/drivers/char/consolemap.c Wed Dec 30 07:28:37 1998 +++ linux-2.2.18/drivers/char/consolemap.c Tue Dec 12 14:17:45 2000 @@ -161,7 +161,112 @@ 0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef, 0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7, 0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff - } + }, + /* Mapping for wide (16-bit) character display, Latin 1 */ + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107, + 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, + 0xf110, 0xf111, 0xf112, 0xf113, 0xf114, 0xf115, 0xf116, 0xf117, + 0xf118, 0xf119, 0xf11a, 0xf11b, 0xf11c, 0xf11d, 0xf11e, 0xf11f, + 0xf120, 0xf121, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, 0xf127, + 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf12c, 0xf12d, 0xf12e, 0xf12f, + 0xf130, 0xf131, 0xf132, 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, + 0xf138, 0xf139, 0xf13a, 0xf13b, 0xf13c, 0xf13d, 0xf13e, 0xf13f, + 0xf140, 0xf141, 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, + 0xf148, 0xf149, 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, + 0xf150, 0xf151, 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, + 0xf158, 0xf159, 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, + 0xf160, 0xf161, 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, + 0xf168, 0xf169, 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, + 0xf170, 0xf171, 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, + 0xf178, 0xf179, 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf17f + }, + /* Mapping for wide (16-bit) character display, VT100 graphics */ + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f, + 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0, + 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, + 0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800, + 0xf801, 0x2500, 0xf803, 0xf804, 0x251c, 0x2524, 0x2534, 0x252c, + 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f, + 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107, + 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, + 0xf110, 0xf111, 0xf112, 0xf113, 0xf114, 0xf115, 0xf116, 0xf117, + 0xf118, 0xf119, 0xf11a, 0xf11b, 0xf11c, 0xf11d, 0xf11e, 0xf11f, + 0xf120, 0xf121, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, 0xf127, + 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf12c, 0xf12d, 0xf12e, 0xf12f, + 0xf130, 0xf131, 0xf132, 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, + 0xf138, 0xf139, 0xf13a, 0xf13b, 0xf13c, 0xf13d, 0xf13e, 0xf13f, + 0xf140, 0xf141, 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, + 0xf148, 0xf149, 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, + 0xf150, 0xf151, 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, + 0xf158, 0xf159, 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, + 0xf160, 0xf161, 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, + 0xf168, 0xf169, 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, + 0xf170, 0xf171, 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, + 0xf178, 0xf179, 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf17f + }, + /* User mapping for wide character fonts */ + { + 0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007, + 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f, + 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017, + 0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, + 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027, + 0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f, + 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, + 0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f, + 0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047, + 0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f, + 0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057, + 0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f, + 0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067, + 0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f, + 0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077, + 0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f, + 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107, + 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, + 0xf110, 0xf111, 0xf112, 0xf113, 0xf114, 0xf115, 0xf116, 0xf117, + 0xf118, 0xf119, 0xf11a, 0xf11b, 0xf11c, 0xf11d, 0xf11e, 0xf11f, + 0xf120, 0xf121, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, 0xf127, + 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf12c, 0xf12d, 0xf12e, 0xf12f, + 0xf130, 0xf131, 0xf132, 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, + 0xf138, 0xf139, 0xf13a, 0xf13b, 0xf13c, 0xf13d, 0xf13e, 0xf13f, + 0xf140, 0xf141, 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, + 0xf148, 0xf149, 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, + 0xf150, 0xf151, 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, + 0xf158, 0xf159, 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, + 0xf160, 0xf161, 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, + 0xf168, 0xf169, 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, + 0xf170, 0xf171, 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, + 0xf178, 0xf179, 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf17f + }, }; /* The standard kernel character-to-font mappings are not invertible --- linux-2.2.18-orig/drivers/video/Config.in Mon Dec 11 09:49:44 2000 +++ linux-2.2.18/drivers/video/Config.in Tue Dec 12 14:17:46 2000 @@ -316,6 +316,7 @@ fi bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 + bool ' Japanese 16x16 font (EXPERIMENTAL)' CONFIG_FONT_KANJI16 fi else bool 'Select compiled-in fonts' CONFIG_FBCON_FONTS @@ -329,6 +330,7 @@ fi bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 + bool ' Japanese 16x16 font (EXPERIMENTAL)' CONFIG_FONT_KANJI16 else define_bool CONFIG_FONT_8x8 y define_bool CONFIG_FONT_8x16 y --- linux-2.2.18-orig/drivers/video/Makefile Mon Dec 11 09:49:44 2000 +++ linux-2.2.18/drivers/video/Makefile Tue Dec 12 14:17:46 2000 @@ -59,6 +59,9 @@ ifeq ($(CONFIG_FONT_PEARL_8x8),y) L_OBJS += font_pearl_8x8.o endif + ifeq ($(CONFIG_FONT_KANJI16),y) + L_OBJS += font_kanji16.o + endif endif # Frame Buffer Devices --- linux-2.2.18-orig/drivers/video/fbcon.c Mon Dec 11 09:49:44 2000 +++ linux-2.2.18/drivers/video/fbcon.c Tue Dec 12 14:17:46 2000 @@ -475,11 +475,16 @@ p->_fontwidthlog = q->_fontwidthlog; p->_fontheightlog = q->_fontheightlog; p->fontdata = q->fontdata; + p->fontwidechars = q->fontwidechars; + p->getchardata = q->getchardata; + p->euc_mode = q->euc_mode; p->userfont = q->userfont; if (p->userfont) { REFCOUNT(p->fontdata)++; charcnt = FNTCHARCNT(p->fontdata); - } + } else if (q->charmask == 0x1FF) { + charcnt = 512; + } con_copy_unimap(con, i); } } @@ -491,8 +496,19 @@ p->_fontwidth = font->width; p->_fontheight = font->height; p->fontdata = font->data; + /* FIXME: these two not set in set_font [achurch] */ + p->fontwidechars = font->has_wide_chars; + p->getchardata = font->getchardata; + if (p->fontwidechars) { + p->euc_mode = 1; + charcnt = 512; /* not really, this is a hack */ + } else { + p->euc_mode = 0; + } fbcon_font_widths(p); } + + conp->vc_widechars = p->fontwidechars; if (!fontwidthvalid(p,fontwidth(p))) { #ifdef CONFIG_MAC @@ -551,8 +567,22 @@ conp->vc_pos += logo_lines * conp->vc_size_row; } } - scr_memsetw((unsigned short *)conp->vc_origin, conp->vc_video_erase_char, - conp->vc_size_row * logo_lines); + /* ++achurch: conp->vc_video_erase_char will not yet be set if our + * font uses bit 8 (hi_font_mask), so we need to generate it here + * ourselves. */ + if (charcnt != 256) { + unsigned short erase_char; + unsigned char color = conp->vc_color << 1; + if (conp->vc_reverse) + color = (color & 0x10) | ((color<<4 | color>>4) & 0xEE); + erase_char = color<<9 | ' '; + scr_memsetw((unsigned short *)conp->vc_origin, erase_char, + conp->vc_size_row * logo_lines); + } else { + scr_memsetw((unsigned short *)conp->vc_origin, + conp->vc_video_erase_char, + conp->vc_size_row * logo_lines); + } } /* @@ -697,6 +727,69 @@ } +/* + * ++achurch: Deal with euc_mode for putc and putcs. This is really an + * ugly HACK. + */ + +static __inline__ int fake_y(struct display *p, int ypos) +{ + int rows = p->vrows; + + ypos -= p->yscroll; + return ypos >= 0 ? ypos : ypos+rows; +} + +static void do_putc(struct vc_data *conp, struct display *p, int c, + int ypos, int xpos) +{ + /* Parse two-byte EUC characters and set the font pointer for the + * low-level driver accordingly when drawing. We set bits 7 and 8 + * to 0x180 on the first character and 0x100 on the second to help + * us distinguish first and second bytes of a two-byte character, + * and only draw when reaching the second character. */ + if (p->euc_mode) { + if ((c & 0x180) == 0x100) { + int offset = (ypos * conp->vc_cols + xpos) << 1; + if (xpos == 0 || (*(conp->vc_sw->con_screen_pos(conp,offset-2)) & 0x180) != 0x180) { + c |= 0x80; + *(conp->vc_sw->con_screen_pos(conp,offset)) = c; + } + } + if ((c & 0x180) == 0x100 && xpos > 0) { + int offset = (ypos * conp->vc_cols + xpos) << 1; + u16 c2 = *(conp->vc_sw->con_screen_pos(conp, offset-2)); + int realc = (c2<<8 & 0x7F00) | (c & 0x7F); + int charsize = fontheight(p) * ((fontwidth(p)+7)/8); + u8 *origdata = p->fontdata; + u8 *chardata = p->getchardata(origdata, realc); + /* FIXME: some drivers won't like this (?) */ + p->fontdata = chardata - ((c2 & p->charmask) * charsize); + p->dispsw->putc(conp, p, c2, real_y(p, ypos), xpos-1); + p->fontdata = chardata - ((c & p->charmask) * charsize) + charsize; + p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos); + p->fontdata = origdata; + } else if ((c & 0x100) == 0) { + p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos); + } + } else { + p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos); + } +} + +static void do_putcs(struct vc_data *conp, struct display *p, + const unsigned short *s, int count, int ypos, int xpos) +{ + if (p->euc_mode && count > 0) { + /* FIXME: this is dumb, is there a better way without modifying s? */ + while (count--) + do_putc(conp, p, *s++, ypos, xpos++); + } else { + p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos); + } +} + + static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos) { int unit = conp->vc_num; @@ -714,7 +807,7 @@ redraw_cursor = 1; } - p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos); + do_putc(conp, p, c, ypos, xpos); if (redraw_cursor) vbl_cursor_cnt = CURSOR_DRAW_DELAY; @@ -739,7 +832,9 @@ cursor_undrawn(); redraw_cursor = 1; } - p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos); + + do_putcs(conp, p, s, count, ypos, xpos); + if (redraw_cursor) vbl_cursor_cnt = CURSOR_DRAW_DELAY; } @@ -938,7 +1033,7 @@ while (count--) { unsigned short *start; unsigned short *le; - unsigned short c; + unsigned short c, c2; int x = 0; unsigned short attr = 1; @@ -949,16 +1044,15 @@ if (attr != (c & 0xff00)) { attr = c & 0xff00; if (s > start) { - p->dispsw->putcs(conp, p, start, s - start, - real_y(p, line), x); + do_putcs(conp, p, start, s - start, line, x); x += s - start; start = s; } } - if (c == scr_readw(d)) { + c2 = scr_readw(d); + if (c == c2 && (!p->euc_mode || s <= start || (c2 & 0x180) != 0x100)) { if (s > start) { - p->dispsw->putcs(conp, p, start, s - start, - real_y(p, line), x); + do_putcs(conp, p, start, s - start, line, x); x += s - start + 1; start = s + 1; } else { @@ -970,7 +1064,7 @@ d++; } while (s < le); if (s > start) - p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x); + do_putcs(conp, p, start, s - start, line, x); line++; if (d == (u16 *)softback_end) d = (u16 *)softback_buf; @@ -993,7 +1087,7 @@ while (count--) { unsigned short *start = s; unsigned short *le = advance_row(s, 1); - unsigned short c; + unsigned short c, c2; int x = 0; unsigned short attr = 1; @@ -1002,16 +1096,15 @@ if (attr != (c & 0xff00)) { attr = c & 0xff00; if (s > start) { - p->dispsw->putcs(conp, p, start, s - start, - real_y(p, line), x); + do_putcs(conp, p, start, s - start, line, x); x += s - start; start = s; } } - if (c == scr_readw(d)) { + c2 = scr_readw(d); + if (c == c2 && (!p->euc_mode || s <= start || (c2 & 0x180) != 0x100)) { if (s > start) { - p->dispsw->putcs(conp, p, start, s - start, - real_y(p, line), x); + do_putcs(conp, p, start, s - start, line, x); x += s - start + 1; start = s + 1; } else { @@ -1024,7 +1117,7 @@ d++; } while (s < le); if (s > start) - p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x); + do_putcs(conp, p, start, s - start, line, x); if (offset > 0) line++; else { @@ -1051,7 +1144,7 @@ unsigned short *start = d; unsigned short *ls = d; unsigned short *le = d + w; - unsigned short c; + unsigned short c, c2; int x = dx; unsigned short attr = 1; @@ -1060,26 +1153,29 @@ if (attr != (c & 0xff00)) { attr = c & 0xff00; if (d > start) { - p->dispsw->putcs(conp, p, start, d - start, dy, x); + do_putcs(conp, p, start, d - start, fake_y(p, dy), x); x += d - start; start = d; } } - if (s >= ls && s < le && c == scr_readw(s)) { - if (d > start) { - p->dispsw->putcs(conp, p, start, d - start, dy, x); - x += d - start + 1; - start = d + 1; - } else { - x++; - start++; + if (s >= ls && s < le) { + c2 = scr_readw(s); + if (c == c2 && (!p->euc_mode || d <= start || (c2 & 0x180) != 0x100)) { + if (d > start) { + do_putcs(conp, p, start, d - start, fake_y(p, dy), x); + x += d - start + 1; + start = d + 1; + } else { + x++; + start++; + } } } s++; d++; } while (d < le); if (d > start) - p->dispsw->putcs(conp, p, start, d - start, dy, x); + do_putcs(conp, p, start, d - start, fake_y(p, dy), x); sy++; dy++; } @@ -1423,6 +1519,7 @@ (--REFCOUNT(p->fontdata) == 0)) kfree(p->fontdata - FONT_EXTRA_WORDS*sizeof(int)); p->fontdata = NULL; + p->getchardata = NULL; p->userfont = 0; } --- linux-2.2.18-orig/drivers/video/font_kanji16.c Thu Jan 1 09:00:00 1970 +++ linux-2.2.18/drivers/video/font_kanji16.c Tue Dec 12 14:17:46 2000 @@ -0,0 +1,7561 @@ +/* 8x16 Japanese font. 2-byte (full-width) characters are 16x16 pixels. */ +/* Contributed by Andrew Church */ + +#include