1 22 23 package org.gjt.sp.jedit.syntax; 24 25 import javax.swing.text.*; 27 import java.awt.font.*; 28 import java.util.List ; 29 31 35 public class DisplayTokenHandler extends DefaultTokenHandler 36 { 37 public static final int MAX_CHUNK_LEN = 100; 39 40 public void init(SyntaxStyle[] styles, 42 FontRenderContext fontRenderContext, 43 TabExpander expander, List <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 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 } 67 72 public List <Chunk> getChunkList() 73 { 74 return out; 75 } 77 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 } 151 153 private SyntaxStyle[] styles; 155 private FontRenderContext fontRenderContext; 156 private TabExpander expander; 157 private float x; 158 159 private List <Chunk> out; 160 private float wrapMargin; 161 private float endX; 162 private Token end; 163 164 private boolean seenNonWhitespace; 165 private float endOfWhitespace; 166 168 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 } 177 protected void initChunk(Chunk chunk, Segment seg) 179 { 180 chunk.init(seg,expander,x,fontRenderContext); 181 } 183 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 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 } 219 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 } 233 } 235 | Popular Tags |