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
;
12 import org
.apache
.log4j
.Logger
;
13 import org
.eclipse
.jface
.text
.source
.Annotation
;
14 import org
.eclipse
.jface
.text
.source
.AnnotationPainter
.SquigglesStrategy
;
15 import org
.eclipse
.swt
.SWT
;
16 import org
.eclipse
.swt
.custom
.StyledText
;
17 import org
.eclipse
.swt
.graphics
.Color
;
18 import org
.eclipse
.swt
.graphics
.GC
;
19 import org
.eclipse
.swt
.graphics
.Point
;
22 * Adds ability to draw multiline squiggles when a <code>StyledText</code>
23 * contains line-wrapping.
29 public class LineWrapSquigglesStrategy
extends SquigglesStrategy
{
30 private static final Logger logger
= Logger
31 .getLogger(LineWrapSquigglesStrategy
.class);
33 public static final String ID
= "linewrap_squigglesstrategy";
39 private int lineHeight
;
43 private StyledText textWidget
;
48 * @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)
50 public void draw(Annotation annotation
, GC gc
, StyledText textWidget
, int offset
, int length
, Color color
) {
54 this.textWidget
= textWidget
;
62 baseline
= textWidget
.getBaseline(offset
);
63 lineHeight
= textWidget
.getLineHeight(offset
);
66 int offsetNewline
= offset
;
67 int end
= offset
+ length
;
69 // Go through the length one character at a time
70 for (int i
= offset
; i
<= end
; i
++) {
72 // If the y of the current offset is different from that of the last offset,
73 // we are on a new line
74 if (right
!= null && textWidget
.getLocationAtOffset(i
).y
> right
.y
) {
76 // Draw a line of squigglies
77 drawPolyline(offsetNewline
, right
);
79 // Save offset of line break
83 // Get x,y position in case the next char is on a new line
84 right
= textWidget
.getLocationAtOffset(i
);
88 // Draw the last line of squigglies
89 drawPolyline(offsetNewline
, right
);
92 textWidget
.redrawRange(offset
, length
, true);
97 * Draws a squiggly line from the offset <code>offsetNewline</code> to
98 * the x,y coordinates at <code>right</code>.
100 * @param offsetNewline
103 private void drawPolyline(int offsetNewline
, Point right
) {
105 // Get offset at last line break
106 Point left
= textWidget
.getLocationAtOffset(offsetNewline
);
108 // Prevent solitary red dot from appearing at EOL
109 if (left
.equals(right
)) {
113 // Only start drawing from 0 if not on the first line
114 if (offsetNewline
!= offset
) {
116 // Offset.x is at the end of the first letter of the new line, not at 0
120 int[] polyline
= computePolyline(left
, right
, baseline
, lineHeight
);
122 gc
.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
123 gc
.setLineStyle(SWT
.LINE_SOLID
);
124 gc
.setForeground(color
);
125 gc
.drawPolyline(polyline
);
129 * Copied verbatim from {@link org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy}
131 * @see org.eclipse.jface.text.source.AnnotationPainter$SquigglesStrategy
139 private int[] computePolyline(Point left
, Point right
, int baseline
, int lineHeight
) {
141 final int WIDTH
= 4; // must be even
142 final int HEIGHT
= 2; // can be any number
144 int peaks
= (right
.x
- left
.x
) / WIDTH
;
145 if (peaks
== 0 && right
.x
- left
.x
> 2)
150 // compute (number of point) * 2
151 int length
= ((2 * peaks
) + 1) * 2;
155 int[] coordinates
= new int[length
];
157 // cache peeks' y-coordinates
158 int top
= left
.y
+ Math
.min(baseline
+ 1, lineHeight
- HEIGHT
- 1);
159 int bottom
= top
+ HEIGHT
;
161 // populate array with peek coordinates
162 for (int i
= 0; i
< peaks
; i
++) {
164 coordinates
[index
]= leftX
+ (WIDTH
* i
);
165 coordinates
[index
+1]= bottom
;
166 coordinates
[index
+2]= coordinates
[index
] + WIDTH
/2;
167 coordinates
[index
+3]= top
;
170 // the last down flank is missing
171 coordinates
[length
-2]= Math
.min(Math
.max(0, right
.x
- 1), left
.x
+ (WIDTH
* peaks
));
172 coordinates
[length
-1]= bottom
;