Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling \n in LineBreakMeasurer

There are thousand articles how to use LineBreakMeasurer to draw multi-line text but there is none about drawing multi-line text taking into account also \n(when you want to force a new line at a specific position in text and not only when the right - or left - margin ends).

The secret seems to lie in BreakIterator, but I couldn't find an implementation which handles \n.

like image 408
adrian.tarau Avatar asked Nov 22 '25 21:11

adrian.tarau


2 Answers

Instead of LineBreakMeasurer's (LBM's) nextLayout(float) method, use the overloaded LBM.nextLayout(float, int, boolean) method. This allows you to limit the text that LBM will include in the returned TextLayout. In your case, you'll instruct it not to go beyond the next newline.

This code snippet should give you the idea. First use LBM.nextOffset to "peek" which character index would be the end of the next layout. Then iterate over your string content up to that offset to see if you find any newline characters. If you do, then use that found limit as the second argument to nextLayout(float, int, boolean) which will tell LBM not to exceed the newline:

int next = lineMeasurer.nextOffset(formatWidth);
int limit = next;
if (limit < totalLength) {
   for (int i = lineMeasurer.getPosition(); i < next; ++i) {
      char c = string.charAt(i);
      if (c == '\n') {
         limit = i;
         break;
      }
   }
}

TextLayout layout = lineMeasurer.nextLayout(formatWidth, limit, false);

References

http://java.sun.com/developer/onlineTraining/Media/2DText/style.html#layout http://java.sun.com/developer/onlineTraining/Media/2DText/Code/LineBreakSample.java

like image 81
aaron Avatar answered Nov 25 '25 10:11

aaron


I find that this code works well for the newline issue. I used atdixon as a template to get this.

while (measurer.getPosition() < paragraph.getEndIndex()) {
   next = measurer.nextOffset(wrappingWidth);
   limit = next;
   charat = tested.indexOf('\n',measurer.getPosition()+1);
   if(next > (charat - measurer.getPosition()) && charat != -1){
      limit = charat - measurer.getPosition();
   }
   layout = measurer.nextLayout(wrappingWidth, measurer.getPosition()+limit, false);
   // Do the rest of your layout and pen work.
}
like image 36
Brett Avatar answered Nov 25 '25 10:11

Brett



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!