Changeset 175565 in webkit


Ignore:
Timestamp:
Nov 4, 2014 12:08:13 PM (9 years ago)
Author:
Alan Bujtas
Message:

Simple line layout: Cleanup line initialization and line closing.
https://bugs.webkit.org/show_bug.cgi?id=138273

Reviewed by Antti Koivisto.

This is in preparation to support multiple render elements.

Move line start and line end activities to dedicated functions.

Covered by existing tests.

  • rendering/SimpleLineLayout.cpp:

(WebCore::SimpleLineLayout::LineState::LineState): Add lineStartRunIndex to be more explicit
about whether a line advanced with new runs. Rename a few members. Introduce LineState::oveflowedFragment
so that line closing can handled separately.
(WebCore::SimpleLineLayout::LineState::commitAndCreateRun):
(WebCore::SimpleLineLayout::LineState::addUncommitted):
(WebCore::SimpleLineLayout::LineState::jumpTo):
(WebCore::SimpleLineLayout::LineState::addUncommittedWhitespace): Deleted. : Remove redundant function.
(WebCore::SimpleLineLayout::LineState::removeCommittedTrailingWhitespace):
(WebCore::SimpleLineLayout::LineState::resetTrailingWhitespace):
(WebCore::SimpleLineLayout::removeTrailingWhitespace): Add resetTrailingWhitespace()
so that all trailing whitespace handling is in one function.
(WebCore::SimpleLineLayout::initializeNewLine): Separate line start and line end initialization/reset.
(WebCore::SimpleLineLayout::createLineRuns):
(WebCore::SimpleLineLayout::closeLineEndingAndAdjustRuns): This function manages all line ending activities.
(WebCore::SimpleLineLayout::createTextRuns):
(WebCore::SimpleLineLayout::create):
(WebCore::SimpleLineLayout::initializeLine): Deleted.

  • rendering/SimpleLineLayout.h:

(WebCore::SimpleLineLayout::Run::Run): Deleted.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r175564 r175565  
     12014-11-04  Zalan Bujtas  <zalan@apple.com>
     2
     3        Simple line layout: Cleanup line initialization and line closing.
     4        https://bugs.webkit.org/show_bug.cgi?id=138273
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This is in preparation to support multiple render elements.
     9
     10        Move line start and line end activities to dedicated functions.
     11
     12        Covered by existing tests.
     13
     14        * rendering/SimpleLineLayout.cpp:
     15        (WebCore::SimpleLineLayout::LineState::LineState): Add lineStartRunIndex to be more explicit
     16        about whether a line advanced with new runs. Rename a few members. Introduce LineState::oveflowedFragment
     17        so that line closing can handled separately.
     18        (WebCore::SimpleLineLayout::LineState::commitAndCreateRun):
     19        (WebCore::SimpleLineLayout::LineState::addUncommitted):
     20        (WebCore::SimpleLineLayout::LineState::jumpTo):
     21        (WebCore::SimpleLineLayout::LineState::addUncommittedWhitespace): Deleted. : Remove redundant function. 
     22        (WebCore::SimpleLineLayout::LineState::removeCommittedTrailingWhitespace):
     23        (WebCore::SimpleLineLayout::LineState::resetTrailingWhitespace):
     24        (WebCore::SimpleLineLayout::removeTrailingWhitespace): Add resetTrailingWhitespace()
     25        so that all trailing whitespace handling is in one function.
     26        (WebCore::SimpleLineLayout::initializeNewLine): Separate line start and line end initialization/reset.
     27        (WebCore::SimpleLineLayout::createLineRuns):
     28        (WebCore::SimpleLineLayout::closeLineEndingAndAdjustRuns): This function manages all line ending activities.
     29        (WebCore::SimpleLineLayout::createTextRuns):
     30        (WebCore::SimpleLineLayout::create):
     31        (WebCore::SimpleLineLayout::initializeLine): Deleted.
     32        * rendering/SimpleLineLayout.h:
     33        (WebCore::SimpleLineLayout::Run::Run): Deleted.
     34
    1352014-11-04  Tim Horton  <timothy_horton@apple.com>
    236
  • trunk/Source/WebCore/rendering/SimpleLineLayout.cpp

    r175259 r175565  
    278278    { }
    279279
    280     TextFragment(unsigned textStart, unsigned textEnd, unsigned textWidth)
     280    TextFragment(unsigned textStart, unsigned textEnd, float textWidth, bool isWhitespaceOnly)
    281281        : start(textStart)
    282282        , isCollapsedWhitespace(false)
    283283        , end(textEnd)
    284         , isWhitespaceOnly(false)
     284        , isWhitespaceOnly(isWhitespaceOnly)
    285285        , isBreakable(false)
    286286        , mustBreak(false)
     
    306306        : availableWidth(0)
    307307        , logicalLeftOffset(0)
     308        , lineStartRunIndex(0)
    308309        , uncommittedStart(0)
    309310        , uncommittedEnd(0)
    310         , uncommittedLeft(0)
    311311        , uncommittedWidth(0)
    312312        , committedWidth(0)
    313         , end(0)
     313        , committedLogicalRight(0)
     314        , position(0)
    314315        , trailingWhitespaceWidth(0)
    315316    {
     
    321322            return;
    322323
    323         lineRuns.append(Run(uncommittedStart, uncommittedEnd, uncommittedLeft, uncommittedLeft + uncommittedWidth, false));
     324        lineRuns.append(Run(uncommittedStart, uncommittedEnd, committedLogicalRight, committedLogicalRight + uncommittedWidth, false));
    324325        // Move uncommitted to committed.
    325326        committedWidth += uncommittedWidth;
     327        committedLogicalRight += committedWidth;
    326328
    327329        uncommittedStart = uncommittedEnd;
    328         uncommittedLeft += uncommittedWidth;
    329330        uncommittedWidth = 0;
    330331    }
     
    332333    void addUncommitted(const TextFragment& fragment)
    333334    {
    334         addUncommitted(fragment.end, fragment.width, fragment.isWhitespaceOnly);
    335     }
    336 
    337     void addUncommitted(unsigned fragmentEnd, float fragmentWidth, bool whitespaceOnly)
    338     {
    339         unsigned uncomittedFragmentLength = fragmentEnd - uncommittedEnd;
    340         uncommittedWidth += fragmentWidth;
    341         uncommittedEnd = fragmentEnd;
    342         end = uncommittedEnd;
    343         trailingWhitespaceWidth = whitespaceOnly ? fragmentWidth : 0;
    344         trailingWhitespaceLength = whitespaceOnly ? uncomittedFragmentLength  : 0;
     335        unsigned uncomittedFragmentLength = fragment.end - uncommittedEnd;
     336        uncommittedWidth += fragment.width;
     337        uncommittedEnd = fragment.end;
     338        position = uncommittedEnd;
     339        trailingWhitespaceWidth = fragment.isWhitespaceOnly ? fragment.width : 0;
     340        trailingWhitespaceLength = fragment.isWhitespaceOnly ? uncomittedFragmentLength  : 0;
    345341    }
    346342
    347343    void addUncommittedWhitespace(float whitespaceWidth)
    348344    {
    349         addUncommitted(uncommittedEnd + 1, whitespaceWidth, true);
    350     }
    351 
    352     void jumpTo(unsigned newPositon, float leftX)
    353     {
    354         end = newPositon;
     345        addUncommitted(TextFragment(uncommittedEnd, uncommittedEnd + 1, whitespaceWidth, true));
     346    }
     347
     348    void jumpTo(unsigned newPositon, float logicalRight)
     349    {
     350        position = newPositon;
    355351
    356352        uncommittedStart = newPositon;
    357353        uncommittedEnd = newPositon;
    358         uncommittedLeft = leftX;
    359354        uncommittedWidth = 0;
     355        committedLogicalRight = logicalRight;
    360356    }
    361357
     
    374370        ASSERT(!uncommittedWidth);
    375371        committedWidth -= trailingWhitespaceWidth;
     372        committedLogicalRight -= trailingWhitespaceWidth;
     373    }
     374
     375    void resetTrailingWhitespace()
     376    {
    376377        trailingWhitespaceWidth = 0;
    377378        trailingWhitespaceLength = 0;
     
    380381    float availableWidth;
    381382    float logicalLeftOffset;
     383    unsigned lineStartRunIndex; // The run that the line starts with.
    382384
    383385    unsigned uncommittedStart;
    384386    unsigned uncommittedEnd;
    385     float uncommittedLeft;
    386387    float uncommittedWidth;
    387388    float committedWidth;
    388     unsigned end; // End position of the current line.
     389    float committedLogicalRight; // Last committed X (coordinate) position.
     390
     391    unsigned position;
     392
    389393    float trailingWhitespaceWidth; // Use this to remove trailing whitespace without re-mesuring the text.
    390394    float trailingWhitespaceLength;
     395
     396    TextFragment oveflowedFragment;
    391397};
    392398
    393399template <typename CharacterType>
    394 static void removeTrailingWhitespace(LineState& line, TextFragment& fragmentForNextLine, Layout::RunVector& lineRuns, const Style& style, const CharacterType* text, unsigned textLength)
     400static void removeTrailingWhitespace(LineState& lineState, Layout::RunVector& lineRuns, const Style& style, const CharacterType* text, unsigned textLength)
    395401{
    396402    bool preWrap = style.wrapLines && !style.collapseWhitespace;
    397403    // Trailing whitespace gets removed when we either collapse whitespace or pre-wrap is present.
    398     if (!(style.collapseWhitespace || preWrap))
     404    if (!(style.collapseWhitespace || preWrap)) {
     405        lineState.resetTrailingWhitespace();
    399406        return;
     407    }
    400408
    401409    ASSERT(lineRuns.size());
    402410    Run& lastRun = lineRuns.last();
    403411
    404     unsigned originalLineEnd = line.end;
     412    unsigned lastPosition = lineState.position;
    405413    bool trailingPreWrapWhitespaceNeedsToBeRemoved = false;
    406414    // When pre-wrap is present, trailing whitespace needs to be removed:
    407     // 1. from the "next line": when at least the first charater fits. When even the first whitespace is wider that the available width, we don't remove any whitespace at all.
     415    // 1. from the "next line": when at least the first charater fits. When even the first whitespace is wider that the available width,
     416    // we don't remove any whitespace at all.
    408417    // 2. from this line: remove whitespace, unless it's the only fragment on the line -so removing the whitesapce would produce an empty line.
    409418    if (preWrap) {
    410         if (fragmentForNextLine.isWhitespaceOnly && !fragmentForNextLine.isEmpty() && line.availableWidth >= line.committedWidth) {
    411             line.end = fragmentForNextLine.end;
    412             fragmentForNextLine = TextFragment();
     419        if (lineState.oveflowedFragment.isWhitespaceOnly && !lineState.oveflowedFragment.isEmpty() && lineState.availableWidth >= lineState.committedWidth) {
     420            lineState.position = lineState.oveflowedFragment.end;
     421            lineState.oveflowedFragment = TextFragment();
    413422        }
    414         if (line.trailingWhitespaceLength)
    415             trailingPreWrapWhitespaceNeedsToBeRemoved = !(line.committedWidth == line.trailingWhitespaceWidth); // Check if we've got only whitespace on this line.
    416     }
    417     if (line.trailingWhitespaceLength && (style.collapseWhitespace || trailingPreWrapWhitespaceNeedsToBeRemoved)) {
    418         lastRun.right -= line.trailingWhitespaceWidth;
    419         lastRun.end -= line.trailingWhitespaceLength;
     423        if (lineState.trailingWhitespaceLength) {
     424            // Check if we've got only whitespace on this line.
     425            trailingPreWrapWhitespaceNeedsToBeRemoved = !(lineState.committedWidth == lineState.trailingWhitespaceWidth);
     426        }
     427    }
     428    if (lineState.trailingWhitespaceLength && (style.collapseWhitespace || trailingPreWrapWhitespaceNeedsToBeRemoved)) {
     429        lastRun.logicalRight -= lineState.trailingWhitespaceWidth;
     430        lastRun.end -= lineState.trailingWhitespaceLength;
    420431        if (lastRun.start == lastRun.end)
    421432            lineRuns.removeLast();
    422         line.removeCommittedTrailingWhitespace();
     433        lineState.removeCommittedTrailingWhitespace();
    423434    }
    424435
    425436    // If we skipped any whitespace and now the line end is a "preserved" newline, skip the newline too as we are wrapping the line here already.
    426     if (originalLineEnd != line.end && style.preserveNewline && line.end < textLength && text[line.end] == '\n')
    427         ++line.end;
    428 }
    429 
    430 template <typename CharacterType>
    431 static void initializeLine(LineState& line, const Style& style, const CharacterType* text, unsigned textLength)
    432 {
    433     line.committedWidth = 0;
    434     line.uncommittedLeft = 0;
    435     line.trailingWhitespaceWidth = 0;
    436     line.trailingWhitespaceLength = 0;
     437    if (lastPosition != lineState.position && style.preserveNewline && lineState.position < textLength && text[lineState.position] == '\n')
     438        ++lineState.position;
     439}
     440
     441template <typename CharacterType>
     442static void initializeNewLine(LineState& lineState, const Style& style, const CharacterType* text, unsigned textLength, unsigned lineStartRunIndex)
     443{
     444    lineState.lineStartRunIndex = lineStartRunIndex;
    437445    // Skip leading whitespace if collapsing whitespace, unless there's an uncommitted fragment pushed from the previous line.
    438446    // FIXME: Be smarter when the run from the previous line does not fit the current line. Right now, we just reprocess it.
    439     if (line.uncommittedWidth && !line.fits(line.uncommittedWidth))
    440         line.jumpTo(line.uncommittedStart, 0); // Start over with this fragment.
    441     else if (!line.uncommittedWidth) {
     447    if (lineState.oveflowedFragment.width) {
     448        if (lineState.fits(lineState.oveflowedFragment.width))
     449            lineState.addUncommitted(lineState.oveflowedFragment);
     450        else
     451            lineState.jumpTo(lineState.oveflowedFragment.start, 0); // Start over with this fragment.
     452    } else {
    442453        unsigned spaceCount = 0;
    443         line.jumpTo(style.collapseWhitespace ? skipWhitespace(text, line.end, textLength, style.preserveNewline, spaceCount) : line.end, 0);
    444     }
     454        lineState.jumpTo(style.collapseWhitespace ? skipWhitespace(text, lineState.position, textLength, style.preserveNewline, spaceCount) : lineState.position, 0);
     455    }
     456    lineState.oveflowedFragment = TextFragment();
    445457}
    446458
     
    529541
    530542template <typename CharacterType>
    531 bool createLineRuns(LineState& line, Layout::RunVector& lineRuns, unsigned& lineCount, LazyLineBreakIterator& lineBreakIterator, const Style& style, const CharacterType* text,
     543bool createLineRuns(LineState& lineState, Layout::RunVector& lineRuns, LazyLineBreakIterator& lineBreakIterator, const Style& style, const CharacterType* text,
    532544    unsigned textLength, const RenderText& textRenderer)
    533545{
    534     unsigned previousNumberOfRuns = lineRuns.size();
    535     TextFragment fragmentForNextLine;
    536     initializeLine(line, style, text, textLength);
    537546    bool lineCanBeWrapped = style.wrapLines || style.breakWordOnOverflow;
    538     while (line.end < textLength) {
     547    while (lineState.position < textLength) {
    539548        // Find the next text fragment. Start from the end of the previous fragment -current line end.
    540         TextFragment fragment = nextFragment(line.end, lineBreakIterator, style, text, textLength, line.width(), textRenderer);
    541         if ((lineCanBeWrapped && !line.fits(fragment.width)) || fragment.mustBreak) {
     549        TextFragment fragment = nextFragment(lineState.position, lineBreakIterator, style, text, textLength, lineState.width(), textRenderer);
     550        if ((lineCanBeWrapped && !lineState.fits(fragment.width)) || fragment.mustBreak) {
    542551            // Overflow wrapping behaviour:
    543552            // 1. Newline character: wraps the line unless it's treated as whitespace.
     
    546555            // 4. First, non-whitespace fragment is either wrapped or kept on the line. (depends on overflow-wrap)
    547556            // 5. Non-whitespace fragment when there's already another fragment on the line gets pushed to the next line.
    548             bool isFirstFragment = !line.width();
     557            bool isFirstFragment = !lineState.width();
    549558            if (fragment.mustBreak) {
    550559                if (isFirstFragment)
    551                     line.addUncommitted(fragment);
     560                    lineState.addUncommitted(fragment);
    552561                else {
    553562                    // No need to add the new line fragment if there's already content on the line. We are about to close this line anyway.
    554                     ++line.end;
     563                    ++lineState.position;
    555564                }
    556565            } else if (style.collapseWhitespace && fragment.isWhitespaceOnly) {
    557566                // Whitespace collapse is on: whitespace that doesn't fit is simply skipped.
    558                 line.end = fragment.end;
     567                lineState.position = fragment.end;
    559568            } else if (fragment.isWhitespaceOnly || ((isFirstFragment && style.breakWordOnOverflow) || !style.wrapLines)) { // !style.wrapLines: bug138102(preserve existing behavior)
    560                 // Whitespace collapse is off or non-whitespace content. split the fragment; (modified)fragment -> this line, fragmentForNextLine -> next line.
     569                // Whitespace collapse is off or non-whitespace content. split the fragment; (modified)fragment -> this lineState, oveflowedFragment -> next line.
    561570                // When this is the only (first) fragment, the first character stays on the line, even if it does not fit.
    562                 fragmentForNextLine = splitFragmentToFitLine(fragment, line.availableWidth - line.width(), isFirstFragment, textRenderer, text, textLength, style);
     571                lineState.oveflowedFragment = splitFragmentToFitLine(fragment, lineState.availableWidth - lineState.width(), isFirstFragment, textRenderer, text, textLength, style);
    563572                if (!fragment.isEmpty()) {
    564573                    // Whitespace fragments can get pushed entirely to the next line.
    565                     line.addUncommitted(fragment);
     574                    lineState.addUncommitted(fragment);
    566575                }
    567576            } else if (isFirstFragment) {
    568577                // Non-breakable non-whitespace first fragment. Add it to the current line. -it overflows though.
    569                 line.addUncommitted(fragment);
     578                lineState.addUncommitted(fragment);
    570579            } else {
    571580                // Non-breakable non-whitespace fragment when there's already a fragment on the line. Push it to the next line.
    572                 fragmentForNextLine = fragment;
     581                lineState.oveflowedFragment = fragment;
    573582            }
    574583            break;
     
    577586        if (fragment.isCollapsedWhitespace) {
    578587            // One trailing whitespace to preserve.
    579             line.addUncommittedWhitespace(style.spaceWidth);
    580             line.commitAndCreateRun(lineRuns);
     588            lineState.addUncommittedWhitespace(style.spaceWidth);
     589            lineState.commitAndCreateRun(lineRuns);
    581590            // And skip the collapsed whitespace.
    582             line.jumpTo(fragment.end, line.width() + fragment.width - style.spaceWidth);
     591            lineState.jumpTo(fragment.end, lineState.width() + fragment.width - style.spaceWidth);
    583592        } else
    584             line.addUncommitted(fragment);
    585     }
    586     line.commitAndCreateRun(lineRuns);
    587     // Postprocessing the runs we added for this line.
    588     if (previousNumberOfRuns != lineRuns.size()) {
    589         removeTrailingWhitespace(line, fragmentForNextLine, lineRuns, style, text, textLength);
    590         lineRuns.last().isEndOfLine = true;
    591         // Adjust runs' position by taking line's alignment into account.
    592         if (float lineLeft = computeLineLeft(style.textAlign, line.availableWidth, line.committedWidth, line.logicalLeftOffset)) {
    593             for (unsigned i = previousNumberOfRuns; i < lineRuns.size(); ++i) {
    594                 lineRuns[i].left += lineLeft;
    595                 lineRuns[i].right += lineLeft;
    596             }
     593            lineState.addUncommitted(fragment);
     594    }
     595    lineState.commitAndCreateRun(lineRuns);
     596    return lineState.position >= textLength && lineState.oveflowedFragment.isEmpty();
     597}
     598
     599template <typename CharacterType>
     600static void closeLineEndingAndAdjustRuns(LineState& lineState, Layout::RunVector& lineRuns, unsigned& lineCount,
     601    const Style& style, const CharacterType* text, unsigned textLength)
     602{
     603    if (lineState.lineStartRunIndex == lineRuns.size())
     604        return;
     605
     606    ASSERT(lineRuns.size());
     607    removeTrailingWhitespace(lineState, lineRuns, style, text, textLength);
     608    // Adjust runs' position by taking line's alignment into account.
     609    if (float lineLogicalLeft = computeLineLeft(style.textAlign, lineState.availableWidth, lineState.committedWidth, lineState.logicalLeftOffset)) {
     610        for (unsigned i = lineState.lineStartRunIndex; i < lineRuns.size(); ++i) {
     611            lineRuns[i].logicalLeft += lineLogicalLeft;
     612            lineRuns[i].logicalRight += lineLogicalLeft;
    597613        }
    598         ++lineCount;
    599     }
    600     if (!fragmentForNextLine.isEmpty())
    601         line.addUncommitted(fragmentForNextLine);
    602     return line.end < textLength || line.uncommittedWidth;
     614    }
     615    lineRuns.last().isEndOfLine = true;
     616    lineState.committedWidth = 0;
     617    lineState.committedLogicalRight = 0;
     618    ++lineCount;
    603619}
    604620
     
    621637    LayoutUnit lineHeight = lineHeightFromFlow(flow);
    622638    LazyLineBreakIterator lineBreakIterator(textRenderer.text(), flow.style().locale());
    623     LineState line;
     639    LineState lineState;
     640    bool isEndOfContent = false;
    624641
    625642    do {
    626643        flow.setLogicalHeight(lineHeight * lineCount + borderAndPaddingBefore);
    627         updateLineConstrains(flow, line.availableWidth, line.logicalLeftOffset);
    628     } while (createLineRuns(line, runs, lineCount, lineBreakIterator, style, text, textLength, textRenderer));
     644        updateLineConstrains(flow, lineState.availableWidth, lineState.logicalLeftOffset);
     645        initializeNewLine(lineState, style, text, textLength, runs.size());
     646        isEndOfContent = createLineRuns(lineState, runs, lineBreakIterator, style, text, textLength, textRenderer);
     647        closeLineEndingAndAdjustRuns(lineState, runs, lineCount, style, text, textLength);
     648    } while (!isEndOfContent);
     649    ASSERT(!lineState.uncommittedWidth);
    629650}
    630651
     
    643664
    644665    textRenderer.clearNeedsLayout();
    645 
    646666    return Layout::create(runs, lineCount);
    647667}
  • trunk/Source/WebCore/rendering/SimpleLineLayout.h

    r175259 r175565  
    4444
    4545struct Run {
    46     Run() { }
    47     Run(unsigned start, float left)
    48         : start(start)
    49         , end(start)
    50         , isEndOfLine(false)
    51         , left(left)
    52         , right(left)
    53     { }
    54     Run(unsigned start, unsigned end, float left, float right, bool isEndOfLine)
     46    Run(unsigned start, unsigned end, float logicalLeft, float logicalRight, bool isEndOfLine)
    5547        : start(start)
    5648        , end(end)
    5749        , isEndOfLine(isEndOfLine)
    58         , left(left)
    59         , right(right)
     50        , logicalLeft(logicalLeft)
     51        , logicalRight(logicalRight)
    6052    { }
    6153
     
    6355    unsigned end : 31;
    6456    unsigned isEndOfLine : 1;
    65     float left;
    66     float right;
     57    float logicalLeft;
     58    float logicalRight;
    6759};
    6860
  • trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h

    r174451 r175565  
    169169
    170170    float baselinePosition = resolver.m_lineHeight * m_iterator.lineIndex() + resolver.m_baseline;
    171     LayoutPoint linePosition(LayoutUnit::fromFloatFloor(run.left), roundToInt(baselinePosition - resolver.m_ascent + resolver.m_borderAndPaddingBefore));
    172     LayoutSize lineSize(LayoutUnit::fromFloatCeil(run.right) - LayoutUnit::fromFloatFloor(run.left), resolver.m_ascent + resolver.m_descent);
     171    LayoutPoint linePosition(LayoutUnit::fromFloatFloor(run.logicalLeft), roundToInt(baselinePosition - resolver.m_ascent + resolver.m_borderAndPaddingBefore));
     172    LayoutSize lineSize(LayoutUnit::fromFloatCeil(run.logicalRight) - LayoutUnit::fromFloatFloor(run.logicalLeft), resolver.m_ascent + resolver.m_descent);
    173173    return LayoutRect(linePosition, lineSize);
    174174}
     
    180180
    181181    float baselinePosition = resolver.m_lineHeight * m_iterator.lineIndex() + resolver.m_baseline;
    182     return FloatPoint(run.left, roundToInt(baselinePosition + resolver.m_borderAndPaddingBefore));
     182    return FloatPoint(run.logicalLeft, roundToInt(baselinePosition + resolver.m_borderAndPaddingBefore));
    183183}
    184184
Note: See TracChangeset for help on using the changeset viewer.