private void paintBackground(
      Graphics2D g, Rectangle clip, int startVisualLine, int endVisualLine) {
    int lineCount = myEditor.getVisibleLineCount();
    final Map<Integer, Couple<Integer>> virtualSelectionMap =
        createVirtualSelectionMap(startVisualLine, endVisualLine);
    for (int visualLine = startVisualLine; visualLine <= endVisualLine; visualLine++) {
      int y = myView.visualLineToY(visualLine);
      LineLayout prefixLayout = myView.getPrefixLayout();
      if (visualLine == 0 && prefixLayout != null) {
        paintBackground(g, myView.getPrefixAttributes(), 0, y, prefixLayout.getWidth());
      }
      if (visualLine >= lineCount) break;
      paintLineFragments(
          g,
          clip,
          visualLine,
          y,
          new LineFragmentPainter() {
            @Override
            public void paintBeforeLineStart(
                Graphics2D g, TextAttributes attributes, int columnEnd, float xEnd, int y) {
              paintBackground(g, attributes, 0, y, xEnd);
              paintSelectionOnSecondSoftWrapLineIfNecessary(g, columnEnd, xEnd, y);
            }

            @Override
            public void paint(
                Graphics2D g,
                VisualLineFragmentsIterator.Fragment fragment,
                int start,
                int end,
                TextAttributes attributes,
                float xStart,
                float xEnd,
                int y) {
              paintBackground(g, attributes, xStart, y, xEnd - xStart);
            }

            @Override
            public void paintAfterLineEnd(
                Graphics2D g, Rectangle clip, IterationState it, int columnStart, float x, int y) {
              paintBackground(
                  g, it.getPastLineEndBackgroundAttributes(), x, y, clip.x + clip.width - x);
              int offset = it.getEndOffset();
              SoftWrap softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset);
              if (softWrap == null) {
                paintVirtualSelectionIfNecessary(
                    g, virtualSelectionMap, columnStart, x, clip.x + clip.width, y);
              } else {
                paintSelectionOnFirstSoftWrapLineIfNecessary(
                    g, columnStart, x, clip.x + clip.width, y);
              }
            }
          });
    }
  }
 private float paintLineLayoutWithEffect(
     Graphics2D g,
     LineLayout layout,
     float x,
     float y,
     @Nullable Color effectColor,
     @Nullable EffectType effectType) {
   float initialX = x;
   for (LineLayout.VisualFragment fragment : layout.getFragmentsInVisualOrder(x)) {
     fragment.draw(g, x, y);
     x = fragment.getEndX();
   }
   if (hasTextEffect(effectColor, effectType)) {
     paintTextEffect(g, initialX, x, (int) y, effectColor, effectType);
   }
   return x;
 }