(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).
This commit is contained in:
Eli Zaretskii 2009-02-14 10:50:29 +00:00
parent b46957e2f4
commit aff01dd96f
2 changed files with 46 additions and 62 deletions

View file

@ -1,3 +1,11 @@
2009-02-14 Eli Zaretskii <eliz@gnu.org>
* msdos.c (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).
2009-02-13 Adrian Robert <Adrian.B.Robert@gmail.com>
* nsfns.m (ns-read-file-name): BLOCK_INPUT while showing dialog.

View file

@ -957,19 +957,20 @@ IT_set_face (int face)
}
}
/* According to RBIL (INTERRUP.A, V-1000), 160 is the maximum possible
width of a DOS display in any known text mode. We multiply by 2 to
accomodate the screen attribute byte. */
#define MAX_SCREEN_BUF 160*2
Lisp_Object Vdos_unsupported_char_glyph;
extern unsigned char *encode_terminal_code (struct glyph *, int,
struct coding_system *);
static void
IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
{
unsigned char *screen_buf, *screen_bp, *screen_buf_end, *bp;
int unsupported_face = 0;
unsigned unsupported_char = '\177';
unsigned char screen_buf[MAX_SCREEN_BUF], *screen_bp, *bp;
int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
register int sl = str_len;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
struct tty_display_info *tty = FRAME_TTY (f);
struct frame *sf;
unsigned char *conversion_buffer;
@ -990,8 +991,6 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
if (str_len <= 0) return;
screen_buf = screen_bp = alloca (str_len * 2);
screen_buf_end = screen_buf + str_len * 2;
sf = SELECTED_FRAME();
/* 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)
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
coding->mode &= ~CODING_MODE_LAST_BLOCK;
screen_bp = &screen_buf[0];
while (sl > 0)
{
int cf;
int n;
/* Glyphs with GLYPH_MASK_PADDING bit set are actually there
only for the redisplay code to know how many columns does
this character occupy on the screen. Skip padding glyphs. */
if (CHAR_GLYPH_PADDING_P (*str))
/* If the face of this glyph is different from the current
screen face, update the screen attribute byte. */
cf = str->face_id;
if (cf != screen_face)
IT_set_face (cf); /* handles invalid faces gracefully */
/* Identify a run of glyphs with the same face. */
for (n = 1; n < sl; ++n)
if (str[n].face_id != cf)
break;
if (n >= sl)
/* This is the last glyph. */
coding->mode |= CODING_MODE_LAST_BLOCK;
conversion_buffer = encode_terminal_code (str, n, coding);
if (coding->produced > 0)
{
str++;
sl--;
}
else
{
/* If the face of this glyph is different from the current
screen face, update the screen attribute byte. */
cf = str->face_id;
if (cf != screen_face)
IT_set_face (cf); /* handles invalid faces gracefully */
if (sl <= 1)
/* This is the last glyph. */
coding->mode |= CODING_MODE_LAST_BLOCK;
conversion_buffer = encode_terminal_code (str, 1, coding);
if (coding->produced > 0)
/* Copy the encoded bytes to the screen buffer. */
for (bp = conversion_buffer; coding->produced--; bp++)
{
if (2*coding->produced > screen_buf_end - screen_bp)
/* Paranoia: discard bytes that would overrun the end of
the screen buffer. */
if (screen_bp - screen_buf <= MAX_SCREEN_BUF - 2)
{
/* The allocated buffer for screen writes is too small.
Flush it and loop again without incrementing STR, so
that the next loop will begin with the same glyph. */
int nbytes = screen_bp - screen_buf;
mouse_off_maybe ();
dosmemput (screen_buf, nbytes, (int)ScreenPrimary + offset);
if (screen_virtual_segment)
dosv_refresh_virtual_screen (offset, nbytes / 2);
new_pos_X += nbytes / 2;
offset += nbytes;
/* Prepare to reuse the same buffer again. */
screen_bp = screen_buf;
continue;
}
else
{
/* There's enough place in the allocated buffer to add
the encoding of this glyph. */
/* Copy the encoded bytes to the allocated buffer. */
for (bp = conversion_buffer; coding->produced--; bp++)
{
*screen_bp++ = (unsigned char)*bp;
*screen_bp++ = ScreenAttrib;
if (tty->termscript)
fputc (*bp, tty->termscript);
}
*screen_bp++ = (unsigned char)*bp;
*screen_bp++ = ScreenAttrib;
}
if (tty->termscript)
fputc (*bp, tty->termscript);
}
/* Update STR and its remaining length. */
str++;
sl--;
}
/* Update STR and its remaining length. */
str += n;
sl -= n;
}
/* Dump whatever is left in the screen buffer. */
/* Dump whatever we have in the screen buffer. */
mouse_off_maybe ();
dosmemput (screen_buf, screen_bp - screen_buf, (int)ScreenPrimary + offset);
if (screen_virtual_segment)