summaryrefslogtreecommitdiff
path: root/src/msdos.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2009-02-14 10:50:29 +0000
committerEli Zaretskii <eliz@gnu.org>2009-02-14 10:50:29 +0000
commitaff01dd96f651db009a0d318a14477ff1f91e1c8 (patch)
tree574a041234433d08db64505135bf141c4ace7ffa /src/msdos.c
parentb46957e2f4dacb404f30586c3675773a23715e16 (diff)
downloademacs-aff01dd96f651db009a0d318a14477ff1f91e1c8.tar.gz
(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.c100
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)
}
}
+/* 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))
- {
- 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 */
+
+ /* 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)
{
- /* 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)