2828import org .eclipse .jface .internal .text .codemining .CodeMiningLineHeaderAnnotation ;
2929
3030import org .eclipse .jface .text .ITextViewer ;
31+ import org .eclipse .jface .text .Position ;
3132import org .eclipse .jface .text .source .Annotation ;
3233import org .eclipse .jface .text .source .AnnotationPainter .IDrawingStrategy ;
3334
@@ -99,7 +100,7 @@ private Font getAnnotationFont(StyledText textWidget) {
99100 if (annotationFont == null ) {
100101 annotationFont = createInlineAnnotationFont (textWidget );
101102 textWidget .setData (INLINE_ANNOTATION_FONT , annotationFont );
102- textWidget .addDisposeListener (e -> ((Font )textWidget .getData (INLINE_ANNOTATION_FONT )).dispose ());
103+ textWidget .addDisposeListener (e -> ((Font ) textWidget .getData (INLINE_ANNOTATION_FONT )).dispose ());
103104 }
104105 return annotationFont ;
105106 }
@@ -154,7 +155,8 @@ public static void draw(AbstractInlinedAnnotation annotation, GC gc, StyledText
154155 private static void draw (LineHeaderAnnotation annotation , GC gc , StyledText textWidget , int offset , int length ,
155156 Color color ) {
156157 int line = textWidget .getLineAtOffset (offset );
157- if (isDeleted (annotation )) {
158+ int charCount = textWidget .getCharCount ();
159+ if (isDeleted (annotation , charCount )) {
158160 // When annotation is deleted, update metrics to null to remove extra spaces of the line header annotation.
159161 if (textWidget .getLineVerticalIndent (line ) > 0 )
160162 textWidget .setLineVerticalIndent (line , 0 );
@@ -180,9 +182,16 @@ private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText text
180182 textWidget .setLineVerticalIndent (line , 0 );
181183 }
182184 // Compute the location of the annotation
183- Rectangle bounds = textWidget .getTextBounds (offset , offset );
184- int x = bounds .x ;
185- int y = bounds .y ;
185+ int x , y ;
186+ if (offset < charCount ) {
187+ Rectangle bounds = textWidget .getTextBounds (offset , offset );
188+ x = bounds .x ;
189+ y = bounds .y ;
190+ } else {
191+ Point locAtOff = textWidget .getLocationAtOffset (offset );
192+ x = locAtOff .x ;
193+ y = locAtOff .y - height ;
194+ }
186195 // Draw the line header annotation
187196 gc .setBackground (textWidget .getBackground ());
188197 annotation .setLocation (x , y );
@@ -193,7 +202,16 @@ private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText text
193202 Rectangle client = textWidget .getClientArea ();
194203 textWidget .redraw (0 , bounds .y , client .width , bounds .height , false );
195204 } else {
196- textWidget .redrawRange (offset , length , true );
205+ if (offset >= charCount ) {
206+ if (charCount > 0 ) {
207+ textWidget .redrawRange (charCount - 1 , 1 , true );
208+ } else {
209+ Rectangle client = textWidget .getClientArea ();
210+ textWidget .redraw (0 , 0 , client .width , client .height , false );
211+ }
212+ } else {
213+ textWidget .redrawRange (offset , length , true );
214+ }
197215 }
198216 }
199217
@@ -212,7 +230,11 @@ private static void draw(LineContentAnnotation annotation, GC gc, StyledText tex
212230 Color color ) {
213231 if (annotation instanceof CodeMiningLineContentAnnotation a ) {
214232 if (a .isAfterPosition ()) {
215- drawAsLeftOf1stCharacter (annotation , gc , textWidget , widgetOffset , length , color );
233+ if (widgetOffset < textWidget .getCharCount ()) {
234+ drawAsLeftOf1stCharacter (annotation , gc , textWidget , widgetOffset , length , color );
235+ } else {
236+ drawAtEndOfDocumentInFirstColumn (annotation , gc , textWidget , widgetOffset , length , color );
237+ }
216238 return ;
217239 }
218240 }
@@ -226,7 +248,7 @@ private static void draw(LineContentAnnotation annotation, GC gc, StyledText tex
226248 }
227249
228250 private static void drawAfterLine (LineContentAnnotation annotation , GC gc , StyledText textWidget , int widgetOffset , int length , Color color ) {
229- if (isDeleted (annotation )) {
251+ if (isDeleted (annotation , textWidget . getCharCount () )) {
230252 return ;
231253 }
232254 if (gc != null ) {
@@ -247,14 +269,43 @@ private static void drawAfterLine(LineContentAnnotation annotation, GC gc, Style
247269 }
248270 }
249271
272+ private static void drawAtEndOfDocumentInFirstColumn (LineContentAnnotation annotation , GC gc , StyledText textWidget , int widgetOffset , int length , Color color ) {
273+ if (isDeleted (annotation , textWidget .getCharCount ())) {
274+ return ;
275+ }
276+ if (gc != null ) {
277+ Point locAtOff = textWidget .getLocationAtOffset (widgetOffset );
278+ int x = locAtOff .x ;
279+ int y = locAtOff .y ;
280+ annotation .setLocation (x , y );
281+ annotation .draw (gc , textWidget , widgetOffset , length , color , x , y );
282+ int width = annotation .getWidth ();
283+ if (width != 0 ) {
284+ if (!gc .getClipping ().contains (x , y )) {
285+ Rectangle client = textWidget .getClientArea ();
286+ int height = textWidget .getLineHeight ();
287+ textWidget .redraw (x , y , client .width , height , false );
288+ }
289+ }
290+ } else {
291+ int charCount = textWidget .getCharCount ();
292+ if (charCount > 0 ) {
293+ textWidget .redrawRange (charCount - 1 , 1 , true );
294+ } else {
295+ Rectangle client = textWidget .getClientArea ();
296+ textWidget .redraw (0 , 0 , client .width , client .height , false );
297+ }
298+ }
299+ }
300+
250301 protected static void drawAsLeftOf1stCharacter (LineContentAnnotation annotation , GC gc , StyledText textWidget , int widgetOffset , int length , Color color ) {
251302 StyleRange style = null ;
252303 try {
253304 style = textWidget .getStyleRangeAtOffset (widgetOffset );
254305 } catch (Exception e ) {
255306 return ;
256307 }
257- if (isDeleted (annotation )) {
308+ if (isDeleted (annotation , textWidget . getCharCount () )) {
258309 // When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation.
259310 if (style != null && style .metrics != null ) {
260311 style .metrics = null ;
@@ -369,7 +420,7 @@ protected static void drawAsRightOfPreviousCharacter(LineContentAnnotation annot
369420 } catch (Exception e ) {
370421 return ;
371422 }
372- if (isDeleted (annotation )) {
423+ if (isDeleted (annotation , textWidget . getCharCount () )) {
373424 // When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation.
374425 if (style != null && style .metrics != null ) {
375426 style .metrics = null ;
@@ -449,7 +500,17 @@ protected static void drawAsRightOfPreviousCharacter(LineContentAnnotation annot
449500 * @param annotation the inlined annotation to check
450501 * @return <code>true</code> if inlined annotation is deleted and <code>false</code> otherwise.
451502 */
452- private static boolean isDeleted (AbstractInlinedAnnotation annotation ) {
453- return annotation .isMarkedDeleted () || annotation .getPosition ().isDeleted () || annotation .getPosition ().getLength () == 0 ;
503+ private static boolean isDeleted (AbstractInlinedAnnotation annotation ,int maxOffset ) {
504+ if (annotation .isMarkedDeleted ()) {
505+ return true ;
506+ }
507+ Position pos = annotation .getPosition ();
508+ if (pos .isDeleted ()) {
509+ return true ;
510+ }
511+ if (pos .getLength () == 0 && pos .getOffset () < maxOffset ) {
512+ return true ;
513+ }
514+ return false ;
454515 }
455516}
0 commit comments