private ImmutableList<CharacterRegion> offsetsOfSubstringByContentCodepointOffsets(
      final OffsetRange<CharOffset> substringContentCodePointsRange) {
    checkArgument(substringContentCodePointsRange.startInclusive().asInt() >= 0);
    checkArgument(
        substringContentCodePointsRange.endInclusive().asInt() < content().lengthInCodePoints());

    final int startEntryIdx = regionIndexContainingContentOffset(
        substringContentCodePointsRange.startInclusive());
    final int endEntryIdx = regionIndexContainingContentOffset(
        substringContentCodePointsRange.endInclusive());

    final ImmutableList.Builder<CharacterRegion> newRegions = ImmutableList.builder();

    // the content offsets of returned substring must be shifted so return substring
    // has offsets starting at zero
    final int shift = -substringContentCodePointsRange.startInclusive().asInt();
    if (startEntryIdx == endEntryIdx) {
      newRegions.add(characterRegions().get(startEntryIdx).fromContentOffsetStartInclusiveToEndExclusive(
          substringContentCodePointsRange.startInclusive(),
          substringContentCodePointsRange.endInclusive().shiftedCopy(1))
          .shiftContentOffsets(shift));
    } else {
      final CharacterRegion newStartRegion = characterRegions().get(startEntryIdx)
          .fromContentOffsetInclusiveToEnd(substringContentCodePointsRange.startInclusive())
          .shiftContentOffsets(shift);
      final CharacterRegion newEndRegion = characterRegions().get(endEntryIdx)
          .fromStartToContentOffsetExclusive(
              substringContentCodePointsRange.endInclusive().shiftedCopy(1))
          .shiftContentOffsets(shift);

      newRegions.add(newStartRegion);
      for (int i = startEntryIdx + 1; i< endEntryIdx; ++i) {
        // internal regions are unaltered and can be used in the new LocatedString
        newRegions.add(characterRegions().get(i)
            .shiftContentOffsets(shift));
      }
      newRegions.add(newEndRegion);
    }

    return newRegions.build();
  }
private ImmutableList < CharacterRegion > offsetsOfSubstringByContentCodepointOffsets ( final OffsetRange < CharOffset > substringContentCodePointsRange ) { checkArgument ( substringContentCodePointsRange . startInclusive ( ) . asInt ( ) >= 0 ) ; checkArgument ( substringContentCodePointsRange . endInclusive ( ) . asInt ( ) < content ( ) . lengthInCodePoints ( ) ) ; final int startEntryIdx = regionIndexContainingContentOffset ( substringContentCodePointsRange . startInclusive ( ) ) ; final int endEntryIdx = regionIndexContainingContentOffset ( substringContentCodePointsRange . endInclusive ( ) ) ; final ImmutableList . Builder < CharacterRegion > newRegions = ImmutableList . builder ( ) ; final int shift = - substringContentCodePointsRange . startInclusive ( ) . asInt ( ) ; if ( startEntryIdx == endEntryIdx ) { newRegions . add ( characterRegions ( ) . get ( startEntryIdx ) . fromContentOffsetStartInclusiveToEndExclusive ( substringContentCodePointsRange . startInclusive ( ) , substringContentCodePointsRange . endInclusive ( ) . shiftedCopy ( 1 ) ) . shiftContentOffsets ( shift ) ) ; } else { final CharacterRegion newStartRegion = characterRegions ( ) . get ( startEntryIdx ) . fromContentOffsetInclusiveToEnd ( substringContentCodePointsRange . startInclusive ( ) ) . shiftContentOffsets ( shift ) ; final CharacterRegion newEndRegion = characterRegions ( ) . get ( endEntryIdx ) . fromStartToContentOffsetExclusive ( substringContentCodePointsRange . endInclusive ( ) . shiftedCopy ( 1 ) ) . shiftContentOffsets ( shift ) ; newRegions . add ( newStartRegion ) ; for ( int i = startEntryIdx + 1 ; i < endEntryIdx ; ++ i ) { newRegions . add ( characterRegions ( ) . get ( i ) . shiftContentOffsets ( shift ) ) ; } newRegions . add ( newEndRegion ) ; } return newRegions . build ( ) ; }
Constructs {@link CharacterRegion}s for a substring.
See {@link #contentLocatedSubstringByContentOffsets}