【问题标题】:How can I improve Java2D performance of TextLayout.draw(..)如何提高 TextLayout.draw(..) 的 Java2D 性能
【发布时间】:2010-07-13 18:19:05
【问题描述】:

我正在使用 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++;
    }

相关代码sn-p如上图所示。 attribText 是之前设置的 AttributtedStringcontextg2d.getFontRenderContext()

【问题讨论】:

  • 让我补充一点:代码在全新的 Ubuntu 10.04 上运行。不知道为什么这会有所作为 - 但我注意到在旧的 Windows XP 上它实际上运行得更快(类似的机器)。不幸的是,Eclipse 分析器在 XP 机器上不起作用,所以我无法判断该方法本身是否仍然比其他方法使用更多的资源,或者它是否只是整体上更快。
  • 再深入一点,我意识到TextLayout.draw() 隐式调用drawGlyphVector(),这是时间接收器。也许真正的问题是:如何使用 Java2D 绘制自动换行的文本,避免使用 TextLayout 并改用 drawString()
  • 你是对的! textlayout.draw() 将绘制文本而不是写它; graphics.drawString() 将写入文本,它确实比 textlayout.draw() 函数快。如果您的文本的一小部分没有特殊属性,您可以调用 g2d.drawString(str.substring(posA, posB), paintX, y);这会更快(我已经在我的应用程序中这样做了);与 posA 和 posB 是 measurer.getPosition() juste before and juste after doing measurer.nextLayout(w).

标签: performance text java-2d


【解决方案1】:

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

【讨论】:

  • 虽然您所说的通常是正确的,但就我而言,我是在画布上绘制的,该画布将是要写入磁盘的位图。我需要画出整个东西才能创造出有意义的图像。而且我还没有发现任何出色的东西。
猜你喜欢
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 2021-10-13
  • 2018-03-01
  • 2020-04-28
  • 2014-09-22
相关资源
最近更新 更多