KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > custom > DisplayRenderer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.custom;
12
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.graphics.*;
15
16 /**
17  * A DisplayRenderer renders the content of a StyledText widget on
18  * a display device.
19  */

20 class DisplayRenderer extends StyledTextRenderer {
21     private StyledText parent; // used to get content and styles during rendering
22
private int topIndex = -1;
23     private TextLayout[] layouts;
24     
25 /**
26  * Creates an instance of <class>DisplayRenderer</class>.
27  * </p>
28  * @param device Device to render on
29  * @param regularFont Font to use for regular text
30  * @param parent <class>StyledText</class> widget to render
31  * @param tabLength length in characters of a tab character
32  */

33 DisplayRenderer(Device device, Font regularFont, StyledText parent, int tabLength) {
34     super(device, regularFont);
35     this.parent = parent;
36     calculateLineHeight();
37     setTabLength(tabLength);
38 }
39 void dispose() {
40     super.dispose();
41     if (layouts != null) {
42         for (int i = 0; i < layouts.length; i++) {
43             TextLayout layout = layouts[i];
44             if (layout != null) super.disposeTextLayout(layout);
45         }
46         topIndex = -1;
47         layouts = null;
48     }
49 }
50 /**
51  * Dispose the specified GC.
52  * </p>
53  * @param gc GC to dispose.
54  */

55 protected void disposeGC(GC gc) {
56     gc.dispose();
57 }
58 /**
59  * Draws the line delimiter selection if the selection extends beyond the given line.
60  * </p>
61  *
62  * @param line the line to draw
63  * @param lineOffset offset of the first character in the line.
64  * Relative to the start of the document.
65  * @param paintX x location to draw at
66  * @param paintY y location to draw at
67  * @param gc GC to draw on
68  */

69 protected void drawLineBreakSelection(String JavaDoc line, int lineOffset, int paintX, int paintY, GC gc) {
70     Point selection = parent.internalGetSelection();
71     int lineLength = line.length();
72     int selectionStart = Math.max(0, selection.x - lineOffset);
73     int selectionEnd = selection.y - lineOffset;
74     int lineEndSpaceWidth = getLineEndSpaceWidth();
75     int lineHeight = getLineHeight();
76     
77     if (selectionEnd == selectionStart || selectionEnd < 0 || selectionStart > lineLength || selectionEnd <= lineLength) {
78         return;
79     }
80     
81     gc.setBackground(parent.getSelectionBackground());
82     gc.setForeground(parent.getSelectionForeground());
83     if ((parent.getStyle() & SWT.FULL_SELECTION) != 0) {
84         Rectangle rect = getClientArea();
85         gc.fillRectangle(paintX, paintY, rect.width - paintX, lineHeight);
86     } else {
87         boolean isWrappedLine = false;
88         if (parent.internalGetWordWrap()) {
89             StyledTextContent content = getContent();
90             int lineEnd = lineOffset + lineLength;
91             int lineIndex = content.getLineAtOffset(lineEnd);
92
93             // is the start offset of the next line the same as the end
94
// offset of this line?
95
if (lineIndex < content.getLineCount() - 1 &&
96                 content.getOffsetAtLine(lineIndex + 1) == lineEnd) {
97                 isWrappedLine = true;
98             }
99         }
100         if (isWrappedLine == false) {
101             // render the line break selection
102
gc.fillRectangle(paintX, paintY, lineEndSpaceWidth, lineHeight);
103         }
104     }
105 }
106 /**
107  * Returns the text segments that should be treated as if they
108  * had a different direction than the surrounding text.
109  * </p>
110  *
111  * @param lineOffset offset of the first character in the line.
112  * 0 based from the beginning of the document.
113  * @param lineText text of the line to specify bidi segments for
114  * @return text segments that should be treated as if they had a
115  * different direction than the surrounding text. Only the start
116  * index of a segment is specified, relative to the start of the
117  * line. Always starts with 0 and ends with the line length.
118  * @exception IllegalArgumentException <ul>
119  * <li>ERROR_INVALID_ARGUMENT - if the segment indices returned
120  * by the listener do not start with 0, are not in ascending order,
121  * exceed the line length or have duplicates</li>
122  * </ul>
123  */

124 protected int[] getBidiSegments(int lineOffset, String JavaDoc lineText) {
125     if (!parent.isBidi()) return null;
126     return parent.getBidiSegments(lineOffset, lineText);
127 }
128 /**
129  * Returns the visible client area that can be used for rendering.
130  * </p>
131  * @return the visible client area that can be used for rendering.
132  */

133 protected Rectangle getClientArea() {
134     return parent.getClientArea();
135 }
136 /**
137  * Returns the <class>StyledTextContent</class> to use for line offset
138  * calculations.
139  * </p>
140  * @return the <class>StyledTextContent</class> to use for line offset
141  * calculations.
142  */

143 protected StyledTextContent getContent() {
144     return parent.internalGetContent();
145 }
146 /**
147  * Returns a new GC to use for rendering and measuring.
148  * When the GC is no longer used it needs to be disposed by
149  * calling disposeGC.
150  * </p>
151  * @return the GC to use for rendering and measuring.
152  * @see #disposeGC
153  */

154 protected GC getGC() {
155     return new GC(parent);
156 }
157 /**
158  * Returns the horizontal scroll position.
159  * </p>
160  * @return the horizontal scroll position.
161  */

162 protected int getHorizontalPixel() {
163     return parent.internalGetHorizontalPixel();
164 }
165 protected int getLeftMargin() {
166     return parent.leftMargin;
167 }
168 /**
169  * @see StyledTextRenderer#getLineBackgroundData
170  */

171 protected StyledTextEvent getLineBackgroundData(int lineOffset, String JavaDoc line) {
172     return parent.getLineBackgroundData(lineOffset, line);
173 }
174 /**
175  * @see StyledTextRenderer#getLineStyleData
176  */

177 protected StyledTextEvent getLineStyleData(int lineOffset, String JavaDoc line) {
178     StyledTextEvent logicalLineEvent = parent.getLineStyleData(lineOffset, line);
179     if (logicalLineEvent != null) {
180         logicalLineEvent = getLineStyleData(logicalLineEvent, lineOffset, line);
181     }
182     return logicalLineEvent;
183 }
184 protected int getOrientation () {
185     return parent.getOrientation();
186 }
187 protected int getRightMargin() {
188     return parent.rightMargin;
189 }
190 protected Color getSelectionBackground() {
191     return parent.getSelectionBackground();
192 }
193 protected Color getSelectionForeground() {
194     return parent.getSelectionForeground();
195 }
196 /**
197  * @see StyledTextRenderer#getSelection
198  */

199 protected Point getSelection() {
200     return parent.internalGetSelection();
201 }
202 /**
203  * @see StyledTextRenderer#getWordWrap
204  */

205 protected boolean getWordWrap() {
206     return parent.getWordWrap();
207 }
208 /**
209  * @see StyledTextRenderer#isFullLineSelection
210  */

211 protected boolean isFullLineSelection() {
212     return (parent.getStyle() & SWT.FULL_SELECTION) != 0;
213 }
214 TextLayout createTextLayout(int lineOffset) {
215     if (!parent.internalGetWordWrap()) {
216         int lineIndex = getContent().getLineAtOffset(lineOffset);
217         updateTopIndex();
218         if (layouts != null) {
219             int layoutIndex = lineIndex - topIndex;
220             if (0 <= layoutIndex && layoutIndex < layouts.length) {
221                 TextLayout layout = layouts[layoutIndex];
222                 if (layout != null) return layout;
223                 return layouts[layoutIndex] = super.createTextLayout(lineIndex);
224             }
225         }
226     }
227     return super.createTextLayout(lineOffset);
228 }
229 void disposeTextLayout (TextLayout layout) {
230     if (layouts != null) {
231         for (int i=0; i<layouts.length; i++) {
232             if (layouts[i] == layout) return;
233         }
234     }
235     super.disposeTextLayout(layout);
236 }
237 void updateTopIndex() {
238     int verticalIncrement = parent.getVerticalIncrement();
239     int topIndex = verticalIncrement == 0 ? 0 : parent.verticalScrollOffset / verticalIncrement;
240     int newLength = Math.max(1 , parent.getPartialBottomIndex() - topIndex + 1);
241     if (layouts == null || topIndex != this.topIndex || newLength != layouts.length) {
242         TextLayout[] newLayouts = new TextLayout[newLength];
243         if (layouts != null) {
244             for(int i=0; i<layouts.length; i++) {
245                 TextLayout layout = layouts[i];
246                 if (layout != null) {
247                     int layoutIndex = (i + this.topIndex) - topIndex;
248                     if (0 <= layoutIndex && layoutIndex < newLayouts.length) {
249                         newLayouts[layoutIndex] = layout;
250                     } else {
251                         super.disposeTextLayout(layout);
252                     }
253                 }
254             }
255         }
256         this.topIndex = topIndex;
257         layouts = newLayouts;
258     }
259 }
260 }
261
Popular Tags