Skip to content

Commit bd76f9f

Browse files
committed
Issue #932: Splitting out drawLineBackground() and drawLineForeground()
Needed to paint entire background in next commit. Signed-off-by: Alexandr Miloslavskiy <[email protected]>
1 parent e9cc756 commit bd76f9f

File tree

2 files changed

+65
-32
lines changed

2 files changed

+65
-32
lines changed

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5926,18 +5926,16 @@ void handlePaint(Event event) {
59265926
if (event.width == 0 || event.height == 0) return;
59275927
if (clientAreaWidth == 0 || clientAreaHeight == 0) return;
59285928

5929-
int startLine = getLineIndex(event.y);
5930-
int y = getLinePixel(startLine);
5931-
int endY = event.y + event.height;
5929+
final int endY = event.y + event.height;
59325930
GC gc = event.gc;
59335931
Color background = getBackground();
59345932
Color foreground = getForeground();
59355933
if (endY > 0) {
5936-
int lineCount = isSingleLine() ? 1 : content.getLineCount();
5937-
int x = leftMargin - horizontalScrollOffset;
5938-
for (int i = startLine; y < endY && i < lineCount; i++) {
5939-
y += renderer.drawLine(i, x, y, gc, background, foreground);
5940-
}
5934+
final int startLine = getLineIndex(event.y);
5935+
final int endLine = isSingleLine() ? 1 : content.getLineCount();
5936+
final int x = leftMargin - horizontalScrollOffset;
5937+
int y = getLinePixel(startLine);
5938+
y += renderer.drawLines(startLine, endLine, x, y, endY, gc, background, foreground);
59415939
if (y < endY) {
59425940
gc.setBackground(background);
59435941
drawBackground(gc, 0, y, clientAreaWidth, endY - y);

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ public LineInfo(LineInfo info) {
183183
}
184184
}
185185
}
186+
187+
private record LineDrawInfo(int index, TextLayout layout, String text, int offset, int height) {
188+
189+
}
190+
186191
static int cap (TextLayout layout, int offset) {
187192
if (layout == null) return offset;
188193
return Math.min (layout.getText().length() -1, Math.max (0, offset));
@@ -452,32 +457,63 @@ void drawBullet(Bullet bullet, GC gc, int paintX, int paintY, int index, int lin
452457
layout.draw(gc, x, paintY);
453458
layout.dispose();
454459
}
455-
int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackground, Color widgetForeground) {
460+
461+
/**
462+
* Caches draw-related info that may be expensive to calculate twice when
463+
* drawing first background and then foreground.
464+
*/
465+
private LineDrawInfo makeLineDrawInfo(int lineIndex) {
456466
TextLayout layout = getTextLayout(lineIndex);
457-
String line = content.getLine(lineIndex);
458-
int lineOffset = content.getOffsetAtLine(lineIndex);
459-
int lineLength = line.length();
467+
String text = content.getLine(lineIndex);
468+
int offset = content.getOffsetAtLine(lineIndex);
469+
int height = layout.getBounds().height;
470+
return new LineDrawInfo(lineIndex, layout, text, offset, height);
471+
}
472+
473+
int drawLines(int startLine, int endLine, int begX, int begY, int endY, GC gc, Color widgetBackground, Color widgetForeground) {
474+
final boolean drawBackBeforeFore = false;
475+
476+
if (drawBackBeforeFore) {
477+
return 0;
478+
}
479+
480+
int y = begY;
481+
for (int iLine = startLine; y < endY && iLine < endLine; iLine++) {
482+
LineDrawInfo lineInfo = makeLineDrawInfo(iLine);
483+
drawLineBackground(lineInfo, y, gc, widgetBackground);
484+
drawLineForeground(lineInfo, begX, y, gc, widgetForeground);
485+
disposeTextLayout(lineInfo.layout);
486+
y += lineInfo.height;
487+
}
488+
return y - begY;
489+
}
490+
491+
private void drawLineBackground(LineDrawInfo lineInfo, int paintY, GC gc, Color widgetBackground) {
460492
Rectangle client = styledText.getClientArea();
461-
Color lineBackground = getLineBackground(lineIndex, null);
462-
StyledTextEvent event = styledText.getLineBackgroundData(lineOffset, line);
493+
Color lineBackground = getLineBackground(lineInfo.index, null);
494+
StyledTextEvent event = styledText.getLineBackgroundData(lineInfo.offset, lineInfo.text);
463495
if (event != null && event.lineBackground != null) lineBackground = event.lineBackground;
464-
int height = layout.getBounds().height;
465-
int verticalIndent = layout.getVerticalIndent();
496+
int verticalIndent = lineInfo.layout.getVerticalIndent();
497+
466498
if (lineBackground != null) {
467499
if (verticalIndent > 0) {
468500
gc.setBackground(widgetBackground);
469501
gc.fillRectangle(client.x, paintY, client.width, verticalIndent);
470502
}
471503
gc.setBackground(lineBackground);
472-
gc.fillRectangle(client.x, paintY + verticalIndent, client.width, height - verticalIndent);
504+
gc.fillRectangle(client.x, paintY + verticalIndent, client.width, lineInfo.height - verticalIndent);
473505
} else {
474506
gc.setBackground(widgetBackground);
475-
styledText.drawBackground(gc, client.x, paintY, client.width, height);
507+
styledText.drawBackground(gc, client.x, paintY, client.width, lineInfo.height);
476508
}
509+
}
510+
511+
private void drawLineForeground(LineDrawInfo lineInfo, int paintX, int paintY, GC gc, Color widgetForeground) {
512+
int lineLength = lineInfo.text.length();
477513
gc.setForeground(widgetForeground);
478-
Point[] selection = intersectingRelativeNonEmptySelections(lineOffset, lineOffset + lineLength);
514+
Point[] selection = intersectingRelativeNonEmptySelections(lineInfo.offset, lineInfo.offset + lineLength);
479515
if (styledText.getBlockSelection() || selection.length == 0) {
480-
layout.draw(gc, paintX, paintY);
516+
lineInfo.layout.draw(gc, paintX, paintY);
481517
} else {
482518
Color selectionFg = styledText.getSelectionForeground();
483519
Color selectionBg = styledText.getSelectionBackground();
@@ -490,7 +526,7 @@ int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackgroun
490526
flags |= SWT.LAST_LINE_SELECTION;
491527
}
492528
// TODO calling draw multiple times here prints line multiple times, overriding some colors
493-
layout.draw(gc, paintX, paintY, start, end - 1, selectionFg, selectionBg, flags);
529+
lineInfo.layout.draw(gc, paintX, paintY, start, end - 1, selectionFg, selectionBg, flags);
494530
}
495531
}
496532

@@ -499,48 +535,47 @@ int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackgroun
499535
int bulletIndex = -1;
500536
if (bullets != null) {
501537
if (bulletsIndices != null) {
502-
int index = lineIndex - topIndex;
538+
int index = lineInfo.index - topIndex;
503539
if (0 <= index && index < CACHE_SIZE) {
504540
bullet = bullets[index];
505541
bulletIndex = bulletsIndices[index];
506542
}
507543
} else {
508544
for (Bullet b : bullets) {
509545
bullet = b;
510-
bulletIndex = bullet.indexOf(lineIndex);
546+
bulletIndex = bullet.indexOf(lineInfo.index);
511547
if (bulletIndex != -1) break;
512548
}
513549
}
514550
}
515551
if (bulletIndex != -1 && bullet != null) {
516-
FontMetrics metrics = layout.getLineMetrics(0);
552+
FontMetrics metrics = lineInfo.layout.getLineMetrics(0);
517553
int lineAscent = metrics.getAscent() + metrics.getLeading();
518554
if (bullet.type == ST.BULLET_CUSTOM) {
519-
bullet.style.start = lineOffset;
555+
bullet.style.start = lineInfo.offset;
520556
styledText.paintObject(gc, paintX, paintY, lineAscent, metrics.getDescent(), bullet.style, bullet, bulletIndex);
521557
} else {
522558
drawBullet(bullet, gc, paintX, paintY, bulletIndex, lineAscent, metrics.getDescent());
523559
}
524560
}
525-
TextStyle[] styles = layout.getStyles();
561+
TextStyle[] styles = lineInfo.layout.getStyles();
526562
int[] ranges = null;
527563
for (int i = 0; i < styles.length; i++) {
528564
if (styles[i].metrics != null) {
529-
if (ranges == null) ranges = layout.getRanges();
565+
if (ranges == null) ranges = lineInfo.layout.getRanges();
530566
int start = ranges[i << 1];
531567
int length = ranges[(i << 1) + 1] - start + 1;
532-
Point point = layout.getLocation(start, false);
533-
FontMetrics metrics = layout.getLineMetrics(layout.getLineIndex(start));
568+
Point point = lineInfo.layout.getLocation(start, false);
569+
FontMetrics metrics = lineInfo.layout.getLineMetrics(lineInfo.layout.getLineIndex(start));
534570
StyleRange style = (StyleRange)((StyleRange)styles[i]).clone();
535-
style.start = start + lineOffset;
571+
style.start = start + lineInfo.offset;
536572
style.length = length;
537573
int lineAscent = metrics.getAscent() + metrics.getLeading();
538574
styledText.paintObject(gc, point.x + paintX, point.y + paintY, lineAscent, metrics.getDescent(), style, null, 0);
539575
}
540576
}
541-
disposeTextLayout(layout);
542-
return height;
543577
}
578+
544579
private Point[] intersectingRelativeNonEmptySelections(int fromOffset, int toOffset) {
545580
int[] selectionRanges = styledText.getSelectionRanges();
546581
int lineLength = toOffset - fromOffset;

0 commit comments

Comments
 (0)