[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