001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * SyntaxUtilities.java
028: *
029: */
030:
031: package org.syntax.jedit;
032:
033: import org.syntax.jedit.tokenmarker.*;
034: import javax.swing.text.*;
035: import java.awt.*;
036:
037: /**
038: * Class with several utility functions used by jEdit's syntax colorizing
039: * subsystem.
040: *
041: * @author Slava Pestov
042: * @version $Id: SyntaxUtilities.java 1167 2008-01-15 18:49:05Z gtoffoli $
043: */
044: public class SyntaxUtilities {
045: /**
046: * Checks if a subregion of a <code>Segment</code> is equal to a
047: * string.
048: * @param ignoreCase True if case should be ignored, false otherwise
049: * @param text The segment
050: * @param offset The offset into the segment
051: * @param match The string to match
052: */
053: public static boolean regionMatches(boolean ignoreCase,
054: Segment text, int offset, String match) {
055: int length = offset + match.length();
056: char[] textArray = text.array;
057: if (length > text.offset + text.count)
058: return false;
059: for (int i = offset, j = 0; i < length; i++, j++) {
060: char c1 = textArray[i];
061: char c2 = match.charAt(j);
062: if (ignoreCase) {
063: c1 = Character.toUpperCase(c1);
064: c2 = Character.toUpperCase(c2);
065: }
066: if (c1 != c2)
067: return false;
068: }
069: return true;
070: }
071:
072: /**
073: * Checks if a subregion of a <code>Segment</code> is equal to a
074: * character array.
075: * @param ignoreCase True if case should be ignored, false otherwise
076: * @param text The segment
077: * @param offset The offset into the segment
078: * @param match The character array to match
079: */
080: public static boolean regionMatches(boolean ignoreCase,
081: Segment text, int offset, char[] match) {
082: int length = offset + match.length;
083: char[] textArray = text.array;
084: if (length > text.offset + text.count)
085: return false;
086: for (int i = offset, j = 0; i < length; i++, j++) {
087: char c1 = textArray[i];
088: char c2 = match[j];
089: if (ignoreCase) {
090: c1 = Character.toUpperCase(c1);
091: c2 = Character.toUpperCase(c2);
092: }
093: if (c1 != c2)
094: return false;
095: }
096: return true;
097: }
098:
099: /**
100: * Returns the default style table. This can be passed to the
101: * <code>setStyles()</code> method of <code>SyntaxDocument</code>
102: * to use the default syntax styles.
103: */
104: public static SyntaxStyle[] getDefaultSyntaxStyles() {
105: SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
106:
107: styles[Token.COMMENT1] = new SyntaxStyle(Color.black, true,
108: false);
109: styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),
110: true, false);
111: styles[Token.KEYWORD1] = new SyntaxStyle(Color.black, false,
112: true);
113: styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta, false,
114: false);
115: styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),
116: false, false);
117: styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),
118: false, false);
119: styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),
120: false, true);
121: styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),
122: false, true);
123: styles[Token.OPERATOR] = new SyntaxStyle(Color.black, false,
124: true);
125: styles[Token.INVALID] = new SyntaxStyle(Color.red, false, true);
126:
127: styles[Token.PARAMETER] = new SyntaxStyle(Color.blue, false,
128: true);
129: styles[Token.PARAMETER_OK] = new SyntaxStyle(
130: new Color(0x009b1f), false, true);
131:
132: return styles;
133: }
134:
135: /**
136: * Paints the specified line onto the graphics context. Note that this
137: * method munges the offset and count values of the segment.
138: * @param line The line segment
139: * @param tokens The token list for the line
140: * @param styles The syntax style list
141: * @param expander The tab expander used to determine tab stops. May
142: * be null
143: * @param gfx The graphics context
144: * @param x The x co-ordinate
145: * @param y The y co-ordinate
146: * @return The x co-ordinate, plus the width of the painted string
147: */
148: public static int paintSyntaxLine(Segment line, Token tokens,
149: SyntaxStyle[] styles, TabExpander expander, Graphics gfx,
150: int x, int y) {
151: Font defaultFont = gfx.getFont();
152: Color defaultColor = gfx.getColor();
153:
154: int offset = 0;
155: for (;;) {
156: byte id = tokens.id;
157: if (id == Token.END)
158: break;
159:
160: int length = tokens.length;
161: if (id == Token.NULL) {
162: if (!defaultColor.equals(gfx.getColor()))
163: gfx.setColor(defaultColor);
164: if (!defaultFont.equals(gfx.getFont()))
165: gfx.setFont(defaultFont);
166: } else {
167: styles[id].setGraphicsFlags(gfx, defaultFont);
168: }
169:
170: line.count = length;
171: x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0);
172: line.offset += length;
173: offset += length;
174:
175: tokens = tokens.next;
176: }
177:
178: return x;
179: }
180:
181: // private members
182: private SyntaxUtilities() {
183: }
184: }
|