[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
lynx-dev [PATCH 2.8.5-dev15] new table logic again
From: |
Ilya Zakharevich |
Subject: |
lynx-dev [PATCH 2.8.5-dev15] new table logic again |
Date: |
Thu, 26 Jun 2003 09:14:35 -0700 |
User-agent: |
Mutt/1.4i |
This patch does what I promised: adds vertical movement of pieces of
multiline cells so that they are shown "as inteded" (if one forgets
about vertical center etc - it is easy to add them, but I do not think
this info is available in gridtext.c).
Enjoy,
Ilya
[This does nothing about 2 or 3 minor deficiencies of my previous
patches. When the patches are incorporated, I'll look for these bugs.]
--- ./src/GridText.c.orig Sat Jun 21 02:31:22 2003
+++ ./src/GridText.c Thu Jun 26 08:58:46 2003
@@ -80,6 +80,10 @@ PRIVATE void HText_trimHightext PARAMS((
BOOLEAN final,
int stop_before));
+PRIVATE void split_line ARGS2(
+ HText *, text,
+ unsigned, split);
+
#ifdef USE_COLOR_STYLE
PRIVATE void LynxResetScreenCache NOARGS
{
@@ -188,7 +192,7 @@ typedef struct {
} HTStyleChange;
#if defined(USE_COLOR_STYLE)
-#define MAX_STYLES_ON_LINE 64
+#define MAX_STYLES_ON_LINE 960 /* Table-in-table may aggregate many styles */
/* buffers used when current line is being aggregated, in split_line() */
static HTStyleChange stylechanges_buffers[2][MAX_STYLES_ON_LINE];
#endif
@@ -2420,6 +2424,8 @@ PUBLIC void HText_beginAppend ARGS1(
#define AT_START_OF_CELL(text) \
(text->stbl \
&& Stbl_at_start_of_cell(text->stbl, text->Lines, text->last_line->size))
+#define START_OF_LAST_CELL(text) \
+ Stbl_start_of_last_cell(text->stbl, text->Lines)
#define DEBUG_SPLITLINE
@@ -2709,11 +2715,11 @@ PRIVATE HTLine * line2pool ARGS2(
}
-/* Probably a flavor which does not add space is needed too... */
-PUBLIC BOOLEAN unsplit_line ARGS3(
+PUBLIC BOOLEAN unsplit_line ARGS4(
HText *, text,
HTLine *, line,
- int, insert)
+ int, insert,
+ int, abs_pos)
{ /* Reverts the effects of split_line(): merges the line with
the preceding line, separating them by space (without
styles). Follows the logic of split_line() backwards;
@@ -2729,6 +2735,11 @@ PUBLIC BOOLEAN unsplit_line ARGS3(
if (text->Lines < 2)
return FALSE;
+ if (abs_pos != -1)
+ insert = abs_pos - previous->size;
+ if (insert < 0)
+ return FALSE;
+
if (previous->size + insert + line->size >= MAX_LINE)
return FALSE;
@@ -2824,6 +2835,25 @@ PUBLIC BOOLEAN unsplit_line ARGS3(
return TRUE;
}
+PRIVATE BOOL split_line_at_cellstart ARGS2(
+ HText *, text,
+ int, before_pos)
+{
+ int pos = text->last_line->size, startpos;
+
+ if (!text->stbl || AT_START_OF_CELL(text))
+ return FALSE;
+ startpos = START_OF_LAST_CELL(text);
+ if (startpos <= 0 || startpos >= before_pos)
+ return FALSE;
+ split_line(text, startpos);
+ if (text->permissible_split > pos - text->last_line->size)
+ text->permissible_split -= pos - text->last_line->size;
+ else
+ text->permissible_split = 0;
+ return TRUE;
+}
+
PRIVATE void split_line ARGS2(
HText *, text,
unsigned, split)
@@ -2847,6 +2877,18 @@ PRIVATE void split_line ARGS2(
HTLine * previous = text->last_line;
HTLine * line;
+ if (text->stbl) { /* Make multiline rows start on a new line */
+ int olen = text->last_line->size;
+ int pos = (split ? split : olen);
+
+ if (split_line_at_cellstart(text, pos)) {
+ int newlen = text->last_line->size;
+
+ if (olen - newlen < pos)
+ split_line(text, pos - (olen - newlen));
+ return;
+ }
+ }
/*
* Set new line.
*/
@@ -3466,6 +3508,85 @@ PRIVATE void split_line ARGS2(
} /* split_line */
+PRIVATE BOOLEAN move_after_line ARGS4(
+ HText *, text,
+ HTLine *, line,
+ int, vert_offset,
+ int, lineno)
+{ /* Moves Line back to be positioned vert_offset lines earlier. */
+ HTLine * line_after = line;
+ int i = vert_offset, new_lineno = lineno - vert_offset + 1;
+ TextAnchor *a, *a_prev = NULL, *a_prev2, *a_prev3;
+ TextAnchor **aPtr = &(text->first_anchor);
+
+ while (--i >= 0)
+ line_after = line_after->prev;
+
+ /* Unlink line */
+ line->next->prev = line->prev;
+ line->prev->next = line->next;
+ /* Link into the new place */
+ line->next = line_after->next;
+ line->prev = line_after;
+ line_after->next = line;
+ line->next->prev = line;
+
+ /* Correct anchors */
+
+ if (!text->first_anchor)
+ return TRUE;
+
+ a = text->last_anchor_before_split;
+ if (a->line_num >= new_lineno - 1)
+ a = text->first_anchor;
+ while (a && a->line_num < new_lineno) /* Over anchors up to line_after */
+ a_prev = a, a = a->next;
+ if (a_prev) { /* optimize for further operations */
+ text->last_anchor_before_split = a_prev;
+ aPtr = &(a_prev->next);
+ }
+ a_prev2 = a_prev;
+ while (a && a->line_num < lineno) { /* Over anchors in between */
+ a->line_num++;
+ a_prev2 = a;
+ a = a->next;
+ }
+ a_prev3 = a_prev2;
+ while (a && a->line_num == lineno) { /* Over anchors in `line' */
+ a->line_num = new_lineno;
+ a_prev3 = a;
+ a = a->next;
+ }
+ if (a_prev != a_prev2 && a_prev2 != a_prev3) { /* Exchange the blocks */
+ a_prev3->next = *aPtr;
+ *aPtr = a_prev2->next;
+ a_prev2->next = a;
+ }
+ return TRUE;
+}
+
+PRIVATE BOOLEAN has_multiline_anchor ARGS3(
+ HText *, text,
+ HTLine *, line,
+ int, lineno)
+{ /* Moves Line back to be positioned vert_offset lines earlier. */
+ TextAnchor *a, *a_prev = NULL;
+
+ if (!text->first_anchor)
+ return FALSE;
+
+ a = text->last_anchor_before_split;
+ if (a->line_num > lineno)
+ a = text->first_anchor;
+ while (a && a->line_num <= lineno) /* Over anchors up to line_after */
+ a_prev = a, a = a->next;
+ if (!a_prev || a_prev->line_num != lineno)
+ return FALSE;
+ if (a_prev->line_pos + a_prev->extent > line->size)
+ return TRUE;
+ return FALSE;
+}
+
/* Allow vertical blank space
** --------------------------
*/
@@ -3551,6 +3672,7 @@ PUBLIC void HText_appendCharacter ARGS2(
int indent;
int limit = 0;
int actual;
+ int flush_cell = 1;
#ifdef DEBUG_APPCH
#ifdef CJK_EX
@@ -4288,6 +4410,7 @@ check_WrapSource:
}
}
+ do_newline:
/*
* Check for end of line.
*/
@@ -4305,6 +4428,13 @@ check_WrapSource:
limit = (WRAP_COLS(text) - 1);
}
+ if (actual >= limit && flush_cell && split_line_at_cellstart(text,actual))
{
+ flush_cell = 0;
+ line = text->last_line;
+ /* Do not change style: essentially, no change was done. */
+ goto do_newline;
+ }
+
if (actual >= limit) {
if (style->wordWrap && HTOutputFormat != WWW_SOURCE) {
@@ -4611,6 +4741,8 @@ PRIVATE int HText_insertBlanksInStblLine
HTStyle *style;
short alignment;
int i = 0, prevline_len = -1, do_unsplit, deleted = 0;
+ int row_start_line = -1, cur_col = -1, cell_line_count = -1;
+ int last_row_start_line, startrow_deleted, vert_move = 1;
lineno = first_lineno = Stbl_getStartLine(me->stbl);
if (lineno < 0 || lineno > me->Lines)
@@ -4633,14 +4765,22 @@ PRIVATE int HText_insertBlanksInStblLine
/* The lineno of this loop runs over line numbers *before* unsplitting,
those which are wired into TRST structures */
for (; line && lineno <= last_lineno; line = nextline, lineno++) {
+ TextAnchor *a_prev_before, *a_start = NULL;
+
nextline = line->next;
+ last_row_start_line = row_start_line;
ninserts = Stbl_getFixupPositions(me->stbl, lineno, oldpos, newpos,
- prevline_len, &do_unsplit);
+ prevline_len, &do_unsplit,
+ &row_start_line,
+ &cur_col, &cell_line_count);
+ if (last_row_start_line != row_start_line)
+ startrow_deleted = deleted;
if (ninserts < 0)
continue;
if (!first_line) {
first_line = line;
first_lineno_pass2 = lineno;
+ a_start = me->last_anchor_before_stbl;
if (TRACE) {
int ip;
CTRACE((tfp, "line %d first to adjust -- newpos:", lineno));
@@ -4679,6 +4819,10 @@ PRIVATE int HText_insertBlanksInStblLine
prevline_len = width;
continue;
}
+ if ( me->last_anchor_before_stbl
+ && me->last_anchor_before_stbl->line_num >= lineno - deleted )
+ a_prev_before = a_start;
+ a_prev_before = me->last_anchor_before_stbl;
mod_line = insert_blanks_in_line(line, lineno - deleted, me,
&me->last_anchor_before_stbl
/*updates++*/,
ninserts, oldpos, newpos);
@@ -4709,14 +4853,58 @@ PRIVATE int HText_insertBlanksInStblLine
}
#endif
}
- if (do_unsplit && unsplit_line(me, line, 0)) {
- deleted++;
- /* Only one line is left is a special case */
- if (me->last_line == me->last_line->next)
- nextline = me->last_line;
- if (line == first_line->next)
- first_line = nextline->prev;
- line = nextline->prev;
+ if (has_multiline_anchor(me,line, lineno - deleted))
+ vert_move = 0;
+ if (vert_move && row_start_line != -1 && cell_line_count != -1
+ && lineno - deleted > (row_start_line - startrow_deleted +
cell_line_count) + 1)
+ move_after_line(me, line,
+ lineno - deleted - (row_start_line -
startrow_deleted + cell_line_count),
+ lineno - deleted);
+ if (do_unsplit != -1) {
+ HTLine *nxt_line = line->next; /* If vert-moved, != nextline */
+ if (unsplit_line(me, line, 0, do_unsplit)) {
+ deleted++;
+ /* Only one line is left is a special case */
+ if (me->last_line == me->last_line->next)
+ nextline = me->last_line;
+ if (line == first_line->next)
+ first_line = nxt_line->prev;
+ line = nextline->prev;
+ } else if (do_unsplit) { /* Need to shift horizontally */
+ int opos = 0, npos = do_unsplit;
+
+ /* Redo insertion with larger offset */
+ me->last_anchor_before_stbl = a_prev_before;
+ mod_line =
+ insert_blanks_in_line(line, lineno - deleted, me,
+ &me->last_anchor_before_stbl
/*updates++*/,
+ 1, &opos, &npos);
+ if (line == me->last_line) {
+ me->last_line = mod_line;
+ } else {
+ added_chars_before += (mod_line->size - line->size);
+ }
+ line->prev->next = mod_line;
+ line->next->prev = mod_line;
+ lines_changed++;
+ if (line == first_line)
+ first_line = mod_line;
+ line = mod_line;
+#ifdef DISP_PARTIAL
+ /*
+ * Make sure modified lines get fully re-displayed after
+ * loading with partial display is done.
+ */
+ if (me->first_lineno_last_disp_partial >= 0) {
+ if (me->first_lineno_last_disp_partial >= lineno) {
+ me->first_lineno_last_disp_partial =
+ me->last_lineno_last_disp_partial = -1;
+ } else if (me->last_lineno_last_disp_partial >= lineno) {
+ me->last_lineno_last_disp_partial = lineno - 1;
+ }
+ }
+#endif
+ }
}
{
int width = HText_TrueLineSize(line, me, FALSE);
--- ./src/TRSTable.c.orig Sat Jun 21 02:30:44 2003
+++ ./src/TRSTable.c Sat Jun 21 12:04:52 2003
@@ -1648,6 +1648,26 @@ PUBLIC BOOL Stbl_at_start_of_cell ARGS3(
return TRUE;
}
+PUBLIC int Stbl_start_of_last_cell ARGS2(
+ STable_info *, me,
+ int, lineno)
+{
+ STable_rowinfo *lastrow;
+ int icell;
+
+ CTRACE2(TRACE_TRST,
+ (tfp, "TRST:Stbl_at_start_of_cell(lineno=%d)\n", lineno));
+ if (me->nrows == 0)
+ return -1;
+ lastrow = me->rows + (me->nrows - 1);
+ if (lastrow->ended != ROW_not_ended)
+ return -1; /* E.g., may be processing </tr> */
+ icell = lastrow->ncells - 1;
+ if (icell >= 0 && lastrow->cells[icell].cLine == lineno)
+ return lastrow->cells[icell].pos;
+ return -1;
+}
+
PUBLIC void Stbl_finishRowInTable ARGS1(
STable_info *, me)
{
@@ -2064,13 +2084,16 @@ PUBLIC short Stbl_getAlignment ARGS1(
return (short)(me ? me->alignment : HT_ALIGN_NONE);
}
-PRIVATE int get_fixup_positions ARGS6(
+PRIVATE int get_fixup_positions ARGS9(
STable_rowinfo *, me,
int *, oldpos,
int *, newpos,
STable_cellinfo *, sumcols,
int, prevline_len,
- int *, do_unsplit)
+ int *, do_unsplit,
+ int *, row_start_line_p,
+ int *, cur_col_p,
+ int *, cell_line_count_p)
{
int i = 0, ip = 0;
int next_i, newlen;
@@ -2080,7 +2103,10 @@ PRIVATE int get_fixup_positions ARGS6(
if (!me)
return -1;
- *do_unsplit = 0;
+ *do_unsplit = -1;
+ (*cell_line_count_p)++;
+ if (!(me->content & IS_CONTINUATION_OF_CELL))
+ *row_start_line_p = me->Line;
while (i < me->ncells) {
int offset, pos;
@@ -2111,12 +2137,16 @@ PRIVATE int get_fixup_positions ARGS6(
}
}
}
- if (unsplit && !me->cells[i].pos && me->cells[i].len && !did_unsplit) {
- did_unsplit = 1;
- if (sumcols[i].pos >= prevline_len) {
- delta = prevline_len;
+ if (!me->cells[i].pos && me->cells[i].len) {
+ if (i != *cur_col_p) {
+ *cell_line_count_p = 0;
+ *cur_col_p = i;
+ }
+ if ((unsplit || *cur_col_p > 0) && !did_unsplit) {
+ did_unsplit = 1;
+ delta = sumcols[i].pos;
ip = 0; /* Undo changes */
- *do_unsplit = 1;
+ *do_unsplit = delta;
}
}
oldpos[ip] = me->cells[i].pos;
@@ -2133,17 +2163,20 @@ PRIVATE int get_fixup_positions ARGS6(
* 0 or greater (number of oldpos/newpos pairs) if we have
* a table row.
*/
-PUBLIC int Stbl_getFixupPositions ARGS6(
+PUBLIC int Stbl_getFixupPositions ARGS9(
STable_info *, me,
int, lineno,
int *, oldpos,
int *, newpos,
int, prevline_len,
- int *, do_unsplit)
+ int *, do_unsplit,
+ int *, row_start_line_p,
+ int *, cur_col_p,
+ int *, cell_line_count_p)
{
STable_rowinfo * row;
int j;
- int ninserts = -1;
+ int ninserts = -1, found = 0;
static int prev_row = 0;
if (!me || !me->nrows)
@@ -2156,11 +2189,16 @@ PUBLIC int Stbl_getFixupPositions ARGS6(
row = me->rows + j;
if (row->Line == lineno) {
prev_row = j;
+ found = 1;
ninserts = get_fixup_positions(row, oldpos, newpos,
- me->sumcols, prevline_len,
do_unsplit);
+ me->sumcols, prevline_len,
+ do_unsplit, row_start_line_p,
+ cur_col_p, cell_line_count_p);
break;
}
}
+ if (!found)
+ *row_start_line_p = -1;
return ninserts;
}
--- ./src/TRSTable.h.orig Sat Jun 21 02:30:08 2003
+++ ./src/TRSTable.h Sat Jun 21 10:06:12 2003
@@ -13,6 +13,7 @@ extern void Stbl_free PARAMS((STable_inf
extern int Stbl_addRowToTable PARAMS((STable_info *, int, int));
extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, int, int, int,
int, int));
extern BOOL Stbl_at_start_of_cell PARAMS((STable_info *, int, int));
+extern int Stbl_start_of_last_cell PARAMS((STable_info *, int));
extern int Stbl_finishCellInTable PARAMS((STable_info *, int, int, int, int));
extern int Stbl_addColInfo PARAMS((STable_info *, int, short, BOOL));
extern int Stbl_finishColGroup PARAMS((STable_info *));
@@ -32,7 +33,10 @@ extern int Stbl_getFixupPositions PARAMS
int * oldpos,
int * newpos,
int prevline_len,
- int * do_unsplit));
+ int * do_unsplit,
+ int * row_start_line_p,
+ int * move_after_p,
+ int * row_count_p));
extern short Stbl_getAlignment PARAMS((STable_info *));
#ifdef EXP_NESTED_TABLES
; To UNSUBSCRIBE: Send "unsubscribe lynx-dev" to address@hidden
- lynx-dev [PATCH 2.8.5-dev15] new table logic again,
Ilya Zakharevich <=