[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:36:00 EDT 2019
[ https://issues.jboss.org/browse/ERT-762?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Eric Williams reassigned ERT-762:
---------------------------------
Sprint: devex #173 Oct 2019
Assignee: Eric Williams
> [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