【发布时间】:2010-07-13 18:19:05
【问题描述】:
我正在使用 Java2D TextLayout 类以及 LineBreakMeasurer 和 AttributedCharacterIterator 将一段文本绘制到一个框中。文本已换行。
分析显示代码非常慢。大部分时间都浪费在了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 是之前设置的 AttributtedString。 context 是g2d.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