Пример #1
0
void GlyphArrangement::justifyGlyphs (const int startIndex, const int num,
                                      const float x, const float y, const float width, const float height,
                                      const Justification& justification)
{
    jassert (num >= 0 && startIndex >= 0);

    if (glyphs.size() > 0 && num > 0)
    {
        const Rectangle<float> bb (getBoundingBox (startIndex, num, ! justification.testFlags (Justification::horizontallyJustified
                                                                                                | Justification::horizontallyCentred)));
        float deltaX = 0.0f;

        if (justification.testFlags (Justification::horizontallyJustified))
            deltaX = x - bb.getX();
        else if (justification.testFlags (Justification::horizontallyCentred))
            deltaX = x + (width - bb.getWidth()) * 0.5f - bb.getX();
        else if (justification.testFlags (Justification::right))
            deltaX = (x + width) - bb.getRight();
        else
            deltaX = x - bb.getX();

        float deltaY = 0.0f;

        if (justification.testFlags (Justification::top))
            deltaY = y - bb.getY();
        else if (justification.testFlags (Justification::bottom))
            deltaY = (y + height) - bb.getBottom();
        else
            deltaY = y + (height - bb.getHeight()) * 0.5f - bb.getY();

        moveRangeOfGlyphs (startIndex, num, deltaX, deltaY);

        if (justification.testFlags (Justification::horizontallyJustified))
        {
            int lineStart = 0;
            float baseY = glyphs.getUnchecked (startIndex)->getBaselineY();

            int i;
            for (i = 0; i < num; ++i)
            {
                const float glyphY = glyphs.getUnchecked (startIndex + i)->getBaselineY();

                if (glyphY != baseY)
                {
                    spreadOutLine (startIndex + lineStart, i - lineStart, width);

                    lineStart = i;
                    baseY = glyphY;
                }
            }

            if (i > lineStart)
                spreadOutLine (startIndex + lineStart, i - lineStart, width);
        }
    }
}
void GlyphArrangement::addJustifiedText (const Font& font,
                                         const String& text,
                                         float x, float y,
                                         const float maxLineWidth,
                                         Justification horizontalLayout)
{
    int lineStartIndex = glyphs.size();
    addLineOfText (font, text, x, y);

    const float originalY = y;

    while (lineStartIndex < glyphs.size())
    {
        int i = lineStartIndex;

        if (glyphs.getReference(i).getCharacter() != '\n'
              && glyphs.getReference(i).getCharacter() != '\r')
            ++i;

        const float lineMaxX = glyphs.getReference (lineStartIndex).getLeft() + maxLineWidth;
        int lastWordBreakIndex = -1;

        while (i < glyphs.size())
        {
            const PositionedGlyph& pg = glyphs.getReference (i);
            const juce_wchar c = pg.getCharacter();

            if (c == '\r' || c == '\n')
            {
                ++i;

                if (c == '\r' && i < glyphs.size()
                     && glyphs.getReference(i).getCharacter() == '\n')
                    ++i;

                break;
            }

            if (pg.isWhitespace())
            {
                lastWordBreakIndex = i + 1;
            }
            else if (pg.getRight() - 0.0001f >= lineMaxX)
            {
                if (lastWordBreakIndex >= 0)
                    i = lastWordBreakIndex;

                break;
            }

            ++i;
        }

        const float currentLineStartX = glyphs.getReference (lineStartIndex).getLeft();
        float currentLineEndX = currentLineStartX;

        for (int j = i; --j >= lineStartIndex;)
        {
            if (! glyphs.getReference (j).isWhitespace())
            {
                currentLineEndX = glyphs.getReference (j).getRight();
                break;
            }
        }

        float deltaX = 0.0f;

        if (horizontalLayout.testFlags (Justification::horizontallyJustified))
            spreadOutLine (lineStartIndex, i - lineStartIndex, maxLineWidth);
        else if (horizontalLayout.testFlags (Justification::horizontallyCentred))
            deltaX = (maxLineWidth - (currentLineEndX - currentLineStartX)) * 0.5f;
        else if (horizontalLayout.testFlags (Justification::right))
            deltaX = maxLineWidth - (currentLineEndX - currentLineStartX);

        moveRangeOfGlyphs (lineStartIndex, i - lineStartIndex,
                           x + deltaX - currentLineStartX, y - originalY);

        lineStartIndex = i;

        y += font.getHeight();
    }
}