void () { if (!myIsDirty) return; CharSequence text = myDocument.getCharsNoThreadCheck(); int lineCount = myLineWidths.size(); int end = myDocument.getTextLength(); int x = 0; for (int line = 0; line < lineCount; line++) { if (myLineWidths.getQuick(line) != -1) continue; x = 0; int offset = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(line, 0))); if (offset >= myDocument.getTextLength()) { myLineWidths.set(line, 0); break; } IterationState state = new IterationState(EditorImpl.this, offset, false); int fontType = state.getMergedAttributes().getFontType(); while (offset < end) { char c = text.charAt(offset); if (offset >= state.getEndOffset()) { state.advance(); fontType = state.getMergedAttributes().getFontType(); } FoldRegion collapsed = state.getCurrentFold(); if (collapsed != null) { String placeholder = collapsed.getPlaceholderText(); for (int i = 0; i < placeholder.length(); i++) { x += charWidth(fontType, placeholder.charAt(i)); } offset = collapsed.getEndOffset(); } else { if (c == '\t') { x = nextTabStop(x); offset++; } else { if (c == '\n') { myLineWidths.set(line, x); if (line + 1 >= lineCount || myLineWidths.getQuick(line + 1) != -1) break; offset++; x = 0; line++; } else { x += charWidth(fontType, c); offset++; } } } } } if (lineCount > 0) { myLineWidths.set(lineCount - 1, x); // Last line can be non-zero length and won't be caught by in-loop procedure since latter only react on \n's } int maxWidth = 0; for (int i = 0; i < lineCount; i++) { maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i)); } mySize = new Dimension(maxWidth, getLineHeight() * lineCount); myIsDirty = false; }