Non Native textLayout do not handle maxHeight

Hi Jules,

 

It looks like that the default TextLayout implementation do not handle maxHeight

 

Any idea what would be the best way to implement this ?

 

Thanks,

Looks like that it doesn't handle word wrapping either.

Some try regarding  maximum height though.

 

We definitly needs a better solution for tex tLayout in general in Juce.

 


void createLayout (const AttributedString& text, TextLayout& layout)
        {
            tokens.ensureStorageAllocated (64);
            layout.ensureStorageAllocated (totalLines);
            addTextRuns (text);
            layoutRuns (layout.getWidth());
            int charPosition = 0;
            int lineStartPosition = 0;
            int runStartPosition = 0;
            ScopedPointer<TextLayout::Line> currentLine;
            ScopedPointer<TextLayout::Run> currentRun;
            bool needToSetLineOrigin = true;
            for (int i = 0; i < tokens.size(); ++i)
            {
                const Token& t = *tokens.getUnchecked (i);
                Array<int> newGlyphs;
                Array<float> xOffsets;
                t.font.getGlyphPositions (getTrimmedEndIfNotAllWhitespace (t.text), newGlyphs, xOffsets);
                if (currentRun == nullptr)  currentRun  = new TextLayout::Run();
                if (currentLine == nullptr) currentLine = new TextLayout::Line();
                if (newGlyphs.size() > 0)
                {
                  if (Rectangle<float>(0.f, 0.f, layout.getWidth(), layout.getHeight()).contains(t.area))
                  {
                    currentRun->glyphs.ensureStorageAllocated (currentRun->glyphs.size() + newGlyphs.size());
                    const Point<float> tokenOrigin (t.area.getPosition().translated (0, t.font.getAscent()));
                    if (needToSetLineOrigin)
                    {
                        needToSetLineOrigin = false;
                        currentLine->lineOrigin = tokenOrigin;
                    }
                    const Point<float> glyphOffset (tokenOrigin - currentLine->lineOrigin);
                    for (int j = 0; j < newGlyphs.size(); ++j)
                    {
                        const float x = xOffsets.getUnchecked (j);
                        currentRun->glyphs.add (TextLayout::Glyph (newGlyphs.getUnchecked(j),
                                                                   glyphOffset.translated (x, 0),
                                                                   xOffsets.getUnchecked (j + 1) - x));
                    }
                  }
                  charPosition += newGlyphs.size();
                }
                if (t.isWhitespace || t.isNewLine)
                    ++charPosition;
                const Token* const nextToken = tokens [i + 1];
                if (nextToken == nullptr) // this is the last token
                {
                    addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition);
                    currentLine->stringRange = Range<int> (lineStartPosition, charPosition);
                    if (! needToSetLineOrigin)
                        layout.addLine (currentLine.release());
                    needToSetLineOrigin = true;
                }
                else if (Rectangle<float>(0.f, 0.f, layout.getWidth(), layout.getHeight()).contains(nextToken->area))
                {
                    if (t.font != nextToken->font || t.colour != nextToken->colour)
                    {
                        addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition);
                        runStartPosition = charPosition;
                    }
                    if (t.line != nextToken->line)
                    {
                        if (currentRun == nullptr)
                            currentRun = new TextLayout::Run();
                        addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition);
                        currentLine->stringRange = Range<int> (lineStartPosition, charPosition);
                        if (! needToSetLineOrigin)
                            layout.addLine (currentLine.release());
                        runStartPosition = charPosition;
                        lineStartPosition = charPosition;
                        needToSetLineOrigin = true;
                    }
                }
            }
            if ((text.getJustification().getFlags() & (Justification::right | Justification::horizontallyCentred)) != 0)
            {
                const float totalW = layout.getWidth();
                const bool isCentred = (text.getJustification().getFlags() & Justification::horizontallyCentred) != 0;
                for (int i = 0; i < layout.getNumLines(); ++i)
                {
                    float dx = totalW - layout.getLine(i).getLineBoundsX().getLength();
                    if (isCentred)
                        dx /= 2.0f;
                    layout.getLine(i).lineOrigin.x += dx;
                }
            }
        }

bump :)