/* * EUGContext.java * * Created on June 26, 2007, 11:59 AM */ package eug.syntax; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Shape; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.MutableAttributeSet; import javax.swing.text.PlainView; import javax.swing.text.Segment; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.Utilities; import javax.swing.text.View; import javax.swing.text.ViewFactory; /** * * @author Michael Myers */ public class EUGContext extends StyleContext implements ViewFactory { private static final long serialVersionUID = 1L; private StyleSet styles; /** * Creates a new instance of EUGContext */ public EUGContext() { styles = new DefaultEUGStyleSet(); ((DefaultEUGStyleSet)styles).addDefaults(); } public View create(Element elem) { return new EUGView(elem); } public StyleSet getStyles() { return styles; } public void setStyles(StyleSet styles) { this.styles = styles; } private class EUGView extends PlainView { private EUGDocument.Scanner scanner; private boolean scannerValid; EUGView(Element elem) { super(elem); scanner = ((EUGDocument) getDocument()).createScanner(); scannerValid = false; } @Override public void paint(Graphics g, Shape a) { super.paint(g, a); scannerValid = false; } @Override protected int drawSelectedText(final Graphics g, int x, int y, int p0, int p1) throws BadLocationException { // Same as drawUnselectedText, but without colors. final Font boldFont = g.getFont().deriveFont(Font.BOLD); final Font plainFont = g.getFont().deriveFont(Font.PLAIN); final Document doc = getDocument(); boolean bold = false; boolean lastBold = false; int mark = p0; g.setColor(Color.BLACK); while (p0 < p1) { updateScanner(p0); int p = Math.min(scanner.getEndOffset(), p1); p = (p <= p0) ? p1 : p; MutableAttributeSet style = styles.getStyle(scanner.lastToken(), scanner.lastStr()); bold = StyleConstants.isBold(style); if (bold != lastBold) { // style change, flush what we have g.setFont(lastBold ? boldFont : plainFont); Segment text = getLineBuffer(); doc.getText(mark, p0 - mark, text); x = Utilities.drawTabbedText(text, x, y, g, this, mark); mark = p0; } lastBold = bold; p0 = p; } // flush remaining g.setFont(lastBold ? boldFont : plainFont); Segment text = getLineBuffer(); doc.getText(mark, p1 - mark, text); return Utilities.drawTabbedText(text, x, y, g, this, mark); } @Override protected int drawUnselectedText(final Graphics g, int x, int y, int p0, int p1) throws BadLocationException { // Copied, with a few changes final Font boldFont = g.getFont().deriveFont(Font.BOLD); final Font plainFont = g.getFont().deriveFont(Font.PLAIN); final Document doc = getDocument(); Color last = null; Color fg; boolean bold = false; boolean lastBold = false; int mark = p0; while (p0 < p1) { updateScanner(p0); int p = Math.min(scanner.getEndOffset(), p1); p = (p <= p0) ? p1 : p; MutableAttributeSet style = styles.getStyle(scanner.lastToken(), scanner.lastStr()); fg = StyleConstants.getForeground(style); bold = StyleConstants.isBold(style); if ((fg != last && last != null) || (bold != lastBold)) { // color change, flush what we have g.setColor(last); g.setFont(lastBold ? boldFont : plainFont); Segment text = getLineBuffer(); doc.getText(mark, p0 - mark, text); x = Utilities.drawTabbedText(text, x, y, g, this, mark); mark = p0; } last = fg; lastBold = bold; p0 = p; } // flush remaining g.setColor(last); g.setFont(lastBold ? boldFont : plainFont); Segment text = getLineBuffer(); doc.getText(mark, p1 - mark, text); return Utilities.drawTabbedText(text, x, y, g, this, mark); } private void updateScanner(int pos) { // Copied, with a few changes if (!scannerValid) { EUGDocument doc = (EUGDocument) getDocument(); scanner.setRange(doc.getScannerStart(pos), doc.getLength()); scannerValid = true; } while (scanner.getEndOffset() <= pos) { scanner.scan(); } } } }