diff options
| author | Eli Zaretskii | 2009-02-14 10:50:29 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 2009-02-14 10:50:29 +0000 |
| commit | aff01dd96f651db009a0d318a14477ff1f91e1c8 (patch) | |
| tree | 574a041234433d08db64505135bf141c4ace7ffa /src/msdos.c | |
| parent | b46957e2f4dacb404f30586c3675773a23715e16 (diff) | |
| download | emacs-aff01dd96f651db009a0d318a14477ff1f91e1c8.tar.gz emacs-aff01dd96f651db009a0d318a14477ff1f91e1c8.zip | |
(MAX_SCREEN_BUF): New macro.
(IT_write_glyphs): Make screen_buf[] always be MAX_SCREEN_BUF-long.
Encode the entire run of glyphs sharing the same face, instead of
doing that one glyph at a time (fixes a bug with displaying
double-size characters).
Diffstat (limited to 'src/msdos.c')
| -rw-r--r-- | src/msdos.c | 100 |
1 files changed, 38 insertions, 62 deletions
diff --git a/src/msdos.c b/src/msdos.c index e4e57646991..6397539574e 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -957,19 +957,20 @@ IT_set_face (int face) | |||
| 957 | } | 957 | } |
| 958 | } | 958 | } |
| 959 | 959 | ||
| 960 | /* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible | ||
| 961 | width of a DOS display in any known text mode. We multiply by 2 to | ||
| 962 | accomodate the screen attribute byte. */ | ||
| 963 | #define MAX_SCREEN_BUF 160*2 | ||
| 964 | |||
| 960 | Lisp_Object Vdos_unsupported_char_glyph; | 965 | Lisp_Object Vdos_unsupported_char_glyph; |
| 961 | extern unsigned char *encode_terminal_code (struct glyph *, int, | 966 | extern unsigned char *encode_terminal_code (struct glyph *, int, |
| 962 | struct coding_system *); | 967 | struct coding_system *); |
| 963 | static void | 968 | static void |
| 964 | IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) | 969 | IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) |
| 965 | { | 970 | { |
| 966 | unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp; | 971 | unsigned char screen_buf[MAX_SCREEN_BUF], *screen_bp, *bp; |
| 967 | int unsupported_face = 0; | ||
| 968 | unsigned unsupported_char = '\177'; | ||
| 969 | int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); | 972 | int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); |
| 970 | register int sl = str_len; | 973 | register int sl = str_len; |
| 971 | register int tlen = GLYPH_TABLE_LENGTH; | ||
| 972 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | ||
| 973 | struct tty_display_info *tty = FRAME_TTY (f); | 974 | struct tty_display_info *tty = FRAME_TTY (f); |
| 974 | struct frame *sf; | 975 | struct frame *sf; |
| 975 | unsigned char *conversion_buffer; | 976 | unsigned char *conversion_buffer; |
| @@ -990,8 +991,6 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) | |||
| 990 | 991 | ||
| 991 | if (str_len <= 0) return; | 992 | if (str_len <= 0) return; |
| 992 | 993 | ||
| 993 | screen_buf = screen_bp = alloca (str_len * 2); | ||
| 994 | screen_buf_end = screen_buf + str_len * 2; | ||
| 995 | sf = SELECTED_FRAME(); | 994 | sf = SELECTED_FRAME(); |
| 996 | 995 | ||
| 997 | /* Since faces get cached and uncached behind our back, we can't | 996 | /* Since faces get cached and uncached behind our back, we can't |
| @@ -1004,73 +1003,50 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) | |||
| 1004 | /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at | 1003 | /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at |
| 1005 | the tail. */ | 1004 | the tail. */ |
| 1006 | coding->mode &= ~CODING_MODE_LAST_BLOCK; | 1005 | coding->mode &= ~CODING_MODE_LAST_BLOCK; |
| 1006 | screen_bp = &screen_buf[0]; | ||
| 1007 | while (sl > 0) | 1007 | while (sl > 0) |
| 1008 | { | 1008 | { |
| 1009 | int cf; | 1009 | int cf; |
| 1010 | int n; | ||
| 1010 | 1011 | ||
| 1011 | /* Glyphs with GLYPH_MASK_PADDING bit set are actually there | 1012 | /* If the face of this glyph is different from the current |
| 1012 | only for the redisplay code to know how many columns does | 1013 | screen face, update the screen attribute byte. */ |
| 1013 | this character occupy on the screen. Skip padding glyphs. */ | 1014 | cf = str->face_id; |
| 1014 | if (CHAR_GLYPH_PADDING_P (*str)) | 1015 | if (cf != screen_face) |
| 1015 | { | 1016 | IT_set_face (cf); /* handles invalid faces gracefully */ |
| 1016 | str++; | 1017 | |
| 1017 | sl--; | 1018 | /* Identify a run of glyphs with the same face. */ |
| 1018 | } | 1019 | for (n = 1; n < sl; ++n) |
| 1019 | else | 1020 | if (str[n].face_id != cf) |
| 1021 | break; | ||
| 1022 | |||
| 1023 | if (n >= sl) | ||
| 1024 | /* This is the last glyph. */ | ||
| 1025 | coding->mode |= CODING_MODE_LAST_BLOCK; | ||
| 1026 | |||
| 1027 | conversion_buffer = encode_terminal_code (str, n, coding); | ||
| 1028 | if (coding->produced > 0) | ||
| 1020 | { | 1029 | { |
| 1021 | /* If the face of this glyph is different from the current | 1030 | /* Copy the encoded bytes to the screen buffer. */ |
| 1022 | screen face, update the screen attribute byte. */ | 1031 | for (bp = conversion_buffer; coding->produced--; bp++) |
| 1023 | cf = str->face_id; | ||
| 1024 | if (cf != screen_face) | ||
| 1025 | IT_set_face (cf); /* handles invalid faces gracefully */ | ||
| 1026 | |||
| 1027 | if (sl <= 1) | ||
| 1028 | /* This is the last glyph. */ | ||
| 1029 | coding->mode |= CODING_MODE_LAST_BLOCK; | ||
| 1030 | |||
| 1031 | conversion_buffer = encode_terminal_code (str, 1, coding); | ||
| 1032 | if (coding->produced > 0) | ||
| 1033 | { | 1032 | { |
| 1034 | if (2*coding->produced > screen_buf_end - screen_bp) | 1033 | /* Paranoia: discard bytes that would overrun the end of |
| 1034 | the screen buffer. */ | ||
| 1035 | if (screen_bp - screen_buf <= MAX_SCREEN_BUF - 2) | ||
| 1035 | { | 1036 | { |
| 1036 | /* The allocated buffer for screen writes is too small. | 1037 | *screen_bp++ = (unsigned char)*bp; |
| 1037 | Flush it and loop again without incrementing STR, so | 1038 | *screen_bp++ = ScreenAttrib; |
| 1038 | that the next loop will begin with the same glyph. */ | ||
| 1039 | int nbytes = screen_bp - screen_buf; | ||
| 1040 | |||
| 1041 | mouse_off_maybe (); | ||
| 1042 | dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset); | ||
| 1043 | if (screen_virtual_segment) | ||
| 1044 | dosv_refresh_virtual_screen (offset, nbytes / 2); | ||
| 1045 | new_pos_X += nbytes / 2; | ||
| 1046 | offset += nbytes; | ||
| 1047 | |||
| 1048 | /* Prepare to reuse the same buffer again. */ | ||
| 1049 | screen_bp = screen_buf; | ||
| 1050 | continue; | ||
| 1051 | } | ||
| 1052 | else | ||
| 1053 | { | ||
| 1054 | /* There's enough place in the allocated buffer to add | ||
| 1055 | the encoding of this glyph. */ | ||
| 1056 | |||
| 1057 | /* Copy the encoded bytes to the allocated buffer. */ | ||
| 1058 | for (bp = conversion_buffer; coding->produced--; bp++) | ||
| 1059 | { | ||
| 1060 | *screen_bp++ = (unsigned char)*bp; | ||
| 1061 | *screen_bp++ = ScreenAttrib; | ||
| 1062 | if (tty->termscript) | ||
| 1063 | fputc (*bp, tty->termscript); | ||
| 1064 | } | ||
| 1065 | } | 1039 | } |
| 1040 | if (tty->termscript) | ||
| 1041 | fputc (*bp, tty->termscript); | ||
| 1066 | } | 1042 | } |
| 1067 | /* Update STR and its remaining length. */ | ||
| 1068 | str++; | ||
| 1069 | sl--; | ||
| 1070 | } | 1043 | } |
| 1044 | /* Update STR and its remaining length. */ | ||
| 1045 | str += n; | ||
| 1046 | sl -= n; | ||
| 1071 | } | 1047 | } |
| 1072 | 1048 | ||
| 1073 | /* Dump whatever is left in the screen buffer. */ | 1049 | /* Dump whatever we have in the screen buffer. */ |
| 1074 | mouse_off_maybe (); | 1050 | mouse_off_maybe (); |
| 1075 | dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset); | 1051 | dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset); |
| 1076 | if (screen_virtual_segment) | 1052 | if (screen_virtual_segment) |