~ubuntu-branches/ubuntu/vivid/drmips/vivid-backports

« back to all changes in this revision

Viewing changes to src/pc/DrMIPS/src/org/fife/ui/rsyntaxtextarea/VisibleWhitespaceTokenPainter.java

  • Committer: Package Import Robot
  • Author(s): Bruno Nova
  • Date: 2014-09-27 12:24:17 UTC
  • Revision ID: package-import@ubuntu.com-20140927122417-2gadkwt9k0u7j4zu
Tags: upstream-1.2.3
Import upstream version 1.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * 03/16/2013
 
3
 *
 
4
 * VisibleWhitespaceTokenPainter - Renders tokens in an instance of
 
5
 * RSyntaxTextArea, with special glyphs to denote spaces and tabs.
 
6
 * 
 
7
 * This library is distributed under a modified BSD license.  See the included
 
8
 * RSyntaxTextArea.License.txt file for details.
 
9
 */
 
10
package org.fife.ui.rsyntaxtextarea;
 
11
 
 
12
import java.awt.Color;
 
13
import java.awt.FontMetrics;
 
14
import java.awt.Graphics2D;
 
15
import javax.swing.text.TabExpander;
 
16
 
 
17
 
 
18
/**
 
19
 * A token painter that visibly renders whitespace (spaces and tabs).<p>
 
20
 *
 
21
 * The current implementation paints as follows:
 
22
 * <ul>
 
23
 *   <li>The first tab or space, if any, is found in the token.</li>
 
24
 *   <li>If a tab was found, all characters up to it are painted as a
 
25
 *       group.</li>
 
26
 *   <li>If a space was found, all characters up to and including it are
 
27
 *       painted (it is painted with a special symbol to denote it as
 
28
 *       a space).</li>
 
29
 *   <li>If neither a tab nor a whitespace was found, all characters in the
 
30
 *       token are painted.</li>
 
31
 *   <li>Repeat until all characters are painted.</li>
 
32
 * </ul>
 
33
 * This means that rendering hints are applied to all groups of characters
 
34
 * within a token, excluding whitespace and tabs.<p>
 
35
 *
 
36
 * A problem with this implementation is that FontMetrics.charsWidth() is still
 
37
 * used to calculate the width of a group of chars painted.  Thus, the group of
 
38
 * characters will be painted with the rendering hints specified, but the
 
39
 * following tab (or group of characters if the current group was the end of a
 
40
 * token) will not necessarily be painted at the proper x-coordinate (as
 
41
 * FontMetrics.charsWidth() returns an <code>int</code> and not a
 
42
 * <code>float</code>).  The way around this would be to calculate the token's
 
43
 * width in such a way that a float is returned (Font.getStringBounds()?).
 
44
 *
 
45
 * @author Robert Futrell
 
46
 * @version 1.0
 
47
 */
 
48
class VisibleWhitespaceTokenPainter extends DefaultTokenPainter {
 
49
 
 
50
 
 
51
        /**
 
52
         * {@inheritDoc}
 
53
         */
 
54
        @Override
 
55
        protected float paintImpl(Token token, Graphics2D g, float x, float y,
 
56
                        RSyntaxTextArea host, TabExpander e, float clipStart,
 
57
                        boolean selected) {
 
58
 
 
59
                int origX = (int)x;
 
60
                int textOffs = token.getTextOffset();
 
61
                char[] text = token.getTextArray();
 
62
                int end = token.getEndOffset();
 
63
                float nextX = x;
 
64
                int flushLen = 0;
 
65
                int flushIndex = textOffs;
 
66
                Color fg, bg;
 
67
                if (selected) {
 
68
                        fg = host.getSelectedTextColor();
 
69
                        bg = null;
 
70
                }
 
71
                else {
 
72
                        fg = host.getForegroundForToken(token);
 
73
                        bg = host.getBackgroundForToken(token);
 
74
                }
 
75
                g.setFont(host.getFontForTokenType(token.getType()));
 
76
                FontMetrics fm = host.getFontMetricsForTokenType(token.getType());
 
77
 
 
78
                int ascent = fm.getAscent();
 
79
                int height = fm.getHeight();
 
80
 
 
81
                for (int i=textOffs; i<end; i++) {
 
82
 
 
83
                        switch (text[i]) {
 
84
 
 
85
                                case '\t':
 
86
 
 
87
                                        // Fill in background.
 
88
                                        nextX = x+fm.charsWidth(text, flushIndex,flushLen);
 
89
                                        float nextNextX = e.nextTabStop(nextX, 0);
 
90
                                        if (bg!=null) {
 
91
                                                paintBackground(x,y, nextNextX-x,height, g,
 
92
                                                                                ascent, host, bg, !selected);
 
93
                                        }
 
94
                                        g.setColor(fg);
 
95
 
 
96
                                        // Paint chars cached before the tab.
 
97
                                        if (flushLen > 0) {
 
98
                                                g.drawChars(text, flushIndex, flushLen, (int)x,(int)y);
 
99
                                                flushLen = 0;
 
100
                                        }
 
101
                                        flushIndex = i + 1;
 
102
 
 
103
                                        // Draw an arrow representing the tab.
 
104
                                        int halfHeight = height / 2;
 
105
                                        int quarterHeight = halfHeight / 2;
 
106
                                        int ymid = (int)y - ascent + halfHeight;
 
107
                                        g.drawLine((int)nextX,ymid, (int)nextNextX,ymid);
 
108
                                        g.drawLine((int)nextNextX,ymid, (int)nextNextX-4,ymid-quarterHeight);
 
109
                                        g.drawLine((int)nextNextX,ymid, (int)nextNextX-4,ymid+quarterHeight);
 
110
 
 
111
                                        x = nextNextX;
 
112
                                        break;
 
113
 
 
114
                                case ' ':
 
115
 
 
116
                                        // NOTE:  There is a little bit of a "fudge factor"
 
117
                                        // here when "smooth text" is enabled, as "width"
 
118
                                        // below may well not be the width given to the space
 
119
                                        // by fm.charsWidth() (it depends on how it places the
 
120
                                        // space with respect to the preceding character).
 
121
                                        // But, we assume the approximation is close enough for
 
122
                                        // our drawing a dot for the space.
 
123
 
 
124
                                        // "flushLen+1" ensures text is aligned correctly (or,
 
125
                                        // aligned the same as in getWidth()).
 
126
                                        nextX = x+fm.charsWidth(text, flushIndex,flushLen+1);
 
127
                                        int width = fm.charWidth(' ');
 
128
 
 
129
                                        // Paint background.
 
130
                                        if (bg!=null) {
 
131
                                                paintBackground(x,y, nextX-x,height, g,
 
132
                                                                                ascent, host, bg, !selected);
 
133
                                        }
 
134
                                        g.setColor(fg);
 
135
 
 
136
                                        // Paint chars before space.
 
137
                                        if (flushLen>0) {
 
138
                                                g.drawChars(text, flushIndex, flushLen, (int)x,(int)y);
 
139
                                                flushLen = 0;
 
140
                                        }
 
141
 
 
142
                                        // Paint a dot representing the space.
 
143
                                        int dotX = (int)(nextX - width/2f); // "2.0f" for FindBugs
 
144
                                        int dotY = (int)(y - ascent + height/2f); // Ditto
 
145
                                        g.drawLine(dotX, dotY, dotX, dotY);
 
146
                                        flushIndex = i + 1;
 
147
                                        x = nextX;
 
148
                                        break;
 
149
 
 
150
 
 
151
                                case '\f':
 
152
                                        // ???
 
153
                                        // fall-through for now.
 
154
 
 
155
                                default:
 
156
                                        flushLen += 1;
 
157
                                        break;
 
158
 
 
159
                        }
 
160
                }
 
161
 
 
162
                nextX = x+fm.charsWidth(text, flushIndex,flushLen);
 
163
 
 
164
                if (flushLen>0 && nextX>=clipStart) {
 
165
                        if (bg!=null) {
 
166
                                paintBackground(x,y, nextX-x,height, g,
 
167
                                                        ascent, host, bg, !selected);
 
168
                        }
 
169
                        g.setColor(fg);
 
170
                        g.drawChars(text, flushIndex, flushLen, (int)x,(int)y);
 
171
                }
 
172
 
 
173
                if (host.getUnderlineForToken(token)) {
 
174
                        g.setColor(fg);
 
175
                        int y2 = (int)(y+1);
 
176
                        g.drawLine(origX,y2, (int)nextX,y2);
 
177
                }
 
178
 
 
179
                // Don't check if it's whitespace - some TokenMakers may return types
 
180
                // other than Token.WHITESPACE for spaces (such as Token.IDENTIFIER).
 
181
                // This also allows us to paint tab lines for MLC's.
 
182
                if (host.getPaintTabLines() && origX==host.getMargin().left) {// && isWhitespace()) {
 
183
                        paintTabLines(token, origX, (int)y, (int)nextX, g, e, host);
 
184
                }
 
185
 
 
186
                return nextX;
 
187
 
 
188
        }
 
189
 
 
190
 
 
191
}
 
 
b'\\ No newline at end of file'