KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > DrawGraphics


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 NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.editor;
21
22 import java.awt.Graphics JavaDoc;
23 import java.awt.Font JavaDoc;
24 import java.awt.Color JavaDoc;
25 import java.awt.List JavaDoc;
26 import java.beans.PropertyChangeEvent JavaDoc;
27 import java.beans.PropertyChangeListener JavaDoc;
28 import javax.swing.text.JTextComponent JavaDoc;
29 import javax.swing.text.Position JavaDoc;
30 import org.netbeans.editor.Annotations;
31 import java.awt.Graphics2D JavaDoc;
32 import java.awt.AlphaComposite JavaDoc;
33 import java.awt.Composite JavaDoc;
34 import java.awt.Shape JavaDoc;
35 import java.awt.Rectangle JavaDoc;
36 import javax.swing.text.View JavaDoc;
37
38 /** Draw graphics functions as abstraction over various kinds of drawing. It's used
39 * for drawing into classic graphics, printing and measuring.
40 * Generally there are only the setters for some properties because
41 * the draw-engine doesn't retrieve the values that it previously
42 * set.
43 *
44 * @author Miloslav Metelka
45 * @version 1.00
46 */

47 interface DrawGraphics {
48     
49     /** Set foreground color */
50     public void setForeColor(Color JavaDoc foreColor);
51
52     /** Set background color */
53     public void setBackColor(Color JavaDoc backColor);
54
55     /** Inform the draw-graphics about the current
56     * background color of the component.
57     */

58     public void setDefaultBackColor(Color JavaDoc defaultBackColor);
59     
60     public void setStrikeThroughColor(Color JavaDoc strikeThroughColor);
61     
62     public void setUnderlineColor(Color JavaDoc underlineColor);
63     
64     public void setWaveUnderlineColor(Color JavaDoc waveUnderlineColor);
65
66     /** Set current font */
67     public void setFont(Font JavaDoc font);
68
69     /** Set the current x-coordinate */
70     public void setX(int x);
71
72     /** Set the current y-coordinate */
73     public void setY(int y);
74
75     /** Set the height of the line. */
76     public void setLineHeight(int lineHeight);
77
78     /** Set the ascent of the line. */
79     public void setLineAscent(int lineAscent);
80
81     /** Get the AWT-graphics to determine whether this draws to a graphics.
82     * This is useful for fast line numbering and others.
83     */

84     public Graphics JavaDoc getGraphics();
85
86     /** Whether draw graphics supports displaying of line numbers.
87     * If not line number displaying is not done.
88     */

89     public boolean supportsLineNumbers();
90
91     /** Initialize this draw graphics before drawing */
92     public void init(DrawContext ctx);
93
94     /** Called when whole drawing ends. Can be used to deallocate
95     * some resources etc.
96     */

97     public void finish();
98
99     /** Fill rectangle at the current [x, y] with the current
100     * background color.
101     * @param width width of the rectangle to fill in points. The current x-coordinate
102     * must be increased by width automatically.
103     */

104     public void fillRect(int width);
105
106     /** Draw characters from the specified offset in the buffer
107     * @param offset offset in the buffer for drawn text; if the text contains
108     * tabs, then offset is set to -1 and length contains the count
109     * of the space characters that correspond to the expanded tabs
110     * @param length length of the text being drawn
111     * @param width width of the text being drawn in points. The current
112     * x-coordinate must be increased by width automatically.
113     */

114     public void drawChars(int offset, int length, int width);
115
116     /** Draw the expanded tab characters.
117     * @param offset offset in the buffer where the tab characters start.
118     * @param length number of the tab characters
119     * @param spaceCount number of spaces that replace the tabs
120     * @param width width of the spaces in points. The current x-coordinate
121     * must be increased by width automatically.
122     */

123     public void drawTabs(int offset, int length, int spaceCount, int width);
124
125     /** Set character buffer from which the characters are drawn. */
126     public void setBuffer(char[] buffer);
127
128     /** This method is called to notify this draw graphics in response
129     * from targetPos parameter passed to draw().
130     * @param offset position that was reached during the drawing.
131     * @param ch character at offset
132     * @param charWidth visual width of the character ch
133     * @param ctx current draw context containing
134     * @return whether the drawing should continue or not. If it returns
135     * false it's guaranteed that this method will not be called again
136     * and the whole draw() method will be stopped. <BR>The only
137     * exception is when the -1 is used as the target offset
138     * when draw() is called which means that every offset
139     * is a potential target offset and must be checked.
140     * In this case the binary search is used when finding
141     * the target offset inside painted fragment. That greatly
142     * improves performance for long fragments because
143     * the font metrics measurements are relatively expensive.
144     */

145     public boolean targetOffsetReached(int offset, char ch, int x,
146                                        int charWidth, DrawContext ctx);
147
148     /** EOL encountered and should be handled. */
149     public void eol();
150     
151     /** Setter for painted view */
152     public void setView(javax.swing.text.View JavaDoc view);
153
154
155     /** Abstract draw-graphics that maintains a fg and bg color, font,
156     * current x and y coordinates.
157     */

158     static abstract class AbstractDG implements DrawGraphics {
159
160         /** Current foreground color */
161         Color JavaDoc foreColor;
162
163         /** Current background color */
164         Color JavaDoc backColor;
165
166         /** Default background color */
167         Color JavaDoc defaultBackColor;
168
169         /** Current font */
170         Font JavaDoc font;
171
172         /** Character buffer from which the data are drawn */
173         char[] buffer;
174
175         /** Current x-coordinate */
176         int x;
177
178         /** Current y-coordinate */
179         int y;
180
181         /** Height of the line being drawn */
182         int lineHeight;
183
184         /** Ascent of the line being drawn */
185         int lineAscent;
186
187         public Color JavaDoc getForeColor() {
188             return foreColor;
189         }
190
191         public void setForeColor(Color JavaDoc foreColor) {
192             this.foreColor = foreColor;
193         }
194
195         public Color JavaDoc getBackColor() {
196             return backColor;
197         }
198
199         public void setBackColor(Color JavaDoc backColor) {
200             this.backColor = backColor;
201         }
202
203         public Color JavaDoc getDefaultBackColor() {
204             return defaultBackColor;
205         }
206
207         public void setDefaultBackColor(Color JavaDoc defaultBackColor) {
208             this.defaultBackColor = defaultBackColor;
209         }
210
211         public Font JavaDoc getFont() {
212             return font;
213         }
214
215         public void setFont(Font JavaDoc font) {
216             this.font = font;
217         }
218
219         public int getX() {
220             return x;
221         }
222
223         public void setX(int x) {
224             this.x = x;
225         }
226
227         public int getY() {
228             return y;
229         }
230
231         public void setY(int y) {
232             this.y = y;
233         }
234
235         public int getLineHeight() {
236             return lineHeight;
237         }
238
239         public void setLineHeight(int lineHeight) {
240             this.lineHeight = lineHeight;
241         }
242
243         public int getLineAscent() {
244             return lineAscent;
245         }
246
247         public void setLineAscent(int lineAscent) {
248             this.lineAscent = lineAscent;
249         }
250
251         public char[] getBuffer() {
252             return buffer;
253         }
254
255         public void setBuffer(char[] buffer) {
256             this.buffer = buffer;
257         }
258
259         public void drawChars(int offset, int length, int width) {
260             x += width;
261         }
262
263         public void drawTabs(int offset, int length, int spaceCount, int width) {
264             x += width;
265         }
266
267         public void setStrikeThroughColor(Color JavaDoc strikeThroughColor) {
268         }
269         
270         public void setUnderlineColor(Color JavaDoc underlineColor) {
271         }
272         
273         public void setWaveUnderlineColor(Color JavaDoc waveUnderlineColor) {
274         }
275         
276         public void setView(javax.swing.text.View JavaDoc view) {
277         }
278         
279     }
280
281     static class SimpleDG extends AbstractDG {
282
283         public Graphics JavaDoc getGraphics() {
284             return null;
285         }
286
287         public boolean supportsLineNumbers() {
288             return false;
289         }
290
291         public void init(DrawContext ctx) {
292         }
293
294         public void finish() {
295         }
296
297         public void fillRect(int width) {
298         }
299
300         public boolean targetOffsetReached(int offset, char ch, int x,
301                                            int charWidth, DrawContext ctx) {
302             return true; // shouldn't reach this place
303
}
304
305         public void eol() {
306         }
307
308     }
309
310     /** Implementation of DrawGraphics to delegate to some Graphics.
311     * It optimizes the drawing by joining together the pieces of
312     * the text drawn with the same font and fg/bg color.
313     */

314     static final class GraphicsDG extends SimpleDG {
315
316         /** Whether debug messages should be displayed */
317         private static final boolean debug
318             = Boolean.getBoolean("netbeans.debug.editor.draw.graphics"); // NOI18N
319

320         private Graphics JavaDoc graphics;
321
322         /** Start of the chars that were not drawn yet. It can be -1
323         * to indicate the buffered characters were just flushed.
324         */

325         private int startOffset = -1;
326
327         /** End of the chars that were not drawn yet */
328         private int endOffset;
329
330         /** X coordinate where the drawing of chars should occur */
331         private int startX;
332
333         /** Y coordinate where the drawing of chars should occur */
334         private int startY;
335
336         private int width;
337
338         private Color JavaDoc strikeThroughColor;
339
340         private Color JavaDoc underlineColor;
341         
342         private Color JavaDoc waveUnderlineColor;
343         
344         /** Whether annotations were drawn on the current line already */
345         private int lastDrawnAnnosY;
346         private int lastDrawnAnnosX;
347         
348         /** Annotation description cached for the lastDrawnAnnosY */
349         private AnnotationDesc[] passiveAnnosAtY;
350
351         /** Alpha used for drawing the glyphs on the background */
352         private AlphaComposite JavaDoc alpha = null;
353
354         /** Access to annotations for this document which will be
355          * drawn on the background */

356         private Annotations annos = null;
357         
358         private boolean drawTextLimitLine;
359         private int textLimitWidth;
360         private int defaultSpaceWidth;
361         private Color JavaDoc textLimitLineColor;
362         private int absoluteX;
363         private int maxWidth;
364         private View JavaDoc view;
365
366         private int bufferStartOffset;
367         private int frameStartOffset = Integer.MAX_VALUE;
368         private int frameEndOffset = frameStartOffset;
369         private JTextComponent JavaDoc component;
370         private PropertyChangeListener JavaDoc componentListener;
371
372         GraphicsDG(Graphics JavaDoc graphics) {
373             this.graphics = graphics;
374             // #33165 - set invalid y initially
375
this.y = -1;
376         }
377
378         public void setForeColor(Color JavaDoc foreColor) {
379             if (!foreColor.equals(this.foreColor)) {
380                 flush();
381                 this.foreColor = foreColor;
382             }
383         }
384
385         public void setBackColor(Color JavaDoc backColor) {
386             if (!backColor.equals(this.backColor)) {
387                 flush();
388                 this.backColor = backColor;
389             }
390         }
391
392         public void setStrikeThroughColor(Color JavaDoc strikeThroughColor) {
393             if ((strikeThroughColor != this.strikeThroughColor)
394                 && (strikeThroughColor == null
395                     || !strikeThroughColor.equals(this.strikeThroughColor))
396             ) {
397                 flush();
398                 this.strikeThroughColor = strikeThroughColor;
399             }
400         }
401
402         public void setUnderlineColor(Color JavaDoc underlineColor) {
403             if ((underlineColor != this.underlineColor)
404                 && (underlineColor == null
405                     || !underlineColor.equals(this.underlineColor))
406             ) {
407                 flush();
408                 this.underlineColor = underlineColor;
409             }
410         }
411
412         public void setWaveUnderlineColor(Color JavaDoc waveUnderlineColor) {
413             if ((waveUnderlineColor != this.waveUnderlineColor)
414                 && (waveUnderlineColor == null
415                     || !waveUnderlineColor.equals(this.waveUnderlineColor))
416             ) {
417                 flush();
418                 this.waveUnderlineColor = waveUnderlineColor;
419             }
420         }
421
422         public void setFont(Font JavaDoc font) {
423             if (!font.equals(this.font)) {
424                 flush();
425                 this.font = font;
426             }
427         }
428
429         public void setX(int x) {
430             if (x != this.x) {
431                 flush();
432                 this.x = x;
433             }
434         }
435
436         public void setY(int y) {
437             if (y != this.y) {
438                 flush();
439                 this.y = y;
440             }
441         }
442
443         public void init(DrawContext ctx) {
444             component = ctx.getEditorUI().getComponent();
445             // initialize reference to annotations
446
annos = ctx.getEditorUI().getDocument().getAnnotations();
447             drawTextLimitLine = ctx.getEditorUI().textLimitLineVisible;
448             textLimitWidth = ctx.getEditorUI().textLimitWidth;
449             defaultSpaceWidth = ctx.getEditorUI().defaultSpaceWidth;
450             textLimitLineColor = ctx.getEditorUI().textLimitLineColor;
451             absoluteX = ctx.getEditorUI().getTextMargin().left;
452             maxWidth = ctx.getEditorUI().getExtentBounds().width;
453             
454             componentListener = new PropertyChangeListener JavaDoc() {
455                 public void propertyChange(PropertyChangeEvent JavaDoc evt) {
456                     if (DrawLayer.TEXT_FRAME_START_POSITION_COMPONENT_PROPERTY.equals(evt.getPropertyName())) {
457                         if (evt.getNewValue() instanceof Position JavaDoc) {
458                             frameStartOffset = ((Position JavaDoc)evt.getNewValue()).getOffset();
459                         } else {
460                             frameStartOffset = Integer.MAX_VALUE;
461                         }
462                     }
463                     if (DrawLayer.TEXT_FRAME_END_POSITION_COMPONENT_PROPERTY.equals(evt.getPropertyName())) {
464                         if (evt.getNewValue() instanceof Position JavaDoc) {
465                             frameEndOffset = ((Position JavaDoc)evt.getNewValue()).getOffset();
466                         } else {
467                             frameEndOffset = Integer.MAX_VALUE;
468                         }
469                     }
470                 }
471             };
472             component.addPropertyChangeListener(componentListener);
473         }
474
475         public void finish() {
476             // flush() already performed in setBuffer(null) and might cause problems here
477
// as this code is typically called from finally clause.
478
//flush();
479
if (component != null) {
480                 component.removePropertyChangeListener(componentListener);
481             }
482         }
483         
484         public void setView(View JavaDoc view){
485             this.view = view;
486         }
487
488         private void flush() {
489             flush(false);
490         }
491
492
493         private void flush(boolean atEOL) {
494             if (y < 0) { // not yet initialized
495
return ;
496             }
497             
498             if (startOffset >= 0 && startOffset != endOffset) { // some text on the line
499
// First possibly fill the rectangle
500
fillRectImpl(startX, startY, x - startX);
501             }
502             
503             // #33165 - for each fragment getPasiveAnnotations() was called
504
// but it can done just once per line.
505
if (lastDrawnAnnosY != y) {
506                 lastDrawnAnnosY = y;
507                 lastDrawnAnnosX = 0;
508                 if (AnnotationTypes.getTypes().isBackgroundDrawing().booleanValue()) {
509                     if (alpha == null)
510                         alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, AnnotationTypes.getTypes().getBackgroundGlyphAlpha().intValue() / 100f);
511                     if (view!=null){
512                         passiveAnnosAtY = annos.getPassiveAnnotations(view.getStartOffset());
513                     }
514                 } else {
515                     passiveAnnosAtY = null;
516                 }
517             }
518             
519             int glyphX=2;
520             if (passiveAnnosAtY != null) {
521                 Graphics2D JavaDoc g2d = (Graphics2D JavaDoc) graphics;
522
523                 Shape JavaDoc shape = graphics.getClip();
524
525                 // set alpha composite
526
Composite JavaDoc origin = g2d.getComposite();
527                 g2d.setComposite(alpha);
528
529                 // clip the drawing area
530
int endX = atEOL ? Integer.MAX_VALUE : x;
531                 int startX = Math.min(lastDrawnAnnosX, this.startX);
532                 Rectangle JavaDoc r = new Rectangle JavaDoc(startX, y, endX - startX, lineHeight);
533                 lastDrawnAnnosX = endX;
534                 r = r.intersection(shape.getBounds());
535                 graphics.setClip(r);
536
537                 for (int i=0; i < passiveAnnosAtY.length; i++) {
538                     g2d.drawImage(passiveAnnosAtY[i].getGlyph(), glyphX, y, null);
539                     glyphX += passiveAnnosAtY[i].getGlyph().getWidth(null)+1;
540                 }
541
542                 // restore original clip region
543
graphics.setClip(shape);
544
545                 // restore original ocmposite
546
g2d.setComposite(origin);
547             }
548
549             // If no text on the line then return + handle incorrect conditions
550
if (startOffset < 0 || startOffset >= endOffset || endOffset > buffer.length) {
551                 startOffset = -1;
552                 return;
553             }
554
555             
556             if (drawTextLimitLine) { // draw limit line
557
Rectangle JavaDoc clip = graphics.getClipBounds();
558                 int lineX = absoluteX + textLimitWidth * defaultSpaceWidth;
559                 if (lineX >= startX && lineX <= x){
560                     Color JavaDoc bakColor = graphics.getColor();
561                     graphics.setColor(textLimitLineColor);
562                     graphics.drawLine(lineX, startY, lineX, startY + lineHeight);
563                     graphics.setColor(bakColor);
564                 }
565             }
566
567             // Text framing support
568
if (frameStartOffset != Integer.MAX_VALUE && bufferStartOffset != -1) {
569                 if (bufferStartOffset + startOffset == frameStartOffset) { // draw vertical line
570
graphics.drawLine(startX, startY, startX, startY + lineHeight);
571                 }
572                 if (bufferStartOffset + startOffset >= frameStartOffset
573                         && bufferStartOffset + endOffset <= frameEndOffset
574                 ) {
575                     graphics.drawLine(startX, startY, x, startY);
576                     graphics.drawLine(startX, startY, x, startY + lineHeight);
577                 }
578                 if (bufferStartOffset + endOffset == frameEndOffset) { // draw vertical line
579
graphics.drawLine(x, startY, x, startY + lineHeight);
580                 }
581             }
582             
583             // Check whether the graphics uses right color
584
graphics.setColor(foreColor);
585             // Check whether the graphics uses right font
586
graphics.setFont(font);
587
588             if (debug) {
589                 String JavaDoc text = new String JavaDoc(buffer, startOffset, endOffset - startOffset);
590                 System.out.println("DrawGraphics: text='" + text // NOI18N
591
+ "', text.length=" + text.length() // NOI18N
592
+ ", x=" + startX + ", y=" + startY // NOI18N
593
+ ", ascent=" + lineAscent // NOI18N
594
+ ", clip=" + graphics.getClipBounds() // NOI18N
595
+ ", color=" + graphics.getColor() // NOI18N
596
);
597             }
598
599             graphics.drawChars(buffer, startOffset, endOffset - startOffset,
600                                startX, startY + lineAscent);
601
602             if (strikeThroughColor != null) { // draw strike-through
603
FontMetricsCache.Info fmcInfo = FontMetricsCache.getInfo(font);
604                 graphics.setColor(strikeThroughColor);
605                 graphics.fillRect(startX,
606                                   (int)(startY + fmcInfo.getStrikethroughOffset(graphics) + lineAscent + 1.5),
607                                   x - startX,
608                                   (int)(fmcInfo.getStrikethroughThickness(graphics) + 0.5)
609                                  );
610             }
611
612             if (waveUnderlineColor != null) { // draw wave underline
613
FontMetricsCache.Info fmcInfo = FontMetricsCache.getInfo(font);
614                 graphics.setColor(waveUnderlineColor);
615
616                 int waveLength = x - startX;
617                 if (waveLength > 0) {
618                     int[] wf = {0, +1, 0, -1};
619                     int[] xArray = new int[waveLength + 1];
620                     int[] yArray = new int[waveLength + 1];
621                     
622                     int yBase = (int)(startY + fmcInfo.getUnderlineOffset(graphics) + lineAscent + 1.5);
623                     for (int i=0;i<=waveLength;i++) {
624                         xArray[i]=startX + i;
625                         yArray[i]=yBase + wf[xArray[i] % 4];
626                     }
627                     graphics.drawPolyline(xArray, yArray, waveLength);
628                 }
629             }
630
631             if (underlineColor != null) { // draw underline
632
FontMetricsCache.Info fmcInfo = FontMetricsCache.getInfo(font);
633                 graphics.setColor(underlineColor);
634                 graphics.fillRect(startX,
635                                   (int)(startY + fmcInfo.getUnderlineOffset(graphics) + lineAscent + 1.5),
636                                   x - startX,
637                                   (int) (fmcInfo.getUnderlineThickness(graphics) + 0.5)
638                                  );
639             }
640
641             startOffset = -1; // signal no characters to draw
642
}
643
644         public Graphics JavaDoc getGraphics() {
645             return graphics;
646         }
647
648         public boolean supportsLineNumbers() {
649             return true;
650         }
651
652         public void fillRect(int width) {
653             fillRectImpl(x, y, width);
654             x += width;
655         }
656
657         private void fillRectImpl(int rx, int ry, int width) {
658             if (width > 0) { // only for non-zero width
659
// only fill for different color than current background
660
if (!backColor.equals(defaultBackColor)) {
661                     graphics.setColor(backColor);
662                     graphics.fillRect(rx, ry, width, lineHeight);
663                 }
664
665             }
666         }
667
668
669         public void drawChars(int offset, int length, int width) {
670             if (length >= 0) {
671                 if (startOffset < 0) { // no token yet
672
startOffset = offset;
673                     endOffset = offset + length;
674                     this.startX = x;
675                     this.startY = y;
676                     this.width = width;
677
678                 } else { // already token before
679
endOffset += length;
680                 }
681             }
682
683             x += width;
684         }
685
686         public void drawTabs(int offset, int length, int spaceCount, int width) {
687             if (width > 0) {
688                 flush();
689                 fillRectImpl(x, y, width);
690                 x += width;
691             }
692         }
693
694         public void setBuffer(char[] buffer) {
695             flush();
696             this.buffer = buffer;
697             startOffset = -1;
698             bufferStartOffset = -1;
699         }
700         
701         void setBufferStartOffset(int bufferStartOffset) {
702             this.bufferStartOffset = bufferStartOffset;
703         }
704
705         public void eol() {
706             if (drawTextLimitLine) { // draw limit line
707
int lineX = absoluteX + textLimitWidth * defaultSpaceWidth;
708                 if (lineX >= x-defaultSpaceWidth){
709                     Color JavaDoc bakColor = graphics.getColor();
710                     graphics.setColor(textLimitLineColor);
711                     Rectangle JavaDoc clipB = graphics.getClipBounds();
712                     if (clipB.width + clipB.x <= lineX){
713                         graphics.setClip(clipB.x, clipB.y, maxWidth, clipB.height);
714                         graphics.drawLine(lineX, y, lineX, y + lineHeight);
715                         graphics.setClip(clipB.x, clipB.y, clipB.width, clipB.height);
716                     }else{
717                         graphics.drawLine(lineX, y, lineX, y + lineHeight);
718                     }
719                     graphics.setColor(bakColor);
720                 }
721             }
722             flush(true);
723         }
724
725     }
726
727     static final class PrintDG extends SimpleDG {
728
729         PrintContainer container;
730
731         /** Whether there were some paints already on the line */
732         boolean lineInited;
733
734         /** Construct the new print graphics
735         * @param container print container to which the tokens
736         * are added.
737         */

738         public PrintDG(PrintContainer container) {
739             this.container = container;
740         }
741
742         public boolean supportsLineNumbers() {
743             return true;
744         }
745
746         public void drawChars(int offset, int length, int width) {
747             if (length > 0) {
748                 lineInited = true; // Fixed 42536
749
char[] chars = new char[length];
750                 System.arraycopy(buffer, offset, chars, 0, length);
751                 container.add(chars, font, foreColor, backColor);
752             }
753         }
754
755         private void printSpaces(int spaceCount) {
756             char[] chars = new char[spaceCount];
757             System.arraycopy(Analyzer.getSpacesBuffer(spaceCount), 0, chars, 0, spaceCount);
758             container.add(chars, font, foreColor, backColor);
759         }
760
761         public void drawTabs(int offset, int length, int spaceCount, int width) {
762             lineInited = true; // Fixed 42536
763
printSpaces(spaceCount);
764         }
765
766         public void eol() {
767             if (!lineInited && container.initEmptyLines()) {
768                 printSpaces(1);
769             }
770             container.eol();
771             lineInited = false; // signal that the next line is not inited yet
772
}
773
774     }
775
776 }
777
Popular Tags