// I tried (MS Word and Lotus Word Pro).
line.fSegments.removeAllElements();
line.fCharLength = 0;
TabStop currentTabStop = new TabStop((int)fLeadingMargin+lineIndent, TabStop.kLeading);
int segmentLimit = measurer.getPosition();
boolean firstSegment = true;
int advanceFromLeadingMargin = lineIndent;
boolean computeSegs = true;
computeTabbedSegments: do {
// compute sementLimit:
if (segmentLimit <= measurer.getPosition()) {
while (segmentLimit < paragraphLimit) {
if (isTab(text.at(segmentLimit++))) {
break;
}
}
}
// NOTE: adjust available width for center tab!!!
//System.out.println("Format width: " + (formatWidth-advanceFromLeadingMargin) +
// "; segmentLimit: " + segmentLimit);
int wrappingWidth = Math.max(formatWidth-advanceFromLeadingMargin, 0);
TextLayout layout = null;
if (firstSegment || wrappingWidth > 0 || segmentLimit > measurer.getPosition()+1) {
layout = measurer.nextLayout(wrappingWidth, segmentLimit, !firstSegment);
}
if (layout == null) {
if (firstSegment) {
// I doubt this would happen, but check anyway
throw new Error("First layout is null!");
}
break computeTabbedSegments;
}
final int measurerPos = measurer.getPosition();
if (measurerPos < segmentLimit) {
computeSegs = false;
if (fFlush == FULLY_JUSTIFIED) {
layout = layout.getJustifiedLayout(wrappingWidth);
}
}
else {
computeSegs = !(measurerPos == paragraphLimit);
}
if (firstSegment) {
firstSegment = false;
// Have to get ltr off of layout. Not available from measurer,
// unfortunately.
line.fLeftToRight = layout.isLeftToRight();
}
BidiSegment segment = new BidiSegment();
segment.fLayout = layout;
int layoutAdvance = (int) Math.ceil(layout.getAdvance());
// position layout relative to leading margin, update logicalPositionOnLine
int relativeTabPosition = currentTabStop.getPosition()-(int)fLeadingMargin;
int logicalPositionOfLayout;
switch (currentTabStop.getType()) {
case TabStop.kTrailing:
logicalPositionOfLayout = Math.max(
relativeTabPosition-layoutAdvance,
advanceFromLeadingMargin);
break;
case TabStop.kCenter:
logicalPositionOfLayout = Math.max(
relativeTabPosition-(layoutAdvance/2),
advanceFromLeadingMargin);
break;
default: // includes decimal tab right now
logicalPositionOfLayout = relativeTabPosition;
break;
}
// position layout in segment
if (line.fLeftToRight) {
segment.fDistanceFromLeadingMargin = logicalPositionOfLayout;
}
else {
segment.fDistanceFromLeadingMargin = logicalPositionOfLayout+layoutAdvance;
}
// update advanceFromLeadingMargin
advanceFromLeadingMargin = logicalPositionOfLayout + layoutAdvance;
// add segment to segment Vector
line.fSegments.addElement(segment);
// get next tab
currentTabStop = fTabRuler.nextTab((int)fLeadingMargin+advanceFromLeadingMargin);
if (currentTabStop.getType() == TabStop.kLeading ||
currentTabStop.getType() == TabStop.kAuto) {
advanceFromLeadingMargin = currentTabStop.getPosition();
//System.out.println("Advance from leading margin:" + advanceFromLeadingMargin);
}
else {
//System.out.println("Non-leading tab, type=" + currentTabStop.getType());
}
} while (computeSegs);
// Now compute fTotalAdvance, fVisibleAdvance. These metrics may be affected
// by a trailing tab.
{
BidiSegment lastSegment = (BidiSegment) line.fSegments.lastElement();
TextLayout lastLayout = lastSegment.fLayout;
if (line.fLeftToRight) {
line.fTotalAdvance = (int) Math.ceil(lastLayout.getAdvance()) +
lastSegment.fDistanceFromLeadingMargin;
line.fVisibleAdvance = (int) Math.ceil(lastLayout.getVisibleAdvance()) +
lastSegment.fDistanceFromLeadingMargin;
}
else {
line.fTotalAdvance = lastSegment.fDistanceFromLeadingMargin;
line.fVisibleAdvance = lastSegment.fDistanceFromLeadingMargin -
(int) Math.ceil(lastLayout.getAdvance() -
lastLayout.getVisibleAdvance());
}
if (isTab(text.at(measurer.getPosition()-1))) {
line.fTotalAdvance = Math.max(line.fTotalAdvance,
currentTabStop.getPosition());
}
}
}