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
    33  	 * string.
    34  	 * @param ignoreCase True if case should be ignored, false otherwise
    35  	 * @param text The segment
    36  	 * @param offset The offset into the segment
    37  	 * @param match The string to match
    38  	 */
    39  	public static boolean regionMatches(boolean ignoreCase, Segment text,
    40  					    int offset, String match)
    41  	{
    42  		int length = offset + match.length();
    43  		char[] textArray = text.array;
    44  		if(length > text.offset + text.count)
    45  			return false;
    46  		for(int i = offset, j = 0; i < length; i++, j++)
    47  		{
    48  			char c1 = textArray[i];
    49  			char c2 = match.charAt(j);
    50  			if(ignoreCase)
    51  			{
    52  				c1 = Character.toUpperCase(c1);
    53  				c2 = Character.toUpperCase(c2);
    54  			}
    55  			if(c1 != c2)
    56  				return false;
    57  		}
    58  		return true;
    59  	}
    60
    61  	/***
    62  	 * Checks if a subregion of a <code>Segment</code> is equal to a
    63  	 * character array.
    64  	 * @param ignoreCase True if case should be ignored, false otherwise
    65  	 * @param text The segment
    66  	 * @param offset The offset into the segment
    67  	 * @param match The character array to match
    68  	 */
    69  	public static boolean regionMatches(boolean ignoreCase, Segment text,
    70  					    int offset, char[] match)
    71  	{
    72  		int length = offset + match.length;
    73  		char[] textArray = text.array;
    74  		if(length > text.offset + text.count)
    75  			return false;
    76  		for(int i = offset, j = 0; i < length; i++, j++)
    77  		{
    78  			char c1 = textArray[i];
    79  			char c2 = match[j];
    80  			if(ignoreCase)
    81  			{
    82  				c1 = Character.toUpperCase(c1);
    83  				c2 = Character.toUpperCase(c2);
    84  			}
    85  			if(c1 != c2)
    86  				return false;
    87  		}
    88  		return true;
    89  	}
    90
    91  	/***
    92  	 * Returns the default style table. This can be passed to the
    93  	 * <code>setStyles()</code> method of <code>SyntaxDocument</code>
    94  	 * to use the default syntax styles.
    95  	 */
    96  	public static SyntaxStyle[] getDefaultSyntaxStyles()
    97  	{
    98  		SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
    99
    100 		styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false);
    101 		styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false);
    102 		styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true);
    103 		styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false);
    104 		styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false);
    105 		styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false);
    106 		styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true);
    107 		styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true);
    108 		styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true);
    109 		styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true);
    110
    111 		return styles;
    112 	}
    113
    114 	/***
    115 	 * Paints the specified line onto the graphics context. Note that this
    116 	 * method munges the offset and count values of the segment.
    117 	 * @param line The line segment
    118 	 * @param tokens The token list for the line
    119 	 * @param styles The syntax style list
    120 	 * @param expander The tab expander used to determine tab stops. May
    121 	 * be null
    122 	 * @param gfx The graphics context
    123 	 * @param x The x co-ordinate
    124 	 * @param y The y co-ordinate
    125 	 * @return The x co-ordinate, plus the width of the painted string
    126 	 */
    127 	public static int paintSyntaxLine(Segment line, Token tokens,
    128 		SyntaxStyle[] styles, TabExpander expander, Graphics gfx,
    129 		int x, int y)
    130 	{
    131 		Font defaultFont = gfx.getFont();
    132 		Color defaultColor = gfx.getColor();
    133
    134 		int offset = 0;
    135 		for(;;)
    136 		{
    137 			byte id = tokens.id;
    138 			if(id == Token.END)
    139 				break;
    140
    141 			int length = tokens.length;
    142 			if(id == Token.NULL)
    143 			{
    144 				if(!defaultColor.equals(gfx.getColor()))
    145 					gfx.setColor(defaultColor);
    146 				if(!defaultFont.equals(gfx.getFont()))
    147 					gfx.setFont(defaultFont);
    148 			}
    149 			else
    150 				styles[id].setGraphicsFlags(gfx,defaultFont);
    151
    152 			line.count = length;
    153 			x = Utilities.drawTabbedText(line,x,y,gfx,expander,0);
    154 			line.offset += length;
    155 			offset += length;
    156
    157 			tokens = tokens.next;
    158 		}
    159
    160 		return x;
    161 	}
    162
    163 	// private members
    164 	private SyntaxUtilities() {}
    165 }