001:/*
002: * Copyright (c) 2001, Jacob Smullyan.
003: *
004: * This is part of SkunkDAV, a WebDAV client. See http://skunkdav.sourceforge.net/
005: * for the latest version.
006: *
007: * SkunkDAV is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License as published
009: * by the Free Software Foundation; either version 2, or (at your option)
010: * any later version.
011: *
012: * SkunkDAV is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with SkunkDAV; see the file COPYING. If not, write to the Free
019: * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
020: * 02111-1307, USA.
021:*/
022:
023:package org.skunk.swing.text.syntax;
024:
025:import java.awt.FontMetrics;
026:import java.awt.Graphics;
027:import javax.swing.text.BadLocationException;
028:import javax.swing.text.Document;
029:import javax.swing.text.Element;
030:import javax.swing.text.JTextComponent;
031:import javax.swing.text.PlainView;
032:import javax.swing.text.Segment;
033:import javax.swing.text.StyledEditorKit;
034:import javax.swing.text.Utilities;
035:import javax.swing.text.View;
036:import javax.swing.text.ViewFactory;
037:import org.skunk.assert.Assertion;
038:import org.skunk.trace.Debug;
039:import org.skunk.util.GappedIntArray;
040:
041:public class SyntaxEditorKit extends StyledEditorKit implements ViewFactory
042:{
043: private SyntaxStyle.SyntaxStyleSet styleSet;
044:
045: public SyntaxEditorKit()
046: {
047: super ();
048: styleSet=SyntaxStyle.getDefaultStyleSet();
049: }
050:
051: public SyntaxEditorKit(SyntaxStyle.SyntaxStyleSet styleSet)
052: {
053: super ();
054: this .styleSet=styleSet;
055: }
056:
057: public SyntaxStyle.SyntaxStyleSet getStyleSet()
058: {
059: return this .styleSet;
060: }
061:
062: public ViewFactory getViewFactory()
063: {
064: return this ;
065: }
066:
067: public View create(Element elem)
068: {
069: return new SyntaxView(elem, styleSet);
070: }
071:
072: public Document createDefaultDocument()
073: {
074: return new SyntaxDocument();
075: }
076:
077:
078:// public static class WrappedSyntaxView extends WrappedPlainView
079:// {
080:// }
081:
082:
083: public static class SyntaxView extends PlainView
084: {
085: private Segment segment = null;
086: private SyntaxStyle.SyntaxStyleSet styleSet;
087:
088: public SyntaxView(Element elem, SyntaxStyle.SyntaxStyleSet styleSet)
089: {
090: super (elem);
091: this .styleSet=styleSet;
092: segment = new Segment();
093: }
094:
095: protected void drawLine(int line, Graphics g, int x, int y)
096: {
097: Element elem = getElement().getElement(line);
098: try
099: {
100: drawElement(elem, g, x, y);
101: }
102: catch (BadLocationException ballocks)
103: {
104: Debug.trace(this , Debug.DP2, ballocks);
105: return;
106: }
107: }
108:
109: private int drawElement(Element elem, Graphics g, int x, int y)
110: throws BadLocationException
111: {
112: int start = elem.getStartOffset();
113: int end = elem.getEndOffset();
114:
115: SyntaxDocument document=(SyntaxDocument) getDocument();
116: GappedIntArray styleBuffer=document.getStyleBuffer();
117: document.getText(start, end - start, segment);
118: if (!document.isTokenizing())
119: {
120: JTextComponent jtc=(JTextComponent) getContainer();
121: g.setFont(jtc.getFont());
122: g.setColor(jtc.getForeground());
123: return Utilities.drawTabbedText(segment, x, y, g, this , start);
124: }
125: else
126: {
127: return drawSyntaxLine(start, end, g, x, y, document, styleBuffer);
128: }
129: }
130:
131: private static void setStyle(Graphics g, SyntaxStyle style)
132: {
133: if (style==null)
134: {
135: if (Debug.DEBUG) Debug.trace(SyntaxEditorKit.SyntaxView.class, Debug.DP2, "null style");
136: style =SyntaxStyle.getStyle(SyntaxStyle.DEFAULT_STYLE);
137: }
138: g.setColor(style.getForegroundColor());
139: g.setFont(style.getFont());
140: }
141:
142: private int drawSyntaxLine(int start,
143: int end,
144: Graphics g,
145: int x,
146: int y,
147: SyntaxDocument doc,
148: GappedIntArray styleBuffer)
149: {
150: if (start>=end) return x;
151: synchronized(styleBuffer)
152: {
153: int styleBuffLen=styleBuffer.length();
154: int[] buffArray;
155: if (end>styleBuffLen)
156: {
157: if (Debug.DEBUG) Debug.trace(this , Debug.DP2, "end, "+end
158: +", greater than the buffer length: "+styleBuffLen);
159: int diff=end-styleBuffLen;
160: int tmpLen=styleBuffLen-start;
161: buffArray=new int[diff+tmpLen];
162: int[] tmpArray=styleBuffer.get(start, tmpLen);
163: System.arraycopy(tmpArray, 0, buffArray, 0, tmpLen);
164: for (int i=0;i<diff;i++)
165: {
166: buffArray[i+tmpLen]=SyntaxStyle.DEFAULT;
167: }
168: }
169: else
170: {
171: buffArray=styleBuffer.get(start, end-start);
172: }
173:
174: if (buffArray==null || buffArray.length==0)
175: return x;
176:
177: int id1=StyleBufferUtilities.getStyle(buffArray[0]);
178: int offset=0;
179: int buffLen=buffArray.length;
180: int lastElem=buffLen-1;
181:
182: for (int i=0;i<buffLen;i++)
183: {
184: int id2=StyleBufferUtilities.getStyle(buffArray[i]);
185: if (id2!=id1 || i==lastElem)
186: {
187: SyntaxStyle s=styleSet.getStyle(id1);
188: if (Debug.DEBUG)
189: Debug.trace(this , Debug.DP7, "style for index {0} is {1}",
190: new Object[] {new Integer(i), s});
191: setStyle(g, s);
192: if (Debug.DEBUG && id1==0)
193: {
194: System.err.println(styleBuffer);
195: System.err.println(GappedIntArray.toString(buffArray));
196: }
197: segment.count=offset;
198: x=Utilities.drawTabbedText(segment, x, y, g, this , start+i);
199: segment.offset+=offset;
200: id1=id2;
201: offset=0;
202: }
203: offset++;
204: }
205: }
206: return x;
207: }
208: }
209:}
210:
211:/* $Log: SyntaxEditorKit.java,v $
212:/* Revision 1.7 2001/02/14 19:15:37 smulloni
213:/* modified usage of the style buffer to pack state information into its ints.
214:/* Previously, I had stipulated that a style could only be used in one state
215:/* per mode; that restriction may now be lifted.
216:/*
217:/* Revision 1.6 2001/02/09 20:00:01 smulloni
218:/* fixed particularly nasty bug in GappedIntArray.set(int, int[]), and other
219:/* bugs in the syntax highlighting system.
220:/*
221:/* Revision 1.5 2001/02/08 18:57:23 smulloni
222:/* fixed several syntax highlighting bugs.
223:/*
224:/* Revision 1.4 2001/02/06 22:13:41 smulloni
225:/* first more-or-less working version of syntax highlighting, with customization.
226:/*
227:/* Revision 1.3 2001/02/02 23:30:33 smulloni
228:/* adding customization features to the text editor.
229:/*
230:/* Revision 1.2 2001/01/30 18:01:27 smulloni
231:/* first working beta of syntax highlighting. Nasty bug in
232:/* GappedIntArray.remove() fixed.
233:/*
234:/* Revision 1.1 2001/01/29 22:30:20 smulloni
235:/* support for custom views for syntax highlighting.
236:/* */
|