private ProperTextRange offsetToYPosition(int start, int end) {
    if (myEditorScrollbarTop == -1 || myEditorTargetHeight == -1) {
      recalcEditorDimensions();
    }
    Document document = myEditor.getDocument();
    int startLineNumber = offsetToLine(start, document);
    int startY;
    int lineCount;
    if (myEditorSourceHeight < myEditorTargetHeight) {
      lineCount = 0;
      startY = myEditorScrollbarTop + startLineNumber * myEditor.getLineHeight();
    } else {
      lineCount = myEditorSourceHeight / myEditor.getLineHeight();
      startY =
          myEditorScrollbarTop + (int) ((float) startLineNumber / lineCount * myEditorTargetHeight);
    }

    int endY;
    if (document.getLineNumber(start) == document.getLineNumber(end)) {
      endY = startY; // both offsets are on the same line, no need to recalc Y position
    } else {
      int endLineNumber = offsetToLine(end, document);
      if (myEditorSourceHeight < myEditorTargetHeight) {
        endY = myEditorScrollbarTop + endLineNumber * myEditor.getLineHeight();
      } else {
        endY =
            myEditorScrollbarTop + (int) ((float) endLineNumber / lineCount * myEditorTargetHeight);
      }
      if (endY < startY) endY = startY;
    }
    return new ProperTextRange(startY, endY);
  }
  private int yPositionToOffset(int y, boolean beginLine) {
    if (myEditorScrollbarTop == -1 || myEditorTargetHeight == -1) {
      recalcEditorDimensions();
    }
    final int safeY = Math.max(0, y - myEditorScrollbarTop);
    VisualPosition visual;
    if (myEditorSourceHeight < myEditorTargetHeight) {
      visual = myEditor.xyToVisualPosition(new Point(0, safeY));
    } else {
      float fraction = Math.max(0, Math.min(1, safeY / (float) myEditorTargetHeight));
      final int lineCount = myEditorSourceHeight / myEditor.getLineHeight();
      visual = new VisualPosition((int) (fraction * lineCount), 0);
    }
    int line = myEditor.visualToLogicalPosition(visual).line;
    Document document = myEditor.getDocument();
    if (line < 0) return 0;
    if (line >= document.getLineCount()) return document.getTextLength();

    return beginLine ? document.getLineStartOffset(line) : document.getLineEndOffset(line);
  }