private BidiRun subRun(int targetStartOffset, int targetEndOffset) {
   assert targetStartOffset < endOffset;
   assert targetEndOffset > startOffset;
   if (targetStartOffset <= startOffset && targetEndOffset >= this.endOffset) {
     return this;
   }
   int start = Math.max(startOffset, targetStartOffset);
   int end = Math.min(endOffset, targetEndOffset);
   BidiRun run = new BidiRun(level, start, end);
   int offset = startOffset;
   for (LineFragment fragment : fragments) {
     if (end <= offset) break;
     int endOffset = offset + fragment.getLength();
     if (start < endOffset) {
       run.fragments.add(
           fragment.subFragment(
               Math.max(start, offset) - offset, Math.min(end, endOffset) - offset));
     }
     offset = endOffset;
   }
   return run;
 }