/**
   * Modifies the passed-in token list to start at the specified offset. For example, if the token
   * list covered positions 20-60 in the document (inclusive) like so:
   *
   * <pre>
   *   [token1] -> [token2] -> [token3] -> [token4]
   *   20     30   31     40   41     50   51     60
   * </pre>
   *
   * and you used this method to make the token list start at position 44, then the token list would
   * be modified to be the following:
   *
   * <pre>
   *   [part-of-old-token3] -> [token4]
   *   44                 50   51     60
   * </pre>
   *
   * Tokens that come before the specified position are forever lost, and the token containing that
   * position is made to begin at that position if necessary. All token types remain the same as
   * they were originally.
   *
   * <p>This method can be useful if you are only interested in part of a token list (i.e., the line
   * it represents), but you don't want to modify the token list yourself.
   *
   * @param tokenList The list to make start at the specified position. This parameter is modified.
   * @param pos The position at which the new token list is to start. If this position is not in the
   *     passed-in token list, returned token list will either be <code>null</code> or the
   *     unpaintable token(s) at the end of the passed-in token list.
   * @param e How to expand tabs.
   * @param textArea The text area from which the token list came.
   * @param x0 The initial x-pixel position of the old token list.
   * @return The width, in pixels, of the part of the token list "removed from the front." This way,
   *     you know the x-offset of the "new" token list.
   */
  public static float makeTokenListStartAt(
      Token tokenList, int pos, TabExpander e, final RSyntaxTextArea textArea, float x0) {

    Token t = tokenList;

    // Loop through the token list until you find the one that contains
    // pos.  Remember the cumulative width of all of these tokens.
    while (t != null && t.isPaintable() && !t.containsPosition(pos)) {
      x0 += t.getWidth(textArea, e, x0);
      t = t.getNextToken();
    }

    // Make the token that contains pos start at pos.
    if (t != null && t.isPaintable() && t.offset != pos) {
      // Number of chars between p0 and token start.
      int difference = pos - t.offset;
      x0 += t.getWidthUpTo(t.textCount - difference + 1, textArea, e, x0);
      t.makeStartAt(pos);
    }

    // Make the passed-in token list point to the proper place.
    // t can be null, for example, if line ends with unended MLC.
    if (t != null && t.isPaintable()) tokenList.copyFrom(t);
    else tokenList = null;
    t = null;

    // Return the x-offset (in pixels) of the newly-modified t.
    return x0;
  }
 /**
  * Determines the width of the given token list taking tabs into consideration and only up to the
  * given index in the document (exclusive).
  *
  * @param tokenList The token list representing the text.
  * @param textArea The text area in which this token list resides.
  * @param e The tab expander. This value cannot be <code>null</code>.
  * @param x0 The x-pixel coordinate of the start of the token list.
  * @param upTo The document position at which you want to stop, exclusive. If this position is
  *     before the starting position of the token list, a width of <code>0</code> will be returned;
  *     similarly, if this position comes after the entire token list, the width of the entire
  *     token list is returned.
  * @return The width of the token list, in pixels, up to, but not including, the character at
  *     position <code>upTo</code>.
  * @see #getTokenListWidth
  */
 public static final float getTokenListWidthUpTo(
     final Token tokenList, RSyntaxTextArea textArea, TabExpander e, float x0, int upTo) {
   float width = 0;
   for (Token t = tokenList; t != null && t.isPaintable(); t = t.getNextToken()) {
     if (t.containsPosition(upTo)) {
       return width + t.getWidthUpTo(upTo - t.offset, textArea, e, x0 + width);
     }
     width += t.getWidth(textArea, e, x0 + width);
   }
   return width;
 }