Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Xmlgraphics-fop Wiki" 
for change notification.

The "AutoTableLayout" page has been changed by GregorBerg:
https://wiki.apache.org/xmlgraphics-fop/AutoTableLayout?action=diff&rev1=2&rev2=3

Comment:
some initial documentation for Patch 2469

  This page contains information about the implementation of the "auto table 
layout" in Apache FOP.
  
+ = Handling of Tables in FOP-2469 =
+ As soon as a table with table-layout="auto" is encountered, FOP has to 
determine the width of each of its columns. Each column has a minimal width and 
a maximal width. It is up to FOP to determine these widths and (if the maximal 
width cannot be used) to find the optimal width (minimal<=optimal<=maximal).
+ 
+  * minimal width: if this width cannot be granted, FOP will most likely 
encounter an overflow (maximal miminmal width of all contained table cells)
+  * maximal width: this is the total amount of width the content of any 
individual table cell requires if it would be rendered without any breaks 
(maximal width of all contained table cells)
+  * optimal width: this width valueis used during the redistribution of space 
and, eventually, it is the width which FOP will use to render the column
+ 
+ To determine these values, FOP has to obtain the corresponding widths of the 
table cells which a column contains. Thus, the !TableCellLayoutManager has to 
recursively ask all of its contained !LayoutManagers for these values.
+ 
+ Currently, most !LayoutManagers simply return the corresponding values of 
their children. Notable exceptions are
+ 
+  * !TableLayoutManager
+  * !TableCellLayoutManager (adds indentations/paddings)
+  * !TextLayoutManager (only determines the length of the longest !KnuthBox - 
currently, '''hyphenation etc. are not considered''')
+ 
+ In the following, simple tables are used as an example to explain the basic 
algorithm of determining the optimal widths of columns in an ''auto table''. 
Afterwards, more specific issues such as colspan and nested tables are 
described.
+ 
+ Reading convention:  w(abc) = width of the string "abc"
+ 
+ == Simple Tables ==
+ ==== Without Breaks ====
+ ||<tablewidth="auto">a ||b ||c ||
+ ||a ||ab ||a b c ||
+ 
+ 
+ The first row is checked and the width of each column is set to the width of 
its first table cell, thus: min/opt/max = w(character). Afterwards, the second 
row is inspected.
+ 
+  * column 1: min/opt/max are identical for the second table-cell and, 
therefore, the column width remains the same
+  * column 2: since this table cell contains two '''consecutive''' letters, 
its minimum increases to their width. Again, the maximum width is identical and 
this column is set to min/opt/max = w(two letters)
+  * column 3: for this table cell, the ''minimum ''value is the width of the 
widest letter since FOP can insert a linebreak after each individual letter. 
The ''maximum ''and ''optimal'' value, however, are w('a b c')
+ 
+ After the table was inspected, each column has a !MinOptMax instance 
representing its viable widths. Since the sum of all max values is less than 
the available space, the opt value (initialized as ''max'') does not need to be 
changed. All columns are rendered using their respective opt/max value.
+ 
+ ==== With Breaks ====
+ ||<tablewidth="200px">a ||b ||c ||
+ ||a ||abcdefghijklmn ||a b c d ||
+ 
+ 
+ The first row is checked and the width of each column is set to the width of 
its first table cell, thus: min/opt/max = w(character). Afterwards, the second 
row is inspected.
+ 
+  * column 1: column width remains the same
+  * column 2: since this table cell contains '''consecutive''' characters,  
its minimum increases to their width. Again, the maximum width is  identical 
and this column is set to min/opt/max = w('abcdefghijklmn')
+  * column 3: for this table cell, the
+   * min ''= ''w(widest character)
+   * max = w('a b c d')
+   * opt (for now) = w('a b c d')
+ 
+ Again, each column has a !MinOptMax instance representing its viable widths. 
In this case, however, the sum of max values is greater than the available 
space. The available space has to redistributed among the columns (cf. 
!ColumnSetup::redistribute()).
+ 
+ Out of a list of all columns, FOP removes those which cannot be shrinked. At 
first, FOP excludes any columns containing only consecutive letters (i.e. min 
== max, in the example the first two columns) and columns which have a static 
width. Then, the remaining columns are set to math.max(column's min value, 
column's max value * shrink factor) - thus, they are either shrinked as far as 
possible or set to their min value.
+ 
+ For the example, columns a and b use their max(=min=opt) value, while column 
c uses its opt value which was shrinked (min = w(character), opt = w(2 
characters and a space), max = ('a b c d')). As a result, column c has a 
linebreak.
+ 
+ ==== Not Enough Space ====
+ In case the sum of all min values is greater than the available space, a 
warning ('columnsInAutoTableTooWide') is produced. FOP sets all columns to 
their respective min value and will most probably produce an overflow.
+ 
+ == Merged Cells ==
+ While tables containing table cells employing row-span values are not a 
problem (please see also 
[[https://issues.apache.org/jira/browse/FOP-2451|FOP-2451]]), col-span table 
cells have to be taken into account. The following three cases exist.
+ 
+ ==== Balanced Expansion/Reduction ====
+ ||<tablewidth="auto">a ||b ||c ||
+ ||||<style="text-align:center">abc abc abc ||a b c ||
+ 
+ 
+ ==== Requires Second Run ====
+ ||||<tablewidth="auto"style="text-align:center">abc abc abc ||a b c ||
+ ||a ||b ||c ||
+ 
+ 
+ ==== Worst Case ====
+ ||||<tablewidth="auto"style="text-align:center">ab (rowspan=2) ||c ||
+ ||a ||||<style="text-align:center">bc (rowspan=2) ||
+ 
+ 
+ text
+ 
+ == Nested Tables ==
+ So far, all scenarios only described the handling of isolated tables. 
However, nested tables are also quite common and, depending on their kind, 
require a specific treatment.
+ 
+ ==== Fixed Table in Auto Table ====
+ ==== Auto Table in Auto Table ====
+ 
+ ----
  = Some Random Ideas =
- 
  Today, FOP works with the Knuth element model in both inline- and 
block-progression-directions. For the auto table layout, we can make use of the 
inline Knuth element lists generated for content in table-cells. Before the 
line-breaking is done all the elements are gathered. By finding the 
largest/widest non-breakable sequence in an element list we can determine the 
minimal width of a column. By determining the full (unbroken) length of each 
element list involved we know how wide a column would have to be to accomodate 
the content without breaking it. Ideally, that latter value is used for the 
column width but if all the columns together would make the table wider than it 
can be, the column widths have to be reduced, in an extreme situation, down to 
the minimum established by the former value. I don't want to suggest any 
details on how to determine what effective width a column should get. The only 
purpose of the above is to give an idea for an approach to implement auto table 
layout.
  
  So, in order to determine the column widths, the element lists have to be 
available early. The !TableRowIterator already supports preflying a full table. 
The problem starts with actually getting at the element lists. Currently, 
!LineLayoutManager directly starts line-breaking in getNextKnuthElements() when 
the element lists are available. This would have to be split, so table layout 
code could access the element lists separately. ATM I'm unsure if block-level 
content in inlines pose a problem to this. That will have to be looked at 
closely. Anyway, it should be taken care that an element list doesn't have to 
be recreated later to do the line-breaking. The number of objects created for 
an element list is already high enough. Creating objects is expensive.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to