View Javadoc

1   /*
2    * SyntaxUtilities.java - Utility functions used by syntax colorizing
3    * Copyright (C) 1999 Slava Pestov
4    *
5    * You may use and modify this package for any purpose. Redistribution is
6    * permitted, in both source and binary form, provided that this notice
7    * remains intact in all source distributions of this package.
8    */
9   
10  package org.syntax.jedit;
11  
12  import java.awt.Color;
13  import java.awt.Font;
14  import java.awt.Graphics;
15  
16  import javax.swing.text.Segment;
17  import javax.swing.text.TabExpander;
18  import javax.swing.text.Utilities;
19  
20  import org.syntax.jedit.tokenmarker.Token;
21  
22  /***
23   * Class with several utility functions used by jEdit's syntax colorizing
24   * subsystem.
25   * 
26   * @author Slava Pestov
27   * @version $Id$
28   */
29  public class SyntaxUtilities
30  {
31  	/***
32  	 * Checks if a subregion of a <code>Segment</code> is equal to a string.
33  	 * 
34  	 * @param ignoreCase
35  	 *           True if case should be ignored, false otherwise
36  	 * @param text
37  	 *           The segment
38  	 * @param offset
39  	 *           The offset into the segment
40  	 * @param match
41  	 *           The string to match
42  	 */
43  	public static boolean regionMatches( boolean ignoreCase, Segment text, int offset, String match )
44  	{
45  		int length = offset + match.length();
46  		char[] textArray = text.array;
47  		if( length > text.offset + text.count )
48  			return false;
49  		for( int i = offset, j = 0; i < length; i++ , j++ )
50  		{
51  			char c1 = textArray[i];
52  			char c2 = match.charAt( j );
53  			if( ignoreCase )
54  			{
55  				c1 = Character.toUpperCase( c1 );
56  				c2 = Character.toUpperCase( c2 );
57  			}
58  			if( c1 != c2 )
59  				return false;
60  		}
61  		return true;
62  	}
63  
64  	/***
65  	 * Checks if a subregion of a <code>Segment</code> is equal to a character
66  	 * array.
67  	 * 
68  	 * @param ignoreCase
69  	 *           True if case should be ignored, false otherwise
70  	 * @param text
71  	 *           The segment
72  	 * @param offset
73  	 *           The offset into the segment
74  	 * @param match
75  	 *           The character array to match
76  	 */
77  	public static boolean regionMatches( boolean ignoreCase, Segment text, int offset, char[] match )
78  	{
79  		int length = offset + match.length;
80  		char[] textArray = text.array;
81  		if( length > text.offset + text.count )
82  			return false;
83  		for( int i = offset, j = 0; i < length; i++ , j++ )
84  		{
85  			char c1 = textArray[i];
86  			char c2 = match[j];
87  			if( ignoreCase )
88  			{
89  				c1 = Character.toUpperCase( c1 );
90  				c2 = Character.toUpperCase( c2 );
91  			}
92  			if( c1 != c2 )
93  				return false;
94  		}
95  		return true;
96  	}
97  
98  	/***
99  	 * Returns the default style table. This can be passed to the
100 	 * <code>setStyles()</code> method of <code>SyntaxDocument</code> to use the
101 	 * default syntax styles.
102 	 */
103 	public static SyntaxStyle[] getDefaultSyntaxStyles()
104 	{
105 		SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
106 
107 		styles[Token.COMMENT1] = new SyntaxStyle( Color.black, true, false );
108 		styles[Token.COMMENT2] = new SyntaxStyle( new Color( 0x990033 ), true, false );
109 		styles[Token.KEYWORD1] = new SyntaxStyle( Color.black, false, true );
110 		styles[Token.KEYWORD2] = new SyntaxStyle( Color.magenta, false, false );
111 		styles[Token.KEYWORD3] = new SyntaxStyle( new Color( 0x009600 ), false, false );
112 		styles[Token.LITERAL1] = new SyntaxStyle( new Color( 0x650099 ), false, false );
113 		styles[Token.LITERAL2] = new SyntaxStyle( new Color( 0x650099 ), false, true );
114 		styles[Token.LABEL] = new SyntaxStyle( new Color( 0x990033 ), false, true );
115 		styles[Token.OPERATOR] = new SyntaxStyle( Color.black, false, true );
116 		styles[Token.INVALID] = new SyntaxStyle( Color.red, false, true );
117 
118 		return styles;
119 	}
120 
121 	/***
122 	 * Paints the specified line onto the graphics context. Note that this method
123 	 * munges the offset and count values of the segment.
124 	 * 
125 	 * @param line
126 	 *           The line segment
127 	 * @param tokens
128 	 *           The token list for the line
129 	 * @param styles
130 	 *           The syntax style list
131 	 * @param expander
132 	 *           The tab expander used to determine tab stops. May be null
133 	 * @param gfx
134 	 *           The graphics context
135 	 * @param x
136 	 *           The x co-ordinate
137 	 * @param y
138 	 *           The y co-ordinate
139 	 * @return The x co-ordinate, plus the width of the painted string
140 	 */
141 	public static int paintSyntaxLine( Segment line, Token tokens, SyntaxStyle[] styles, TabExpander expander,
142 			Graphics gfx, int x, int y )
143 	{
144 		Font defaultFont = gfx.getFont();
145 		Color defaultColor = gfx.getColor();
146 
147 		int offset = 0;
148 		for( ;; )
149 		{
150 			byte id = tokens.id;
151 			if( id == Token.END )
152 				break;
153 
154 			int length = tokens.length;
155 			if( id == Token.NULL )
156 			{
157 				if( !defaultColor.equals( gfx.getColor() ) )
158 					gfx.setColor( defaultColor );
159 				if( !defaultFont.equals( gfx.getFont() ) )
160 					gfx.setFont( defaultFont );
161 			}
162 			else
163 				styles[id].setGraphicsFlags( gfx, defaultFont );
164 
165 			line.count = length;
166 			x = Utilities.drawTabbedText( line, x, y, gfx, expander, 0 );
167 			line.offset += length;
168 			offset += length;
169 
170 			tokens = tokens.next;
171 		}
172 
173 		return x;
174 	}
175 
176 	// private members
177 	private SyntaxUtilities()
178 	{
179 	}
180 }