private static void addFragments(
     BidiRun run,
     char[] text,
     int start,
     int end,
     int fontStyle,
     FontPreferences fontPreferences,
     FontRenderContext fontRenderContext,
     @Nullable TabFragment tabFragment) {
   Font currentFont = null;
   int currentIndex = start;
   for (int i = start; i < end; i++) {
     char c = text[i];
     if (c == '\t' && tabFragment != null) {
       assert run.level == 0;
       addTextFragmentIfNeeded(
           run, text, currentIndex, i, currentFont, fontRenderContext, run.isRtl());
       run.fragments.add(tabFragment);
       currentFont = null;
       currentIndex = i + 1;
     } else {
       Font font =
           ComplementaryFontsRegistry.getFontAbleToDisplay(c, fontStyle, fontPreferences)
               .getFont();
       if (!font.equals(currentFont)) {
         addTextFragmentIfNeeded(
             run, text, currentIndex, i, currentFont, fontRenderContext, run.isRtl());
         currentFont = font;
         currentIndex = i;
       }
     }
   }
   addTextFragmentIfNeeded(
       run, text, currentIndex, end, currentFont, fontRenderContext, run.isRtl());
 }
 boolean isRtlLocation(int offset, boolean leanForward) {
   if (offset == 0 && !leanForward) return false;
   for (BidiRun run : myBidiRunsInLogicalOrder) {
     if (offset < run.endOffset || offset == run.endOffset && !leanForward) return run.isRtl();
   }
   return false;
 }
    @Override
    public VisualFragment next() {
      if (!hasNext()) {
        throw new NoSuchElementException();
      }
      BidiRun run = myRuns[myRunIndex];

      if (myRunIndex == 0 && myFragmentIndex == 0) {
        myFragment.startLogicalColumn +=
            (run.isRtl() ? run.endOffset : run.startOffset) - myFragment.startOffset;
      } else {
        myFragment.startLogicalColumn = myFragment.getEndLogicalColumn();
        if (myFragmentIndex == 0) {
          myFragment.startLogicalColumn +=
              (run.isRtl() ? run.endOffset : run.startOffset) - myFragment.getEndOffset();
        }
        myFragment.startVisualColumn = myFragment.getEndVisualColumn();
        myFragment.startX = myFragment.getEndX();
      }

      myFragment.isRtl = run.isRtl();
      myFragment.delegate =
          run.fragments.get(
              run.isRtl() ? run.fragments.size() - 1 - myFragmentIndex : myFragmentIndex);
      myFragment.startOffset =
          run.isRtl() ? run.endOffset - myOffsetInsideRun : run.startOffset + myOffsetInsideRun;

      myOffsetInsideRun += myFragment.getLength();
      myFragmentIndex++;
      if (myFragmentIndex >= run.fragments.size()) {
        myFragmentIndex = 0;
        myOffsetInsideRun = 0;
        myRunIndex++;
      }

      return myFragment;
    }