case TRAILING:
horizontalAlignment = label.getComponentOrientation().isLeftToRight() ? RIGHT : LEFT;
break;
}
for (StyledText styledText : _styledTexts) {
StyleRange style = styledText.styleRange;
int size = (style != null && (style.isSuperscript() || style.isSubscript())) ? Math.round((float) defaultFontSize / style.getFontShrinkRatio()) : defaultFontSize;
font = getFont(label);
if (style != null && ((style.getFontStyle() != -1 && font.getStyle() != style.getFontStyle()) || font.getSize() != size)) {
font = FontUtils.getCachedDerivedFont(font, style.getFontStyle() == -1 ? font.getStyle() : style.getFontStyle(), size);
fm2 = label.getFontMetrics(font);
maxRowHeight = Math.max(maxRowHeight, fm2.getHeight());
minStartY = Math.max(minStartY, fm2.getAscent());
}
}
boolean lineWrap = label.isLineWrap();
if (!lineWrap) {
for (StyledText styledText : _styledTexts) {
if (styledText.text.endsWith("\n")) {
lineWrap = true;
break;
}
}
}
if (lineWrap && textY < minStartY) {
textY = minStartY;
}
int nextRowStartIndex = 0;
int rowCount = 0;
int rowStartOffset = 0;
for (int i = 0; i < _styledTexts.size(); i++) {
StyledText styledText = _styledTexts.get(i);
StyleRange style = styledText.styleRange;
if (mnemonicIndex >= 0 && styledText.text.length() - nextRowStartIndex > mnemonicIndex - charDisplayed) {
displayMnemonic = true;
mneIndex = mnemonicIndex - charDisplayed;
}
else {
displayMnemonic = false;
}
charDisplayed += styledText.text.length() - nextRowStartIndex;
if (styledText.text.contains("\r") || styledText.text.contains("\n")) {
boolean lastRow = (label.getMaxRows() > 0 && rowCount >= label.getMaxRows() - 1) || textY + maxRowHeight + Math.max(0, label.getRowGap()) > labelHeight;
if (horizontalAlignment != LEFT && g != null) {
if (lastRow && i != _styledTexts.size() - 1) {
x += fm.stringWidth("...");
}
paintRow(label, g, startX, x, endX, textY, rowStartOffset, style.getStart() + styledText.text.length(), lastRow);
}
rowStartOffset = style.getStart();
nextRowStartIndex = 0;
nextFm2 = null;
if (!lastRow) {
rowStartOffset += style.getLength();
rowCount++;
x = startX;
textY += maxRowHeight + Math.max(0, label.getRowGap());
continue; // continue to paint "..." if lastRow is true
}
else if (horizontalAlignment != LEFT && g != null) {
break;
}
}
y = textY;
if (nextFm2 == null) {
int size = (style != null &&
(style.isSuperscript() || style.isSubscript())) ? Math.round((float) defaultFontSize / style.getFontShrinkRatio()) : defaultFontSize;
font = getFont(label);
if (style != null && ((style.getFontStyle() != -1 && font.getStyle() != style.getFontStyle()) || font.getSize() != size)) {
font = FontUtils.getCachedDerivedFont(font, style.getFontStyle() == -1 ? font.getStyle() : style.getFontStyle(), size);
fm2 = label.getFontMetrics(font);
}
else {
fm2 = fm;
}
}
else {
fm2 = nextFm2;
}
if (g != null) {
g.setFont(font);
}
boolean stop = false;
String s = styledText.text.substring(Math.min(nextRowStartIndex, styledText.text.length()));
if (s.contains("\r") || s.contains("\n")) {
s = "...";
stop = true;
}
int strWidth = fm2.stringWidth(s);
boolean wrapped = false;
int widthLeft = endX - x;
if (widthLeft < strWidth && widthLeft >= 0) {
if (label.isLineWrap() && ((label.getMaxRows() > 0 && rowCount < label.getMaxRows() - 1) || label.getMaxRows() <= 0) && y + maxRowHeight + Math.max(0, label.getRowGap()) <= labelHeight) {
wrapped = true;
int availLength = s.length() * widthLeft / strWidth + 1;
int nextWordStartIndex;
int nextRowStartIndexInSubString = 0;
boolean needBreak = false;
boolean needContinue = false;
int loopCount = 0;
do {
String subString = s.substring(0, Math.max(0, Math.min(availLength, s.length())));
int firstRowWordEndIndex = findFirstRowWordEndIndex(subString);
nextWordStartIndex = firstRowWordEndIndex < 0 ? 0 : findNextWordStartIndex(s, firstRowWordEndIndex);
if (firstRowWordEndIndex < 0) {
if (x != startX) {
boolean lastRow = label.getMaxRows() > 0 && rowCount >= label.getMaxRows() - 1;
if (horizontalAlignment != LEFT && g != null) {
paintRow(label, g, startX, x, endX, textY, rowStartOffset, style.getStart() + Math.min(nextRowStartIndex, styledText.text.length()), lastRow);
}
textY += maxRowHeight + Math.max(0, label.getRowGap());
x = startX;
i--;
rowCount++;
rowStartOffset = style.getStart() + Math.min(nextRowStartIndex, styledText.text.length());
if (lastRow) {
needBreak = true;
}
needContinue = true;
break;
}
else {
firstRowWordEndIndex = 0;
nextWordStartIndex = Math.min(s.length(), availLength);
}
}
nextRowStartIndexInSubString = firstRowWordEndIndex + 1;
String subStringThisRow = s.substring(0, Math.min(nextRowStartIndexInSubString, s.length()));
strWidth = fm2.stringWidth(subStringThisRow);
if (strWidth > widthLeft) {
availLength = subString.length() * widthLeft / strWidth;
}
loopCount++;
if (loopCount > 15) {
System.err.println("Painting Styled Label Error: " + styledText);
break;
}
} while (strWidth > widthLeft && availLength > 0);
if (needBreak) {
break;
}
if (needContinue) {
continue;
}
while (nextRowStartIndexInSubString < nextWordStartIndex) {
strWidth += fm2.charWidth(s.charAt(nextRowStartIndexInSubString));
if (strWidth >= widthLeft) {
break;
}
nextRowStartIndexInSubString++;
}
s = s.substring(0, Math.min(nextRowStartIndexInSubString, s.length()));
strWidth = fm2.stringWidth(s);
charDisplayed -= styledText.text.length() - nextRowStartIndex;
if (displayMnemonic) {
if (mnemonicIndex >= 0 && s.length() > mnemonicIndex - charDisplayed) {
displayMnemonic = true;
mneIndex = mnemonicIndex - charDisplayed;
}
else {
displayMnemonic = false;
}
}
charDisplayed += s.length();
nextRowStartIndex += nextRowStartIndexInSubString;
}
else {
// use this method to clip string
s = SwingUtilities.layoutCompoundLabel(label, fm2, s, null, label.getVerticalAlignment(), label.getHorizontalAlignment(),
label.getVerticalTextPosition(), label.getHorizontalTextPosition(), new Rectangle(x, y, widthLeft, labelHeight), new Rectangle(), new Rectangle(), 0);
strWidth = fm2.stringWidth(s);
}
stop = !lineWrap || y + maxRowHeight + Math.max(0, label.getRowGap()) > labelHeight || (label.getMaxRows() > 0 && rowCount >= label.getMaxRows() - 1);
}
else if (lineWrap) {
nextRowStartIndex = 0;
}
else if (i < _styledTexts.size() - 1) {
StyledText nextStyledText = _styledTexts.get(i + 1);
String nextText = nextStyledText.text;
StyleRange nextStyle = nextStyledText.styleRange;
int size = (nextStyle != null &&
(nextStyle.isSuperscript() || nextStyle.isSubscript())) ? Math.round((float) defaultFontSize / nextStyle.getFontShrinkRatio()) : defaultFontSize;
font = getFont(label);
if (nextStyle != null && ((nextStyle.getFontStyle() != -1 && font.getStyle() != nextStyle.getFontStyle()) || font.getSize() != size)) {
font = FontUtils.getCachedDerivedFont(font, nextStyle.getFontStyle() == -1 ? font.getStyle() : nextStyle.getFontStyle(), size);
nextFm2 = label.getFontMetrics(font);
}
else {
nextFm2 = fm;
}