void (@NotNull RangeHighlighter marker, @NotNull Rectangle clip, @NotNull Graphics g) { Color separatorColor = marker.getLineSeparatorColor(); LineSeparatorRenderer lineSeparatorRenderer = marker.getLineSeparatorRenderer(); if (separatorColor == null && lineSeparatorRenderer == null) { return; } int line = marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP ? marker.getDocument() .getLineNumber(marker.getStartOffset()) : marker.getDocument().getLineNumber(marker.getEndOffset()); if (line < 0 || line >= myDocument.getLineCount()) { return; } // There is a possible case that particular logical line occupies more than one visual line (because of soft wraps processing), // hence, we need to consider that during calculating 'y' position for the last visual line used for the target logical // line representation. int y; SeparatorPlacement placement = marker.getLineSeparatorPlacement(); if (placement == SeparatorPlacement.TOP) { y = visibleLineToY(logicalToVisualLine(line)); } else if (line + 1 >= myDocument.getLineCount()) { y = visibleLineToY(offsetToVisualLine(myDocument.getTextLength()) + 1); } else { y = logicalLineToY(line + 1); } y -= 1; if (y + getLineHeight() < clip.y || y > clip.y + clip.height) return; int endShift = clip.x + clip.width; g.setColor(separatorColor); if (mySettings.isRightMarginShown() && myScheme.getColor(EditorColors.RIGHT_MARGIN_COLOR) != null) { endShift = Math.min(endShift, mySettings.getRightMargin(myProject) * EditorUtil.getSpaceWidth(Font.PLAIN, this)); } if (lineSeparatorRenderer != null) { lineSeparatorRenderer.drawLine(g, 0, endShift, y); } else { UIUtil.drawLine(g, 0, y, endShift, y); } }