lynx-dev
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]