InlineSequenceElement contentElement = null;
int contentIndex = start;
for (int i = start; i < endIndex; i++)
{
final InlineSequenceElement element = sequenceElements[i];
final RenderNode node = nodes[i];
if (element instanceof StartSequenceElement ||
element instanceof EndSequenceElement)
{
width += element.getMaximumWidth(node);
continue;
}
width += element.getMaximumWidth(node);
contentElement = element;
contentIndex = i;
}
final long nextPosition = getPosition() + width;
final long lastPageBreak = getPageBreak(getPagebreakCount() - 1);
// Do we cross a page boundary?
if (nextPosition > lastPageBreak)
{
// On outer break: Stop processing
// Dont write through to the stored position; but prepare if
// we have to fallback ..
long position = getPosition();
for (int i = start; i < endIndex; i++)
{
final InlineSequenceElement element = sequenceElements[i];
final RenderNode node = nodes[i];
elementPositions[i] = position;
final long elementWidth = element.getMaximumWidth(node);
elementDimensions[i] = elementWidth;
position += elementWidth;
}
// we cross a pagebreak. Stop working on it - we bail out here.
if (contentElement instanceof TextSequenceElement)
{
// the element may be splittable. Test, and if so, give a hint to the
// outside world ..
setSkipIndex(endIndex);
setBreakableIndex(contentIndex);
return (start);
}
// This is the first element and it still does not fit. How evil.
if (start == 0)
{
if (contentElement instanceof InlineBoxSequenceElement)
{
final RenderNode node = nodes[contentIndex];
if ((node.getNodeType() & LayoutNodeTypes.MASK_BOX) == LayoutNodeTypes.MASK_BOX)
{
// OK, limit the size of the box to the maximum line width and
// revalidate it.
final long contentPosition = elementPositions[contentIndex];
final RenderBox box = (RenderBox) node;
final long maxWidth = (getEndOfLine() - contentPosition);
computeInlineBlock(box, contentPosition, maxWidth);
elementDimensions[endIndex - 1] = node.getCachedWidth();
}
}
setSkipIndex(endIndex);
}
return (start);
}
final long innerPagebreak = getPageBreak(getPageSegment());
if (nextPosition > innerPagebreak)
{
// It is an inner pagebreak and the current element would not fit into the remaining space.
// Move the element to the next page segment (but only if the start is not on
setPosition(innerPagebreak);
setPageSegment(getPageSegment() + 1);
}
// No, it is an ordinary advance ..
// Check, whether we hit an item-sequence element
if (contentElement instanceof InlineBoxSequenceElement == false)
{
for (int i = start; i < endIndex; i++)
{
final RenderNode node = nodes[i];
final InlineSequenceElement element = sequenceElements[i];
elementPositions[i] = getPosition();
final long elementWidth = element.getMaximumWidth(node);
elementDimensions[i] = elementWidth;
addPosition(elementWidth);
}
return endIndex;
}
// Handle the ItemSequence element.
// This is a bit more complicated. So we encountered an inline-block
// element here. That means, the element will try to occuppy its
// maximum-content-width.
// Log.debug("Advance block at index " + contentIndex);
// final long ceWidth = contentElement.getMinimumWidth();
// final long extraSpace = contentElement.getMaximumWidth();
// Log.debug("Advance block: Min " + ceWidth);
// Log.debug("Advance block: Max " + extraSpace);
final RenderNode contentNode = nodes[contentIndex];
final long itemElementWidth = contentElement.getMaximumWidth(contentNode);
if ((contentNode.getNodeType() & LayoutNodeTypes.MASK_BOX) == LayoutNodeTypes.MASK_BOX)
{
final RenderBox box = (RenderBox) contentNode;
computeInlineBlock(box, getPosition(), itemElementWidth);
}
else
{
contentNode.setCachedX(getPosition());
contentNode.setCachedWidth(itemElementWidth);
}
final long preferredEndingPos = getPosition() + itemElementWidth;
if (preferredEndingPos > getEndOfLine())
{
// We would eat the whole space up to the end of the line and more
// So lets move that element to the next line instead...
// But: We could easily end in an endless loop here. So check whether
// the element is the first in the line
if (start == 0)
{
// As it is guaranteed, that each chunk contains at least one item,
// checking for start == 0 is safe enough ..
return endIndex;
}
return start;
}
for (int i = start; i < contentIndex; i++)
{
final InlineSequenceElement element = sequenceElements[i];
final RenderNode node = nodes[contentIndex];
final long elementWidth = element.getMaximumWidth(node);
elementPositions[i] = getPosition();
elementDimensions[i] = elementWidth;
addPosition(elementWidth);
}
elementPositions[contentIndex] = getPosition();
elementDimensions[contentIndex] = itemElementWidth;
setPosition(preferredEndingPos);
for (int i = contentIndex + 1; i < endIndex; i++)
{
final InlineSequenceElement element = sequenceElements[i];
final RenderNode node = nodes[contentIndex];
final long elementWidth = element.getMaximumWidth(node);
elementPositions[i] = getPosition();
elementDimensions[i] = elementWidth;
addPosition(elementWidth);
}