mirror of
https://github.com/tmux/tmux.git
synced 2026-02-25 04:15:04 +00:00
Associate each visible_ranges with some other object (tty, popup_data, etc) so
it is easier to keep track of its lifecycle, but still avoid allocating for each use.
This commit is contained in:
10
menu.c
10
menu.c
@@ -34,6 +34,7 @@ struct menu_data {
|
||||
|
||||
struct cmd_find_state fs;
|
||||
struct screen s;
|
||||
struct visible_ranges r;
|
||||
|
||||
u_int px;
|
||||
u_int py;
|
||||
@@ -181,15 +182,16 @@ menu_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy)
|
||||
}
|
||||
|
||||
/* Return parts of the input range which are not obstructed by the menu. */
|
||||
void
|
||||
struct visible_ranges *
|
||||
menu_check_cb(__unused struct client *c, void *data, u_int px, u_int py,
|
||||
u_int nx, struct visible_ranges *r)
|
||||
u_int nx)
|
||||
{
|
||||
struct menu_data *md = data;
|
||||
struct menu *menu = md->menu;
|
||||
|
||||
server_client_overlay_range(md->px, md->py, menu->width + 4,
|
||||
menu->count + 2, px, py, nx, r);
|
||||
menu->count + 2, px, py, nx, &md->r);
|
||||
return (&md->r);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -232,7 +234,9 @@ menu_free_cb(__unused struct client *c, void *data)
|
||||
if (md->cb != NULL)
|
||||
md->cb(md->menu, UINT_MAX, KEYC_NONE, md->data);
|
||||
|
||||
free(md->r.ranges);
|
||||
screen_free(&md->s);
|
||||
|
||||
menu_free(md->menu);
|
||||
free(md);
|
||||
}
|
||||
|
||||
79
popup.c
79
popup.c
@@ -39,6 +39,9 @@ struct popup_data {
|
||||
struct grid_cell defaults;
|
||||
struct colour_palette palette;
|
||||
|
||||
struct visible_ranges r;
|
||||
struct visible_ranges or[2];
|
||||
|
||||
struct job *job;
|
||||
struct input_ctx *ictx;
|
||||
int status;
|
||||
@@ -164,50 +167,57 @@ popup_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy)
|
||||
}
|
||||
|
||||
/* Return parts of the input range which are not obstructed by the popup. */
|
||||
static void
|
||||
popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx,
|
||||
struct visible_ranges *r)
|
||||
static struct visible_ranges *
|
||||
popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx)
|
||||
{
|
||||
struct popup_data *pd = data;
|
||||
static struct visible_ranges or[2] = { { NULL, 0, 0 }, { NULL, 0, 0 } };
|
||||
u_int i, j, k = 0;
|
||||
struct popup_data *pd = data;
|
||||
struct visible_ranges *r = &pd->r;
|
||||
struct visible_ranges *mr;
|
||||
u_int i, j, k = 0;
|
||||
|
||||
if (pd->md != NULL) {
|
||||
/* Check each returned range for the menu against the popup. */
|
||||
menu_check_cb(c, pd->md, px, py, nx, r);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
server_client_overlay_range(pd->px, pd->py, pd->sx,
|
||||
pd->sy, r->ranges[i].px, py, r->ranges[i].nx, &or[i]);
|
||||
}
|
||||
/*
|
||||
* Work out the visible ranges for the menu (that is, the
|
||||
* ranges not covered by the menu). A menu should have at most
|
||||
* two ranges and we rely on this being the case.
|
||||
*/
|
||||
mr = menu_check_cb(c, pd->md, px, py, nx);
|
||||
if (mr->used > 2)
|
||||
fatalx("too many menu ranges");
|
||||
|
||||
/* Caller must free when no longer used. */
|
||||
if (r->size == 0) {
|
||||
r->ranges = xcalloc(2, sizeof(struct visible_range));
|
||||
r->size = 2;
|
||||
r->used = 0;
|
||||
/*
|
||||
* Walk the ranges still visible under the menu and check if
|
||||
* each is visible under the popup as well. At most there can be
|
||||
* three total ranges if popup and menu do not intersect.
|
||||
*/
|
||||
for (i = 0; i < mr->used; i++) {
|
||||
server_client_overlay_range(pd->px, pd->py, pd->sx,
|
||||
pd->sy, r->ranges[i].px, py, r->ranges[i].nx,
|
||||
&pd->or[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* or has up to OVERLAY_MAX_RANGES non-overlapping ranges,
|
||||
* ordered from left to right. Collect them in the output.
|
||||
* We now have nonoverlapping ranges from left to right.
|
||||
* Combine them together into the output.
|
||||
*/
|
||||
for (i = 0; i < r->used; i++) {
|
||||
/* Each or[i] only has up to 2 ranges. */
|
||||
for (j = 0; j < or[i].used; j++) {
|
||||
if (or[i].ranges[j].nx > 0) {
|
||||
r->ranges[k].px = or[i].ranges[j].px;
|
||||
r->ranges[k].nx = or[i].ranges[j].nx;
|
||||
k++;
|
||||
}
|
||||
server_client_ensure_ranges(r, 3);
|
||||
for (i = 0; i < mr->used; i++) {
|
||||
for (j = 0; j < pd->or[i].used; j++) {
|
||||
if (pd->or[i].ranges[j].nx == 0)
|
||||
continue;
|
||||
if (k >= 3)
|
||||
fatalx("too many popup & menu ranges");
|
||||
r->ranges[k].px = pd->or[i].ranges[j].px;
|
||||
r->ranges[k].nx = pd->or[i].ranges[j].nx;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
return (r);
|
||||
}
|
||||
|
||||
server_client_overlay_range(pd->px, pd->py, pd->sx, pd->sy,
|
||||
px, py, nx, r);
|
||||
|
||||
return;
|
||||
server_client_overlay_range(pd->px, pd->py, pd->sx, pd->sy, px, py, nx,
|
||||
r);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -288,6 +298,9 @@ popup_free_cb(struct client *c, void *data)
|
||||
job_free(pd->job);
|
||||
input_free(pd->ictx);
|
||||
|
||||
free(pd->or[0].ranges);
|
||||
free(pd->or[1].ranges);
|
||||
free(pd->r.ranges);
|
||||
screen_free(&pd->s);
|
||||
colour_palette_free(&pd->palette);
|
||||
|
||||
@@ -551,7 +564,7 @@ popup_key_cb(struct client *c, void *data, struct key_event *event)
|
||||
(event->key == '\033' || event->key == ('c'|KEYC_CTRL)))
|
||||
return (1);
|
||||
if (pd->job == NULL && (pd->flags & POPUP_CLOSEANYKEY) &&
|
||||
!KEYC_IS_MOUSE(event->key) && !KEYC_IS_PASTE(event->key))
|
||||
!KEYC_IS_MOUSE(event->key) && !KEYC_IS_PASTE(event->key))
|
||||
return (1);
|
||||
if (pd->job != NULL) {
|
||||
if (KEYC_IS_MOUSE(event->key)) {
|
||||
|
||||
@@ -808,23 +808,23 @@ screen_redraw_draw_border_arrows(struct screen_redraw_ctx *ctx, u_int i,
|
||||
static void
|
||||
screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
||||
{
|
||||
struct client *c = ctx->c;
|
||||
struct session *s = c->session;
|
||||
struct window *w = s->curw->window;
|
||||
struct options *oo = w->options;
|
||||
struct tty *tty = &c->tty;
|
||||
struct format_tree *ft;
|
||||
struct window_pane *wp, *active = server_client_get_pane(c);
|
||||
struct grid_cell gc;
|
||||
const struct grid_cell *tmp;
|
||||
static struct visible_ranges r = { NULL, 0, 0 };
|
||||
u_int cell_type;
|
||||
u_int x = ctx->ox + i, y = ctx->oy + j;
|
||||
int isolates;
|
||||
struct client *c = ctx->c;
|
||||
struct session *s = c->session;
|
||||
struct window *w = s->curw->window;
|
||||
struct options *oo = w->options;
|
||||
struct tty *tty = &c->tty;
|
||||
struct format_tree *ft;
|
||||
struct window_pane *wp, *active = server_client_get_pane(c);
|
||||
struct grid_cell gc;
|
||||
const struct grid_cell *tmp;
|
||||
u_int cell_type;
|
||||
u_int x = ctx->ox + i, y = ctx->oy + j;
|
||||
int isolates;
|
||||
struct visible_ranges *r;
|
||||
|
||||
if (c->overlay_check != NULL) {
|
||||
c->overlay_check(c, c->overlay_data, x, y, 1, &r);
|
||||
if (r.ranges[0].nx + r.ranges[1].nx == 0)
|
||||
r = c->overlay_check(c, c->overlay_data, x, y, 1);
|
||||
if (server_client_ranges_is_empty(r))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -938,14 +938,15 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
|
||||
static void
|
||||
screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
||||
{
|
||||
struct client *c = ctx->c;
|
||||
struct window *w = c->session->curw->window;
|
||||
struct tty *tty = &c->tty;
|
||||
struct screen *s = wp->screen;
|
||||
struct colour_palette *palette = &wp->palette;
|
||||
struct grid_cell defaults;
|
||||
static struct visible_ranges vr;
|
||||
u_int i, j, top, x, y, px, width, r;
|
||||
struct client *c = ctx->c;
|
||||
struct window *w = c->session->curw->window;
|
||||
struct tty *tty = &c->tty;
|
||||
struct screen *s = wp->screen;
|
||||
struct colour_palette *palette = &wp->palette;
|
||||
struct grid_cell defaults;
|
||||
struct visible_ranges *r;
|
||||
struct visible_range *rr;
|
||||
u_int i, j, k, top, x, y, width;
|
||||
|
||||
if (wp->base.mode & MODE_SYNC)
|
||||
screen_write_stop_sync(wp);
|
||||
@@ -989,22 +990,15 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
||||
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
|
||||
__func__, c->name, wp->id, i, j, x, y, width);
|
||||
|
||||
/* xxxx Breaking up the tty_draw_line like this isn't fully working. */
|
||||
tty_check_overlay_range(tty, x, y, width, &vr);
|
||||
|
||||
tty_default_colours(&defaults, wp);
|
||||
|
||||
for (r=0; r < vr.used; r++) {
|
||||
if (vr.ranges[r].nx == 0)
|
||||
continue;
|
||||
/* Convert window coordinates to tty coordinates. */
|
||||
px = vr.ranges[r].px;
|
||||
/* i is px of cell, add px of region, sub the
|
||||
* pane offset. If you don't sub offset,
|
||||
* contents of pane shifted. note: i apparently unnec.
|
||||
*/
|
||||
tty_draw_line(tty, s, /* i + */ vr.ranges[r].px - wp->xoff, j,
|
||||
vr.ranges[r].nx, px, y, &defaults, palette);
|
||||
r = tty_check_overlay_range(tty, x, y, width);
|
||||
for (k = 0; k < r->used; k++) {
|
||||
rr = &r->ranges[k];
|
||||
if (rr->nx != 0) {
|
||||
tty_draw_line(tty, s, rr->px - wp->xoff, j,
|
||||
rr->nx, rr->px, y, &defaults, palette);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +161,29 @@ server_client_clear_overlay(struct client *c)
|
||||
server_redraw_client(c);
|
||||
}
|
||||
|
||||
/* Are these ranges empty? That is, nothing is visible. */
|
||||
int
|
||||
server_client_ranges_is_empty(struct visible_ranges *r)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < r->used; i++) {
|
||||
if (r->ranges[i].nx != 0)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Ensure we have space for at least n ranges. */
|
||||
void
|
||||
server_client_ensure_ranges(struct visible_ranges *r, u_int n)
|
||||
{
|
||||
if (r->size >= n)
|
||||
return;
|
||||
r->ranges = xrecallocarray(r->ranges, r->size, n, sizeof *r->ranges);
|
||||
r->size = n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given overlay position and dimensions, return parts of the input range which
|
||||
* are visible.
|
||||
@@ -169,22 +192,17 @@ void
|
||||
server_client_overlay_range(u_int x, u_int y, u_int sx, u_int sy, u_int px,
|
||||
u_int py, u_int nx, struct visible_ranges *r)
|
||||
{
|
||||
u_int ox, onx;
|
||||
|
||||
/* Caller must free when no longer used. */
|
||||
if (r->size == 0) {
|
||||
r->ranges = xcalloc(2, sizeof(struct visible_range));
|
||||
r->size = 2;
|
||||
r->used = 0;
|
||||
}
|
||||
u_int ox, onx;
|
||||
|
||||
/* Trivial case of no overlap in the y direction. */
|
||||
if (py < y || py > y + sy - 1) {
|
||||
server_client_ensure_ranges(r, 1);
|
||||
r->ranges[0].px = px;
|
||||
r->ranges[0].nx = nx;
|
||||
r->used = 1;
|
||||
return;
|
||||
}
|
||||
server_client_ensure_ranges(r, 2);
|
||||
|
||||
/* Visible bit to the left of the popup. */
|
||||
if (px < x) {
|
||||
|
||||
48
tmux.h
48
tmux.h
@@ -956,7 +956,7 @@ struct screen_sel;
|
||||
struct screen_titles;
|
||||
struct screen {
|
||||
char *title;
|
||||
char *path;
|
||||
char *path;
|
||||
struct screen_titles *titles;
|
||||
|
||||
struct grid *grid; /* grid data */
|
||||
@@ -1532,6 +1532,19 @@ struct key_event {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/* Visible range array element. */
|
||||
struct visible_range {
|
||||
u_int px; /* start */
|
||||
u_int nx; /* length */
|
||||
};
|
||||
|
||||
/* Visible areas not obstructed. */
|
||||
struct visible_ranges {
|
||||
struct visible_range *ranges; /* dynamically allocated array */
|
||||
u_int used; /* number of entries in ranges */
|
||||
u_int size; /* allocated capacity of ranges */
|
||||
};
|
||||
|
||||
/* Terminal definition. */
|
||||
struct tty_term {
|
||||
char *name;
|
||||
@@ -1599,6 +1612,7 @@ struct tty {
|
||||
size_t discarded;
|
||||
|
||||
struct termios tio;
|
||||
struct visible_ranges r;
|
||||
|
||||
struct grid_cell cell;
|
||||
struct grid_cell last_cell;
|
||||
@@ -1915,28 +1929,15 @@ struct client_window {
|
||||
};
|
||||
RB_HEAD(client_windows, client_window);
|
||||
|
||||
/* Visible range array element. */
|
||||
struct visible_range {
|
||||
u_int px; /* Start */
|
||||
u_int nx; /* Length */
|
||||
};
|
||||
|
||||
/* Visible areas not obstructed. */
|
||||
struct visible_ranges {
|
||||
struct visible_range *ranges; /* dynamically allocated array */
|
||||
size_t used; /* number of entries in ranges */
|
||||
size_t size; /* allocated capacity of ranges */
|
||||
};
|
||||
|
||||
/* Client connection. */
|
||||
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
|
||||
typedef void (*prompt_free_cb)(void *);
|
||||
typedef void (*overlay_check_cb)(struct client*, void *, u_int, u_int, u_int,
|
||||
struct visible_ranges *);
|
||||
typedef struct visible_ranges *(*overlay_check_cb)(struct client*, void *,
|
||||
u_int, u_int, u_int);
|
||||
typedef struct screen *(*overlay_mode_cb)(struct client *, void *, u_int *,
|
||||
u_int *);
|
||||
u_int *);
|
||||
typedef void (*overlay_draw_cb)(struct client *, void *,
|
||||
struct screen_redraw_ctx *);
|
||||
struct screen_redraw_ctx *);
|
||||
typedef int (*overlay_key_cb)(struct client *, void *, struct key_event *);
|
||||
typedef void (*overlay_free_cb)(struct client *, void *);
|
||||
typedef void (*overlay_resize_cb)(struct client *, void *);
|
||||
@@ -2559,8 +2560,8 @@ void tty_default_attributes(struct tty *, const struct grid_cell *,
|
||||
void tty_update_mode(struct tty *, int, struct screen *);
|
||||
const struct grid_cell *tty_check_codeset(struct tty *,
|
||||
const struct grid_cell *);
|
||||
void tty_check_overlay_range(struct tty *, u_int, u_int, u_int,
|
||||
struct visible_ranges *);
|
||||
struct visible_ranges *tty_check_overlay_range(struct tty *, u_int, u_int,
|
||||
u_int);
|
||||
|
||||
/* tty-draw.c */
|
||||
void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
|
||||
@@ -2577,7 +2578,6 @@ void tty_close(struct tty *);
|
||||
void tty_free(struct tty *);
|
||||
void tty_update_features(struct tty *);
|
||||
void tty_set_selection(struct tty *, const char *, const char *, size_t);
|
||||
u_int tty_cell_width(const struct grid_cell *, u_int);
|
||||
void tty_write(void (*)(struct tty *, const struct tty_ctx *),
|
||||
struct tty_ctx *);
|
||||
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
|
||||
@@ -2920,6 +2920,8 @@ void server_client_set_overlay(struct client *, u_int, overlay_check_cb,
|
||||
overlay_mode_cb, overlay_draw_cb, overlay_key_cb,
|
||||
overlay_free_cb, overlay_resize_cb, void *);
|
||||
void server_client_clear_overlay(struct client *);
|
||||
void server_client_ensure_ranges(struct visible_ranges *, u_int);
|
||||
int server_client_ranges_is_empty(struct visible_ranges *);
|
||||
void server_client_overlay_range(u_int, u_int, u_int, u_int, u_int, u_int,
|
||||
u_int, struct visible_ranges *);
|
||||
void server_client_set_key_table(struct client *, const char *);
|
||||
@@ -3623,8 +3625,8 @@ int menu_display(struct menu *, int, int, struct cmdq_item *,
|
||||
const char *, const char *, struct cmd_find_state *,
|
||||
menu_choice_cb, void *);
|
||||
struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *);
|
||||
void menu_check_cb(struct client *, void *, u_int, u_int, u_int,
|
||||
struct visible_ranges *);
|
||||
struct visible_ranges *menu_check_cb(struct client *, void *, u_int, u_int,
|
||||
u_int);
|
||||
void menu_draw_cb(struct client *, void *,
|
||||
struct screen_redraw_ctx *);
|
||||
void menu_free_cb(struct client *, void *);
|
||||
|
||||
94
tty.c
94
tty.c
@@ -66,8 +66,6 @@ static void tty_emulate_repeat(struct tty *, enum tty_code_code,
|
||||
enum tty_code_code, u_int);
|
||||
static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
|
||||
static int tty_check_overlay(struct tty *, u_int, u_int);
|
||||
void tty_check_overlay_range(struct tty *, u_int, u_int, u_int,
|
||||
struct visible_ranges *);
|
||||
|
||||
#ifdef ENABLE_SIXEL
|
||||
static void tty_write_one(void (*)(struct tty *, const struct tty_ctx *),
|
||||
@@ -523,6 +521,8 @@ void
|
||||
tty_free(struct tty *tty)
|
||||
{
|
||||
tty_close(tty);
|
||||
|
||||
free(tty->r.ranges);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1411,66 +1411,34 @@ tty_check_codeset(struct tty *tty, const struct grid_cell *gc)
|
||||
return (&new);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the effective display width (in terminal columns) of a grid cell
|
||||
* when it will be drawn at terminal column atcol.
|
||||
*/
|
||||
u_int
|
||||
tty_cell_width(const struct grid_cell *gcp, u_int atcol)
|
||||
{
|
||||
/* Tabs expand to the next tab stop (tab width = 8). */
|
||||
if (gcp->flags & GRID_FLAG_TAB)
|
||||
return (8 - (atcol % 8));
|
||||
/* Normal characters: width stored in cell (1 or 2 usually). */
|
||||
return (gcp->data.width);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a single character is obstructed by the overlay and return a
|
||||
* boolean.
|
||||
*/
|
||||
/* Check if a single character is covered by the overlay. */
|
||||
static int
|
||||
tty_check_overlay(struct tty *tty, u_int px, u_int py)
|
||||
{
|
||||
static struct visible_ranges r = { NULL, 0, 0 };
|
||||
struct visible_ranges *r;
|
||||
|
||||
/*
|
||||
* A unit width range will always return nx[2] == 0 from a check, even
|
||||
* with multiple overlays, so it's sufficient to check just the first
|
||||
* two entries.
|
||||
* With a single character, if there is anything visible (that is, the
|
||||
* range is not empty), it must be that character.
|
||||
*/
|
||||
if (r.size == 0) {
|
||||
r.ranges = xcalloc(2, sizeof(struct visible_range));
|
||||
r.size = 2;
|
||||
}
|
||||
|
||||
tty_check_overlay_range(tty, px, py, 1, &r);
|
||||
if (r.ranges[0].nx + r.ranges[1].nx == 0)
|
||||
return (0);
|
||||
return (1);
|
||||
r = tty_check_overlay_range(tty, px, py, 1);
|
||||
return (!server_client_ranges_is_empty(r));
|
||||
}
|
||||
|
||||
/* Return parts of the input range which are visible. */
|
||||
void
|
||||
tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx,
|
||||
struct visible_ranges *r)
|
||||
struct visible_ranges *
|
||||
tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
|
||||
if (r->size == 0) {
|
||||
r->ranges = xcalloc(2, sizeof(struct visible_range));
|
||||
r->size = 2;
|
||||
}
|
||||
|
||||
if (c->overlay_check == NULL) {
|
||||
r->ranges[0].px = px;
|
||||
r->ranges[0].nx = nx;
|
||||
r->used = 1;
|
||||
return;
|
||||
server_client_ensure_ranges(&tty->r, 1);
|
||||
tty->r.ranges[0].px = px;
|
||||
tty->r.ranges[0].nx = nx;
|
||||
tty->r.used = 1;
|
||||
return (&tty->r);
|
||||
}
|
||||
|
||||
c->overlay_check(c, c->overlay_data, px, py, nx, r);
|
||||
return;
|
||||
return (c->overlay_check(c, c->overlay_data, px, py, nx));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SIXEL
|
||||
@@ -1998,7 +1966,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
const struct grid_cell *gcp = ctx->cell;
|
||||
struct screen *s = ctx->s;
|
||||
static struct visible_ranges r = { NULL, 0, 0 };
|
||||
struct visible_ranges *r;
|
||||
u_int px, py, i, vis = 0;
|
||||
|
||||
px = ctx->xoff + ctx->ocx - ctx->wox;
|
||||
@@ -2015,9 +1983,9 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||
|
||||
/* Handle partially obstructed wide characters. */
|
||||
if (gcp->data.width > 1) {
|
||||
tty_check_overlay_range(tty, px, py, gcp->data.width, &r);
|
||||
for (i = 0; i < r.used; i++)
|
||||
vis += r.ranges[i].nx;
|
||||
r = tty_check_overlay_range(tty, px, py, gcp->data.width);
|
||||
for (i = 0; i < r->used; i++)
|
||||
vis += r->ranges[i].nx;
|
||||
if (vis < gcp->data.width) {
|
||||
tty_draw_line(tty, s, s->cx, s->cy, gcp->data.width,
|
||||
px, py, &ctx->defaults, ctx->palette);
|
||||
@@ -2043,7 +2011,8 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||
void
|
||||
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
struct visible_ranges r = { NULL, 0, 0 };
|
||||
struct visible_ranges *r;
|
||||
struct visible_range *rr;
|
||||
u_int i, px, py, cx;
|
||||
char *cp = ctx->ptr;
|
||||
|
||||
@@ -2068,20 +2037,21 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
|
||||
|
||||
tty_margin_off(tty);
|
||||
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette, ctx->s->hyperlinks);
|
||||
tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette,
|
||||
ctx->s->hyperlinks);
|
||||
|
||||
/* Get tty position from pane position for overlay check. */
|
||||
px = ctx->xoff + ctx->ocx - ctx->wox;
|
||||
py = ctx->yoff + ctx->ocy - ctx->woy;
|
||||
|
||||
tty_check_overlay_range(tty, px, py, ctx->num, &r);
|
||||
for (i = 0; i < r.used; i++) {
|
||||
if (r.ranges[i].nx == 0)
|
||||
continue;
|
||||
/* Convert back to pane position for printing. */
|
||||
cx = r.ranges[i].px - ctx->xoff + ctx->wox;
|
||||
tty_cursor_pane_unless_wrap(tty, ctx, cx, ctx->ocy);
|
||||
tty_putn(tty, cp + r.ranges[i].px - px, r.ranges[i].nx, r.ranges[i].nx);
|
||||
r = tty_check_overlay_range(tty, px, py, ctx->num);
|
||||
for (i = 0; i < r->used; i++) {
|
||||
rr = &r->ranges[i];
|
||||
if (rr->nx != 0) {
|
||||
cx = rr->px - ctx->xoff + ctx->wox;
|
||||
tty_cursor_pane_unless_wrap(tty, ctx, cx, ctx->ocy);
|
||||
tty_putn(tty, cp + rr->px - px, rr->nx, rr->nx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user