1 #pragma once
2 
3 #include <stddef.h>
4 #include "debug.h"
5 #include "terminal.h"
6 
7 struct grid *grid_snapshot(const struct grid *grid);
8 void grid_free(struct grid *grid);
9 
10 void grid_swap_row(struct grid *grid, int row_a, int row_b);
11 struct row *grid_row_alloc(int cols, bool initialize);
12 void grid_row_free(struct row *row);
13 
14 void grid_resize_without_reflow(
15     struct grid *grid, int new_rows, int new_cols,
16     int old_screen_rows, int new_screen_rows);
17 
18 void grid_resize_and_reflow(
19     struct grid *grid, int new_rows, int new_cols,
20     int old_screen_rows, int new_screen_rows,
21     size_t tracking_points_count,
22     struct coord *const _tracking_points[static tracking_points_count]);
23 
24 static inline int
grid_row_absolute(const struct grid * grid,int row_no)25 grid_row_absolute(const struct grid *grid, int row_no)
26 {
27     return (grid->offset + row_no) & (grid->num_rows - 1);
28 }
29 
30 static inline int
grid_row_absolute_in_view(const struct grid * grid,int row_no)31 grid_row_absolute_in_view(const struct grid *grid, int row_no)
32 {
33     return (grid->view + row_no) & (grid->num_rows - 1);
34 }
35 
36 static inline struct row *
_grid_row_maybe_alloc(struct grid * grid,int row_no,bool alloc_if_null)37 _grid_row_maybe_alloc(struct grid *grid, int row_no, bool alloc_if_null)
38 {
39     xassert(grid->offset >= 0);
40 
41     int real_row = grid_row_absolute(grid, row_no);
42     struct row *row = grid->rows[real_row];
43 
44     if (row == NULL && alloc_if_null) {
45         row = grid_row_alloc(grid->num_cols, false);
46         grid->rows[real_row] = row;
47     }
48 
49     xassert(row != NULL);
50     return row;
51 }
52 
53 static inline struct row *
grid_row(struct grid * grid,int row_no)54 grid_row(struct grid *grid, int row_no)
55 {
56     return _grid_row_maybe_alloc(grid, row_no, false);
57 }
58 
59 static inline struct row *
grid_row_and_alloc(struct grid * grid,int row_no)60 grid_row_and_alloc(struct grid *grid, int row_no)
61 {
62     return _grid_row_maybe_alloc(grid, row_no, true);
63 }
64 
65 static inline struct row *
grid_row_in_view(struct grid * grid,int row_no)66 grid_row_in_view(struct grid *grid, int row_no)
67 {
68     xassert(grid->view >= 0);
69 
70     int real_row = grid_row_absolute_in_view(grid, row_no);
71     struct row *row = grid->rows[real_row];
72 
73     xassert(row != NULL);
74     return row;
75 }
76 
77 void grid_row_uri_range_put(
78     struct row *row, int col, const char *uri, uint64_t id);
79 void grid_row_uri_range_add(struct row *row, struct row_uri_range range);
80 void grid_row_uri_range_erase(struct row *row, int start, int end);
81 
82 static inline void
grid_row_uri_range_destroy(struct row_uri_range * range)83 grid_row_uri_range_destroy(struct row_uri_range *range)
84 {
85     free(range->uri);
86 }
87 
88 static inline void
grid_row_reset_extra(struct row * row)89 grid_row_reset_extra(struct row *row)
90 {
91     struct row_data *extra = row->extra;
92 
93     if (likely(extra == NULL))
94         return;
95 
96     for (size_t i = 0; i < extra->uri_ranges.count; i++)
97         grid_row_uri_range_destroy(&extra->uri_ranges.v[i]);
98     free(extra->uri_ranges.v);
99 
100     free(extra);
101     row->extra = NULL;
102 }
103