Project

General

Profile

Download (4.67 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy 
4
* http://www.e-taxonomy.eu
5
* 
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.taxeditor.editor.name.container;
11

    
12
import org.eclipse.jface.text.source.Annotation;
13
import org.eclipse.jface.text.source.AnnotationPainter.SquigglesStrategy;
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.custom.StyledText;
16
import org.eclipse.swt.graphics.Color;
17
import org.eclipse.swt.graphics.GC;
18
import org.eclipse.swt.graphics.Point;
19

    
20
/**
21
 * Adds ability to draw multiline squiggles when a <code>StyledText</code>
22
 * contains line-wrapping.
23
 *
24
 * @author p.ciardelli
25
 * @created 21.11.2008
26
 * @version 1.0
27
 */
28
public class LineWrapSquigglesStrategy extends SquigglesStrategy {
29
	
30
	/** Constant <code>ID="linewrap_squigglesstrategy"</code> */
31
	public static final String ID = "linewrap_squigglesstrategy"; //$NON-NLS-1$
32

    
33
	private GC gc;
34

    
35
	private Color color;
36

    
37
	private int lineHeight;
38

    
39
	private int baseline;
40

    
41
	private StyledText textWidget;
42

    
43
	private int offset;
44
	
45
	/* (non-Javadoc)
46
	 * @see org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy#draw(org.eclipse.jface.text.source.Annotation, org.eclipse.swt.graphics.GC, org.eclipse.swt.custom.StyledText, int, int, org.eclipse.swt.graphics.Color)
47
	 */
48
	/** {@inheritDoc} */
49
	public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
50
		
51
		this.gc = gc;
52
		this.color = color;
53
		this.textWidget = textWidget;
54
		this.offset = offset;
55
		
56
		if (gc != null) {
57

    
58
			if (length < 1)
59
				return;
60
			
61
			baseline = textWidget.getBaseline(offset);
62
			lineHeight = textWidget.getLineHeight(offset);
63
			
64
			Point right = null;
65
			int offsetNewline = offset;
66
			int end = offset + length;
67
						
68
			// Go through the length one character at a time
69
			for (int i = offset; i <= end; i++) {
70
				
71
				// If the y of the current offset is different from that of the last offset,
72
				//	we are on a new line
73
				if (right != null && textWidget.getLocationAtOffset(i).y > right.y) {
74
										
75
					// Draw a line of squigglies
76
					drawPolyline(offsetNewline, right);
77

    
78
					// Save offset of line break
79
					offsetNewline = i;
80
				}
81
								
82
				// Get x,y position in case the next char is on a new line
83
				right = textWidget.getLocationAtOffset(i);					
84
					
85
			}
86
			
87
			// Draw the last line of squigglies 
88
			drawPolyline(offsetNewline, right);
89

    
90
		} else {
91
			textWidget.redrawRange(offset, length, true);
92
		}
93
	}
94
	
95
	/**
96
	 * Draws a squiggly line from the offset <code>offsetNewline</code> to
97
	 * the x,y coordinates at <code>right</code>.
98
	 * 
99
	 * @param offsetNewline
100
	 * @param right
101
	 */
102
	private void drawPolyline(int offsetNewline, Point right) {
103

    
104
		// Get offset at last line break
105
		Point left = textWidget.getLocationAtOffset(offsetNewline);
106
		
107
		// Prevent solitary red dot from appearing at EOL
108
		if (left.equals(right)) {
109
			return;
110
		}
111
		
112
		// Only start drawing from 0 if not on the first line
113
		if (offsetNewline != offset) {
114
			
115
			// Offset.x is at the end of the first letter of the new line, not at 0
116
			left.x = 0;
117
		}
118
		
119
		int[] polyline= computePolyline(left, right, baseline, lineHeight);
120

    
121
		gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
122
		gc.setLineStyle(SWT.LINE_SOLID);
123
		gc.setForeground(color);
124
		gc.drawPolyline(polyline);
125
	}
126

    
127
	/**
128
	 * Copied verbatim from {@link org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy} 
129
	 * 
130
	 * @see org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy
131
	 *  
132
	 * @param left
133
	 * @param right
134
	 * @param baseline
135
	 * @param lineHeight
136
	 * @return
137
	 */
138
	private int[] computePolyline(Point left, Point right, int baseline, int lineHeight) {
139

    
140
		final int WIDTH= 4; // must be even
141
		final int HEIGHT= 2; // can be any number
142

    
143
		int peaks= (right.x - left.x) / WIDTH;
144
		if (peaks == 0 && right.x - left.x > 2)
145
			peaks= 1;
146

    
147
		int leftX= left.x;
148

    
149
		// compute (number of point) * 2
150
		int length= ((2 * peaks) + 1) * 2;
151
		if (length < 0)
152
			return new int[0];
153

    
154
		int[] coordinates= new int[length];
155

    
156
		// cache peeks' y-coordinates
157
		int top= left.y + Math.min(baseline + 1, lineHeight - HEIGHT - 1);
158
		int bottom= top + HEIGHT;
159

    
160
		// populate array with peek coordinates
161
		for (int i= 0; i < peaks; i++) {
162
			int index= 4 * i;
163
			coordinates[index]= leftX + (WIDTH * i);
164
			coordinates[index+1]= bottom;
165
			coordinates[index+2]= coordinates[index] + WIDTH/2;
166
			coordinates[index+3]= top;
167
		}
168

    
169
		// the last down flank is missing
170
		coordinates[length-2]= Math.min(Math.max(0, right.x - 1), left.x + (WIDTH * peaks));
171
		coordinates[length-1]= bottom;
172

    
173
		return coordinates;
174
	}
175
}
(4-4/6)