KickJava   Java API By Example, From Geeks To Geeks.

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


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  
14 import java.util.Hashtable JavaDoc;
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.graphics.*;
18
19 /**
20  * A PrintRenderer renders the content of a StyledText widget on
21  * a printer device.
22  * Print rendering may occur in a non-UI thread. Therefore all
23  * requests for styles, content and any other information normally
24  * stored in the StyledText widget are served from cached data.
25  * Caching also guarantees immutable data for threaded printing.
26  */

27 class PrintRenderer extends StyledTextRenderer {
28     StyledTextContent logicalContent; // logical, unwrapped, content
29
WrappedContent content; // wrapped content
30
Rectangle clientArea; // printer client area
31
GC gc; // printer GC, there can be only one GC for each printer device
32
Hashtable JavaDoc lineBackgrounds; // line background colors used during rendering
33
Hashtable JavaDoc lineStyles; // line styles colors used during rendering
34
Hashtable JavaDoc bidiSegments; // bidi segments used during rendering on bidi platforms
35

36 /**
37  * Creates an instance of <class>PrintRenderer</class>.
38  * </p>
39  * @param device Device to render on
40  * @param regularFont Font to use for regular text.
41  * @param gc printer GC to use for rendering. There can be only one GC for
42  * each printer device at any given time.
43  * @param logicalContent StyledTextContent to print.
44  * @param lineBackgrounds line background colors to use during rendering.
45  * @param lineStyles line styles colors to use during rendering.
46  * @param bidiSegments bidi segments to use during rendering on bidi platforms.
47  * @param leftMargin margin to the left of the text.
48  * @param tabLength length in characters of a tab character
49  * @param clientArea the printer client area.
50  */

51 PrintRenderer(
52         Device device, Font regularFont, GC gc,
53         StyledTextContent logicalContent, Hashtable JavaDoc lineBackgrounds,
54         Hashtable JavaDoc lineStyles, Hashtable JavaDoc bidiSegments,
55         int tabLength, Rectangle clientArea) {
56     super(device, regularFont);
57     this.logicalContent = logicalContent;
58     this.lineBackgrounds = lineBackgrounds;
59     this.lineStyles = lineStyles;
60     this.bidiSegments = bidiSegments;
61     this.clientArea = clientArea;
62     this.gc = gc;
63     calculateLineHeight();
64     setTabLength(tabLength);
65     content = new WrappedContent(this, logicalContent);
66     // wrapLines requires tab width to be known
67
content.wrapLines();
68 }
69 /**
70  * Disposes the resource created by the receiver.
71  */

72 protected void dispose() {
73     content = null;
74     super.dispose();
75 }
76 /**
77  * Do nothing. PrintRenderer does not create GCs.
78  * @see StyledTextRenderer#disposeGC
79  */

80 protected void disposeGC(GC gc) {
81 }
82 /**
83  * Do not print the selection.
84  * @see StyledTextRenderer#drawLineSelectionBackground
85  */

86 protected void drawLineBreakSelection(String JavaDoc line, int lineOffset, int paintX, int paintY, GC gc) {
87 }
88 /**
89  * Returns from cache the text segments that should be treated as
90  * if they had a different direction than the surrounding text.
91  * <p>
92  * Use cached data.
93  * </p>
94  *
95  * @param lineOffset offset of the first character in the line.
96  * 0 based from the beginning of the document.
97  * @param line text of the line to specify bidi segments for
98  * @return text segments that should be treated as if they had a
99  * different direction than the surrounding text. Only the start
100  * index of a segment is specified, relative to the start of the
101  * line. Always starts with 0 and ends with the line length.
102  * @exception IllegalArgumentException <ul>
103  * <li>ERROR_INVALID_ARGUMENT - if the segment indices returned
104  * by the listener do not start with 0, are not in ascending order,
105  * exceed the line length or have duplicates</li>
106  * </ul>
107  */

108 protected int[] getBidiSegments(int lineOffset, String JavaDoc lineText) {
109     int lineLength = lineText.length();
110     int logicalLineOffset = getLogicalLineOffset(lineOffset);
111     int[] segments = (int []) bidiSegments.get(new Integer JavaDoc(logicalLineOffset));
112     
113     if (segments == null) {
114         segments = new int[] {0, lineLength};
115     }
116     else {
117         // cached bidi segments are for logical lines.
118
// make sure that returned segments match requested line since
119
// line wrapping may require either entire or part of logical
120
// line bidi segments
121
int logicalLineIndex = logicalContent.getLineAtOffset(lineOffset);
122         int logicalLineLength = logicalContent.getLine(logicalLineIndex).length();
123         
124         if (lineOffset != logicalLineOffset || lineLength != logicalLineLength) {
125             int lineOffsetDelta = lineOffset - logicalLineOffset;
126             int newSegmentCount = 0;
127             int[] newSegments = new int[segments.length];
128             
129             for (int i = 0; i < segments.length; i++) {
130                 newSegments[i] = Math.max(0, segments[i] - lineOffsetDelta);
131                 if (newSegments[i] > lineLength) {
132                     newSegments[i] = lineLength;
133                     newSegmentCount++;
134                     break;
135                 }
136                 if (i == 0 || newSegments[i] > 0) {
137                     newSegmentCount++;
138                 }
139             }
140             segments = new int[newSegmentCount];
141             for (int i = 0, newIndex = 0; i < newSegments.length && newIndex < newSegmentCount; i++) {
142                 if (i == 0 || newSegments[i] > 0) {
143                     segments[newIndex++] = newSegments[i];
144                 }
145             }
146         }
147     }
148     return segments;
149 }
150 /**
151  * Returns the printer client area.
152  * </p>
153  * @return the visible client area that can be used for rendering.
154  * @see StyledTextRenderer#getClientArea
155  */

156 protected Rectangle getClientArea() {
157     return clientArea;
158 }
159 /**
160  * Returns the <class>StyledTextContent</class> to use for line offset
161  * calculations.
162  * This is the wrapped content, calculated in the constructor from the
163  * logical printing content.
164  * </p>
165  * @return the <class>StyledTextContent</class> to use for line offset
166  * calculations.
167  */

168 protected StyledTextContent getContent() {
169     return content;
170 }
171 /**
172  * Returns the printer GC to use for rendering and measuring.
173  * There can be only one GC for each printer device at any given
174  * time.
175  * </p>
176  * @return the printer GC to use for rendering and measuring.
177  */

178 protected GC getGC() {
179     return gc;
180 }
181 /**
182  * Returns 0. Scrolling does not affect printing. Text is wrapped
183  * for printing.
184  * </p>
185  * @return 0
186  * @see StyledTextRenderer#getHorizontalPixel
187  */

188 protected int getHorizontalPixel() {
189     return 0;
190 }
191 /**
192  * Returns the start offset of the line at the given offset.
193  * </p>
194  * @param visualLineOffset an offset that may be anywhere within a
195  * line.
196  * @return the start offset of the line at the given offset,
197  * relative to the start of the document.
198  */

199 private int getLogicalLineOffset(int visualLineOffset) {
200     int logicalLineIndex = logicalContent.getLineAtOffset(visualLineOffset);
201     
202     return logicalContent.getOffsetAtLine(logicalLineIndex);
203 }
204 protected int getOrientation () {
205     int mask = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT;
206     return gc.getStyle() & mask;
207 }
208 protected Color getSelectionBackground() {
209     return null;
210 }
211 protected Color getSelectionForeground() {
212     return null;
213 }
214 /**
215  * Return cached line background data.
216  * @see StyledTextRenderer#getLineBackgroundData
217  */

218 protected StyledTextEvent getLineBackgroundData(int lineOffset, String JavaDoc line) {
219     int logicalLineOffset = getLogicalLineOffset(lineOffset);
220     
221     return (StyledTextEvent) lineBackgrounds.get(new Integer JavaDoc(logicalLineOffset));
222 }
223 /**
224  * Return cached line style background data.
225  * @see StyledTextRenderer#getLineStyleData
226  */

227 protected StyledTextEvent getLineStyleData(int lineOffset, String JavaDoc line) {
228     int logicalLineOffset = getLogicalLineOffset(lineOffset);
229     StyledTextEvent logicalLineEvent = (StyledTextEvent) lineStyles.get(new Integer JavaDoc(logicalLineOffset));
230     
231     if (logicalLineEvent != null) {
232         StyledTextEvent clone = new StyledTextEvent((StyledTextContent) logicalLineEvent.data);
233         clone.detail = logicalLineEvent.detail;
234         clone.styles = logicalLineEvent.styles;
235         clone.text = logicalLineEvent.text;
236         logicalLineEvent = getLineStyleData(clone, lineOffset, line);
237     }
238     return logicalLineEvent;
239 }
240 /**
241  * Selection is not printed.
242  * </p>
243  * @return Point(0,0)
244  * @see StyledTextRenderer#getSelection
245  */

246 protected Point getSelection() {
247     return new Point(0, 0);
248 }
249 /**
250  * Printed content is always wrapped.
251  * </p>
252  * @return true
253  * @see StyledTextRenderer#getWordWrap
254  */

255 protected boolean getWordWrap() {
256     return true;
257 }
258 /**
259  * Selection is not printed. Returns false.
260  * <p>
261  * @return false
262  * @see StyledTextRenderer#isFullLineSelection
263  */

264 protected boolean isFullLineSelection() {
265     return false;
266 }
267 }
268
Popular Tags