1 23 24 package org.gjt.sp.jedit.syntax; 25 26 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 35 40 public class Chunk extends Token 41 { 42 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 if(x + _x + chunks.width > clipRect.x 63 && x + _x < clipRect.x + clipRect.width) 64 { 65 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 } 94 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 if(x + _x + chunks.width > clipRect.x 120 && x + _x < clipRect.x + clipRect.width) 121 { 122 if(chunks.accessable) 123 { 124 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 } } 136 } 137 138 _x += chunks.width; 139 chunks = (Chunk)chunks.next; 140 } 141 142 return _x; 143 } 145 152 public static float offsetToX(Chunk chunks, int offset) 153 { 154 if(chunks != null && offset < chunks.offset) 155 { 156 throw new ArrayIndexOutOfBoundsException (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 } 174 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 } 200 public boolean accessable; 202 public boolean visible; 203 public boolean initialized; 204 205 public SyntaxStyle style; 207 public Color background; 210 public float width; 211 public GlyphVector gv; 212 public String str; 213 215 public Chunk(float width, int offset, ParserRuleSet rules) 217 { 218 super(Token.NULL,offset,0,rules); 219 this.width = width; 220 } 222 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 } 234 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 } 246 public final float offsetToX(int offset) 248 { 249 if(!visible) 250 return 0.0f; 251 else 252 return getPositions()[offset * 2]; 253 } 255 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 return -1; 287 } 289 public void init(Segment seg, TabExpander expander, float x, 291 FontRenderContext fontRenderContext) 292 { 293 initialized = true; 294 295 if(!accessable) 296 { 297 } 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 (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 } 320 private float[] positions; 322 } 324 | Popular Tags |