static void adjustRunOffsets(Vector<Run, 4>& lineRuns, ETextAlign textAlign, float lineWidth, float availableWidth)
{
    float lineLeft = computeLineLeft(textAlign, availableWidth - lineWidth);
    for (unsigned i = 0; i < lineRuns.size(); ++i) {
        lineRuns[i].left = floor(lineLeft + lineRuns[i].left);
        lineRuns[i].right = ceil(lineLeft + lineRuns[i].right);
    }
}
static void closeLineEndingAndAdjustRuns(LineState& line, Layout::RunVector& runs, unsigned previousRunCount, unsigned& lineCount, const TextFragmentIterator& textFragmentIterator)
{
    if (previousRunCount == runs.size())
        return;
    ASSERT(runs.size());
    removeTrailingWhitespace(line, runs, textFragmentIterator);
    if (!runs.size())
        return;
    // Adjust runs' position by taking line's alignment into account.
    if (float lineLogicalLeft = computeLineLeft(textFragmentIterator.style().textAlign, line.availableWidth(), line.width(), line.logicalLeftOffset())) {
        for (unsigned i = previousRunCount; i < runs.size(); ++i) {
            runs[i].logicalLeft += lineLogicalLeft;
            runs[i].logicalRight += lineLogicalLeft;
        }
    }
    runs.last().isEndOfLine = true;
    ++lineCount;
}
void createTextRuns(Layout::RunVector& runs, unsigned& lineCount, RenderBlockFlow& flow, RenderText& textRenderer)
{
    const Style style(flow.style());

    const CharacterType* text = textRenderer.text()->characters<CharacterType>();
    const unsigned textLength = textRenderer.textLength();

    LayoutUnit borderAndPaddingBefore = flow.borderAndPaddingBefore();
    LayoutUnit lineHeight = lineHeightFromFlow(flow);

    LazyLineBreakIterator lineBreakIterator(textRenderer.text(), flow.style().locale());

    unsigned lineEnd = 0;
    while (lineEnd < textLength) {
        if (style.collapseWhitespace)
            lineEnd = skipWhitespaces(text, lineEnd, textLength, style.preserveNewline);

        unsigned lineStart = lineEnd;

        // LineWidth reads the current y position from the flow so keep it updated.
        flow.setLogicalHeight(lineHeight * lineCount + borderAndPaddingBefore);
        LineWidth lineWidth(flow, false, DoNotIndentText);

        auto lineRuns = createLineRuns(lineStart, lineWidth, lineBreakIterator, style, text, textLength, textRenderer);

        lineEnd = lineRuns.last().end;
        if (lineStart == lineEnd)
            continue;

        lineRuns.last().isEndOfLine = true;

        float lineLeft = computeLineLeft(style.textAlign, lineWidth);
        adjustRunOffsets(lineRuns, lineLeft);

        for (unsigned i = 0; i < lineRuns.size(); ++i)
            runs.append(lineRuns[i]);

        ++lineCount;
    }
}