//ComputedLayoutProperties nlp = new ComputedLayoutProperties()
final RenderLength bcw = computeBlockContextWidth(box);
final StaticBoxLayoutProperties blp = box.getStaticBoxLayoutProperties();
final long rbcw = bcw.resolve(0);
final BoxDefinition boxDefinition = box.getBoxDefinition();
final ComputedLayoutProperties clp = new ComputedLayoutProperties();
if (box instanceof TableCellRenderBox)
{
// Table cells have borders and paddings, but no margins ..
computeBorder(boxDefinition, clp, rbcw);
// the computed width of table-cells is not known yet ...
// This is computed later ..
// We have to check the column-model for that and have to see
// whether that one has some hints. If the cell has an explicit
// width, we can use that one.
final RenderLength preferredWidth = boxDefinition.getPreferredWidth();
if (preferredWidth == RenderLength.AUTO)
{
// The cell itself did not define anything. But maybe the column
// had a definition?
final TableCellRenderBox cellBox = (TableCellRenderBox) box;
final TableColumnModel columnModel = cellBox.getTable().getColumnModel();
final int colIdx = cellBox.getColumnIndex();
if (colIdx < 0)
{
throw new IllegalStateException("Table has not been validated yet.");
}
final int maxIdx = colIdx + cellBox.getColSpan();
if (maxIdx >= columnModel.getColumnCount())
{
// No definition. Therefore the cell will not have a computed width.
// (The effective width will be auto-computed in later steps.)
// Yeah, we *could* start guessing, but I dont support our user's
// lazyness. Shall they suffer from their own mis-definitions.
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(RenderLength.AUTO);
box.setComputedLayoutProperties(clp);
}
else
{
long width = 0;
for (int i = colIdx; i < maxIdx; i++)
{
// Check, whether one of the columns will have an autoWidth --
final TableColumn column = columnModel.getColumn(i);
final RenderLength definedWidth = column.getDefinedWidth();
if (definedWidth == RenderLength.AUTO)
{
// No go.
width = -1;
break;
}
width += definedWidth.resolve(rbcw);
}
if (width > 0)
{
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(new RenderLength(width, false));
box.setComputedLayoutProperties(clp);
}
else
{
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(RenderLength.AUTO);
box.setComputedLayoutProperties(clp);
}
}
}
else
{
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(preferredWidth.resolveToRenderLength(rbcw));
box.setComputedLayoutProperties(clp);
}
return true;
}
if (box instanceof TableRowRenderBox ||
box instanceof TableSectionRenderBox)
{
// rows and sections have neither paddings, margins or borders ..
// See 17.6.1 of [CSS21]
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(bcw);
box.setComputedLayoutProperties(clp);
return true;
}
// Every other Block-Level-element.
computeBorder(boxDefinition, clp, rbcw);
// For reference: The following formula defines the behaviour on AUTO
//
// (width of containing block) =
// margin-left + border-left + padding-left + width +
// padding-right + border-right + margin-right
// On horizontal flow: If margin-top or -bottom is auto, then
// the margin resolves to zero
clp.setMarginTop(boxDefinition.getMarginTop().resolve(rbcw));
clp.setMarginBottom(boxDefinition.getMarginBottom().resolve(rbcw));
// According to the box-model, there are five cases
// Case1: None of Width and Margin-left-right is auto.
final RenderLength marginLeft = boxDefinition.getMarginLeft();
final RenderLength marginRight = boxDefinition.getMarginRight();
final RenderLength preferredWidth = boxDefinition.getPreferredWidth();
if (preferredWidth != RenderLength.AUTO)
{
if (marginLeft != RenderLength.AUTO &&
marginRight != RenderLength.AUTO)
{
final long mlValue = marginLeft.resolve(rbcw);
final long mrValue = marginRight.resolve(rbcw);
final long pwValue = preferredWidth.resolve(rbcw);
// Sub-Case 1: The defined values satisfy the constraints defined by
// the formula
if (mlValue + mrValue + pwValue == rbcw)
{
// fine. Accept these values
clp.setMarginLeft(mlValue);
clp.setMarginRight(mrValue);
}
// Sub-Case 2: They dont ..
else if (box.isDirectionLTR())
{
clp.setMarginLeft(mlValue);
clp.setMarginRight(rbcw - mlValue - pwValue);
}
else
{
clp.setMarginLeft(rbcw - mrValue - pwValue);
clp.setMarginRight(mrValue);
}
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(new RenderLength(pwValue, false));
box.setComputedLayoutProperties(clp);
return true;
}
// If exactly one of width, margin-left or margin-right is 'auto',
// its value is computed from the equation.
if (marginLeft == RenderLength.AUTO &&
marginRight != RenderLength.AUTO)
{
final long mrValue = marginRight.resolve(rbcw);
final long pwValue = preferredWidth.resolve(rbcw);
clp.setMarginLeft(rbcw - mrValue - pwValue);
clp.setMarginRight(mrValue);
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(new RenderLength(pwValue, false));
box.setComputedLayoutProperties(clp);
return true;
}
if (marginLeft != RenderLength.AUTO &&
marginRight == RenderLength.AUTO)
{
final long mlValue = marginLeft.resolve(rbcw);
final long pwValue = preferredWidth.resolve(rbcw);
clp.setMarginLeft(mlValue);
clp.setMarginRight(rbcw - mlValue - pwValue);
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(new RenderLength(pwValue, false));
box.setComputedLayoutProperties(clp);
return true;
}
}
// If width and one or both margins are 'auto', the margins that
// are 'auto' are set to 0 and the equation is solved for width.
else // if (preferredWidth == RenderLength.AUTO)
{
final long mlValue = marginLeft.resolve(rbcw);
final long mrValue = marginRight.resolve(rbcw);
clp.setMarginLeft(mlValue);
clp.setMarginRight(mrValue);
if (box instanceof TableRenderBox)
{
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(RenderLength.AUTO);
box.setComputedLayoutProperties(clp);
}
else if (bcw == RenderLength.AUTO)
{
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(RenderLength.AUTO);
box.setComputedLayoutProperties(clp);
}
else
{
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(new RenderLength((rbcw - mlValue - mrValue), false));
box.setComputedLayoutProperties(clp);
}
return true;
}
// If both margin-left and margin-right are 'auto', the equation is
// solved under the extra constraint that margin-left = margin-right.
final long pwValue = preferredWidth.resolve(rbcw);
final long margins = rbcw - pwValue;
final long mlValue = margins / 2;
clp.setMarginLeft(mlValue);
clp.setMarginRight(margins - mlValue);
clp.setBlockContextWidth(bcw);
clp.setComputedWidth(new RenderLength(pwValue, false));
box.setComputedLayoutProperties(clp);
return true;
}