openInlineBoxes = new ArrayList();
}
remainingWidth -= c.getBlockFormattingContext().getFloatDistance(c, currentLine, remainingWidth);
CalculatedStyle parentStyle = box.getStyle();
int minimumLineHeight = (int) parentStyle.getLineHeight(c);
int indent = (int) parentStyle.getFloatPropertyProportionalWidth(CSSName.TEXT_INDENT, maxAvailableWidth, c);
remainingWidth -= indent;
contentStart += indent;
MarkerData markerData = c.getCurrentMarkerData();
if (markerData != null && box.getStyle().isListMarkerInside()) {
remainingWidth -= markerData.getLayoutWidth();
contentStart += markerData.getLayoutWidth();
}
c.setCurrentMarkerData(null);
List pendingFloats = new ArrayList();
int pendingLeftMBP = 0;
int pendingRightMBP = 0;
boolean hasFirstLinePEs = false;
List pendingInlineLayers = new ArrayList();
if (c.getFirstLinesTracker().hasStyles()) {
box.styleText(c, c.getFirstLinesTracker().deriveAll(box.getStyle()));
hasFirstLinePEs = true;
}
boolean needFirstLetter = c.getFirstLettersTracker().hasStyles();
boolean zeroWidthInlineBlock = false;
int lineOffset = 0;
for (Iterator i = box.getInlineContent().iterator(); i.hasNext(); ) {
Styleable node = (Styleable)i.next();
if (node.getStyle().isInline()) {
InlineBox iB = (InlineBox)node;
CalculatedStyle style = iB.getStyle();
if (iB.isStartsHere()) {
previousIB = currentIB;
currentIB = new InlineLayoutBox(c, iB.getElement(), style, maxAvailableWidth);
openInlineBoxes.add(iB);
iBMap.put(iB, currentIB);
if (previousIB == null) {
currentLine.addChildForLayout(c, currentIB);
} else {
previousIB.addInlineChild(c, currentIB);
}
if (currentIB.getElement() != null) {
String name = c.getNamespaceHandler().getAnchorName(currentIB.getElement());
if (name != null) {
c.addBoxId(name, currentIB);
}
String id = c.getNamespaceHandler().getID(currentIB.getElement());
if (id != null) {
c.addBoxId(id, currentIB);
}
}
//To break the line well, assume we don't just want to paint padding on next line
pendingLeftMBP += style.getMarginBorderPadding(
c, maxAvailableWidth, CalculatedStyle.LEFT);
pendingRightMBP += style.getMarginBorderPadding(
c, maxAvailableWidth, CalculatedStyle.RIGHT);
}
LineBreakContext lbContext = new LineBreakContext();
lbContext.setMaster(iB.getText());
lbContext.setTextNode(iB.getTextNode());
if (iB.isDynamicFunction()) {
lbContext.setMaster(iB.getContentFunction().getLayoutReplacementText());
}
do {
lbContext.reset();
int fit = 0;
if (lbContext.getStart() == 0) {
fit += pendingLeftMBP + pendingRightMBP;
}
boolean trimmedLeadingSpace = false;
if (hasTrimmableLeadingSpace(
currentLine, style, lbContext, zeroWidthInlineBlock)) {
trimmedLeadingSpace = true;
trimLeadingSpace(lbContext);
}
lbContext.setEndsOnNL(false);
zeroWidthInlineBlock = false;
if (lbContext.getStartSubstring().length() == 0) {
break;
}
if (needFirstLetter && !lbContext.isFinished()) {
InlineLayoutBox firstLetter =
addFirstLetterBox(c, currentLine, currentIB, lbContext,
maxAvailableWidth, remainingWidth);
remainingWidth -= firstLetter.getInlineWidth();
if (currentIB.isStartsHere()) {
pendingLeftMBP -= currentIB.getStyle().getMarginBorderPadding(
c, maxAvailableWidth, CalculatedStyle.LEFT);
}
needFirstLetter = false;
} else {
lbContext.saveEnd();
InlineText inlineText = layoutText(
c, iB.getStyle(), remainingWidth - fit, lbContext, false);
if (!lbContext.isUnbreakable() ||
(lbContext.isUnbreakable() && ! currentLine.isContainsContent())) {
if (iB.isDynamicFunction()) {
inlineText.setFunctionData(new FunctionData(
iB.getContentFunction(), iB.getFunction()));
}
inlineText.setTrimmedLeadingSpace(trimmedLeadingSpace);
currentLine.setContainsDynamicFunction(inlineText.isDynamicFunction());
currentIB.addInlineChild(c, inlineText);
currentLine.setContainsContent(true);
lbContext.setStart(lbContext.getEnd());
remainingWidth -= inlineText.getWidth();
if (currentIB.isStartsHere()) {
int marginBorderPadding =
currentIB.getStyle().getMarginBorderPadding(
c, maxAvailableWidth, CalculatedStyle.LEFT);
pendingLeftMBP -= marginBorderPadding;
remainingWidth -= marginBorderPadding;
}
} else {
lbContext.resetEnd();
}
}
if (lbContext.isNeedsNewLine()) {
saveLine(currentLine, c, box, minimumLineHeight,
maxAvailableWidth, pendingFloats,
hasFirstLinePEs, pendingInlineLayers, markerData,
contentStart, isAlwaysBreak(c, box, breakAtLine, lineOffset));
lineOffset++;
markerData = null;
contentStart = 0;
if (currentLine.isFirstLine() && hasFirstLinePEs) {
lbContext.setMaster(TextUtil.transformText(iB.getText(), iB.getStyle()));
}
previousLine = currentLine;
currentLine = newLine(c, previousLine, box);
currentIB = addOpenInlineBoxes(
c, currentLine, openInlineBoxes, maxAvailableWidth, iBMap);
previousIB = currentIB.getParent() instanceof LineBox ?
null : (InlineLayoutBox) currentIB.getParent();
remainingWidth = maxAvailableWidth;
remainingWidth -= c.getBlockFormattingContext().getFloatDistance(c, currentLine, remainingWidth);
}
} while (!lbContext.isFinished());
if (iB.isEndsHere()) {
int rightMBP = style.getMarginBorderPadding(
c, maxAvailableWidth, CalculatedStyle.RIGHT);
pendingRightMBP -= rightMBP;
remainingWidth -= rightMBP;