Skip to content

Commit

Permalink
Issue #932: Splitting out drawLineBackground() and drawLineForeground()
Browse files Browse the repository at this point in the history
Needed to paint entire background in next commit.

Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
  • Loading branch information
SyntevoAlex committed Jan 31, 2024
1 parent 213d31a commit 6f3b89e
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5926,18 +5926,16 @@ void handlePaint(Event event) {
if (event.width == 0 || event.height == 0) return;
if (clientAreaWidth == 0 || clientAreaHeight == 0) return;

int startLine = getLineIndex(event.y);
int y = getLinePixel(startLine);
int endY = event.y + event.height;
final int endY = event.y + event.height;
GC gc = event.gc;
Color background = getBackground();
Color foreground = getForeground();
if (endY > 0) {
int lineCount = isSingleLine() ? 1 : content.getLineCount();
int x = leftMargin - horizontalScrollOffset;
for (int i = startLine; y < endY && i < lineCount; i++) {
y += renderer.drawLine(i, x, y, gc, background, foreground);
}
final int startLine = getLineIndex(event.y);
final int endLine = isSingleLine() ? 1 : content.getLineCount();
final int x = leftMargin - horizontalScrollOffset;
int y = getLinePixel(startLine);
y += renderer.drawLines(startLine, endLine, x, y, endY, gc, background, foreground);
if (y < endY) {
gc.setBackground(background);
drawBackground(gc, 0, y, clientAreaWidth, endY - y);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ public LineInfo(LineInfo info) {
}
}
}

private static class LineDrawInfo {
int index;
TextLayout layout;
String text;
int offset;
int height;
}

static int cap (TextLayout layout, int offset) {
if (layout == null) return offset;
return Math.min (layout.getText().length() -1, Math.max (0, offset));
Expand Down Expand Up @@ -452,32 +461,65 @@ void drawBullet(Bullet bullet, GC gc, int paintX, int paintY, int index, int lin
layout.draw(gc, x, paintY);
layout.dispose();
}
int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackground, Color widgetForeground) {
TextLayout layout = getTextLayout(lineIndex);
String line = content.getLine(lineIndex);
int lineOffset = content.getOffsetAtLine(lineIndex);
int lineLength = line.length();

/**
* Caches draw-related info that may be expensive to calculate twice when
* drawing first background and then foreground.
*/
private LineDrawInfo makeLineDrawInfo(int lineIndex) {
LineDrawInfo info = new LineDrawInfo();
info.index = lineIndex;
info.layout = getTextLayout(lineIndex);
info.text = content.getLine(lineIndex);
info.offset = content.getOffsetAtLine(lineIndex);
info.height = info.layout.getBounds().height;
return info;
}

int drawLines(int startLine, int endLine, int begX, int begY, int endY, GC gc, Color widgetBackground, Color widgetForeground) {
final boolean drawBackBeforeFore = false;

if (drawBackBeforeFore) {
return 0;
}

int y = begY;
for (int iLine = startLine; y < endY && iLine < endLine; iLine++) {
LineDrawInfo lineInfo = makeLineDrawInfo(iLine);
drawLineBackground(lineInfo, y, gc, widgetBackground);
drawLineForeground(lineInfo, begX, y, gc, widgetForeground);
disposeTextLayout(lineInfo.layout);
y += lineInfo.height;
}
return y - begY;
}

private void drawLineBackground(LineDrawInfo lineInfo, int paintY, GC gc, Color widgetBackground) {
Rectangle client = styledText.getClientArea();
Color lineBackground = getLineBackground(lineIndex, null);
StyledTextEvent event = styledText.getLineBackgroundData(lineOffset, line);
Color lineBackground = getLineBackground(lineInfo.index, null);
StyledTextEvent event = styledText.getLineBackgroundData(lineInfo.offset, lineInfo.text);
if (event != null && event.lineBackground != null) lineBackground = event.lineBackground;
int height = layout.getBounds().height;
int verticalIndent = layout.getVerticalIndent();
int verticalIndent = lineInfo.layout.getVerticalIndent();

if (lineBackground != null) {
if (verticalIndent > 0) {
gc.setBackground(widgetBackground);
gc.fillRectangle(client.x, paintY, client.width, verticalIndent);
}
gc.setBackground(lineBackground);
gc.fillRectangle(client.x, paintY + verticalIndent, client.width, height - verticalIndent);
gc.fillRectangle(client.x, paintY + verticalIndent, client.width, lineInfo.height - verticalIndent);
} else {
gc.setBackground(widgetBackground);
styledText.drawBackground(gc, client.x, paintY, client.width, height);
styledText.drawBackground(gc, client.x, paintY, client.width, lineInfo.height);
}
}

private void drawLineForeground(LineDrawInfo lineInfo, int paintX, int paintY, GC gc, Color widgetForeground) {
int lineLength = lineInfo.text.length();
gc.setForeground(widgetForeground);
Point[] selection = intersectingRelativeNonEmptySelections(lineOffset, lineOffset + lineLength);
Point[] selection = intersectingRelativeNonEmptySelections(lineInfo.offset, lineInfo.offset + lineLength);
if (styledText.getBlockSelection() || selection.length == 0) {
layout.draw(gc, paintX, paintY);
lineInfo.layout.draw(gc, paintX, paintY);
} else {
Color selectionFg = styledText.getSelectionForeground();
Color selectionBg = styledText.getSelectionBackground();
Expand All @@ -490,7 +532,7 @@ int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackgroun
flags |= SWT.LAST_LINE_SELECTION;
}
// TODO calling draw multiple times here prints line multiple times, overriding some colors
layout.draw(gc, paintX, paintY, start, end - 1, selectionFg, selectionBg, flags);
lineInfo.layout.draw(gc, paintX, paintY, start, end - 1, selectionFg, selectionBg, flags);
}
}

Expand All @@ -499,48 +541,47 @@ int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackgroun
int bulletIndex = -1;
if (bullets != null) {
if (bulletsIndices != null) {
int index = lineIndex - topIndex;
int index = lineInfo.index - topIndex;
if (0 <= index && index < CACHE_SIZE) {
bullet = bullets[index];
bulletIndex = bulletsIndices[index];
}
} else {
for (Bullet b : bullets) {
bullet = b;
bulletIndex = bullet.indexOf(lineIndex);
bulletIndex = bullet.indexOf(lineInfo.index);
if (bulletIndex != -1) break;
}
}
}
if (bulletIndex != -1 && bullet != null) {
FontMetrics metrics = layout.getLineMetrics(0);
FontMetrics metrics = lineInfo.layout.getLineMetrics(0);
int lineAscent = metrics.getAscent() + metrics.getLeading();
if (bullet.type == ST.BULLET_CUSTOM) {
bullet.style.start = lineOffset;
bullet.style.start = lineInfo.offset;
styledText.paintObject(gc, paintX, paintY, lineAscent, metrics.getDescent(), bullet.style, bullet, bulletIndex);
} else {
drawBullet(bullet, gc, paintX, paintY, bulletIndex, lineAscent, metrics.getDescent());
}
}
TextStyle[] styles = layout.getStyles();
TextStyle[] styles = lineInfo.layout.getStyles();
int[] ranges = null;
for (int i = 0; i < styles.length; i++) {
if (styles[i].metrics != null) {
if (ranges == null) ranges = layout.getRanges();
if (ranges == null) ranges = lineInfo.layout.getRanges();
int start = ranges[i << 1];
int length = ranges[(i << 1) + 1] - start + 1;
Point point = layout.getLocation(start, false);
FontMetrics metrics = layout.getLineMetrics(layout.getLineIndex(start));
Point point = lineInfo.layout.getLocation(start, false);
FontMetrics metrics = lineInfo.layout.getLineMetrics(lineInfo.layout.getLineIndex(start));
StyleRange style = (StyleRange)((StyleRange)styles[i]).clone();
style.start = start + lineOffset;
style.start = start + lineInfo.offset;
style.length = length;
int lineAscent = metrics.getAscent() + metrics.getLeading();
styledText.paintObject(gc, point.x + paintX, point.y + paintY, lineAscent, metrics.getDescent(), style, null, 0);
}
}
disposeTextLayout(layout);
return height;
}

private Point[] intersectingRelativeNonEmptySelections(int fromOffset, int toOffset) {
int[] selectionRanges = styledText.getSelectionRanges();
int lineLength = toOffset - fromOffset;
Expand Down

0 comments on commit 6f3b89e

Please sign in to comment.