grid: reflow: handle styled underlines

This commit is contained in:
Daniel Eklöf 2024-06-24 00:57:03 +02:00
parent 8e2402605e
commit b20302c2a7
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

166
grid.c
View file

@ -238,6 +238,18 @@ uri_range_append(struct row_data *extra, int start, int end, uint64_t id,
uri_range_append_no_strdup(extra, start, end, id, xstrdup(uri)); uri_range_append_no_strdup(extra, start, end, id, xstrdup(uri));
} }
static void
curly_range_append(struct row_data *extra, int start, int end,
struct curly_range_data data)
{
range_ensure_size(&extra->curly_ranges, 1);
extra->curly_ranges.v[extra->curly_ranges.count++] = (struct row_range){
.start = start,
.end = end,
.curly = data,
};
}
static void static void
range_delete(struct row_ranges *ranges, enum row_range_type type, size_t idx) range_delete(struct row_ranges *ranges, enum row_range_type type, size_t idx)
{ {
@ -303,8 +315,8 @@ grid_snapshot(const struct grid *grid)
} }
for (int i = 0; i < extra->curly_ranges.count; i++) { for (int i = 0; i < extra->curly_ranges.count; i++) {
//const struct row_range *range = &extra->curly_ranges.v[i]; const struct row_range *range = &extra->curly_ranges.v[i];
BUG("TODO"); curly_range_append(clone_extra, range->start, range->end, range->curly);
} }
} else } else
clone_row->extra = NULL; clone_row->extra = NULL;
@ -535,18 +547,17 @@ grid_resize_without_reflow(
uri_range_append(new_extra, start, end, range->uri.id, range->uri.uri); uri_range_append(new_extra, start, end, range->uri.id, range->uri.uri);
} }
for (int i = 0; i < old_extra->uri_ranges.count; i++) { for (int i = 0; i < old_extra->curly_ranges.count; i++) {
const struct row_range *range = &old_extra->uri_ranges.v[i]; const struct row_range *range = &old_extra->curly_ranges.v[i];
if (range->start >= new_cols) { if (range->start >= new_cols) {
/* The whole range is truncated */ /* The whole range is truncated */
continue; continue;
} }
//const int start = range->start; const int start = range->start;
//const int end = min(range->end, new_cols - 1); const int end = min(range->end, new_cols - 1);
//uri_range_append(new_extra, start, end, range->uri.id, range->uri.uri); curly_range_append(new_extra, start, end, range->curly);
BUG("TODO");
} }
} }
@ -623,8 +634,8 @@ reflow_uri_range_start(struct row_range *range, struct row *new_row,
int new_col_idx) int new_col_idx)
{ {
ensure_row_has_extra_data(new_row); ensure_row_has_extra_data(new_row);
uri_range_append_no_strdup uri_range_append_no_strdup(
(new_row->extra, new_col_idx, -1, range->uri.id, range->uri.uri); new_row->extra, new_col_idx, -1, range->uri.id, range->uri.uri);
range->uri.uri = NULL; range->uri.uri = NULL;
} }
@ -643,6 +654,33 @@ reflow_uri_range_end(struct row_range *range, struct row *new_row,
new_range->end = new_col_idx; new_range->end = new_col_idx;
} }
static void
reflow_curly_range_start(struct row_range *range, struct row *new_row,
int new_col_idx)
{
ensure_row_has_extra_data(new_row);
curly_range_append(new_row->extra, new_col_idx, -1, range->curly);
}
static void
reflow_curly_range_end(struct row_range *range, struct row *new_row,
int new_col_idx)
{
struct row_data *extra = new_row->extra;
xassert(extra->curly_ranges.count > 0);
struct row_range *new_range =
&extra->curly_ranges.v[extra->curly_ranges.count - 1];
xassert(new_range->curly.style == range->curly.style);
xassert(new_range->curly.color_src == range->curly.color_src);
xassert(new_range->curly.color == range->curly.color);
xassert(new_range->end < 0);
new_range->end = new_col_idx;
}
static struct row * static struct row *
_line_wrap(struct grid *old_grid, struct row **new_grid, struct row *row, _line_wrap(struct grid *old_grid, struct row **new_grid, struct row *row,
int *row_idx, int *col_idx, int row_count, int col_count) int *row_idx, int *col_idx, int row_count, int col_count)
@ -703,6 +741,21 @@ _line_wrap(struct grid *old_grid, struct row **new_grid, struct row *row,
} }
} }
if (extra->curly_ranges.count > 0) {
struct row_range *range =
&extra->curly_ranges.v[extra->curly_ranges.count - 1];
if (range->end < 0) {
/* Terminate URI range on the previous row */
range->end = col_count - 1;
/* Open a new range on the new/current row */
ensure_row_has_extra_data(new_row);
curly_range_append(new_row->extra, 0, -1, range->curly);
}
}
return new_row; return new_row;
} }
@ -887,12 +940,13 @@ grid_resize_and_reflow(
tp = NULL; tp = NULL;
/* Does this row have any URIs? */ /* Does this row have any URIs? */
struct row_range *range, *range_terminator; struct row_range *uri_range, *uri_range_terminator;
struct row_range *curly_range, *curly_range_terminator;
struct row_data *extra = old_row->extra; struct row_data *extra = old_row->extra;
if (extra != NULL && extra->uri_ranges.count > 0) { if (extra != NULL && extra->uri_ranges.count > 0) {
range = &extra->uri_ranges.v[0]; uri_range = &extra->uri_ranges.v[0];
range_terminator = &extra->uri_ranges.v[extra->uri_ranges.count]; uri_range_terminator = &extra->uri_ranges.v[extra->uri_ranges.count];
/* Make sure the *last* URI range's end point is included /* Make sure the *last* URI range's end point is included
* in the copy */ * in the copy */
@ -900,18 +954,32 @@ grid_resize_and_reflow(
&extra->uri_ranges.v[extra->uri_ranges.count - 1]; &extra->uri_ranges.v[extra->uri_ranges.count - 1];
col_count = max(col_count, last_on_row->end + 1); col_count = max(col_count, last_on_row->end + 1);
} else } else
range = range_terminator = NULL; uri_range = uri_range_terminator = NULL;
if (extra != NULL && extra->curly_ranges.count > 0) {
curly_range = &extra->curly_ranges.v[0];
curly_range_terminator = &extra->curly_ranges.v[extra->curly_ranges.count];
const struct row_range *last_on_row =
&extra->curly_ranges.v[extra->curly_ranges.count - 1];
col_count = max(col_count, last_on_row->end + 1);
} else
curly_range = curly_range_terminator = NULL;
for (int start = 0, left = col_count; left > 0;) { for (int start = 0, left = col_count; left > 0;) {
int end; int end;
bool tp_break = false; bool tp_break = false;
bool uri_break = false; bool uri_break = false;
bool curly_break = false;
bool ftcs_break = false; bool ftcs_break = false;
/* Figure out where to end this chunk */ /* Figure out where to end this chunk */
{ {
const int uri_col = range != range_terminator const int uri_col = uri_range != uri_range_terminator
? ((range->start >= start ? range->start : range->end) + 1) ? ((uri_range->start >= start ? uri_range->start : uri_range->end) + 1)
: INT_MAX;
const int curly_col = curly_range != curly_range_terminator
? ((curly_range->start >= start ? curly_range->start : curly_range->end) + 1)
: INT_MAX; : INT_MAX;
const int tp_col = tp != NULL ? tp->col + 1 : INT_MAX; const int tp_col = tp != NULL ? tp->col + 1 : INT_MAX;
const int ftcs_col = old_row->shell_integration.cmd_start >= start const int ftcs_col = old_row->shell_integration.cmd_start >= start
@ -920,9 +988,10 @@ grid_resize_and_reflow(
? old_row->shell_integration.cmd_end + 1 ? old_row->shell_integration.cmd_end + 1
: INT_MAX; : INT_MAX;
end = min(col_count, min(min(tp_col, uri_col), ftcs_col)); end = min(col_count, min(min(tp_col, min(uri_col, curly_col)), ftcs_col));
uri_break = end == uri_col; uri_break = end == uri_col;
curly_break = end == curly_col;
tp_break = end == tp_col; tp_break = end == tp_col;
ftcs_break = end == ftcs_col; ftcs_break = end == ftcs_col;
} }
@ -1033,15 +1102,28 @@ grid_resize_and_reflow(
} }
if (uri_break) { if (uri_break) {
xassert(range != NULL); xassert(uri_range != NULL);
if (range->start == end - 1) if (uri_range->start == end - 1)
reflow_uri_range_start(range, new_row, new_col_idx - 1); reflow_uri_range_start(uri_range, new_row, new_col_idx - 1);
if (range->end == end - 1) { if (uri_range->end == end - 1) {
reflow_uri_range_end(range, new_row, new_col_idx - 1); reflow_uri_range_end(uri_range, new_row, new_col_idx - 1);
grid_row_uri_range_destroy(range); grid_row_uri_range_destroy(uri_range);
range++; uri_range++;
}
}
if (curly_break) {
xassert(curly_range != NULL);
if (curly_range->start == end - 1)
reflow_curly_range_start(curly_range, new_row, new_col_idx - 1);
if (curly_range->end == end - 1) {
reflow_curly_range_end(curly_range, new_row, new_col_idx - 1);
grid_row_curly_range_destroy(curly_range);
curly_range++;
} }
} }
@ -1067,20 +1149,26 @@ grid_resize_and_reflow(
if (r + 1 < old_rows) if (r + 1 < old_rows)
line_wrap(); line_wrap();
else if (new_row->extra != NULL && else if (new_row->extra != NULL) {
new_row->extra->uri_ranges.count > 0) if (new_row->extra->uri_ranges.count > 0) {
{ /*
/* * line_wrap() "closes" still-open URIs. Since
* line_wrap() "closes" still-open URIs. Since this is * this is the *last* row, and since we're
* the *last* row, and since we're line-breaking due * line-breaking due to a hard line-break (rather
* to a hard line-break (rather than running out of * than running out of cells in the "new_row"),
* cells in the "new_row"), there shouldn't be an open * there shouldn't be an open URI (it would have
* URI (it would have been closed when we reached the * been closed when we reached the end of the URI
* end of the URI while reflowing the last "old" * while reflowing the last "old" row).
* row). */
*/ int last_idx = new_row->extra->uri_ranges.count - 1;
uint32_t last_idx = new_row->extra->uri_ranges.count - 1; xassert(new_row->extra->uri_ranges.v[last_idx].end >= 0);
xassert(new_row->extra->uri_ranges.v[last_idx].end >= 0); }
if (new_row->extra->curly_ranges.count > 0) {
int last_idx = new_row->extra->curly_ranges.count - 1;
xassert(new_row->extra->curly_ranges.v[last_idx].end >= 0);
}
} }
} }
@ -1112,6 +1200,8 @@ grid_resize_and_reflow(
for (size_t i = 0; i < row->extra->uri_ranges.count; i++) for (size_t i = 0; i < row->extra->uri_ranges.count; i++)
xassert(row->extra->uri_ranges.v[i].end >= 0); xassert(row->extra->uri_ranges.v[i].end >= 0);
for (size_t i = 0; i < row->extra->curly_ranges.count; i++)
xassert(row->extra->curly_ranges.v[i].end >= 0);
verify_no_overlapping_ranges(row->extra); verify_no_overlapping_ranges(row->extra);
verify_ranges_are_sorted(row->extra); verify_ranges_are_sorted(row->extra);