Я использую класс Java2D TextLayout
вместе с LineBreakMeasurer
и AttributedCharacterIterator
, чтобы нарисовать кусок текста в поле. Текст завернут.Как улучшить производительность Java2D в TextLayout.draw (..)
Профилирование показывает мне, что код очень медленный. Большая часть времени теряется в методе 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
- AttributtedString
, установленный ранее. context
- g2d.getFontRenderContext()
.
Позвольте мне что-то добавить: код работает на новом Ubuntu 10.04. Не уверен, почему это должно измениться, но я заметил, что на старой Windows XP он работает намного быстрее (аналогичная машина). К сожалению, профилировщик Eclipse не работает на компьютере XP, поэтому я не могу судить, использует ли этот метод больше ресурсов, чем остальные, или если он просто быстрее в целом. – kongo09
Копаясь немного глубже, я понял, что 'TextLayout.draw()' неявно называет 'drawGlyphVector()', который является потоком времени. Может быть, реальный вопрос: как сделать текст с текстом с Java2D, избегая «TextLayout» и используя 'drawString()' вместо этого? – kongo09
Вы правы! textlayout.draw() будет рисовать текст и не писать; graphics.drawString() будет писать текст, и это действительно быстрее, чем функция textlayout.draw(). Если у вас нет специального атрибута для небольшой части текста, вы можете вызвать g2d.drawString (str.substring (posA, posB), paintX, y); который будет действительно быстрее (я сделал это в своем приложении); с posA и posB являются measurer.getPosition() juste before и juste после выполнения measurer.nextLayout (w). – Alexxx