May 2001, S.Geerken@ping.de Last update: Dec 2004 ======= DwTable ======= A container widget for rendering tables. The DwTable Widget ================== DwTable is a container widget for rendering tables. It aligns other DwWidgets (normally DwPage), according to the following rules: 1. All columns have have the same width W, except: - W is less than the minimal column width, or - W is greater than the maximal column width. Furthermore, W is - less than all minimal widths of columns not having W as width, and - greater than all maximal widths of columns not having W as width. 2. The table tries to use exactly the whole available width, except if it is not possible, because the it is less/greater than the minimal/maximal table width. This is simple to implement for columns with COLSPAN == 1, using a_Dw_get_extremes for getting the minimal and maximal widths. For arbitrary COLSPAN values, an approach described in "Subtables" is used to get optimal results (as described above) in most cases, while the rendering remains fast. Subtables ========= A table is divided into subtables, which do not (in most cases) share spanning cells, until single columns are left. Cells spanning the whole width are removed before dividing further. Example: +---+-------+---+ | A | B | C | +---+-------+---+ | D | E | +---+-------+---+ | F | G | H | +---+-------+---+ ' ' ` ` ' ' ` ` +---+-------+ +---+ | A | B | | C | +---+-------+ +---+ removed --> | D | | E | +---+-------+ +---+ | F | G | | H | +---+-------+ +---+ ' ' ` ` final ' ' ` ` +---+ +-------+ | A | | B | <-. +---+ +-------+ >- removed | F | | G | <-' +---+ +-------+ final ' ' ` ` ' ' ` ` [empty] [empty] final final There is a structure, DwTableSub, for holding all the information. It is rebuilt when new cells are added. Do not confuse this with nested tables, these are represented by the Dw widget hierarchy. If table cells overlap horizontally, they are (virtually) divided. The minimal and maximal widths are apportioned to the other columns (resulting in a non optimal layout): +-------+---+---+ | A | B | C | +---+---+---+---+ | D | E | +---+-----------+ ' ' ` ` ' ' ` ` +-------+ +---+---+ | A | | B | C | +---+---+ +---+---+ | D |1/3| | 2/3 E | | | E | | | +---+---+ +-------+ Example for a non-optimal case ------------------------------ The HTML document fragment
Text LongText
Text LongText
will result in: | 0 | 1 | 2 | +------------+----------+ | Text | LongText | +------+-----+----------+ | Text | LongText | +------+----------------+ The width of column 1 is determined by the half of the minimal width of the LongText. An optimal rendering would be something like: ,- 1 | 0 || 2 | +-------+----------+ | Text | LongText | +------++----------+ | Text | LongText | +------+-----------+ Algorithms ========== Calculating extremes -------------------- The extremes of all subtables are calculated by Dw_table_sub_get_extremes and stored in DwTableSub: minimal/maximal width (sub table) = - for single column: maximum of all minimal/maximal widths - otherwise: maximum of 1. all minimal/maximal widths of cells spanning the whole width, and 2. the sum of the minimal/maximal widths of the sub-subtables In step 1, the width argument is used to adjust the maximum and minimum width of the whole subtable and mark it as fixed. todo: describe percentages. Calculating column widths ------------------------- The calculation is based on a fixed width, which is, at the top, the width set by a_Dw_widget_set_width. This is corrected by the minimal and maximal width of the whole table, and, if given, the width attribute of the table. At each level, the available width is always between the minimal and the maximal width of the subtable. For single columns, the width is the passed fixed width. Otherwise: 1. Calculate relative widths, they effect the minimal and maximal widths. (Temporally, not permanently!) 2. The sum of these corrected minima may be greater as the fixed width of the subtable. In this case, decrease them again to match exactly the fixed width, then use them as sub-subtable fixed widths and finish. Otherwise, continue: 3. If the extremes of the spanning widths of the subtable are greater than the sum of sub-subtables extremes, adjust the extremes of sub-subtables which are not fixed, i.e., where no width argument (either percentage or fixed) freezes the width. 4. Use an iteration on the subtables, to determine the column widths, see Dw_table_sub_calc_col_widths for details. 5. After this, apply this recursively on all subtables and pass the subtable width as fixed width. Borders, Paddings, Spacing ========================== Currently, DwTable supports only the separated borders model (see CSS specification). Borders, paddings, spacing is done by creating DwStyle structures with values equivalent to following CSS: TABLE { border: outset ; border-collapse: separate; border-spacing: background-color: } TD TH { border: inset ; padding: background-color: } Here, refers to the attribute bar of the tag foo. See Html_open_table and Html_open_table_cell for more details.