private void doPaintLineNumbers(Graphics2D g, int startVisualLine, int endVisualLine, int offset,
                                  @NotNull LineNumberConverter converter) {
    int lastLine = myEditor.logicalToVisualPosition(
      new LogicalPosition(endLineNumber(), 0))
      .line;
    endVisualLine = Math.min(endVisualLine, lastLine);
    if (startVisualLine > endVisualLine) {
      return;
    }

    Color color = myEditor.getColorsScheme().getColor(EditorColors.LINE_NUMBERS_COLOR);
    Color colorUnderCaretRow = myEditor.getColorsScheme().getColor(EditorColors.LINE_NUMBER_ON_CARET_ROW_COLOR);
    Font font = getFontForLineNumbers();
    g.setFont(font);
    int viewportStartY = myEditor.getScrollingModel().getVisibleArea().y;

    AffineTransform old = setMirrorTransformIfNeeded(g, getLineNumberAreaOffset(), getLineNumberAreaWidth());
    try {
      int caretLogicalLine = myEditor.getCaretModel().getLogicalPosition().line;
      VisualLinesIterator visLinesIterator = new VisualLinesIterator(myEditor, startVisualLine);
      while (!visLinesIterator.atEnd() && visLinesIterator.getVisualLine() <= endVisualLine) {
        if (!visLinesIterator.isCustomFoldRegionLine() &&
            (!visLinesIterator.startsWithSoftWrap() || visLinesIterator.getY() <= viewportStartY)) {
          int logicalLine = visLinesIterator.getDisplayedLogicalLine();
          String lineToDisplay = converter.convertLineNumberToString(myEditor, logicalLine + 1);
          if (lineToDisplay != null) {
            int y = visLinesIterator.getY();
            if (y < viewportStartY && visLinesIterator.endsWithSoftWrap()) {  // "sticky" line number
              if (!myEditor.isStickyLinePainting()) { // suppress shifting line number of wrapped line on sticky lines panel IDEA-345706
                y = viewportStartY;
              }
            }
            if (myEditor.isInDistractionFreeMode()) {
              Color fgColor = myTextFgColors.get(visLinesIterator.getVisualLine());
              g.setColor(fgColor != null ? fgColor : color != null ? color : JBColor.blue);
            }
            else {
              g.setColor(color);
            }

            if (colorUnderCaretRow != null && caretLogicalLine == logicalLine) {
              if (!myEditor.isStickyLinePainting()) { // suppress gutter line number under caret on sticky lines panel
                g.setColor(colorUnderCaretRow);
              }
            }

            Icon iconOnTheLine = null;
            Icon hoverIcon = null;
            if (ExperimentalUI.isNewUI() /*&& EditorUtil.isRealFileEditor(getEditor())*/ && EditorUtil.isBreakPointsOnLineNumbers()) {
              VisualPosition visualPosition = myEditor.logicalToVisualPosition(new LogicalPosition(logicalLine, 0));
              Optional<GutterMark> breakpoint = getGutterRenderers(visualPosition.line).stream()
                .filter(r -> r instanceof GutterIconRenderer &&
                             ((GutterIconRenderer)r).getAlignment() == GutterIconRenderer.Alignment.LINE_NUMBERS)
                .findFirst();
              if (breakpoint.isPresent()) {
                iconOnTheLine = breakpoint.get().getIcon();
              }
              if ((myAlphaContext.isVisible() || isGutterContextMenuShown()) &&
                  Objects.equals(getClientProperty("active.line.number"), logicalLine)) {
                Object activeIcon = getClientProperty("line.number.hover.icon");
                if (activeIcon instanceof Icon) {
                  hoverIcon = (Icon)activeIcon;
                }
              }
            }
            if (myEditor.isStickyLinePainting()) {
              // suppress breakpoint icon to print line number on the sticky lines panel
              iconOnTheLine = null;
            }

            if (iconOnTheLine == null && hoverIcon == null) {
              int textOffset = isMirrored() ?
                               offset - getLineNumberAreaWidth() - 1 :
                               offset - FontLayoutService.getInstance().stringWidth(g.getFontMetrics(), lineToDisplay);

              g.drawString(lineToDisplay, textOffset, y + myEditor.getAscent());
            }
            else if (hoverIcon != null && iconOnTheLine == null) {
              Icon icon = scaleIcon(hoverIcon);
              int iconX = offset - icon.getIconWidth();
              int iconY = y + (visLinesIterator.getLineHeight() - icon.getIconHeight()) / 2;
              float alpha = JBUI.getFloat("Breakpoint.iconHoverAlpha", 0.5f);
              alpha = Math.max(0, Math.min(alpha, 1));
              GraphicsUtil.paintWithAlpha(g, alpha, () -> icon.paintIcon(this, g, iconX, iconY));
            }
          }
        }
        visLinesIterator.advance();
      }
    }
    finally {
      if (old != null) g.setTransform(old);
    }
  }
private void doPaintLineNumbers(Graphics2D g, int startVisualLine, int endVisualLine, int offset,
                                  @NotNull LineNumberConverter converter)