private Chunk subChunk(EditorView view, BidiRun run, int line, int targetStartOffset, int targetEndOffset,
                           @Nullable Runnable quickEvaluationListener) {
      assert isReal();
      assert targetStartOffset < endOffset;
      assert targetEndOffset > startOffset;
      int start = Math.max(startOffset, targetStartOffset);
      int end = Math.min(endOffset, targetEndOffset);
      if (quickEvaluationListener != null && fragments == null) {
        quickEvaluationListener.run();
        Chunk chunk = new SyntheticChunk(start, end);
        int startColumn = view.getLogicalPositionCache().offsetToLogicalColumn(line, start);
        int endColumn = view.getLogicalPositionCache().offsetToLogicalColumn(line, end);
        chunk.fragments = Collections.singletonList(new ApproximationFragment(end - start, endColumn - startColumn,
                                                                              view.getMaxCharWidth()));
        return chunk;
      }
      if (start == startOffset && end == endOffset) {
        return this;
      }
      ensureLayout(view, run, line);
      Chunk chunk = new SyntheticChunk(start, end);
      chunk.fragments = new ArrayList<>();
      int offset = startOffset;
      for (LineFragment fragment : fragments) {
        if (end <= offset) break;
        int endOffset = offset + fragment.getLength();
        if (start < endOffset) {
          chunk.fragments.add(fragment.subFragment(Math.max(start, offset) - offset, Math.min(end, endOffset) - offset));
        }
        offset = endOffset;
      }
      return chunk;
    }
private Chunk subChunk(EditorView view, BidiRun run, int line, int targetStartOffset, int targetEndOffset,
                           @Nullable Runnable quickEvaluationListener)