KickJava   Java API By Example, From Geeks To Geeks.

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


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

23
24 package org.gjt.sp.jedit.syntax;
25
26 //{{{ Imports
27
import javax.swing.text.*;
28 import java.awt.font.*;
29 import java.awt.geom.*;
30 import java.awt.*;
31
32 import org.gjt.sp.jedit.Debug;
33 //}}}
34

35 /**
36  * A syntax token with extra information required for painting it
37  * on screen.
38  * @since jEdit 4.1pre1
39  */

40 public class Chunk extends Token
41 {
42     //{{{ paintChunkList() method
43
/**
44      * Paints a chunk list.
45      * @param chunks The chunk list
46      * @param gfx The graphics context
47      * @param x The x co-ordinate
48      * @param y The y co-ordinate
49      * @return The width of the painted text
50      * @since jEdit 4.2pre1
51      */

52     public static float paintChunkList(Chunk chunks,
53         Graphics2D gfx, float x, float y, boolean glyphVector)
54     {
55         Rectangle clipRect = gfx.getClipBounds();
56
57         float _x = 0.0f;
58
59         while(chunks != null)
60         {
61             // only paint visible chunks
62
if(x + _x + chunks.width > clipRect.x
63                 && x + _x < clipRect.x + clipRect.width)
64             {
65                 // Useful for debugging purposes
66
if(Debug.CHUNK_PAINT_DEBUG)
67                 {
68                     gfx.draw(new Rectangle2D.Float(x + _x,y - 10,
69                         chunks.width,10));
70                 }
71
72                 if(chunks.accessable && chunks.visible)
73                 {
74                     gfx.setFont(chunks.style.getFont());
75                     gfx.setColor(chunks.style.getForegroundColor());
76
77                     if(glyphVector && chunks.gv != null)
78                         gfx.drawGlyphVector(chunks.gv,x + _x,y);
79                     else if(chunks.str != null)
80                     {
81                         gfx.drawString(chunks.str,
82                             (int)(x + _x),(int)y);
83                     }
84                 }
85             }
86
87             _x += chunks.width;
88             chunks = (Chunk)chunks.next;
89         }
90
91         return _x;
92     } //}}}
93

94     //{{{ paintChunkBackgrounds() method
95
/**
96      * Paints the background highlights of a chunk list.
97      * @param chunks The chunk list
98      * @param gfx The graphics context
99      * @param x The x co-ordinate
100      * @param y The y co-ordinate
101      * @return The width of the painted backgrounds
102      * @since jEdit 4.2pre1
103      */

104     public static float paintChunkBackgrounds(Chunk chunks,
105         Graphics2D gfx, float x, float y)
106     {
107         Rectangle clipRect = gfx.getClipBounds();
108
109         float _x = 0.0f;
110
111         FontMetrics forBackground = gfx.getFontMetrics();
112
113         int ascent = forBackground.getAscent();
114         int height = forBackground.getHeight();
115
116         while(chunks != null)
117         {
118             // only paint visible chunks
119
if(x + _x + chunks.width > clipRect.x
120                 && x + _x < clipRect.x + clipRect.width)
121             {
122                 if(chunks.accessable)
123                 {
124                     //{{{ Paint token background color if necessary
125
Color bgColor = chunks.background;
126                     if(bgColor != null)
127                     {
128                         gfx.setColor(bgColor);
129
130                         gfx.fill(new Rectangle2D.Float(
131                             x + _x,y - ascent,
132                             _x + chunks.width - _x,
133                             height));
134                     } //}}}
135
}
136             }
137
138             _x += chunks.width;
139             chunks = (Chunk)chunks.next;
140         }
141
142         return _x;
143     } //}}}
144

145     //{{{ offsetToX() method
146
/**
147      * Converts an offset in a chunk list into an x co-ordinate.
148      * @param chunks The chunk list
149      * @param offset The offset
150      * @since jEdit 4.1pre1
151      */

152     public static float offsetToX(Chunk chunks, int offset)
153     {
154         if(chunks != null && offset < chunks.offset)
155         {
156             throw new ArrayIndexOutOfBoundsException JavaDoc(offset + " < "
157                 + chunks.offset);
158         }
159
160         float x = 0.0f;
161
162         while(chunks != null)
163         {
164             if(chunks.accessable && offset < chunks.offset + chunks.length)
165                 return x + chunks.offsetToX(offset - chunks.offset);
166
167             x += chunks.width;
168             chunks = (Chunk)chunks.next;
169         }
170
171         return x;
172     } //}}}
173

174     //{{{ xToOffset() method
175
/**
176      * Converts an x co-ordinate in a chunk list into an offset.
177      * @param chunks The chunk list
178      * @param x The x co-ordinate
179      * @param round Round up to next letter if past the middle of a letter?
180      * @return The offset within the line, or -1 if the x co-ordinate is too
181      * far to the right
182      * @since jEdit 4.1pre1
183      */

184     public static int xToOffset(Chunk chunks, float x, boolean round)
185     {
186         float _x = 0.0f;
187
188         while(chunks != null)
189         {
190             if(chunks.accessable && x < _x + chunks.width)
191                 return chunks.xToOffset(x - _x,round);
192
193             _x += chunks.width;
194             chunks = (Chunk)chunks.next;
195         }
196
197         return -1;
198     } //}}}
199

200     //{{{ Instance variables
201
public boolean accessable;
202     public boolean visible;
203     public boolean initialized;
204
205     // set up after init()
206
public SyntaxStyle style;
207     // this is either style.getBackgroundColor() or
208
// styles[defaultID].getBackgroundColor()
209
public Color background;
210     public float width;
211     public GlyphVector gv;
212     public String JavaDoc str;
213     //}}}
214

215     //{{{ Chunk constructor
216
public Chunk(float width, int offset, ParserRuleSet rules)
217     {
218         super(Token.NULL,offset,0,rules);
219         this.width = width;
220     } //}}}
221

222     //{{{ Chunk constructor
223
public Chunk(byte id, int offset, int length, ParserRuleSet rules,
224         SyntaxStyle[] styles, byte defaultID)
225     {
226         super(id,offset,length,rules);
227         accessable = true;
228         style = styles[id];
229         background = style.getBackgroundColor();
230         if(background == null)
231             background = styles[defaultID].getBackgroundColor();
232     } //}}}
233

234     //{{{ getPositions() method
235
public final float[] getPositions()
236     {
237         if(gv == null)
238             return null;
239
240         if(positions == null)
241             positions = gv.getGlyphPositions(0,length,null);
242
243         return positions;
244     } //}}}
245

246     //{{{ offsetToX() method
247
public final float offsetToX(int offset)
248     {
249         if(!visible)
250             return 0.0f;
251         else
252             return getPositions()[offset * 2];
253     } //}}}
254

255     //{{{ xToOffset() method
256
public final int xToOffset(float x, boolean round)
257     {
258         if(!visible)
259         {
260             if(round && width - x < x)
261                 return offset + length;
262             else
263                 return offset;
264         }
265         else
266         {
267             float[] pos = getPositions();
268
269             for(int i = 0; i < length; i++)
270             {
271                 float glyphX = pos[i*2];
272                 float nextX = (i == length - 1
273                     ? width : pos[i*2+2]);
274
275                 if(nextX > x)
276                 {
277                     if(!round || nextX - x > x - glyphX)
278                         return offset + i;
279                     else
280                         return offset + i + 1;
281                 }
282             }
283         }
284
285         // wtf?
286
return -1;
287     } //}}}
288

289     //{{{ init() method
290
public void init(Segment seg, TabExpander expander, float x,
291         FontRenderContext fontRenderContext)
292     {
293         initialized = true;
294
295         if(!accessable)
296         {
297             // do nothing
298
}
299         else if(length == 1 && seg.array[seg.offset + offset] == '\t')
300         {
301             visible = false;
302             float newX = expander.nextTabStop(x,offset + length);
303             width = newX - x;
304         }
305         else
306         {
307             visible = true;
308
309             str = new String JavaDoc(seg.array,seg.offset + offset,length);
310             
311             Rectangle2D logicalBounds;
312             gv = style.getFont().createGlyphVector(
313                 fontRenderContext, str);
314             logicalBounds = gv.getLogicalBounds();
315
316             width = (float)logicalBounds.getWidth();
317         }
318     } //}}}
319

320     //{{{ Private members
321
private float[] positions;
322     //}}}
323
}
324
Popular Tags