[jbosstools-issues] [JBoss JIRA] (ERT-762) [GTK] Performance of TextLayout.getBounds() is very bad for long text [EBZ#551588]

Eric Williams (Jira) issues at jboss.org
Wed Oct 2 11:37:00 EDT 2019


     [ https://issues.jboss.org/browse/ERT-762?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Eric Williams resolved ERT-762.
-------------------------------
    Resolution: Done


> [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
>            Assignee: Eric Williams
>            Priority: Major
>              Labels: 4.14_M1, SWT, bzira
>
> 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