[BACK]Return to screen-write.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/screen-write.c between version 1.221 and 1.222

version 1.221, 2023/09/14 13:01:35 version 1.222, 2023/09/15 15:49:05
Line 32 
Line 32 
                     const char *);                      const char *);
 static int      screen_write_overwrite(struct screen_write_ctx *,  static int      screen_write_overwrite(struct screen_write_ctx *,
                     struct grid_cell *, u_int);                      struct grid_cell *, u_int);
 static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,  static int      screen_write_combine(struct screen_write_ctx *,
                     const struct utf8_data *, u_int *, u_int *);                      const struct grid_cell *);
   
 struct screen_write_citem {  struct screen_write_citem {
         u_int                           x;          u_int                           x;
Line 1742 
Line 1742 
   
         if (ci->used == 0)          if (ci->used == 0)
                 return;                  return;
         ctx->flags &= ~SCREEN_WRITE_COMBINE;  
   
         before = screen_write_collect_trim(ctx, s->cy, s->cx, ci->used,          before = screen_write_collect_trim(ctx, s->cy, s->cx, ci->used,
             &wrapped);              &wrapped);
Line 1841 
Line 1840 
 {  {
         struct screen           *s = ctx->s;          struct screen           *s = ctx->s;
         struct grid             *gd = s->grid;          struct grid             *gd = s->grid;
         struct grid_cell         copy;          const struct utf8_data  *ud = &gc->data;
         const struct utf8_data  *ud = &gc->data, *previous = NULL, *combine;  
         struct grid_line        *gl;          struct grid_line        *gl;
         struct grid_cell_entry  *gce;          struct grid_cell_entry  *gce;
         struct grid_cell         tmp_gc, now_gc;          struct grid_cell         tmp_gc, now_gc;
         struct tty_ctx           ttyctx;          struct tty_ctx           ttyctx;
         u_int                    sx = screen_size_x(s), sy = screen_size_y(s);          u_int                    sx = screen_size_x(s), sy = screen_size_y(s);
         u_int                    width = ud->width, xx, last, cx, cy;          u_int                    width = ud->width, xx, not_wrap;
         int                      selected, skip = 1;          int                      selected, skip = 1;
   
         /* Ignore padding cells. */          /* Ignore padding cells. */
         if (gc->flags & GRID_FLAG_PADDING)          if (gc->flags & GRID_FLAG_PADDING)
                 return;                  return;
   
         /* Check if this cell needs to be combined with the previous cell. */          /* Get the previous cell to check for combining. */
         if (ctx->flags & SCREEN_WRITE_COMBINE)          if (screen_write_combine(ctx, gc) != 0)
                 previous = &ctx->previous;  
         switch (utf8_try_combined(ud, previous, &combine, &width)) {  
         case UTF8_DISCARD_NOW:  
                 log_debug("%s: UTF8_DISCARD_NOW (width %u)", __func__, width);  
                 ctx->flags &= ~SCREEN_WRITE_COMBINE;  
                 return;                  return;
         case UTF8_WRITE_NOW:  
                 log_debug("%s: UTF8_WRITE_NOW (width %u)", __func__, width);  
                 ctx->flags &= ~SCREEN_WRITE_COMBINE;  
                 break;  
         case UTF8_COMBINE_NOW:  
                 log_debug("%s: UTF8_COMBINE_NOW (width %u)", __func__, width);  
                 screen_write_collect_flush(ctx, 0, __func__);  
                 gc = screen_write_combine(ctx, combine, &xx, &cx);  
                 if (gc != NULL) {  
                         cx = s->cx; cy = s->cy;  
                         screen_write_set_cursor(ctx, xx, s->cy);  
                         screen_write_initctx(ctx, &ttyctx, 0);  
                         ttyctx.cell = gc;  
                         tty_write(tty_cmd_cell, &ttyctx);  
                         s->cx = cx; s->cy = cy;  
                 }  
                 ctx->flags &= ~SCREEN_WRITE_COMBINE;  
                 return;  
         case UTF8_WRITE_MAYBE_COMBINE:  
                 log_debug("%s: UTF8_WRITE_MAYBE_COMBINE (width %u)", __func__,  
                     width);  
                 utf8_copy(&ctx->previous, ud);  
                 ctx->flags |= SCREEN_WRITE_COMBINE;  
                 break;  
         case UTF8_DISCARD_MAYBE_COMBINE:  
                 log_debug("%s: UTF8_DISCARD_MAYBE_COMBINE (width %u)", __func__,  
                     width);  
                 utf8_copy(&ctx->previous, ud);  
                 ctx->flags |= SCREEN_WRITE_COMBINE;  
                 return;  
         }  
         if (width != ud->width) {  
                 memcpy(&copy, gc, sizeof copy);  
                 copy.data.width = width;  
                 gc = ©  
         }  
         ud = NULL;  
   
         /* Flush any existing scrolling. */          /* Flush any existing scrolling. */
         screen_write_collect_flush(ctx, 1, __func__);          screen_write_collect_flush(ctx, 1, __func__);
Line 1991 
Line 1947 
          * Move the cursor. If not wrapping, stick at the last character and           * Move the cursor. If not wrapping, stick at the last character and
          * replace it.           * replace it.
          */           */
         last = !(s->mode & MODE_WRAP);          not_wrap = !(s->mode & MODE_WRAP);
         if (s->cx <= sx - last - width)          if (s->cx <= sx - not_wrap - width)
                 screen_write_set_cursor(ctx, s->cx + width, -1);                  screen_write_set_cursor(ctx, s->cx + width, -1);
         else          else
                 screen_write_set_cursor(ctx,  sx - last, -1);                  screen_write_set_cursor(ctx,  sx - not_wrap, -1);
   
         /* Create space for character in insert mode. */          /* Create space for character in insert mode. */
         if (s->mode & MODE_INSERT) {          if (s->mode & MODE_INSERT) {
Line 2015 
Line 1971 
         }          }
 }  }
   
 /* Combine a UTF-8 zero-width character onto the previous. */  /* Combine a UTF-8 zero-width character onto the previous if necessary. */
 static const struct grid_cell *  static int
 screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud,  screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
     u_int *xx, u_int *cx)  
 {  {
         struct screen           *s = ctx->s;          struct screen           *s = ctx->s;
         struct grid             *gd = s->grid;          struct grid             *gd = s->grid;
         static struct grid_cell  gc;          const struct utf8_data  *ud = &gc->data;
         u_int                    n, width;          u_int                    n, cx = s->cx, cy = s->cy;
           struct grid_cell         last;
           struct tty_ctx           ttyctx;
           int                      force_wide = 0, zero_width = 0;
   
         /* Can't combine if at 0. */          /*
         if (s->cx == 0) {           * Is this character which makes no sense without being combined? If
                 *xx = 0;           * this is true then flag it here and discard the character (return 1)
                 return (NULL);           * if we cannot combine it.
         }           */
         *xx = s->cx;          if (utf8_is_zwj(ud))
                   zero_width = 1;
           else if (utf8_is_vs(ud))
                   zero_width = force_wide = 1;
           else if (ud->width == 0)
                   zero_width = 1;
   
         /* Empty data is out. */          /* Cannot combine empty character or at left. */
         if (ud->size == 0)          if (ud->size < 2 || cx == 0)
                 fatalx("UTF-8 data empty");                  return (zero_width);
           log_debug("%s: character %.*s at %u,%u (width %u)", __func__,
               (int)ud->size, ud->data, cx, cy, ud->width);
   
         /* Retrieve the previous cell. */          /* Find the cell to combine with. */
         for (n = 1; n <= s->cx; n++) {          n = 1;
                 grid_view_get_cell(gd, s->cx - n, s->cy, &gc);          grid_view_get_cell(gd, cx - n, cy, &last);
                 if (~gc.flags & GRID_FLAG_PADDING)          if (cx != 1 && (last.flags & GRID_FLAG_PADDING)) {
                         break;                  n = 2;
                   grid_view_get_cell(gd, cx - n, cy, &last);
         }          }
         if (n > s->cx)          if (n != last.data.width || (last.flags & GRID_FLAG_PADDING))
                 return (NULL);                  return (zero_width);
   
         /* Check there is enough space. */          /*
         if (gc.data.size + ud->size > sizeof gc.data.data)           * Check if we need to combine characters. This could be zero width
                 return (NULL);           * (zet above), a modifier character (with an existing Unicode
         (*xx) -= n;           * character) or a previous ZWJ.
            */
           if (!zero_width) {
                   if (utf8_is_modifier(ud)) {
                           if (last.data.size < 2)
                                   return (0);
                           force_wide = 1;
                   } else if (!utf8_has_zwj(&last.data))
                           return (0);
           }
   
         log_debug("%s: %.*s onto %.*s at %u,%u (width %u)", __func__,          /* Combining; flush any pending output. */
             (int)ud->size, ud->data, (int)gc.data.size, gc.data.data, *xx,          screen_write_collect_flush(ctx, 0, __func__);
             s->cy, gc.data.width);  
   
           log_debug("%s: %.*s -> %.*s at %u,%u (offset %u, width %u)", __func__,
               (int)ud->size, ud->data, (int)last.data.size, last.data.data,
               cx - n, cy, n, last.data.width);
   
         /* Append the data. */          /* Append the data. */
         memcpy(gc.data.data + gc.data.size, ud->data, ud->size);          memcpy(last.data.data + last.data.size, ud->data, ud->size);
         gc.data.size += ud->size;          last.data.size += ud->size;
         width = gc.data.width;  
   
         /* If this is U+FE0F VARIATION SELECTOR-16, force the width to 2. */          /* Force the width to 2 for modifiers and variation selector. */
         if (gc.data.width == 1 &&          if (last.data.width == 1 && force_wide) {
             ud->size == 3 &&                  last.data.width = 2;
             memcmp(ud->data, "\357\270\217", 3) == 0) {                  n = 2;
                 grid_view_set_padding(gd, (*xx) + 1, s->cy);                  cx++;
                 gc.data.width = 2;          } else
                 width += 2;                  force_wide = 0;
         }  
   
         /* Set the new cell. */          /* Set the new cell. */
         grid_view_set_cell(gd, *xx, s->cy, &gc);          grid_view_set_cell(gd, cx - n, cy, &last);
           if (force_wide)
                   grid_view_set_padding(gd, cx, cy);
   
         *cx = (*xx) + width;          /*
         log_debug("%s: character at %u; cursor at %u", __func__, *xx, *cx);           * Redraw the combined cell. If forcing the cell to width 2, reset the
         return (&gc);           * cached cursor position in the tty, since we don't really know
            * whether the terminal thought the character was width 1 or width 2
            * and what it is going to do now.
            */
           screen_write_set_cursor(ctx, cx - n, cy);
           screen_write_initctx(ctx, &ttyctx, 0);
           ttyctx.cell = &last;
           ttyctx.num = force_wide; /* reset cached cursor position */
           tty_write(tty_cmd_cell, &ttyctx);
           screen_write_set_cursor(ctx, cx, cy);
   
           return (1);
 }  }
   
 /*  /*

Legend:
Removed from v.1.221  
changed lines
  Added in v.1.222