lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev Re: [PATCH 2.8.4pre.2] Preserve horizontal alignment inside mul


From: Ilya Zakharevich
Subject: lynx-dev Re: [PATCH 2.8.4pre.2] Preserve horizontal alignment inside multi-line cells in tables
Date: Fri, 22 Jun 2001 04:56:11 -0400
User-agent: Mutt/1.2.5i

The current logic of TRST ignores the horizontal alignment *inside* a
multi-line cell of a table.  This limitation lead to Thomas thinking
there is a bug in TRST code (see www.tin.com), when a contents with a
horizontal alignment (e.g., <ul>) is put in a table cell.

The patch below introduces a *limited* logic to take this info into
account.  It should work OK as far as the last non-empty line of the
cell is ended by a "line-end" command, not by a </td> (I think this is
more or less automatic with contents using horizontal formatting).

Enjoy,
Ilya

--- src/GridText.c      2001/06/15 07:25:01     1.1
+++ src/GridText.c      2001/06/15 23:24:20
@@ -2962,6 +2962,20 @@ PRIVATE void split_line ARGS2(
        }
     }
 
+    switch (style->alignment) {
+       case HT_CENTER :
+           previous->offset = previous->offset + indent + spare/2;
+           break;
+       case HT_RIGHT :
+           previous->offset = previous->offset + indent + spare;
+           break;
+       case HT_LEFT :
+       case HT_JUSTIFY :               /* Not implemented */
+       default:
+           previous->offset = previous->offset + indent;
+           break;
+    } /* switch */
+
     if (text->stbl)
        /*
         *  Notify simple table stuff of line split, so that it can
@@ -2976,22 +2990,9 @@ PRIVATE void split_line ARGS2(
         */
        Stbl_lineBreak(text->stbl,
                       text->Lines - 1,
+                      previous->offset,
                       previous->size - ctrl_chars_on_previous_line);
 
-    switch (style->alignment) {
-       case HT_CENTER :
-           previous->offset = previous->offset + indent + spare/2;
-           break;
-       case HT_RIGHT :
-           previous->offset = previous->offset + indent + spare;
-           break;
-       case HT_LEFT :
-       case HT_JUSTIFY :               /* Not implemented */
-       default:
-           previous->offset = previous->offset + indent;
-           break;
-    } /* switch */
-
     text->in_line_1 = NO;              /* unless caller sets it otherwise */
 
     /*
@@ -4711,7 +4712,7 @@ PUBLIC void HText_startStblTD ARGS5(
        rowspan = 1;
     }
     if (Stbl_addCellToTable(me->stbl, colspan, rowspan, alignment, isheader,
-                           me->Lines, HText_LastLineSize(me,FALSE)) < 0)
+                           me->Lines, HText_LastLineOffset(me), 
HText_LastLineSize(me,FALSE)) < 0)
        HText_cancelStbl(me);   /* give up */
 }
 
@@ -4723,7 +4724,7 @@ PUBLIC void HText_endStblTD ARGS1(
     if (!me || !me->stbl)
        return;
     if (Stbl_finishCellInTable(me->stbl, TRST_ENDCELL_ENDTD,
-                              me->Lines, HText_LastLineSize(me,FALSE)) < 0)
+                              me->Lines, HText_LastLineOffset(me), 
HText_LastLineSize(me,FALSE)) < 0)
        HText_cancelStbl(me);   /* give up */
 }
 
@@ -8302,6 +8303,14 @@ PUBLIC int HText_LastLineSize ARGS2(
     if (!text || !text->last_line || !text->last_line->size)
        return 0;
     return HText_TrueLineSize(text->last_line, text, IgnoreSpaces);
+}
+
+PUBLIC int HText_LastLineOffset ARGS1(
+       HText *,        text)
+{
+    if (!text || !text->last_line)
+       return 0;
+    return  text->last_line->offset;
 }
 
 PUBLIC int HText_PreviousLineSize ARGS2(
--- src/GridText.h      2001/06/15 08:45:29     1.1
+++ src/GridText.h      2001/06/15 08:48:32
@@ -158,6 +158,7 @@ extern BOOL HTLoadedDocumentEightbit NOP
 extern void HText_setNodeAnchorBookmark PARAMS((CONST char *bookmark));
 extern char * HTLoadedDocumentBookmark NOPARAMS;
 extern int HText_LastLineSize PARAMS((HText *me, BOOL IgnoreSpaces));
+extern int HText_LastLineOffset PARAMS((HText *me));
 extern int HText_PreviousLineSize PARAMS((HText *me, BOOL IgnoreSpaces));
 extern void HText_NegateLineOne PARAMS((HText *text));
 extern BOOL HText_inLineOne PARAMS((HText *text));
--- src/TRSTable.c      2001/06/15 07:25:14     1.1
+++ src/TRSTable.c      2001/06/22 08:42:14
@@ -84,6 +84,13 @@ enum ended_state {
        ROW_ended_by_splitline
 };
 
+#define HAS_END_OF_CELL                1
+#define HAS_BEG_OF_CELL                        2
+#define IS_CONTINUATION_OF_CELL        4
+#define OFFSET_IS_VALID                        8
+#define OFFSET_IS_VALID_LAST_CELL      0x10
+#define BELIEVE_OFFSET                 0x20
+
 typedef struct _STable_rowinfo {
     /* Each row may be displayed on many display lines, but we fix up
        positions of cells on this display line only: */
@@ -113,7 +120,9 @@ typedef struct _STable_rowinfo {
        reset to the line of icell_core.
      */
        BOOL    fixed_line;     /* if we have a 'core' line of cells */
-       BOOL    ended;          /* if we saw </tr> */
+       enum ended_state ended; /* if we saw </tr> etc */
+       int     content;        /* Whether contains end-of-cell etc */
+       int     offset;         /* >=0 after line break in a multiline cell */
        int     allocated;      /* number of table cells allocated */
        STable_cellinfo * cells;
        int     alignment;      /* global align attribute for this row */
@@ -970,6 +979,8 @@ PRIVATE int Stbl_reserveCellsInTable ARG
        for (i = 0; i < growby; i++) {
            row = rows + me->allocated_rows + i;
            row->allocated = 0;
+           row->offset = 0;
+           row->content = 0;
            if (!me->rowspans2eog.allocated) {
                row->cells = NULL;
            } else {
@@ -1078,6 +1089,8 @@ PUBLIC int Stbl_addRowToTable ARGS3(
                    row->ncells = 0;
                    row->fixed_line = NO;
                    row->alignment = HT_ALIGN_NONE;
+                   row->offset = 0;
+                   row->content = 0;
                }
            }
            if (rows) {
@@ -1268,7 +1281,7 @@ PRIVATE int Stbl_fakeFinishCellInTable A
           are needed. */
        if (finishing) {
            /* Fake </TD> at BOL */
-           if (Stbl_finishCellInTable(me, end_td, lineno, 0) < 0) {
+           if (Stbl_finishCellInTable(me, end_td, lineno, 0, 0) < 0) {
                return -1;
            }
        }
@@ -1281,6 +1294,7 @@ PRIVATE int Stbl_fakeFinishCellInTable A
            return -1;
        }
        lastrow = me->rows + (me->nrows - 1);
+       lastrow->content = IS_CONTINUATION_OF_CELL;
        for (i = 0; i < lastrow->allocated; i++) {
            if (lastrow->cells[i].alignment == RESERVEDCELL) {
                need_reserved = 1;
@@ -1355,9 +1369,10 @@ PRIVATE int Stbl_fakeFinishCellInTable A
        while (++i <= ncells) {
            /* XXXX A lot of args may be wrong... */
            if (Stbl_addCellToTable(me, (i==ncells ? cs : 1), rs, al,
-                                   ih, lineno, 0) < 0) {
+                                   ih, lineno, 0, 0) < 0) {
                return -1;
            }
+           lastrow->content &= ~HAS_BEG_OF_CELL; /* BEG_OF_CELL was fake */
            /* We cannot run out of width here, so it is safe to not
               call Stbl_finishCellInTable(), but Stbl_finishCellInRow. */
            if (!finishing || (i != ncells)) {
@@ -1378,13 +1393,14 @@ PRIVATE int Stbl_fakeFinishCellInTable A
 /*
  * Returns -1 on error, otherwise 0.
  */
-PUBLIC int Stbl_addCellToTable ARGS7(
+PUBLIC int Stbl_addCellToTable ARGS8(
     STable_info *,     me,
     int,               colspan,
     int,               rowspan,
     int,               alignment,
     int,               isheader,
     int,               lineno,
+    int,               offset_not_used_yet,
     int,               pos)
 {
     STable_states * s = &me->s;
@@ -1398,9 +1414,9 @@ PUBLIC int Stbl_addCellToTable ARGS7(
     if (!me->rows || !me->nrows)
        return -1;              /* no row started! */
                                /* ##850_fail_if_fail?? */
-    if (me->rows[me->nrows - 1].ended)
+    if (me->rows[me->nrows - 1].ended != ROW_not_ended)
        Stbl_addRowToTable(me, alignment, lineno);
-    Stbl_finishCellInTable(me, TRST_ENDCELL_ENDTD, lineno, pos);
+    Stbl_finishCellInTable(me, TRST_ENDCELL_ENDTD, lineno, 0, pos);
     lastrow = me->rows + (me->nrows - 1);
 
 #ifdef EXP_NESTED_TABLES
@@ -1436,6 +1452,7 @@ PUBLIC int Stbl_addCellToTable ARGS7(
        /* me->rows may now have been realloc'd, make lastrow valid pointer */
        lastrow = me->rows + (me->nrows - 1);
     }
+    lastrow->content |= HAS_BEG_OF_CELL;
 
     {
        int growby = 0;
@@ -1486,10 +1503,11 @@ PUBLIC int Stbl_addCellToTable ARGS7(
 /*
  * Returns -1 on error, otherwise 0.
  */
-PUBLIC int Stbl_finishCellInTable ARGS4(
+PUBLIC int Stbl_finishCellInTable ARGS5(
     STable_info *,     me,
     int,               end_td,
     int,               lineno,
+    int,               offset,
     int,               pos)
 {
     STable_states * s = &me->s;
@@ -1498,15 +1516,15 @@ PUBLIC int Stbl_finishCellInTable ARGS4(
     int i;
 
     CTRACE2(TRACE_TRST,
-           (tfp, "TRST:Stbl_finishCellInTable(lineno=%d, pos=%d, end_td=%d)\n",
-                 lineno, pos, (int)end_td));
+           (tfp, "TRST:Stbl_finishCellInTable(lineno=%d, pos=%d, off=%d, 
end_td=%d)\n",
+                 lineno, pos, offset, (int)end_td));
     if (me->nrows == 0)
        return -1;
     lastrow = me->rows + (me->nrows - 1);
     icell = lastrow->ncells - 1;
     if (icell < 0)
        return icell;
-    if (s->x_td == -1) {       /* Stray </TD> or safety-call */
+    if (s->x_td == -1) {       /* Stray </TD> or just-in-case, as on </TR> */
        if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK)
            lastrow->ended = ROW_ended_by_splitline;
        return 0;
@@ -1570,8 +1588,12 @@ PUBLIC int Stbl_finishCellInTable ARGS4(
        me->maxpos = me->sumcols[me->allocated_sumcols-1].pos;
     }
 
-    if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK)
+    if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK) {
        lastrow->ended = ROW_ended_by_splitline;
+       lastrow->content |= BELIEVE_OFFSET;
+       lastrow->offset = offset;
+    }
+    
 #ifdef EXP_NESTED_TABLES /* maxlen may already include contribution of a cell 
in this column */
     if (nested_tables) {
        if (me->maxlen > MAX_STBL_POS)
@@ -1705,6 +1727,99 @@ PUBLIC int Stbl_finishTABLE ARGS1(
        s->pending_len = 0;
     }
     Stbl_finishRowInTable(me);
+    /* take into account offsets on multi-line cells.
+       XXX We cannot do it honestly, since two cells on the same row may
+       participate in multi-line table entries, and we preserve only
+       one offset per row.  This implementation may ignore
+       horizontal offsets for the last row of a multirow table entry.  */
+    for (i = 0; i < me->nrows - 1; i++) {
+       int j = i + 1, leading = i, non_empty;
+       STable_rowinfo *nextrow = me->rows + j;
+       int minoffset, have_offsets;
+       int foundcell = -1, max_width;
+
+       if ((nextrow->content & (IS_CONTINUATION_OF_CELL | HAS_BEG_OF_CELL | 
BELIEVE_OFFSET))
+           != (IS_CONTINUATION_OF_CELL | BELIEVE_OFFSET))
+           continue;                   /* Not a continuation line */
+       minoffset = nextrow[-1].offset; /* Line before first continuation */
+       CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_finishTABLE, l=%d, offset=%d, 
ended=%d.\n",
+                            i, nextrow[-1].offset, nextrow[-1].ended));
+
+       /* Find the common part of the requested offsets */
+       while (j < me->nrows
+              && ((nextrow->content & (IS_CONTINUATION_OF_CELL | 
HAS_BEG_OF_CELL | BELIEVE_OFFSET))
+                  == (IS_CONTINUATION_OF_CELL | BELIEVE_OFFSET))) {
+           if (minoffset > nextrow->offset)
+               minoffset = nextrow->offset;
+           CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_finishTABLE, l=%d, offset=%d, 
ended=%d.\n",
+                                j, nextrow->offset, nextrow[-1].ended));
+           nextrow++;
+           j++;
+       }
+       i = j - 1;                      /* Continue after this line */
+       /* Cancel the common part of offsets */
+       j = leading;                    /* Restart */
+       nextrow = me->rows + j;         /* Line before first continuation */
+       have_offsets = 0;
+       nextrow->content |= OFFSET_IS_VALID_LAST_CELL;
+       while (j <= i) {                /* A continuation line */
+           nextrow->offset -= minoffset;
+           nextrow->content |= OFFSET_IS_VALID;
+           if (nextrow->offset)
+               have_offsets = 1;
+           nextrow++;
+           j++;
+       }
+       if (!have_offsets)
+           continue;                   /* No offsets to deal with */
+
+       /* Find the cell number */
+       foundcell = -1;
+       j = leading + 1;                /* Restart */
+       nextrow = me->rows + j;         /* First continuation line */
+       while (foundcell == -1 && j <= i) { /* A continuation line */
+           int curcell = -1;
+
+           while (foundcell == -1 && ++curcell < nextrow->ncells)
+               if (nextrow->cells[curcell].len)
+                   foundcell = curcell, non_empty = j;
+           nextrow++;
+           j++;
+       }
+       if (foundcell == -1)            /* Can it happen? */
+           continue;
+       /* Find the max width */
+       max_width = 0;
+       j = leading;                    /* Restart */
+       nextrow = me->rows + j;         /* Include the pre-continuation line */
+       while (j <= i) {                /* A continuation line */
+           if (nextrow->ncells > foundcell) {
+               int curwid = nextrow->cells[foundcell].len + nextrow->offset;
+
+               if (curwid > max_width)
+                   max_width = curwid;
+           }
+           nextrow++;
+           j++;
+       }
+       /* Update the widths */
+       j = non_empty;                  /* Restart from the first nonempty */
+       nextrow = me->rows + j;
+       /* Register the increase of the width */
+       update_sumcols0(me->sumcols, me->rows + non_empty,
+                       0 /* width only */, max_width,
+                       foundcell, nextrow->cells[foundcell].colspan,
+                       me->allocated_sumcols);
+       j = leading;                    /* Restart from pre-continuation */
+       nextrow = me->rows + j;
+       while (j <= i) {                /* A continuation line */
+           if (nextrow->ncells > foundcell)
+               nextrow->cells[foundcell].len = max_width;
+           nextrow++;
+           j++;
+       }
+    }                                  /* END of Offsets processing */
+
     for (i = 0; i < me->ncols; i++) {
        if (me->sumcols[i].pos < curpos) {
            me->sumcols[i].pos = curpos;
@@ -1739,6 +1854,8 @@ PRIVATE int get_fixup_positions ARGS4(
     if (!me)
        return -1;
     while (i < me->ncells) {
+       int offset;
+
        next_i = i + HTMAX(1, me->cells[i].colspan);
        if (me->cells[i].cLine != me->Line) {
            if (me->cells[i].cLine > me->Line)
@@ -1747,7 +1864,13 @@ PRIVATE int get_fixup_positions ARGS4(
            continue;
        }
        oldpos[ip] = me->cells[i].pos;
-       newpos[ip] = sumcols[i].pos;
+       if ((me->content & OFFSET_IS_VALID)
+           && (i == me->ncells - 1
+               || !((me->content & OFFSET_IS_VALID_LAST_CELL))))
+           offset = me->offset;
+       else
+           offset = 0;
+       newpos[ip] = sumcols[i].pos + offset;
        if ((me->cells[i].alignment == HT_CENTER ||
             me->cells[i].alignment == HT_RIGHT) &&
            me->cells[i].len > 0) {
@@ -1829,7 +1952,7 @@ PUBLIC void Stbl_update_enclosing ARGS3(
            max_width, me->startline, last_lineno));
     for (l = me->startline; l <= last_lineno; l++) {
        /* Fake <BR> in appropriate positions */
-       if (Stbl_finishCellInTable(me->enclosing, TRST_ENDCELL_LINEBREAK, l, 
max_width) < 0) {
+       if (Stbl_finishCellInTable(me->enclosing, TRST_ENDCELL_LINEBREAK, l, 0, 
max_width) < 0) {
            /* It is not handy to let the caller delete me->enclosing,
               and it does not buy us anything.  Do it directly. */
            STable_info *stbl = me->enclosing;
--- src/TRSTable.h      2001/06/15 08:38:11     1.1
+++ src/TRSTable.h      2001/06/15 08:45:58
@@ -10,8 +10,8 @@ extern STable_info * Stbl_startTABLE PAR
 extern int Stbl_finishTABLE PARAMS((STable_info *));
 extern void Stbl_free PARAMS((STable_info *));
 extern int Stbl_addRowToTable PARAMS((STable_info *, int, int));
-extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, int, int, int, 
int));
-extern int Stbl_finishCellInTable PARAMS((STable_info *, int, int, int));
+extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, int, int, int, 
int, 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 *));
 extern int Stbl_addRowGroup PARAMS((STable_info *, short));
@@ -20,7 +20,7 @@ extern int Stbl_addRowGroup PARAMS((STab
 #define TRST_ENDCELL_LINEBREAK 0
 #define TRST_ENDCELL_MASK      1
 #define TRST_FAKING_CELLS      2
-#define Stbl_lineBreak(stbl,l,pos) Stbl_finishCellInTable(stbl, 
TRST_ENDCELL_LINEBREAK, l, pos)
+#define Stbl_lineBreak(stbl,l,off,pos) Stbl_finishCellInTable(stbl, 
TRST_ENDCELL_LINEBREAK, l, off, pos)
 
 extern int Stbl_getStartLine PARAMS((STable_info *));
 extern int Stbl_getFixupPositions PARAMS((

; To UNSUBSCRIBE: Send "unsubscribe lynx-dev" to address@hidden

reply via email to

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