void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float textAnchorStartOffset)
{
    bool wasInitialLayout = isInitialLayout();

    RenderSVGTextPath* textPath = toRenderSVGTextPath(flowBox->renderer());
    Path path = textPath->layoutPath();

    float baselineShift = calculateBaselineShift(textPath);

    layoutPath = path;
    layoutPathLength = path.length();

    if (layoutPathLength <= 0.0f)
        return;

    startOffset = textPath->startOffset();

    if (textPath->startOffset() >= 0.0f && textPath->startOffset() <= 1.0f)
        startOffset *= layoutPathLength;

    startOffset += textAnchorStartOffset;
    currentOffset = startOffset;

    // Only baseline-shift is handled through the normal layout system
    addStackContent(BaselineShiftStack, baselineShift);

    if (wasInitialLayout) {
        xStackChanged = false;
        yStackChanged = false;
        dxStackChanged = false;
        dyStackChanged = false;
        angleStackChanged = false;
        baselineShiftStackChanged = false;
    }
}
void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayoutEngine& lineLayout)
{
    ASSERT(object);

    m_inPathLayout = true;
    RenderSVGTextPath* textPath = toRenderSVGTextPath(object);

    Path path = textPath->layoutPath();
    if (path.isEmpty())
        return;
    m_textPathCalculator = new Path::PositionCalculator(path);
    m_textPathStartOffset = textPath->startOffset();
    m_textPathLength = path.length();
    if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1)
        m_textPathStartOffset *= m_textPathLength;

    float totalLength = 0;
    unsigned totalCharacters = 0;

    lineLayout.m_chunkLayoutBuilder.buildTextChunks(lineLayout.m_lineLayoutBoxes);
    const Vector<SVGTextChunk>& textChunks = lineLayout.m_chunkLayoutBuilder.textChunks();

    unsigned size = textChunks.size();
    for (unsigned i = 0; i < size; ++i) {
        const SVGTextChunk& chunk = textChunks.at(i);

        float length = 0;
        unsigned characters = 0;
        chunk.calculateLength(length, characters);

        // Handle text-anchor as additional start offset for text paths.
        m_textPathStartOffset += chunk.calculateTextAnchorShift(length);

        totalLength += length;
        totalCharacters += characters;
    }

    m_textPathCurrentOffset = m_textPathStartOffset;

    // Eventually handle textLength adjustments.
    SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown;
    float desiredTextLength = 0;

    if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textPath)) {
        SVGLengthContext lengthContext(textContentElement);
        lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumValue();
        if (textContentElement->textLengthIsSpecifiedByUser())
            desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext);
        else
            desiredTextLength = 0;
    }

    if (!desiredTextLength)
        return;

    if (lengthAdjust == SVGLengthAdjustSpacing)
        m_textPathSpacing = (desiredTextLength - totalLength) / totalCharacters;
    else
        m_textPathScaling = desiredTextLength / totalLength;
}