KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > terminalemulator > Line


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is Terminal Emulator.
16  * The Initial Developer of the Original Software is Sun Microsystems, Inc..
17  * Portions created by Sun Microsystems, Inc. are Copyright (C) 2001.
18  * All Rights Reserved.
19  *
20  * Contributor(s): Ivan Soleimanipour.
21  */

22
23 /*
24  * "Line.java"
25  * Line.java 1.12 01/07/24
26  */

27
28 package org.netbeans.lib.terminalemulator;
29
30 class Line {
31     public int glyph_glyph;
32     public int glyph_rendition; // Background color for the whole line
33
// This is independent of per-character
34
// rendition.
35

36     private char buf[]; // actual characters
37
private int attr[]; // attributes (allocated on demand)
38

39     // SHOULD use shorts?
40
private int capacity; // == buf.length == attr.length
41
private int length; // how much of buf and attr is filled
42

43
44     public Line() {
45     reset();
46     }
47
48     public void reset() {
49     length = 0;
50     capacity = 32;
51     buf = new char[capacity];
52     attr = null;
53     glyph_glyph = 0;
54     glyph_rendition = 0;
55     wrapped = false;
56     about_to_wrap = false;
57     }
58
59
60     public int capacity() {
61     return capacity;
62     }
63
64     /**
65      * Number of characters in the line.
66      * charArray()[length()] is where the cursor or newline would be.
67      *
68      */

69     public int length() {
70     return length;
71     }
72
73     public boolean hasAttributes() {
74     return attr != null;
75     }
76
77     public void setWrapped(boolean wrapped) {
78     this.wrapped = wrapped;
79     }
80     public boolean isWrapped() {
81     return wrapped;
82     }
83     // SHOULD collapse wrapped with about_to_wrap into a bitfield
84
private boolean wrapped;
85
86
87
88     public boolean setAboutToWrap(boolean about_to_wrap) {
89     boolean old_about_to_wrap = about_to_wrap;
90     this.about_to_wrap = about_to_wrap;
91     return old_about_to_wrap;
92     }
93     public boolean isAboutToWrap() {
94     return about_to_wrap;
95     }
96     // Perhaps SHOULD have a state: normal, about-to-wrap, wrapped.
97
private boolean about_to_wrap;
98
99
100     /**
101      * Return true if we've already seen attributes for this line
102      * or 'a' is the first one, in which case we allocate the 'attr' array.
103      */

104     private boolean haveAttributes(int a) {
105     if (attr == null && a != 0) {
106         attr = new int[capacity];
107     }
108     return attr != null;
109     }
110
111
112     public char [] charArray() {
113     return buf;
114     }
115
116     public int [] attrArray() {
117     return attr;
118     }
119
120
121     public byte width(MyFontMetrics metrics, int at) {
122     if (at >= capacity)
123         return 1;
124     return (byte) metrics.wcwidth(buf[at]);
125     }
126
127     /*
128      * Convert a cell column to a buffer column.
129      */

130     public int cellToBuf(MyFontMetrics metrics, int target_col) {
131     if (metrics.isMultiCell()) {
132         int bc = 0;
133         int vc = 0;
134         for(;;) {
135         int w = width(metrics, bc);
136         if (vc + w - 1 >= target_col)
137             break;
138         vc += w;
139         bc++;
140         }
141         return bc;
142     } else {
143         return target_col;
144     }
145     }
146
147     /*
148      * Convert a buffer column to a cell column.
149      */

150     public int bufToCell(MyFontMetrics metrics, int target_col) {
151     if (metrics.isMultiCell()) {
152         int vc = 0;
153         for (int bc = 0; bc < target_col; bc++) {
154         vc += width(metrics, bc);
155         }
156         return vc;
157     } else {
158         return target_col;
159     }
160     }
161
162
163
164     public StringBuffer JavaDoc stringBuffer() {
165     // only used for word finding
166
// Grrr, why don't we have: new StringBuffer(buf, 0, length);
167
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(length);
168     return sb.append(buf, 0, length);
169     }
170
171     /*
172      * Ensure that we have at least 'min_capacity'.
173      */

174     private void ensureCapacity(Term term, int min_capacity) {
175
176     term.noteColumn(this, min_capacity);
177
178     if (min_capacity <= capacity)
179         return; // nothing to do
180

181     // doubling
182
int new_capacity = (length+1) * 2;
183     if (new_capacity < 0)
184         new_capacity = Integer.MAX_VALUE;
185     else if (min_capacity > new_capacity)
186         new_capacity = min_capacity;
187
188
189     char new_buf[] = new char[new_capacity];
190     System.arraycopy(buf, 0, new_buf, 0, length);
191     buf = new_buf;
192
193     if (attr != null) {
194         int new_attr[] = new int[new_capacity];
195         System.arraycopy(attr, 0, new_attr, 0, length);
196         attr = new_attr;
197     }
198
199     capacity = new_capacity;
200     }
201
202     /**
203      * Insert character and attribute at 'column' and shift everything
204      * past 'column' right.
205      */

206     public void insertCharAt(Term term, char c, int column, int a) {
207     int new_length = length + 1;
208
209     if (column >= length) {
210         new_length = column+1;
211         ensureCapacity(term, new_length);
212         // fill any newly opened gap (between length and column) with SP
213
for (int fx = length; fx < column; fx++)
214         buf[fx] = ' ';
215     } else {
216         ensureCapacity(term, new_length);
217         System.arraycopy(buf, column, buf, column + 1, length - column);
218         if (haveAttributes(a))
219         System.arraycopy(attr, column, attr, column + 1, length - column);
220     }
221
222     term.checkForMultiCell(c);
223
224     buf[column] = c;
225     if (haveAttributes(a))
226         attr[column] = a;
227
228     length = new_length;
229     }
230
231     /*
232      * Generic addition and modification.
233      * Line will grow to accomodate column.
234      */

235     public void setCharAt(Term term, char c, int column, int a) {
236     if (column >= length) {
237         ensureCapacity(term, column+1);
238         // fill any newly opened gap (between length and column) with SP
239
for (int fx = length; fx < column; fx++)
240         buf[fx] = ' ';
241         length = column+1;
242     }
243     term.checkForMultiCell(c);
244     buf[column] = c;
245     if (haveAttributes(a)) {
246         attr[column] = a;
247     }
248     }
249
250     public void deleteCharAt(int column) {
251     if (column < 0 || column >= length)
252         return;
253     System.arraycopy(buf, column+1, buf, column, length-column-1);
254     buf[length-1] = 0;
255     if (attr != null) {
256         System.arraycopy(attr, column+1, attr, column, length-column-1);
257         attr[length-1] = 0;
258     }
259     // SHOULD move this up
260
length--;
261     }
262
263     public void clearToEndFrom(Term term, int col) {
264     ensureCapacity(term, col+1);
265
266     // Grrr, why is there a System.arrayCopy() but no System.arrayClear()?
267
for (int cx = col; cx < length; cx++)
268         buf[cx] = ' ';
269     if (attr != null) {
270         for (int cx = col; cx < length; cx++)
271         attr[cx] = ' ';
272     }
273     length = col;
274     }
275
276
277
278     /*
279      * Used for selections
280      * If the ecol is past the actual line length a "\n" is appended.
281      */

282     public String JavaDoc text(int bcol, int ecol) {
283     /* DEBUG
284     System.out.println("Line.text(bcol " + bcol + " ecol " + ecol + ")"); // NOI18N
285     System.out.println("\tlength " + length); // NOI18N
286     */

287
288
289     String JavaDoc newline = ""; // NOI18N
290

291     // This only happens for 'empty' lines below the cursor.
292
// Actually it also happens for 'empty' lines in the middle.
293
// See issue 31951 for example.
294
// So in order to get newlines in selected text we will also get
295
// newlines from the 'empty' lines below the cursor.
296
// This is in fact what xterm does.
297
// DtTerm doesn't allow selection of the 'empty' lines below the
298
// cursor, but that is issue 21577 and is not easy to solve.
299

300     if (length == 0)
301         return "\n";
302
303     if (ecol >= length) {
304         // The -1 snuffs out the newline.
305
ecol = length-1;
306         newline = "\n"; // NOI18N
307

308         if (bcol >= length)
309         bcol = length-1;
310     }
311     return new String JavaDoc(buf, bcol, ecol-bcol+1) + newline;
312     }
313
314     public void setCharacterAttribute(int bcol, int ecol,
315                       int value, boolean on) {
316     // HACK: value is the ANSI code, haveAttributes takes out own
317
// compact encoding, but it only checks for 0 so it's OK.
318
if (!haveAttributes(value))
319         return;
320
321     if (on) {
322         for (int c = bcol; c <= ecol; c++)
323         attr[c] = Attr.setAttribute(attr[c], value);
324     } else {
325         for (int c = bcol; c <= ecol; c++)
326         attr[c] = Attr.unsetAttribute(attr[c], value);
327     }
328     }
329 }
330
Popular Tags