1
/* This software is subject to the terms of the Common Public License
2
You must accept the terms of this license to use this software.
4
Copyright (C) 2002, International Business Machines Corporation
5
and others. All Rights Reserved.
7
Further information about Common Public License Version 0.5 is obtained
8
from url http://oss.software.ibm.com/developer/opensource/license-cpl.html */
10
#include "../config.h"
11
#include "screen_row.h"
16
Char Blank = {" ",1,1,1};
18
SPECIAL_GRAPHICS = '0',
23
#define ON_ERROR(row, func) \
24
if(row->buffer.value_max < row->buffer.value_length) \
25
fprintf(stderr,"%s: value_max %d, value_length %d\n", \
26
func, row->buffer.value_max ,row->buffer.value_length); \
28
#define IS_SAME_INDEX(row,col1,col2) (row->buffer.cell_to_char[(col1)] == row->buffer.cell_to_char[(col2)])
29
#define GET_INDEX(row,col) ((col < row->num_columns && row->buffer.cell_to_char[(col)] >= 0) ? row->buffer.cell_to_char[(col)] : row->buffer.value_length)
30
#define SET_INDEX(row,col,val) (row->buffer.cell_to_char[(col)] = (val))
31
#define CLEAR_CELL(row,col) (row->buffer.cell_to_char[(col)] = -1)
32
#define EXPAND_BUFFER(row,size,msg) \
36
while(last_col < row->num_columns && Row_is_char_drawn(row,last_col)) \
38
columns_needs = row->num_columns - last_col;\
39
if(columns_needs < (size)) \
40
columns_needs = (size); \
41
row->buffer.value = realloc(row->buffer.value, \
42
row->buffer.value_max+columns_needs); \
43
row->buffer.value_max += columns_needs; \
46
#define COPY_TO(row,index,mbchar) \
48
memcpy(row->buffer.value+index, Char_get_string(mbchar), Char_get_length(mbchar)); \
51
#define CellAttr_init(attr, bold, blink, inverse, underline, foreground, background, charset) \
53
memset(attr,0,sizeof(CellAttributes)); \
54
if(bold) (attr)[ATTRIBUTES]|=BOLD; \
55
if(blink) (attr)[ATTRIBUTES]|=BLINK; \
56
if(inverse)(attr)[ATTRIBUTES]|=INVERSE; \
57
if(underline)(attr)[ATTRIBUTES]|=UNDERLINE; \
58
(attr)[COLOR]|=foreground; \
59
(attr)[COLOR]|=(background<<4); \
60
(attr)[CHARSET]|=charset; \
63
static void simple_clear_cells(Row *row, int start, int end)
67
if(start < 0 || row->num_columns < start ||
68
end < 0 || row->num_columns < end ||
72
"simple clear cells, row->num_columns = %d start = %d end = %d\n",
73
row->num_columns,start,end);
78
for(i=start;i<end;i++)
82
Row_set_updated(row,start,end);
85
static void RowBuffer_shrink(Row *row, int size)
87
if(Row_is_char_drawn(row,size-1))
89
/* edge character is double width */
90
if(IS_SAME_INDEX(row,size-1,size))
92
/* delete edge char */
93
row->buffer.value_length = GET_INDEX(row,(size-1));
94
CLEAR_CELL(row,(size-1));
96
else if(Row_is_char_drawn(row,size))
98
row->buffer.value_length = GET_INDEX(row,size);
102
row->buffer.value_max = size < row->buffer.value_length ? row->buffer.value_length : size;
103
row->buffer.value = (char *)realloc(row->buffer.value,
104
row->buffer.value_max);
106
if(row->num_columns < row->buffer.value_max ||
107
row->num_columns < row->buffer.value_length ||
108
row->buffer.value_max < row->buffer.value_length)
109
fprintf(stderr,"row->num_columns %d, row->buffer.value_max %d\n",
110
row->num_columns, row->buffer.value_max);
114
static void shift_buffer(Row *row, int dest, int src, int length)
116
if( row->buffer.value_max < dest + length )
118
EXPAND_BUFFER(row,(dest+length-row->buffer.value_max),"shift_buffer");
120
memmove(row->buffer.value + dest, row->buffer.value + src, length);
122
if(row->buffer.value_max < row->buffer.value_length)
123
fprintf(stderr,"shift_buffer: row->num_columns %d, row->buffer.value_max %d\n",
124
row->num_columns, row->buffer.value_max);
128
static void shift_index(Row *row, int start, int index_diff)
131
while(index < row->num_columns && Row_is_char_drawn(row,index))
133
/* row->buffer.cell_to_char[index] += index_diff; */
134
SET_INDEX(row,index,(GET_INDEX(row,index)+index_diff));
139
static void shift_cells(Row *row, int start , int value)
141
int length = row->num_columns - start;
146
memmove(row->buffer.cell_to_char + start + value,
147
row->buffer.cell_to_char + start,
149
memmove(row->buffer.attrs + start + value,
150
row->buffer.attrs + start,
151
length*sizeof(CellAttributes));
152
Row_set_updated(row,start,row->num_columns);
155
simple_clear_cells(row,row->num_columns+value,row->num_columns);
160
static void RowBuffer_add_char(Row *row, int col, Char *mbchar)
164
index = GET_INDEX(row,col);
166
if(row->buffer.value_max < index + Char_get_length(mbchar))
169
(index + Char_get_length(mbchar) - row->buffer.value_max),
170
"RowBuffer_add_char()");
172
for(w=0;w<Char_get_width(mbchar);w++)
174
/* do this row->buffer.cell_to_char[col+w] = index; */
175
SET_INDEX(row,(col+w),index);
177
/* terminate column */
178
if(col+w < row->num_columns)
179
CLEAR_CELL(row,col+w);
180
COPY_TO(row,index,mbchar);
181
row->buffer.value_length = index + Char_get_length(mbchar);
182
Row_set_updated(row,col,col+Char_get_width(mbchar));
184
if(row->buffer.value_max < row->buffer.value_length)
185
fprintf(stderr,"add_char, row->num_columns %d, row->buffer.value_max %d\n",
186
row->num_columns, row->buffer.value_max);
190
static int get_end_index(Row *row, int col, int col_width)
192
if(row->num_columns < col + col_width ||
193
(!Row_is_char_drawn(row,(col+col_width))) )
194
return row->buffer.value_length;
195
return GET_INDEX(row,col+col_width);
198
static int has_next_char(Row *row, int col, int width)
200
if(col == row->num_columns - width) /* col is right edge of row */
202
if(!Row_is_char_drawn(row,col+1)) /* col+1 has no char */
206
if(IS_SAME_INDEX(row,col,col+1))
207
return has_next_char(row,col+1,width);
212
return has_next_char(row,col+1,width-1); /* col+width is multicolumn,
216
static void RowBuffer_replace_char(Row *row, int col, Char *mbchar)
218
int start_index = GET_INDEX(row,col);
219
int ex_end_index = get_end_index(row,col,Char_get_width(mbchar));
220
int bytes_length = ex_end_index - start_index;
223
if(bytes_length == Char_get_length(mbchar))
224
COPY_TO(row, start_index, mbchar);
227
int diff = Char_get_length(mbchar) - bytes_length;
228
shift_buffer(row,start_index + Char_get_length(mbchar), ex_end_index,
229
row->buffer.value_length - ex_end_index);
230
shift_index(row,col+Char_get_width(mbchar),diff);
231
COPY_TO(row, start_index, mbchar);
232
row->buffer.value_length += diff;
235
for(w=1;w<Char_get_width(mbchar);w++)
237
/* do this row->buffer.cell_to_char[col+w] = start_index; */
238
SET_INDEX(row,(col+w),start_index);
240
Row_set_updated(row,col,col+Char_get_length(mbchar));
242
if(row->buffer.value_max < row->buffer.value_length)
245
"replace_char after : col %d, num_columns %d, value_length %d, value_max %d\n",
246
col, row->num_columns, row->buffer.value_length,
247
row->buffer.value_max);
249
"replace_char after: bytes_length %d, mbchar->length %d ex_end_index %d\n",
250
bytes_length, Char_get_length(mbchar), ex_end_index);
255
static void RowBuffer_simple_replace_space(Row *row, int col)
257
row->buffer.value[GET_INDEX(row,col)] = ' ';
258
row->buffer.attrs[col][0] = row->buffer.attrs[col][1] = row->buffer.attrs[col][3] = 0;
259
row->buffer.attrs[col][2] = ASCII; /* ASCII */
260
Row_set_updated(row,col,(col+1));
263
Row *Row_new(int col)
266
row = (Row *)malloc(sizeof(Row));
269
perror("Row_new(1)");
272
row->buffer.cell_to_char = NULL;
273
row->buffer.value = NULL;
274
row->buffer.attrs = NULL;
276
row->buffer.cell_to_char = (int *)calloc(col,sizeof(int));
277
if(row->buffer.cell_to_char == NULL)
279
perror("Row_new(2)");
283
row->buffer.value = (char *)calloc(col,sizeof(char));
284
if(row->buffer.value == NULL)
286
perror("Row_new(3)");
290
row->buffer.attrs = (CellAttributes *)calloc(col,sizeof(CellAttributes));
291
if(row->buffer.attrs == NULL)
293
perror("Row_new(4)");
297
row->buffer.value_max = col;
298
row->num_columns = col;
300
Row_clear_updated(row);
305
if(row->buffer.cell_to_char)
306
free(row->buffer.cell_to_char);
307
if(row->buffer.value)
308
free(row->buffer.value);
309
if(row->buffer.attrs)
310
free(row->buffer.attrs);
316
void Row_destroy(Row *row)
320
if(row->buffer.cell_to_char)
321
free(row->buffer.cell_to_char);
322
if(row->buffer.value)
323
free(row->buffer.value);
324
if(row->buffer.attrs)
325
free(row->buffer.attrs);
330
int Row_is_multicolumn_start(Row *row, int col)
333
if(row->num_columns <= col || col < 0)
336
"Row_is_multicolumn_start, row->num_cols = %d, col = %d\n",
337
row->num_columns,col);
341
if(col == 0 || row->num_columns < col)
344
if(Row_is_char_drawn(row,col) &&
345
!(IS_SAME_INDEX(row,col-1,col)) )
352
int Row_find_multicolum_char_start_column(Row *row, int col)
356
if(row->num_columns <= col || col < 0)
359
"Row_find_multicolumn_char_start_column, row->num_cols = %d, col = %d\n",
360
row->num_columns,col);
364
if(row->num_columns < col)
368
if(Row_is_multicolumn_start(row,c))
375
int Row_get_cell_width(Row *row,int col)
379
if(row->num_columns <= col || col < 0)
382
"Row_get_cell_width, row->num_cols = %d, col = %d\n",
383
row->num_columns,col);
387
if(row->num_columns <= col)
389
if(col == row->num_columns - 1)
391
if(IS_SAME_INDEX(row,col,col+1))
392
w += Row_get_cell_width(row,col+1);
397
int Row_add_char(Row *row, int col, Char *mbchar, int bold, int blink,
398
int inverse, int underline, int foreground, int background,
403
if(col < 0 || /* invalid */
404
row->num_columns <= col || /* invalid */
405
row->num_columns < col + Char_get_width(mbchar)) /* no colunm space left */
409
"Row_add_char: row->num_cols %d, col %d, mbchar->width %d\n",
410
row->num_columns, col, Char_get_width(mbchar));
416
if(IS_COMBINED(mbchar))
421
if(Row_is_char_drawn(row,c) &&
422
Row_is_multicolumn_start(row,c))
424
/* found proper cell */
425
int last_index = get_end_index(row,c,Row_get_cell_width(row,c));
426
shift_buffer(row, last_index + Char_get_length(mbchar), last_index,
427
row->buffer.value_length - last_index);
428
COPY_TO(row, last_index, mbchar);
429
row->buffer.value_length += Char_get_length(mbchar);
430
row->buffer.attrs[c][NUM_COMBINED]++;
435
/* failed to find proper cell to add combined char */
439
for(w=0;w<Char_get_width(mbchar);w++)
441
CellAttr_init(row->buffer.attrs[col+w],bold,blink,inverse,underline,
442
foreground,background,charset);
445
if(Row_is_char_drawn(row,col))
447
/* take care of character over the 2nd column
448
of multibyte character */
449
if(!Row_is_multicolumn_start(row,col))
451
/* This only cares double column character.
452
Do I need to care more than 2 ? */
453
RowBuffer_simple_replace_space(row, col-1);
454
/* do this row->buffer.cell_to_char[col] += 1; */
455
SET_INDEX(row,col,(GET_INDEX(row,col)+1));
458
/* take care of multi column character over the
459
only the first column of multi column character */
460
if(Char_get_width(mbchar) > 1 && Row_get_cell_width(row,col+1) > 1)
462
SET_INDEX(row,(col+1),
463
(get_end_index(row,col+Char_get_width(mbchar),1) - 1));
464
RowBuffer_simple_replace_space(row, col+Char_get_width(mbchar));
465
Row_set_updated(row,col,col+Char_get_width(mbchar)+1);
468
if(has_next_char(row,col,Char_get_width(mbchar)))
470
if(Char_get_width(mbchar) == 1 &&
471
Row_get_cell_width(row,col) != Char_get_width(mbchar))
473
/* do this, row->buffer.cell_to_char[col+1] = get_end_index(row,col+1,1)-1 */
474
SET_INDEX(row,(col+1),(get_end_index(row,col+1,1) - 1));
475
RowBuffer_simple_replace_space(row, col+1);
477
RowBuffer_replace_char(row,col,mbchar);
481
RowBuffer_add_char(row,col,mbchar);
486
if(0 <= col-1 && !(Row_is_char_drawn(row,col-1)))
488
Row_add_char(row,col-1,&Blank,0,0,0,0,0,0,ASCII);
490
RowBuffer_add_char(row,col,mbchar);
493
if(row->buffer.value_max < row->buffer.value_length)
495
"Row_add_char: col %d, num_columns %d, value_length %d, value_max %d\n",
496
col, row->num_columns, row->buffer.value_length,
497
row->buffer.value_max);
502
void Row_resize(Row *row, int size)
504
if(row && row->num_columns != size)
506
int old = row->num_columns;
509
RowBuffer_shrink(row,size);
511
row->buffer.attrs = (CellAttributes *)realloc(row->buffer.attrs,
512
size*sizeof(CellAttributes));
513
row->buffer.cell_to_char = (int *)realloc(row->buffer.cell_to_char,
515
row->num_columns = size;
516
if(old < row->num_columns)
518
simple_clear_cells(row,old,row->num_columns);
522
ON_ERROR(row,"Row_resize");
526
int Row_clear_cells(Row *row, int start_col, int end_col)
532
if(row->num_columns < start_col || start_col < 0 ||
533
row->num_columns < end_col || end_col < 0 ||
536
"Row_clear_cells: row->num_cols = %d, start_col = %d end_col = %d\n",
537
row->num_columns,start_col,end_col);
539
if( end_col < start_col)
541
scol = 0 < start_col ? start_col : 0;
542
ecol = end_col < row->num_columns ? end_col : row->num_columns ;
544
if(!Row_is_char_drawn(row,scol))
545
return 0; /* do not need to clear */
547
scol = Row_find_multicolum_char_start_column(row,scol);
549
if(ecol < row->num_columns &&
550
Row_is_char_drawn(row,ecol) &&
551
!Row_is_multicolumn_start(row,ecol))
553
ecol = Row_find_multicolum_char_start_column(row,ecol);
554
ecol += Row_get_cell_width(row,ecol);
557
if(row->num_columns <= ecol || !Row_is_char_drawn(row,ecol))
558
{ /* we have no string on the right. just clear cells */
559
row->buffer.value_length = GET_INDEX(row,scol);
560
simple_clear_cells(row,scol,ecol);
563
{ /* we have string on the right. This case, insert SPACES */
564
int old_length = old_length = GET_INDEX(row,ecol) - GET_INDEX(row,scol);
565
int new_length = ecol - scol; /* white space consumes just one byte */
568
GET_INDEX(row,scol) + new_length,
570
row->buffer.value_length - GET_INDEX(row,ecol));
571
for(i=scol,j=0;i<ecol;i++,j++)
573
/* do this, row->buffer.cell_to_char[i] = GET_INDEX(row,scol) + j; */
574
SET_INDEX(row,i,(GET_INDEX(row,scol) + j));
575
RowBuffer_simple_replace_space(row,i);
577
row->buffer.value_length += (new_length - old_length);
579
Row_set_wrapped(row,NOT_WRAPPED);
581
ON_ERROR(row,"Row_clear_cells");
586
int Row_clear(Row *row)
588
Row_set_wrapped(row,NOT_WRAPPED);
589
simple_clear_cells(row,0,row->num_columns);
590
row->buffer.value_length = 0;
592
ON_ERROR(row,"Row_clear");
597
void Row_set_selection(Row *row ,int scol, int ecol, int selected)
601
if(row->num_columns < scol || scol < 0 ||
602
row->num_columns < ecol || ecol < 0 ||
605
"Row_set_selection, row->num_cols = %d, scol = %d ecol = %d\n",
606
row->num_columns,scol,ecol);
610
for(c=scol;c<ecol;c++)
612
row->buffer.attrs[c][ATTRIBUTES] |= SELECTED;
617
for(c=scol;c<ecol;c++)
619
row->buffer.attrs[c][ATTRIBUTES] &= (~SELECTED);
622
Row_set_updated(row,scol,ecol);
624
ON_ERROR(row,"Row_set_selection");
628
int Row_compose_bytes(Row *row, int col_start, int col_end,
629
char *str, int str_len,
630
int *total_len, int *total_width, int pad)
638
if(row->num_columns < col_start || col_start < 0 ||
639
col_end < 0 || col_end < col_start)
642
"Row_compose_bytes, row->num_cols = %d, col_start = %d col_end = %d\n",
643
row->num_columns,col_start,col_end);
647
if(row->buffer.value_length <= 0)
652
int min = str_len < row->num_columns ? str_len : row->num_columns;
667
if(col_end <= col_start)
672
if(col_end > row->num_columns)
673
col_end = row->num_columns;
678
while(scol < row->num_columns && !Row_is_multicolumn_start(row,scol))
680
while(scol < ecol && !Row_is_char_drawn(row,ecol-1))
683
buf_start = GET_INDEX(row,scol);
684
buf_end = GET_INDEX(row,ecol);
685
*total_len = buf_end - buf_start;
687
if(str_len < *total_len)
688
*total_len = str_len;
689
memcpy(str, (row->buffer.value + buf_start) ,*total_len);
691
*total_width = ecol - scol;
692
if(pad && *total_width < (col_end - col_start))
694
int num_spaces = row->num_columns - *total_width;
695
int num_left = (str_len > *total_len) ? (str_len - *total_len) : 0;
696
int min = num_spaces < num_left ? num_spaces : num_left;
701
memcpy(str + *total_len + c, " ", 1);
707
ON_ERROR(row,"Row_compose_bytes");
712
static void simple_delete_right(Row *row, int col_start)
714
col_start = Row_find_multicolum_char_start_column(row,col_start);
715
row->buffer.value_length = GET_INDEX(row,col_start);
716
simple_clear_cells(row,col_start,row->num_columns);
717
Row_set_updated(row,col_start,row->num_columns);
720
int Row_insert_cells(Row *row, int col_start, int num_spaces)
723
int src_index = GET_INDEX(row,col_start);
724
int length = GET_INDEX(row,row->num_columns - num_spaces) - GET_INDEX(row,col_start);
726
if( (col_start < 0) ||
727
(row->num_columns-1 <= col_start) ||
728
(!Row_is_char_drawn(row,col_start)) )
731
fprintf(stderr,"Row_insert_cells: invalid colmun: %d\n", col_start);
736
/* inserting cells till right side */
737
if( row->num_columns <= col_start + num_spaces )
739
row->buffer.value_length = GET_INDEX(row,col_start);
740
simple_delete_right(row,col_start);
744
if(Row_get_cell_width(row,row->num_columns-num_spaces-1 ) > 1)
746
/* double column on the edge should be removed */
747
row->buffer.value_length = GET_INDEX(row,row->num_columns-num_spaces-1);
748
CLEAR_CELL(row,row->num_columns-num_spaces-1);
751
if(!Row_is_multicolumn_start(row,col_start))
753
if(Row_is_char_drawn(row,col_start+1))
755
RowBuffer_simple_replace_space(row, col_start-1);
756
/* do this, row->buffer.cell_to_char[col_start] += 1; */
757
SET_INDEX(row,col_start,(GET_INDEX(row,col_start)+1));
758
Row_add_char(row,col_start,&Blank,0,0,0,0,0,0,ASCII);
762
Row_clear_cells(row,col_start-1,col_start+1);
767
/* Now we have to insert SPACES */
768
if(Row_is_char_drawn(row,row->num_columns-1-num_spaces))
769
row->buffer.value_length = GET_INDEX(row,row->num_columns-num_spaces);
770
row->buffer.value_length += num_spaces;
772
shift_cells(row,col_start, num_spaces);
773
shift_index(row, (col_start + num_spaces), num_spaces);
774
shift_buffer(row,src_index+num_spaces, src_index, length);
777
RowBuffer_simple_replace_space(row, i);
778
for(i++;i<col_start+num_spaces;i++)
780
/* do this, row->buffer.cell_to_char[i] = GET_INDEX(row,(i-1))+1; */
781
SET_INDEX(row,i,(GET_INDEX(row,(i-1))+1));
782
RowBuffer_simple_replace_space(row, i);
785
if(row->buffer.value_max < row->buffer.value_length)
787
fprintf(stderr,"Row_insert_cells after : num_columns %d, value_max = %d, value_length %d\n", row->num_columns, row->buffer.value_max, row->buffer.value_length);
793
/* col_start must be coordinated pointing at the fisrt column of
794
multi column character */
795
static void simple_delete_cells(Row *row, int col_start, int num)
801
dest_index = GET_INDEX(row,col_start);
802
src_index = GET_INDEX(row,col_start+num);
803
diff = src_index - dest_index;
805
shift_cells(row,col_start+num,-num);
806
shift_buffer(row,dest_index,src_index,row->buffer.value_max-src_index);
807
shift_index(row,col_start,-diff);
808
row->buffer.value_length -= diff;
809
Row_set_updated(row,col_start,row->num_columns);
812
int Row_delete_cells(Row *row, int col_start, int num)
815
/* invalid case, do nothing */
816
if(col_start < 0 || row->num_columns -1 <= col_start || num < 0)
819
if(row->num_columns <= col_start || col_start < 0 || num < 0)
822
"Row_delete_cells, row->num_cols = %d, col_start = %d\n",
823
row->num_columns,col_start);
829
/* No need to delete characters */
830
if(!Row_is_char_drawn(row,col_start))
833
/* delete right side, we don't need to shift right side string */
834
if( (row->num_columns <= col_start + num) ||
835
!Row_is_char_drawn(row,col_start+num) )
837
simple_delete_right(row,col_start);
840
/* if we will try to delete only fisrt(or some) column(s)
841
of multicolumn char */
842
else if(!Row_is_multicolumn_start(row,col_start+num))
844
int end_col = Row_find_multicolum_char_start_column(row,col_start+num);
845
/* if the char has another char on right */
846
if(has_next_char(row,end_col,
847
end_col + Row_get_cell_width(row, end_col)))
850
row->buffer.cell_to_char[col_start+num]=GET_INDEX(row,col_start+num+1)-1 */
851
SET_INDEX(row,(col_start+num),(GET_INDEX(row,col_start+num+1)-1));
852
RowBuffer_simple_replace_space(row, col_start+num);
854
else /* if that multi column char is the last char */
856
simple_delete_right(row,col_start);
860
/* Now we have to delete and shift right side of string */
862
/* if col_start is not first column of multicolumn char
863
replace left side columns as spaces
865
if(!Row_is_multicolumn_start(row,col_start))
867
/* only handle double width char */
869
row->buffer.cell_to_char[col_start] = GET_INDEX(row,col_start-1) + 1; */
870
SET_INDEX(row,col_start,(GET_INDEX(row,col_start-1) + 1));
871
RowBuffer_simple_replace_space(row, col_start-1);
873
simple_delete_cells(row,col_start,num);
876
ON_ERROR(row,"Row_delete_cells");
881
int Row_copy(Row *src, Row *dest)
883
int num_col = src->num_columns < dest->num_columns ? src->num_columns : dest->num_columns;
884
int last_index = GET_INDEX(src,num_col);
886
if(dest->buffer.value_max < last_index)
888
dest->buffer.value = realloc(dest->buffer.value,last_index);
889
dest->buffer.value_max = last_index;
892
memcpy(dest->buffer.value,src->buffer.value,last_index);
893
dest->buffer.value_length = last_index;
895
memcpy(dest->buffer.cell_to_char,
896
src->buffer.cell_to_char,
897
num_col*sizeof(int));
898
memcpy(dest->buffer.attrs,
900
num_col*sizeof(CellAttributes));
901
if(num_col < dest->num_columns)
903
simple_clear_cells(dest,num_col,dest->num_columns);
906
ON_ERROR(src,"Row_copy(src)");
907
ON_ERROR(dest,"Row_copy(dest)");
912
void Row_set_char_drawn(Row *row, int col,int value)
915
if(row->num_columns <= col || col < 0)
917
"Row_set_char_drawn, row->num_cols = %d, col = %d\n",
918
row->num_columns,col);
920
if(!value && Row_is_char_drawn(row,col))
922
if(has_next_char(row,col,Row_get_cell_width(row,col)))
924
int end_index = GET_INDEX(row,col+Row_get_cell_width(row,col));
925
int start_index = GET_INDEX(row,col);
927
if(end_index > start_index+1)
929
int diff = end_index - start_index - 1;
930
shift_buffer(row,end_index,start_index+1,row->num_columns-end_index);
931
shift_index(row,start_index+1,diff);
934
RowBuffer_simple_replace_space(row,col);
942
ON_ERROR(row,"Row_set_char_drawn");