/** * 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; }