Changeset 85685 in webkit


Ignore:
Timestamp:
May 3, 2011 4:28:11 PM (13 years ago)
Author:
leviw@chromium.org
Message:

2011-05-03 Levi Weintraub <leviw@chromium.org>

Reviewed by Eric Seidel.

Refactor computeInlineDirectionPositionsForLine into smaller functions
https://bugs.webkit.org/show_bug.cgi?id=60072

Split three functions off from computeInlineDirectionPositionsForLine
to improve its readability.

No new tests since this is just moving code around.

  • rendering/RenderBlock.h:
  • rendering/RenderBlockLineLayout.cpp: (WebCore::RenderBlock::setMarginsForRubyRun): (WebCore::setLogicalWidthForTextRun): (WebCore::computeExpansionForJustifiedText): (WebCore::RenderBlock::computeInlineDirectionPositionsForLine):
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r85684 r85685  
     12011-05-03  Levi Weintraub  <leviw@chromium.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Refactor computeInlineDirectionPositionsForLine into smaller functions
     6        https://bugs.webkit.org/show_bug.cgi?id=60072
     7
     8        Split three functions off from computeInlineDirectionPositionsForLine
     9        to improve its readability.
     10
     11        No new tests since this is just moving code around.
     12
     13        * rendering/RenderBlock.h:
     14        * rendering/RenderBlockLineLayout.cpp:
     15        (WebCore::RenderBlock::setMarginsForRubyRun):
     16        (WebCore::setLogicalWidthForTextRun):
     17        (WebCore::computeExpansionForJustifiedText):
     18        (WebCore::RenderBlock::computeInlineDirectionPositionsForLine):
     19
    1202011-05-03  David Kilzer  <ddkilzer@apple.com>
    221
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r85668 r85685  
    4545struct PaintInfo;
    4646class LineInfo;
     47class RenderRubyRun;
    4748
    4849template <class Iterator, class Run> class BidiResolver;
     
    507508    InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox);
    508509
     510    void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
     511
    509512    void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
    510513    void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r85668 r85685  
    444444}
    445445
     446void RenderBlock::setMarginsForRubyRun(BidiRun* run, RenderRubyRun* renderer, RenderObject* previousObject, const LineInfo& lineInfo)
     447{
     448    int startOverhang;
     449    int endOverhang;
     450    RenderObject* nextObject = 0;
     451    for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) {
     452        if (!runWithNextObject->m_object->isPositioned() && !runWithNextObject->m_box->isLineBreak()) {
     453            nextObject = runWithNextObject->m_object;
     454            break;
     455        }
     456    }
     457    renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRightDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang);
     458    setMarginStartForChild(renderer, -startOverhang);
     459    setMarginEndForChild(renderer, -endOverhang);
     460}
     461
     462static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo,
     463                                   GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
     464{
     465    HashSet<const SimpleFontData*> fallbackFonts;
     466    GlyphOverflow glyphOverflow;
     467   
     468    // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
     469    if (lineBox->fitsToGlyphs()) {
     470        // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization
     471        // will keep us from computing glyph bounds in nearly all cases.
     472        bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading();
     473        int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache);
     474        int rootDescent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().descent() : 0;
     475        int rootAscent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() : 0;
     476        int boxAscent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() - baselineShift;
     477        int boxDescent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift;
     478        if (boxAscent > rootDescent ||  boxDescent > rootAscent)
     479            glyphOverflow.computeBounds = true;
     480    }
     481   
     482    int hyphenWidth = 0;
     483    if (static_cast<InlineTextBox*>(run->m_box)->hasHyphen()) {
     484        const AtomicString& hyphenString = renderer->style()->hyphenString();
     485        hyphenWidth = renderer->style(lineInfo.isFirstLine())->font().width(TextRun(hyphenString.characters(), hyphenString.length()));
     486    }
     487    run->m_box->setLogicalWidth(renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth);
     488    if (!fallbackFonts.isEmpty()) {
     489        ASSERT(run->m_box->isText());
     490        GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
     491        ASSERT(it->second.first.isEmpty());
     492        copyToVector(fallbackFonts, it->second.first);
     493        run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
     494    }
     495    if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
     496        ASSERT(run->m_box->isText());
     497        GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
     498        it->second.second = glyphOverflow;
     499        run->m_box->clearKnownToHaveNoOverflow();
     500    }
     501}
     502
     503static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth)
     504{
     505    if (expansionOpportunityCount && availableLogicalWidth > totalLogicalWidth) {
     506        size_t i = 0;
     507        for (BidiRun* r = firstRun; r; r = r->next()) {
     508            if (!r->m_box || r == trailingSpaceRun)
     509                continue;
     510           
     511            if (r->m_object->isText()) {
     512                unsigned opportunitiesInRun = expansionOpportunities[i++];
     513               
     514                ASSERT(opportunitiesInRun <= expansionOpportunityCount);
     515               
     516                // Only justify text if whitespace is collapsed.
     517                if (r->m_object->style()->collapseWhiteSpace()) {
     518                    InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box);
     519                    float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
     520                    textBox->setExpansion(expansion);
     521                    totalLogicalWidth += expansion;
     522                }
     523                expansionOpportunityCount -= opportunitiesInRun;
     524                if (!expansionOpportunityCount)
     525                    break;
     526            }
     527        }
     528    }
     529}
     530
    446531void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd,
    447532                                                         GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
     
    465550        if (r->m_object->isText()) {
    466551            RenderText* rt = toRenderText(r->m_object);
    467 
    468552            if (textAlign == JUSTIFY && r != trailingSpaceRun) {
    469553                if (!isAfterExpansion)
     
    479563                needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length;
    480564            }
    481             HashSet<const SimpleFontData*> fallbackFonts;
    482             GlyphOverflow glyphOverflow;
    483 
    484             // Always compute glyph overflow if the block's line-box-contain value is "glyphs".
    485             if (lineBox->fitsToGlyphs()) {
    486                 // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization
    487                 // will keep us from computing glyph bounds in nearly all cases.
    488                 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading();
    489                 int baselineShift = lineBox->verticalPositionForBox(r->m_box, verticalPositionCache);
    490                 int rootDescent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().descent() : 0;
    491                 int rootAscent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() : 0;
    492                 int boxAscent = rt->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() - baselineShift;
    493                 int boxDescent = rt->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift;
    494                 if (boxAscent > rootDescent ||  boxDescent > rootAscent)
    495                     glyphOverflow.computeBounds = true;
    496             }
    497 
    498             int hyphenWidth = 0;
    499             if (static_cast<InlineTextBox*>(r->m_box)->hasHyphen()) {
    500                 const AtomicString& hyphenString = rt->style()->hyphenString();
    501                 hyphenWidth = rt->style(lineInfo.isFirstLine())->font().width(TextRun(hyphenString.characters(), hyphenString.length()));
    502             }
    503             r->m_box->setLogicalWidth(rt->width(r->m_start, r->m_stop - r->m_start, totalLogicalWidth, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth);
    504             if (!fallbackFonts.isEmpty()) {
    505                 ASSERT(r->m_box->isText());
    506                 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
    507                 ASSERT(it->second.first.isEmpty());
    508                 copyToVector(fallbackFonts, it->second.first);
    509                 r->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
    510             }
    511             if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
    512                 ASSERT(r->m_box->isText());
    513                 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(static_cast<InlineTextBox*>(r->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).first;
    514                 it->second.second = glyphOverflow;
    515                 r->m_box->clearKnownToHaveNoOverflow();
    516             }
     565
     566            setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache);
    517567        } else {
    518568            isAfterExpansion = false;
    519569            if (!r->m_object->isRenderInline()) {
    520570                RenderBox* renderBox = toRenderBox(r->m_object);
    521                 if (renderBox->isRubyRun()) {
    522                     int startOverhang;
    523                     int endOverhang;
    524                     RenderObject* nextObject = 0;
    525                     for (BidiRun* runWithNextObject = r->next(); runWithNextObject; runWithNextObject = runWithNextObject->next()) {
    526                         if (!runWithNextObject->m_object->isPositioned() && !runWithNextObject->m_box->isLineBreak()) {
    527                             nextObject = runWithNextObject->m_object;
    528                             break;
    529                         }
    530                     }
    531                     toRenderRubyRun(renderBox)->getOverhang(lineInfo.isFirstLine(), renderBox->style()->isLeftToRightDirection() ? previousObject : nextObject, renderBox->style()->isLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhang);
    532                     setMarginStartForChild(renderBox, -startOverhang);
    533                     setMarginEndForChild(renderBox, -endOverhang);
    534                 }
     571                if (renderBox->isRubyRun())
     572                    setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
    535573                r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
    536574                totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
     
    595633    }
    596634
    597     if (expansionOpportunityCount && availableLogicalWidth > totalLogicalWidth) {
    598         size_t i = 0;
    599         for (BidiRun* r = firstRun; r; r = r->next()) {
    600             if (!r->m_box || r == trailingSpaceRun)
    601                 continue;
    602 
    603             if (r->m_object->isText()) {
    604                 unsigned opportunitiesInRun = expansionOpportunities[i++];
    605 
    606                 ASSERT(opportunitiesInRun <= expansionOpportunityCount);
    607 
    608                 // Only justify text if whitespace is collapsed.
    609                 if (r->m_object->style()->collapseWhiteSpace()) {
    610                     InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box);
    611                     float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
    612                     textBox->setExpansion(expansion);
    613                     totalLogicalWidth += expansion;
    614                 }
    615                 expansionOpportunityCount -= opportunitiesInRun;
    616                 if (!expansionOpportunityCount)
    617                     break;
    618             }
    619         }
    620     }
     635    computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth);
    621636
    622637    // The widths of all runs are now known.  We can now place every inline box (and
Note: See TracChangeset for help on using the changeset viewer.