/** * Returns a token. * * @param line The segment from which to get the token's text. * @param beg The starting offset of the token's text in the segment. * @param end The ending offset of the token's text in the segment. * @param startOffset The offset in the document of the token. * @param type The type of token. * @return The token. */ public Token createToken( final char[] line, final int beg, final int end, final int startOffset, final int type) { Token token = tokenList[currentFreeToken]; token.set(line, beg, end, startOffset, type); currentFreeToken++; if (currentFreeToken == size) augmentTokenList(); return token; }
/** * Gets the next token from a tokenizer. * * @param wantWhitespace If true, leading whitespace will be returned as a token. * @param wantComment If true, comments are returned as tokens. * @return The next token in the stream. * @throws TextParseException The input was invalid. * @throws IOException An I/O error occurred. */ public Token get(boolean wantWhitespace, boolean wantComment) throws IOException { int type; int c; if (ungottenToken) { ungottenToken = false; if (current.type == WHITESPACE) { if (wantWhitespace) { return current; } } else if (current.type == COMMENT) { if (wantComment) { return current; } } else { if (current.type == EOL) { line++; } return current; } } int skipped = skipWhitespace(); if (skipped > 0 && wantWhitespace) { return current.set(WHITESPACE, null); } type = IDENTIFIER; sb.setLength(0); while (true) { c = getChar(); if (c == -1 || delimiters.indexOf(c) != -1) { if (c == -1) { if (quoting) throw exception("EOF in " + "quoted string"); else if (sb.length() == 0) { return current.set(EOF, null); } else { return current.set(type, sb); } } if (sb.length() == 0 && type != QUOTED_STRING) { if (c == '(') { multiline++; skipWhitespace(); continue; } else if (c == ')') { if (multiline <= 0) throw exception("invalid " + "close " + "parenthesis"); multiline--; skipWhitespace(); continue; } else if (c == '"') { if (!quoting) { quoting = true; delimiters = quotes; type = QUOTED_STRING; } else { quoting = false; delimiters = delim; skipWhitespace(); } continue; } else if (c == '\n') { return current.set(EOL, null); } else if (c == ';') { while (true) { c = getChar(); if (c == '\n' || c == -1) { break; } sb.append((char) c); } if (wantComment) { ungetChar(c); return current.set(COMMENT, sb); } else if (c == -1 && type != QUOTED_STRING) { checkUnbalancedParens(); return current.set(EOF, null); } else if (multiline > 0) { skipWhitespace(); sb.setLength(0); continue; } else { return current.set(EOL, null); } } else { throw new IllegalStateException(); } } else { ungetChar(c); } break; } else if (c == '\\') { c = getChar(); if (c == -1) { throw exception("unterminated escape sequence"); } sb.append('\\'); } else if (quoting && c == '\n') { throw exception("newline in quoted string"); } sb.append((char) c); } if (sb.length() == 0 && type != QUOTED_STRING) { checkUnbalancedParens(); return current.set(EOF, null); } return current.set(type, sb); }
/** * Draws a single view (i.e., a line of text for a wrapped view), wrapping the text onto multiple * lines if necessary. * * @param painter The painter to use to render tokens. * @param g The graphics context in which to paint. * @param r The rectangle in which to paint. * @param view The <code>View</code> to paint. * @param fontHeight The height of the font being used. * @param y The y-coordinate at which to begin painting. */ protected void drawView( TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight, int y) { float x = r.x; LayeredHighlighter h = (LayeredHighlighter) host.getHighlighter(); RSyntaxDocument document = (RSyntaxDocument) getDocument(); Element map = getElement(); int p0 = view.getStartOffset(); int lineNumber = map.getElementIndex(p0); int p1 = view.getEndOffset(); // - 1; setSegment(p0, p1 - 1, document, drawSeg); // System.err.println("drawSeg=='" + drawSeg + "' (p0/p1==" + p0 + "/" + p1 + ")"); int start = p0 - drawSeg.offset; Token token = document.getTokenListForLine(lineNumber); // If this line is an empty line, then the token list is simply a // null token. In this case, the line highlight will be skipped in // the loop below, so unfortunately we must manually do it here. if (token != null && token.type == Token.NULL) { h.paintLayeredHighlights(g, p0, p1, r, host, this); return; } // Loop through all tokens in this view and paint them! while (token != null && token.isPaintable()) { int p = calculateBreakPosition(p0, token, x); x = r.x; h.paintLayeredHighlights(g, p0, p, r, host, this); while (token != null && token.isPaintable() && token.offset + token.textCount - 1 < p) { // <=p) { x = painter.paint(token, g, x, y, host, this); token = token.getNextToken(); } if (token != null && token.isPaintable() && token.offset < p) { int tokenOffset = token.offset; tempToken.set(drawSeg.array, tokenOffset - start, p - 1 - start, tokenOffset, token.type); painter.paint(tempToken, g, x, y, host, this); token.makeStartAt(p); } p0 = (p == p0) ? p1 : p; y += fontHeight; } // End of while (token!=null && token.isPaintable()). // NOTE: We should re-use code from Token (paintBackground()) here, // but don't because I'm just too lazy. if (host.getEOLMarkersVisible()) { g.setColor(host.getForegroundForTokenType(Token.WHITESPACE)); g.setFont(host.getFontForTokenType(Token.WHITESPACE)); g.drawString("\u00B6", x, y - fontHeight); } }