2010-07-13 1 views
3

Я использую класс 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().

+0

Позвольте мне что-то добавить: код работает на новом Ubuntu 10.04. Не уверен, почему это должно измениться, но я заметил, что на старой Windows XP он работает намного быстрее (аналогичная машина). К сожалению, профилировщик Eclipse не работает на компьютере XP, поэтому я не могу судить, использует ли этот метод больше ресурсов, чем остальные, или если он просто быстрее в целом. – kongo09

+0

Копаясь немного глубже, я понял, что 'TextLayout.draw()' неявно называет 'drawGlyphVector()', который является потоком времени. Может быть, реальный вопрос: как сделать текст с текстом с Java2D, избегая «TextLayout» и используя 'drawString()' вместо этого? – kongo09

+0

Вы правы! 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

ответ

0

Это сообщение довольно старое, поэтому я надеюсь, что вы нашли решение, которое работает для ваших нужд. Если вам не о чем подумать. Вам нужно всего лишь нарисовать текст, который находится внутри видимой области. Поскольку вы знаете координату y каждой строки, легко проверить, находится ли y в пределах getVisibleRect(). Только рисование необходимого текста значительно повышает производительность (предполагая, что ваш текст длиннее одной страницы).

+0

Хотя то, что вы говорите, в целом прав, в моем случае я рисовал на холсте, который будет растровым изображением на диске. Мне нужно сделать все, чтобы создать осмысленный образ. И я еще не нашел ничего блестящего. – kongo09

 Смежные вопросы

  • Нет связанных вопросов^_^