如何提高 TextLayout.draw(..) 的 Java2D 性能

发布于 2024-09-10 02:01:08 字数 1992 浏览 3 评论 0原文

我使用 Java2D TextLayout 类以及 LineBreakMeasurerAttributedCharacterIterator 将一段文本绘制到框中。文本已换行。

分析表明代码非常慢。大部分时间都浪费在了方法TextLayout.draw(..)上。

有人对提高速度有建议吗?

    // Get iterator for string
    AttributedCharacterIterator iterator = attribText.getIterator();

    // Create measurer
    LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, context);

    // loop over the lines
    int i = 1;
    while (measurer.getPosition() < iterator.getEndIndex()) {
        // Get line
        TextLayout textLayout = measurer.nextLayout(w);

        // get measurements
        float ascent  = textLayout.getAscent();
        float descent = textLayout.getDescent();
        float leading = textLayout.getLeading();
        float size    = ascent + descent;

        // Move down to baseline
        if( i == 1 ) {
            if( coverType == CoverType.SPINE ) {
                y = (box.height-size)/2;
                y -= (size+leading)*(lines-1)/2;
            } else if( vAlign == Alignment.Center ) {
                y += (h-size)/2-(size+leading)*(lines-1)/2;
            } else if( vAlign == Alignment.Bottom ) {
                y += (h-size) - (size+leading)*(lines-1);
            }
        }
        y += ascent;

        // calculate starting point for alignment
        float paintX = x;
        switch( hAlign ) {
            case Right: {
                paintX = x + w - textLayout.getVisibleAdvance();
                break;
            }
            case Center: {
                paintX = x + (w - textLayout.getVisibleAdvance())/2;
                break;
            }
        }

        // Draw line
        textLayout.draw(g2d, paintX, y);

        // Move down to top of next line
        y += descent + leading;
        i++;
    }

相关代码片段如上所示。 attribText是之前设置的AttributtedStringcontextg2d.getFontRenderContext()

I'm using the Java2D TextLayout class together with a LineBreakMeasurer and an AttributedCharacterIterator to draw a piece of text into a box. The text is wrapped.

Profiling shows me that the code is very slow. Most of the time is lost in the method TextLayout.draw(..).

Does anyone have a suggestion for speed improvement?

    // Get iterator for string
    AttributedCharacterIterator iterator = attribText.getIterator();

    // Create measurer
    LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, context);

    // loop over the lines
    int i = 1;
    while (measurer.getPosition() < iterator.getEndIndex()) {
        // Get line
        TextLayout textLayout = measurer.nextLayout(w);

        // get measurements
        float ascent  = textLayout.getAscent();
        float descent = textLayout.getDescent();
        float leading = textLayout.getLeading();
        float size    = ascent + descent;

        // Move down to baseline
        if( i == 1 ) {
            if( coverType == CoverType.SPINE ) {
                y = (box.height-size)/2;
                y -= (size+leading)*(lines-1)/2;
            } else if( vAlign == Alignment.Center ) {
                y += (h-size)/2-(size+leading)*(lines-1)/2;
            } else if( vAlign == Alignment.Bottom ) {
                y += (h-size) - (size+leading)*(lines-1);
            }
        }
        y += ascent;

        // calculate starting point for alignment
        float paintX = x;
        switch( hAlign ) {
            case Right: {
                paintX = x + w - textLayout.getVisibleAdvance();
                break;
            }
            case Center: {
                paintX = x + (w - textLayout.getVisibleAdvance())/2;
                break;
            }
        }

        // Draw line
        textLayout.draw(g2d, paintX, y);

        // Move down to top of next line
        y += descent + leading;
        i++;
    }

The relevant code snippet is shown above. attribText is an AttributtedString set before. context is the g2d.getFontRenderContext().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

栖迟 2024-09-17 02:01:08

这篇文章现在已经很旧了,所以我希望您已经找到了适合您需求的解决方案。如果你还没有,这里有一些值得思考的事情。您只需要绘制可见区域内的文本。由于您知道每条线的 y 坐标,因此可以轻松检查 y 是否位于 getVisibleRect() 的范围内。仅绘制必要的文本可以极大地提高性能(当然假设您的文本比单页长)。

This post is rather old now so I hope you have found a solution that works for your needs. If you haven't here is something to think about. You only need to draw the text that is within the visible region. Since you know the y coordinate of each line it is easy to check to see if the y lies within the bounds of getVisibleRect(). Only painting the text that is necessary greatly improves performance (assuming of course that your text is longer than a single page).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文