[jbosstools-issues] [JBoss JIRA] (ERT-762) [GTK] Performance of TextLayout.getBounds() is very bad for long text [EBZ#551588]
Friendly Jira Robot (Jira)
issues at jboss.org
Tue Oct 1 10:26:00 EDT 2019
Friendly Jira Robot created ERT-762:
---------------------------------------
Summary: [GTK] Performance of TextLayout.getBounds() is very bad for long text [EBZ#551588]
Key: ERT-762
URL: https://issues.jboss.org/browse/ERT-762
Project: Eclipse Release Train
Issue Type: Task
Components: Platform
Reporter: Friendly Jira Robot
I've noticed a slow performance of TextLayout.getBounds() method on Linux. The profiler shows an excessive amount of calls to OS.pango_layout_get_line_count(layout) method. Looking through the code I'm noticing that this is due to the bad design in TextLayout class, as it repeats calls to same OS methods repeatedly in a loop.
The TextLayout.getBounds() method looks like this:
public Rectangle getBounds() {
checkLayout();
Rectangle bounds = DPIUtil.autoScaleDown(getDevice(), getBoundsInPixels());
int lineCount = OS.pango_layout_get_line_count(layout);
int totalLineheight = getScaledVerticalIndent();
for (int i = 0; i < lineCount; i++) {
totalLineheight += this.getLineBounds(i).height + OS.PANGO_PIXELS(OS.pango_layout_get_spacing(layout));
}
bounds.height = totalLineheight;
return bounds;
}
Here I believe the result of OS.pango_layout_get_spacing(layout) could be cached. Further down the line this calls TextLayout.getLineBoundsInPixels method.
Rectangle getLineBoundsInPixels(int lineIndex) {
computeRuns();
int lineCount = OS.pango_layout_get_line_count(layout);
if (!(0 <= lineIndex && lineIndex < lineCount)) SWT.error(SWT.ERROR_INVALID_RANGE);
long iter = OS.pango_layout_get_iter(layout);
if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES);
for (int i = 0; i < lineIndex; i++) OS.pango_layout_iter_next_line(iter);
PangoRectangle rect = new PangoRectangle();
OS.pango_layout_iter_get_line_extents(iter, null, rect);
OS.pango_layout_iter_free(iter);
int x = OS.PANGO_PIXELS(rect.x);
int y = OS.PANGO_PIXELS(rect.y);
int width = OS.PANGO_PIXELS(rect.width);
int height = OS.PANGO_PIXELS(rect.height);
if (ascentInPoints != -1 && descentInPoints != -1) {
height = Math.max (height, DPIUtil.autoScaleUp(getDevice(), ascentInPoints + descentInPoints));
}
x += Math.min (indent, wrapIndent);
return new Rectangle(x, y, width, height);
}
This method repeats the call to OS.pango_layout_get_line_count. Also things like computeRuns() and OS.pango_layout_get_iter(layout) could be done once per TextLayout.getBounds call. Done in a loop this quickly escalates to slow performance.
I believe TextLayout.getBounds() should be refactored to minimize repeated calls and reuse results.
--
This message was sent by Atlassian Jira
(v7.13.8#713008)
More information about the jbosstools-issues
mailing list