void (@NotNull Graphics g, @NotNull Rectangle clip, @NotNull LogicalPosition clipStartPosition, int clipStartOffset, int clipEndOffset) { myCurrentFontType = null; myLastCache = null; int lineHeight = getLineHeight(); int visibleLine = clip.y / lineHeight; int startLine = clipStartPosition.line; int start = clipStartOffset; Point position = new Point(0, visibleLine * lineHeight); if (startLine == 0 && myPrefixText != null) { position.x = drawStringWithSoftWraps(g, new CharArrayCharSequence(myPrefixText), 0, myPrefixText.length, position, clip, myPrefixAttributes.getEffectColor(), myPrefixAttributes.getEffectType(), myPrefixAttributes.getFontType(), myPrefixAttributes.getForegroundColor(), -1, PAINT_NO_WHITESPACE); } if (startLine >= myDocument.getLineCount() || startLine < 0) { if (position.x > 0) flushCachedChars(g); return; } LineIterator lIterator = createLineIterator(); lIterator.start(start); if (lIterator.atEnd()) { return; } IterationState iterationState = new IterationState(this, start, clipEndOffset, isPaintSelection()); TextAttributes attributes = iterationState.getMergedAttributes(); Color currentColor = attributes.getForegroundColor(); if (currentColor == null) { currentColor = getForegroundColor(); } Color effectColor = attributes.getEffectColor(); EffectType effectType = attributes.getEffectType(); int fontType = attributes.getFontType(); g.setColor(currentColor); CharSequence chars = myDocument.getImmutableCharSequence(); LineWhitespacePaintingStrategy context = new LineWhitespacePaintingStrategy(); context.update(chars, lIterator); while (!iterationState.atEnd() && !lIterator.atEnd()) { int hEnd = iterationState.getEndOffset(); int lEnd = lIterator.getEnd(); if (hEnd >= lEnd) { FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start); if (collapsedFolderAt == null) { drawStringWithSoftWraps(g, chars, start, lEnd - lIterator.getSeparatorLength(), position, clip, effectColor, effectType, fontType, currentColor, clipStartOffset, context); final VirtualFile file = getVirtualFile(); if (myProject != null && file != null && !isOneLineMode()) { int offset = position.x; String additionalText = ""; for (EditorLinePainter painter : EditorLinePainter.EP_NAME.getExtensions()) { Collection<LineExtensionInfo> extensions = painter.getLineExtensions(myProject, file, lIterator.getLineNumber()); if (extensions != null && !extensions.isEmpty()) { for (LineExtensionInfo info : extensions) { final String text = info.getText(); additionalText += text; position.x = drawString(g, text, 0, text.length(), position, clip, info.getEffectColor() == null ? effectColor : info.getEffectColor(), info.getEffectType() == null ? effectType : info.getEffectType(), info.getFontType(), info.getColor() == null ? currentColor : info.getColor(), context); } } } for (char ch : additionalText.toCharArray()) { offset += EditorUtil.charWidth(ch, Font.ITALIC, this); } myLinePaintersWidth = Math.max(myLinePaintersWidth, offset); } position.x = 0; if (position.y > clip.y + clip.height) { break; } position.y += lineHeight; start = lEnd; } // myBorderEffect.eolReached(g, this); lIterator.advance(); if (!lIterator.atEnd()) { context.update(chars, lIterator); } } else { FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); if (collapsedFolderAt != null) { SoftWrap softWrap = mySoftWrapModel.getSoftWrap(collapsedFolderAt.getStartOffset()); if (softWrap != null) { position.x = drawStringWithSoftWraps( g, chars, collapsedFolderAt.getStartOffset(), collapsedFolderAt.getStartOffset(), position, clip, effectColor, effectType, fontType, currentColor, clipStartOffset, context ); } int foldingXStart = position.x; position.x = drawString( g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, fontType, currentColor, PAINT_NO_WHITESPACE); //drawStringWithSoftWraps(g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, // fontType, currentColor, logicalPosition); BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, position.x, getLineHeight(), effectColor, effectType); } else { position.x = drawStringWithSoftWraps(g, chars, start, Math.min(hEnd, lEnd - lIterator.getSeparatorLength()), position, clip, effectColor, effectType, fontType, currentColor, clipStartOffset, context); } iterationState.advance(); attributes = iterationState.getMergedAttributes(); currentColor = attributes.getForegroundColor(); if (currentColor == null) { currentColor = getForegroundColor(); } effectColor = attributes.getEffectColor(); effectType = attributes.getEffectType(); fontType = attributes.getFontType(); start = iterationState.getStartOffset(); } } FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); if (collapsedFolderAt != null) { int foldingXStart = position.x; int foldingXEnd = drawStringWithSoftWraps( g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, fontType, currentColor, clipStartOffset, PAINT_NO_WHITESPACE); BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, foldingXEnd, getLineHeight(), effectColor, effectType); // myBorderEffect.collapsedFolderReached(g, this); } final SoftWrap softWrap = mySoftWrapModel.getSoftWrap(clipEndOffset); if (softWrap != null) { mySoftWrapModel.paint(g, SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED, position.x, position.y, getLineHeight()); } flushCachedChars(g); }