KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > syntax > DisplayTokenHandler


1 /*
2  * DisplayTokenHandler.java - converts tokens to chunks
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2003 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.syntax;
24
25 //{{{ Imports
26
import javax.swing.text.*;
27 import java.awt.font.*;
28 import java.util.List JavaDoc;
29 //}}}
30

31 /**
32  * Creates {@link Chunk} objects that can be painted on screen.
33  * @version $Id: DisplayTokenHandler.java 8258 2006-12-25 21:39:27Z kpouer $
34  */

35 public class DisplayTokenHandler extends DefaultTokenHandler
36 {
37     // don't have chunks longer than 100 characters to avoid slowing things down
38
public static final int MAX_CHUNK_LEN = 100;
39
40     //{{{ init() method
41
public void init(SyntaxStyle[] styles,
42         FontRenderContext fontRenderContext,
43         TabExpander expander, List JavaDoc<Chunk> out,
44         float wrapMargin)
45     {
46         super.init();
47
48         x = 0.0f;
49
50         this.styles = styles;
51         this.fontRenderContext = fontRenderContext;
52         this.expander = expander;
53
54         // SILLY: allow for anti-aliased characters' "fuzz"
55
if(wrapMargin != 0.0f)
56             this.wrapMargin = wrapMargin += 2.0f;
57         else
58             this.wrapMargin = 0.0f;
59
60         this.out = out;
61
62         seenNonWhitespace = false;
63         endX = endOfWhitespace = 0.0f;
64         end = null;
65     } //}}}
66

67     //{{{ getChunkList() method
68
/**
69      * Returns the list of chunks.
70      * @since jEdit 4.1pre7
71      */

72     public List JavaDoc<Chunk> getChunkList()
73     {
74         return out;
75     } //}}}
76

77     //{{{ handleToken() method
78
/**
79      * Called by the token marker when a syntax token has been parsed.
80      * @param seg The segment containing the text
81      * @param id The token type (one of the constants in the
82      * {@link Token} class).
83      * @param offset The start offset of the token
84      * @param length The number of characters in the token
85      * @param context The line context
86      * @since jEdit 4.2pre3
87      */

88     public void handleToken(Segment seg, byte id, int offset, int length,
89         TokenMarker.LineContext context)
90     {
91         if(id == Token.END)
92         {
93             if(firstToken != null)
94                 out.add(merge((Chunk)firstToken,seg));
95             return;
96         }
97
98         for(int splitOffset = 0; splitOffset < length; splitOffset += MAX_CHUNK_LEN)
99         {
100             int splitLength = Math.min(length - splitOffset,MAX_CHUNK_LEN);
101             Chunk chunk = createChunk(id,offset + splitOffset,splitLength,context);
102             addToken(chunk,context);
103
104             if(wrapMargin != 0.0f)
105             {
106                 initChunk(chunk,seg);
107                 x += chunk.width;
108
109                 if(Character.isWhitespace(seg.array[
110                     seg.offset + chunk.offset]))
111                 {
112                     if(seenNonWhitespace)
113                     {
114                         end = lastToken;
115                         endX = x;
116                     }
117                     else
118                         endOfWhitespace = x;
119                 }
120                 else
121                 {
122                     if(x > wrapMargin
123                         && end != null
124                         && seenNonWhitespace)
125                     {
126                         Chunk nextLine = new Chunk(endOfWhitespace,
127                             end.offset + end.length,
128                             getParserRuleSet(context));
129                         initChunk(nextLine,seg);
130
131                         nextLine.next = end.next;
132                         end.next = null;
133
134                         if(firstToken != null)
135                             out.add(merge((Chunk)firstToken,seg));
136
137                         firstToken = nextLine;
138
139                         x = x - endX + endOfWhitespace;
140
141                         end = null;
142                         endX = x;
143                     }
144
145                     seenNonWhitespace = true;
146                 }
147             }
148         }
149     } //}}}
150

151     //{{{ Private members
152

153     //{{{ Instance variables
154
private SyntaxStyle[] styles;
155     private FontRenderContext fontRenderContext;
156     private TabExpander expander;
157     private float x;
158
159     private List JavaDoc<Chunk> out;
160     private float wrapMargin;
161     private float endX;
162     private Token end;
163
164     private boolean seenNonWhitespace;
165     private float endOfWhitespace;
166     //}}}
167

168     //{{{ createChunk() method
169
private Chunk createChunk(byte id, int offset, int length,
170         TokenMarker.LineContext context)
171     {
172         return new Chunk(id,offset,length,
173             getParserRuleSet(context),styles,
174             context.rules.getDefault());
175     } //}}}
176

177     //{{{ initChunk() method
178
protected void initChunk(Chunk chunk, Segment seg)
179     {
180         chunk.init(seg,expander,x,fontRenderContext);
181     } //}}}
182

183     //{{{ merge() method
184
private Chunk merge(Chunk first, Segment seg)
185     {
186         if(first == null)
187             return null;
188
189         Chunk chunk = first;
190         while(chunk.next != null)
191         {
192             Chunk next = (Chunk)chunk.next;
193             if(canMerge(chunk,next,seg))
194             {
195                 // in case already initialized; un-initialize it
196
chunk.initialized = false;
197                 chunk.length += next.length;
198                 chunk.width += next.width;
199                 chunk.next = next.next;
200             }
201             else
202             {
203                 if(!chunk.initialized)
204                 {
205                     initChunk(chunk,seg);
206                     if(wrapMargin == 0.0f)
207                         x += chunk.width;
208                 }
209                 chunk = next;
210             }
211         }
212
213         if(!chunk.initialized)
214             initChunk(chunk,seg);
215
216         return first;
217     } //}}}
218

219     //{{{ canMerge() method
220
private static boolean canMerge(Chunk c1, Chunk c2, Segment seg)
221     {
222         if(!c1.accessable || !c2.accessable)
223             return false;
224
225         char ch1 = seg.array[seg.offset + c1.offset];
226         char ch2 = seg.array[seg.offset + c2.offset];
227
228         return ((c1.style == c2.style)
229             && ch1 != '\t' && ch2 != '\t'
230             && (c1.length + c2.length <= MAX_CHUNK_LEN));
231     } //}}}
232

233     //}}}
234
}
235
Popular Tags