start on grid cell allocation so we can get to displaying text ;)

NB: unfinished yet

Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
Chris Michael 2014-12-05 16:04:27 -05:00
parent bc848afcdc
commit 692f58c421
2 changed files with 297 additions and 2 deletions

View File

@ -230,13 +230,188 @@ _smart_size(Evas_Object *obj, int w, int h, Eina_Bool force)
_selection_set(obj, EINA_FALSE);
/* TODO: call grid resize function to allocate cells */
/* call grid resize function to allocate cells */
_grid_resize(obj, w, h);
_smart_calculate(obj);
evas_event_thaw(sd->evas);
}
static void
_grid_cell_copy(Grid *sd, Grid_Cell *src, Grid_Cell *dst, int n)
{
int i = 0;
for (; i < n; i++)
{
/* TODO */
/* _handle_block_codepoint_overwrite(sd, dst[i].codepoint, src[i].codepoint); */
dst[i] = src[i];
}
}
static void
_grid_limit_coord(Grid *sd, Grid_State *state)
{
state->wrapnext = 0;
if (state->cx >= sd->w) state->cx = sd->w - 1;
if (state->cy >= sd->h) state->cy = sd->h - 1;
if (state->had_cr_x >= sd->w) state->had_cr_x = sd->w - 1;
if (state->had_cr_y >= sd->h) state->had_cr_y = sd->h - 1;
}
ssize_t
_grid_line_length(const Grid_Cell *cells, ssize_t nb_cells)
{
ssize_t len = nb_cells;
for (len = nb_cells - 1; len >= 0; len--)
{
const Grid_Cell *cell;
cell = cells + len;
if ((cell->codepoint != 0) && (cell->att.bg != COL_INVIS))
return len + 1;
}
return 0;
}
static int
_grid_line_find_top(Grid *sd, int y_end, int *top)
{
int y_start = y_end;
while (y_start > 0)
{
if (GRID_CELLS(sd, sd->w - 1, y_start - 1).att.autowrapped)
y_start--;
else
{
*top = y_start;
return 0;
}
}
while (-y_start < sd->backscroll_num)
{
Grid_Save *gs;
gs = sd->back[(y_start + sd->backpos - 1 + sd->backmax) % sd->backmax];
if (gs)
gs = _grid_save_extract(gs);
if (!gs) return -1;
sd->back[(y_start + sd->backpos - 1 + sd->backmax) % sd->backmax] = gs;
if (gs->cell[gs->w - 1].att.autowrapped)
y_start--;
else
{
*top = y_start;
return 0;
}
}
*top = y_start;
return 0;
}
static int
_grid_line_rewrap(Grid *sd, int y_start, int y_end, Grid_Cell *cells2, Grid_Save **back2, int w2, int y2_end, int *new_y2_start)
{
int x, x2, y, y2, y2_start;
int len, len_last, len_remaining, copy_width, ts2_width;
Grid_Save *gs, *gs2;
Grid_Cell *line, *line2 = NULL;
if (y_end >= 0)
len_last = _grid_line_length(&GRID_CELLS(sd, 0, y_end), sd->w);
else
{
gs = _grid_save_extract(sd->back[(y_end + sd->backpos +
sd->backmax) % sd->backmax]);
if (!gs) return -1;
sd->back[(y_end + sd->backpos + sd->backmax) % sd->backmax] = gs;
len_last = gs->w;
}
len_remaining = len_last + (y_end - y_start) * sd->w;
y2_start = y2_end;
if (len_remaining)
y2_start -= (len_remaining + w2 - 1) / w2 - 1;
else
{
if (y2_start < 0)
back2[y2_start + sd->backmax] = _grid_save_new(0);
*new_y2_start = y2_start;
return 0;
}
if (-y2_start > sd->backmax)
{
y_start += ((-y2_start - sd->backmax) * w2) / sd->w;
x = ((-y2_start - sd->backmax) * w2) % sd->w;
len_remaining -= (-y2_start - sd->backmax) * w2;
y2_start = -sd->backmax;
}
else
x = 0;
y = y_start;
x2 = 0;
y2 = y2_start;
while (y <= y_end)
{
if (y >= 0)
line = &GRID_CELLS(sd, 0, y);
else
{
gs = _grid_save_extract(sd->back[(y + sd->backpos +
sd->backmax) % sd->backmax]);
if (!gs) return -1;
sd->back[(y + sd->backpos + sd->backmax) % sd->backmax] = gs;
line = gs->cell;
}
if (y == y_end)
len = len_last;
else
len = sd->w;
line[len - 1].att.autowrapped = 0;
while (x < len)
{
copy_width = MIN(len - x, w2 - x2);
if (x2 == 0)
{
if (y2 >= 0)
line2 = cells2 + (y2 * w2);
else
{
ts2_width = MIN(len_remaining, w2);
gs2 = _grid_save_new(ts2_width);
if (!gs2) return -1;
line2 = gs2->cell;
back2[y2 + sd->backmax] = gs2;
}
}
if (line2)
{
_grid_cell_copy(sd, line + x, line2 + x2, copy_width);
x += copy_width;
x2 += copy_width;
len_remaining -= copy_width;
if ((x2 == w2) && (y2 != y2_end))
{
line2[x2 - 1].att.autowrapped = 1;
x2 = 0;
y2++;
}
}
}
x = 0;
y++;
}
*new_y2_start = y2_start;
return 0;
}
/* external functions */
Evas_Object *
_grid_add(Evas *evas)
@ -323,3 +498,73 @@ _grid_window_set(Evas_Object *obj, Evas_Object *win)
if (!(sd = evas_object_smart_data_get(obj))) return;
sd->win = win;
}
void
_grid_resize(Evas_Object *obj, int nw, int nh)
{
Grid *sd;
Grid_Cell *new_cells = NULL;
Grid_Save **new_back = NULL;
int y_start, y_end, new_y_start = 0, new_y_end, i;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
if ((sd->w == nw) && (sd->h == nh)) return;
if ((nw == nh) && (nw == 1)) return;
_grid_save_freeze();
new_cells = calloc(1, sizeof(Grid_Cell) * nw * nh);
if (!new_cells) goto err;
free(sd->cells2);
sd->cells2 = calloc(1, sizeof(Grid_Cell) * nw * nh);
if (!sd->cells2) goto err;
new_back = calloc(sizeof(Grid_Save *), sd->backmax);
y_end = sd->state.cy;
new_y_end = nh - 1;
while ((y_end >= -sd->backscroll_num) && (new_y_end >= -sd->backmax))
{
if (_grid_line_find_top(sd, y_end, &y_start) < 0) goto err;
if (_grid_line_rewrap(sd, y_start, y_end, new_cells,
new_back, nw, new_y_end,
&new_y_start) < 0)
goto err;
y_end = y_start - 1;
new_y_end = new_y_start - 1;
}
free(sd->cells);
sd->cells = new_cells;
for (i = 1; i <= sd->backscroll_num; i++)
_grid_save_free(sd->back[(sd->backpos - i + sd->backmax) % sd->backmax]);
free(sd->back);
sd->back = new_back;
sd->w = nw;
sd->h = nh;
sd->state.cy = MIN((nh - 1) - new_y_start, nh - 1);
sd->state.cx = _grid_line_length(new_cells + ((nh - 1) * nw), nw);
sd->circular_offset = MAX(new_y_start, 0);
sd->backpos = 0;
sd->backscroll_num = MAX(-new_y_start, 0);
sd->state.had_cr = 0;
/* if (altbuf) termpty_screen_swap(ty); */
_grid_limit_coord(sd, &(sd->state));
_grid_limit_coord(sd, &(sd->swap));
_grid_limit_coord(sd, &(sd->save));
_grid_save_thaw();
return;
err:
_grid_save_thaw();
free(new_cells);
free(new_back);
}

View File

@ -1,6 +1,20 @@
#ifndef _GRID_H_
# define _GRID_H_ 1
#define COL_DEF 0
#define COL_BLACK 1
#define COL_RED 2
#define COL_GREEN 3
#define COL_YELLOW 4
#define COL_BLUE 5
#define COL_MAGENTA 6
#define COL_CYAN 7
#define COL_WHITE 8
#define COL_INVIS 9
#define COL_INVERSE 10
#define COL_INVERSEBG 11
typedef struct _Grid_Att Grid_Att;
struct _Grid_Att
{
@ -59,6 +73,33 @@ struct _Grid_Save_Comp
unsigned int wout; // output width in Grid_Cells
};
typedef struct _Grid_State Grid_State;
struct _Grid_State
{
int cx, cy;
Grid_Att att;
unsigned char charset;
unsigned char charsetch;
unsigned char chset[4];
int scroll_y1, scroll_y2;
int had_cr_x, had_cr_y;
int margin_top; // soon, more to come...
unsigned int multibyte : 1;
unsigned int alt_kp : 1;
unsigned int insert : 1;
unsigned int appcursor : 1;
unsigned int wrap : 1;
unsigned int wrapnext : 1;
unsigned int hidecursor : 1;
unsigned int crlf : 1;
unsigned int had_cr : 1;
unsigned int send_bs : 1;
unsigned int kbd_lock : 1;
unsigned int reverse : 1;
unsigned int no_autorepeat : 1;
unsigned int cjk_ambiguous_wide : 1;
};
typedef struct _Grid Grid;
struct _Grid
{
@ -70,10 +111,12 @@ struct _Grid
int w, h;
int backmax, backpos;
int circular_offset, circular_offset2;
int backmax, backpos, backscroll_num;
Grid_Cell *cells, *cells2;
Grid_Save **back;
Grid_State state, save, swap;
struct
{
@ -98,5 +141,12 @@ struct _Grid
Evas_Object *_grid_add(Evas *evas);
void _grid_update(Evas_Object *obj);
void _grid_window_set(Evas_Object *obj, Evas_Object *win);
void _grid_resize(Evas_Object *obj, int nw, int nh);
#define GRID_CELLS(SD, X, Y) \
SD->cells[X + (((Y + SD->circular_offset) % SD->h) * SD->w)]
#define GRID_FMTCLR(ATT) \
(ATT).autowrapped = (ATT).newline = (ATT).tab = 0
#endif