001: package workbench.gui.editor;
002:
003: /*
004: * SyntaxUtilities.java - Utility functions used by syntax colorizing
005: * Copyright (C) 1999 Slava Pestov
006: *
007: * You may use and modify this package for any purpose. Redistribution is
008: * permitted, in both source and binary form, provided that this notice
009: * remains intact in all source distributions of this package.
010: */
011:
012: import java.awt.Color;
013: import java.awt.Font;
014: import java.awt.Graphics;
015:
016: import javax.swing.text.Segment;
017: import javax.swing.text.TabExpander;
018: import javax.swing.text.Utilities;
019: import workbench.resource.Settings;
020:
021: /**
022: * Class with several utility functions used by jEdit's syntax colorizing
023: * subsystem.
024: *
025: * @author Slava Pestov
026: * @version $Id: SyntaxUtilities.java,v 1.10 2007/12/17 20:41:20 thomas Exp $
027: */
028: public class SyntaxUtilities {
029: /**
030: * Checks if a subregion of a <code>Segment</code> is equal to a
031: * string.
032: * @param ignoreCase True if case should be ignored, false otherwise
033: * @param text The segment
034: * @param offset The offset into the segment
035: * @param match The string to match
036: */
037: public static boolean regionMatches(boolean ignoreCase,
038: Segment text, int offset, String match) {
039: int length = offset + match.length();
040: char[] textArray = text.array;
041: if (length > text.offset + text.count) {
042: return false;
043: }
044: for (int i = offset, j = 0; i < length; i++, j++) {
045: char c1 = textArray[i];
046: char c2 = match.charAt(j);
047: if (ignoreCase) {
048: c1 = Character.toUpperCase(c1);
049: c2 = Character.toUpperCase(c2);
050: }
051: if (c1 != c2) {
052: return false;
053: }
054: }
055: return true;
056: }
057:
058: /**
059: * Checks if a subregion of a <code>Segment</code> is equal to a
060: * character array.
061: * @param ignoreCase True if case should be ignored, false otherwise
062: * @param text The segment
063: * @param offset The offset into the segment
064: * @param match The character array to match
065: */
066: public static boolean regionMatches(boolean ignoreCase,
067: Segment text, int offset, char[] match) {
068: int length = offset + match.length;
069: char[] textArray = text.array;
070: if (length > text.offset + text.count) {
071: return false;
072: }
073: for (int i = offset, j = 0; i < length; i++, j++) {
074: char c1 = textArray[i];
075: char c2 = match[j];
076: if (ignoreCase) {
077: c1 = Character.toUpperCase(c1);
078: c2 = Character.toUpperCase(c2);
079: }
080: if (c1 != c2) {
081: return false;
082: }
083: }
084: return true;
085: }
086:
087: /**
088: * Returns the default style table. This can be passed to the
089: * <code>setStyles()</code> method of <code>SyntaxDocument</code>
090: * to use the default syntax styles.
091: */
092: public static SyntaxStyle[] getDefaultSyntaxStyles() {
093: SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
094:
095: Settings sett = Settings.getInstance();
096:
097: styles[Token.COMMENT1] = new SyntaxStyle(sett.getColor(
098: "workbench.editor.color.comment1", Color.GRAY), true,
099: false);
100: styles[Token.COMMENT2] = new SyntaxStyle(sett.getColor(
101: "workbench.editor.color.comment2", Color.GRAY), true,
102: false);
103: styles[Token.KEYWORD1] = new SyntaxStyle(sett.getColor(
104: "workbench.editor.color.keyword1", Color.BLUE), false,
105: false);
106: styles[Token.KEYWORD2] = new SyntaxStyle(sett.getColor(
107: "workbench.editor.color.keyword2", Color.MAGENTA),
108: false, false);
109: styles[Token.KEYWORD3] = new SyntaxStyle(
110: sett.getColor("workbench.editor.color.keyword3",
111: new Color(0x009600)), false, false);
112: styles[Token.LITERAL1] = new SyntaxStyle(
113: sett.getColor("workbench.editor.color.literal1",
114: new Color(0x650099)), false, false);
115: styles[Token.LITERAL2] = new SyntaxStyle(
116: sett.getColor("workbench.editor.color.literal2",
117: new Color(0x650099)), false, false);
118: styles[Token.LABEL] = new SyntaxStyle(sett.getColor(
119: "workbench.editor.color.label", new Color(0x990033)),
120: false, true);
121: styles[Token.OPERATOR] = new SyntaxStyle(sett.getColor(
122: "workbench.editor.color.operator", Color.BLACK), false,
123: false);
124: styles[Token.INVALID] = new SyntaxStyle(sett.getColor(
125: "workbench.editor.color.invalid", Color.RED), false,
126: true);
127:
128: return styles;
129: }
130:
131: /**
132: * Paints the specified line onto the graphics context. Note that this
133: * method munges the offset and count values of the segment.
134: * @param line The line segment
135: * @param tokens The token list for the line
136: * @param styles The syntax style list
137: * @param expander The tab expander used to determine tab stops. May
138: * be null
139: * @param gfx The graphics context
140: * @param x The x co-ordinate
141: * @param y The y co-ordinate
142: * @param addwidth Additional spacing to be added to the line width
143: * @return The x co-ordinate, plus the width of the painted string
144: */
145: public static int paintSyntaxLine(Segment line, Token tokens,
146: SyntaxStyle[] styles, TabExpander expander, Graphics gfx,
147: int x, int y, int addwidth) {
148: if (tokens == null)
149: return x;
150:
151: Font defaultFont = gfx.getFont();
152: Color defaultColor = gfx.getColor();
153:
154: while (true) {
155: if (tokens == null) {
156: gfx.setColor(defaultColor);
157: gfx.setFont(defaultFont);
158: break;
159: }
160:
161: int length = tokens.length;
162: if (tokens.id == Token.NULL) {
163: gfx.setColor(defaultColor);
164: gfx.setFont(defaultFont);
165: } else {
166: styles[tokens.id].setGraphicsFlags(gfx, defaultFont);
167: }
168: line.count = length;
169: x = Utilities.drawTabbedText(line, x, y, gfx, expander,
170: addwidth);
171: line.offset += length;
172:
173: tokens = tokens.next;
174: }
175:
176: return x;
177: }
178:
179: // private members
180: private SyntaxUtilities() {
181: }
182: }
|