void update() {
        LetterQuad l = head;
        int lineCount = 1;
        BitmapCharacter ellipsis = font.getCharSet().getCharacter(block.getEllipsisChar());
        float ellipsisWidth = ellipsis!=null? ellipsis.getWidth()*getScale(): 0;

        while (!l.isTail()) {
            if (l.isInvalid()) {
                l.update(block);
                // Without a text block, the next line always returns false = no text wrap will be applied.
                if (l.isInvalid(block)) {
                    switch (block.getLineWrapMode()) {
                    case Character:
                        lineWrap(l);
                        lineCount++;
                        break;
                    case Word:
                        if (!l.isBlank()) {
                            // search last blank character before this word
                            LetterQuad blank = l;
                            while (!blank.isBlank()) {
                                if (blank.isLineStart() || blank.isHead()) {
                                    lineWrap(l);
                                    lineCount++;
                                    blank = null;
                                    break;
                                }
                                blank = blank.getPrevious();
                            }
                            if (blank != null) {
                                blank.setEndOfLine();
                                lineCount++;
                                while (blank != l) {
                                    blank = blank.getNext();
                                    blank.invalidate();
                                    blank.update(block);
                                }
                            }
                        }
                        break;
                    case NoWrap:
                        LetterQuad cursor = l.getPrevious();
                        while (cursor.isInvalid(block, ellipsisWidth) && !cursor.isLineStart()) {
                            cursor = cursor.getPrevious();
                        }
                        cursor.setBitmapChar(ellipsis);
                        cursor.update(block);
                        cursor = cursor.getNext();
                        while (!cursor.isTail() && !cursor.isLineFeed()) {
                            cursor.setBitmapChar(null);
                            cursor.update(block);
                            cursor = cursor.getNext();
                        }
                        break;
                    case Clip:
                        // Clip the character that falls out of bounds
                        l.clip(block);

                        // Clear the rest up to the next line feed.
                        // = for texts attached to a text block, all coming characters are cleared except a linefeed is explicitly used
                        for (LetterQuad q = l.getNext(); !q.isTail() && !q.isLineFeed(); q = q.getNext()) {
                            q.setBitmapChar(null);
                            q.update(block);
                        }
                        break;
                    }
                }
            } else if (current.isInvalid(block)) {
                invalidate(current);
            }
            if (l.isEndOfLine()) {
                lineCount++;
            }
            l = l.getNext();
        }

        block.setLineCount(lineCount);
        align();
        rewind();
    }
Manage and align LetterQuads
@author YongHoon
jme3-core/src/main/java/com/jme3/font/Letters.java