2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.taxeditor
.editor
.name
.container
;
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
;
21 * Adds ability to draw multiline squiggles when a <code>StyledText</code>
22 * contains line-wrapping.
28 public class LineWrapSquigglesStrategy
extends SquigglesStrategy
{
30 /** Constant <code>ID="linewrap_squigglesstrategy"</code> */
31 public static final String ID
= "linewrap_squigglesstrategy";
37 private int lineHeight
;
41 private StyledText textWidget
;
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)
49 public void draw(Annotation annotation
, GC gc
, StyledText textWidget
, int offset
, int length
, Color color
) {
53 this.textWidget
= textWidget
;
61 baseline
= textWidget
.getBaseline(offset
);
62 lineHeight
= textWidget
.getLineHeight(offset
);
65 int offsetNewline
= offset
;
66 int end
= offset
+ length
;
68 // Go through the length one character at a time
69 for (int i
= offset
; i
<= end
; i
++) {
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
) {
75 // Draw a line of squigglies
76 drawPolyline(offsetNewline
, right
);
78 // Save offset of line break
82 // Get x,y position in case the next char is on a new line
83 right
= textWidget
.getLocationAtOffset(i
);
87 // Draw the last line of squigglies
88 drawPolyline(offsetNewline
, right
);
91 textWidget
.redrawRange(offset
, length
, true);
96 * Draws a squiggly line from the offset <code>offsetNewline</code> to
97 * the x,y coordinates at <code>right</code>.
99 * @param offsetNewline
102 private void drawPolyline(int offsetNewline
, Point right
) {
104 // Get offset at last line break
105 Point left
= textWidget
.getLocationAtOffset(offsetNewline
);
107 // Prevent solitary red dot from appearing at EOL
108 if (left
.equals(right
)) {
112 // Only start drawing from 0 if not on the first line
113 if (offsetNewline
!= offset
) {
115 // Offset.x is at the end of the first letter of the new line, not at 0
119 int[] polyline
= computePolyline(left
, right
, baseline
, lineHeight
);
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
);
128 * Copied verbatim from {@link org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy}
130 * @see org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy
138 private int[] computePolyline(Point left
, Point right
, int baseline
, int lineHeight
) {
140 final int WIDTH
= 4; // must be even
141 final int HEIGHT
= 2; // can be any number
143 int peaks
= (right
.x
- left
.x
) / WIDTH
;
144 if (peaks
== 0 && right
.x
- left
.x
> 2)
149 // compute (number of point) * 2
150 int length
= ((2 * peaks
) + 1) * 2;
154 int[] coordinates
= new int[length
];
156 // cache peeks' y-coordinates
157 int top
= left
.y
+ Math
.min(baseline
+ 1, lineHeight
- HEIGHT
- 1);
158 int bottom
= top
+ HEIGHT
;
160 // populate array with peek coordinates
161 for (int i
= 0; i
< peaks
; 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
;
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
;