Changeset 116718 in webkit


Ignore:
Timestamp:
May 10, 2012 7:08:06 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Eliminate duplicated code for culled line box in RenderInline
https://bugs.webkit.org/show_bug.cgi?id=85725

This patch extracts the common part of culledInlineBoundingBox() /
culledInlineAbsoluteRects() / culledInlineAbsoluteQuads() to become a
template function generateCulledLineBoxRects(). The template function
accepts a new parameter, GeneratorContext functor, which will be
invoked everytime a new line box rect has been generated. The generated
rect will be in local coordinate. The functor will be responsible for
appropriate transformation, then appending to vector or union with
existing bounding box.

Patch by Tien-Ren Chen <trchen@chromium.org> on 2012-05-10
Reviewed by Eric Seidel.

No new tests. No change in behavior.

  • rendering/RenderInline.cpp:

(WebCore):
(WebCore::RenderInline::generateLineBoxRects):
(WebCore::RenderInline::generateCulledLineBoxRects):
(WebCore::RenderInline::absoluteRects):
(WebCore::RenderInline::absoluteQuads):
(WebCore::RenderInline::linesBoundingBox):
(WebCore::RenderInline::culledInlineVisualOverflowBoundingBox):
(WebCore::RenderInline::addFocusRingRects):

  • rendering/RenderInline.h:

(RenderInline):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r116717 r116718  
     12012-05-10  Tien-Ren Chen  <trchen@chromium.org>
     2
     3        Eliminate duplicated code for culled line box in RenderInline
     4        https://bugs.webkit.org/show_bug.cgi?id=85725
     5
     6        This patch extracts the common part of culledInlineBoundingBox() /
     7        culledInlineAbsoluteRects() / culledInlineAbsoluteQuads() to become a
     8        template function generateCulledLineBoxRects(). The template function
     9        accepts a new parameter, GeneratorContext functor, which will be
     10        invoked everytime a new line box rect has been generated. The generated
     11        rect will be in local coordinate. The functor will be responsible for
     12        appropriate transformation, then appending to vector or union with
     13        existing bounding box.
     14
     15        Reviewed by Eric Seidel.
     16
     17        No new tests. No change in behavior.
     18
     19        * rendering/RenderInline.cpp:
     20        (WebCore):
     21        (WebCore::RenderInline::generateLineBoxRects):
     22        (WebCore::RenderInline::generateCulledLineBoxRects):
     23        (WebCore::RenderInline::absoluteRects):
     24        (WebCore::RenderInline::absoluteQuads):
     25        (WebCore::RenderInline::linesBoundingBox):
     26        (WebCore::RenderInline::culledInlineVisualOverflowBoundingBox):
     27        (WebCore::RenderInline::addFocusRingRects):
     28        * rendering/RenderInline.h:
     29        (RenderInline):
     30
    1312012-05-10  Abhishek Arya  <inferno@chromium.org>
    232
  • trunk/Source/WebCore/rendering/RenderInline.cpp

    r116446 r116718  
    506506}
    507507
    508 void RenderInline::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
     508template<typename GeneratorContext>
     509void RenderInline::generateLineBoxRects(GeneratorContext yield) const
    509510{
    510511    if (!alwaysCreateLineBoxes())
    511         culledInlineAbsoluteRects(this, rects, toLayoutSize(accumulatedOffset));
     512        generateCulledLineBoxRects(yield, this);
    512513    else if (InlineFlowBox* curr = firstLineBox()) {
    513514        for (; curr; curr = curr->nextLineBox())
    514             rects.append(enclosingIntRect(FloatRect(accumulatedOffset + curr->topLeft(), curr->size())));
     515            yield(FloatRect(curr->topLeft(), curr->size()));
    515516    } else
    516         rects.append(IntRect(roundedIntPoint(accumulatedOffset), IntSize()));
    517 
    518     if (continuation()) {
    519         if (continuation()->isBox()) {
    520             RenderBox* box = toRenderBox(continuation());
    521             continuation()->absoluteRects(rects, toLayoutPoint(accumulatedOffset - containingBlock()->location() + box->size()));
    522         } else
    523             continuation()->absoluteRects(rects, toLayoutPoint(accumulatedOffset - containingBlock()->location()));
    524     }
    525 }
    526 
    527 void RenderInline::culledInlineAbsoluteRects(const RenderInline* container, Vector<IntRect>& rects, const LayoutSize& offset) const
     517        yield(FloatRect());
     518}
     519
     520template<typename GeneratorContext>
     521void RenderInline::generateCulledLineBoxRects(GeneratorContext yield, const RenderInline* container) const
    528522{
    529523    if (!culledInlineFirstLineBox()) {
    530         rects.append(IntRect(offset.width(), offset.height(), 0, 0));
     524        yield(FloatRect());
    531525        return;
    532526    }
    533527
    534528    bool isHorizontal = style()->isHorizontalWritingMode();
     529
    535530    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
    536531        if (curr->isFloatingOrPositioned())
     
    545540                int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    546541                int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    547                 FloatRect result;
    548542                if (isHorizontal)
    549                     result = FloatRect(offset.width() + currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), offset.height() + logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight);
     543                    yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight));
    550544                else
    551                     result = FloatRect(offset.width() + logicalTop, offset.height() + currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, currBox->height() + currBox->marginHeight());
    552                 rects.append(enclosingIntRect(result));
     545                    yield(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, currBox->height() + currBox->marginHeight()));
    553546            }
    554547        } else if (curr->isRenderInline()) {
     
    556549            RenderInline* currInline = toRenderInline(curr);
    557550            if (!currInline->alwaysCreateLineBoxes())
    558                 currInline->culledInlineAbsoluteRects(container, rects, offset);
     551                currInline->generateCulledLineBoxRects(yield, container);
    559552            else {
    560553                for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
     
    562555                    int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    563556                    int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    564                     FloatRect result;
    565557                    if (isHorizontal)
    566                         result = FloatRect(offset.width() + childLine->x() - childLine->marginLogicalLeft(),
    567                             offset.height() + logicalTop,
     558                        yield(FloatRect(childLine->x() - childLine->marginLogicalLeft(),
     559                            logicalTop,
    568560                            childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight(),
    569                             logicalHeight);
     561                            logicalHeight));
    570562                    else
    571                         result = FloatRect(offset.width() + logicalTop,
    572                             offset.height() + childLine->y() - childLine->marginLogicalLeft(),
     563                        yield(FloatRect(logicalTop,
     564                            childLine->y() - childLine->marginLogicalLeft(),
    573565                            logicalHeight,
    574                             childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight());
    575                     rects.append(enclosingIntRect(result));
     566                            childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight()));
    576567                }
    577568            }
     
    582573                int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    583574                int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    584                 FloatRect result;
    585575                if (isHorizontal)
    586                     result = FloatRect(offset.width() + childText->x(), offset.height() + logicalTop, childText->logicalWidth(), logicalHeight);
     576                    yield(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));
    587577                else
    588                     result = FloatRect(offset.width() + logicalTop, offset.height() + childText->y(), logicalHeight, childText->logicalWidth());
    589                 rects.append(enclosingIntRect(result));
     578                    yield(FloatRect(logicalTop, childText->y(), logicalHeight, childText->logicalWidth()));
    590579            }
    591580        }
     
    593582}
    594583
     584namespace {
     585
     586class AbsoluteRectsGeneratorContext {
     587public:
     588    AbsoluteRectsGeneratorContext(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset)
     589        : m_rects(rects)
     590        , m_accumulatedOffset(accumulatedOffset) { }
     591
     592    void operator()(const FloatRect& rect)
     593    {
     594        IntRect intRect = enclosingIntRect(rect);
     595        intRect.move(m_accumulatedOffset.x(), m_accumulatedOffset.y());
     596        m_rects.append(intRect);
     597    }
     598private:
     599    Vector<IntRect>& m_rects;
     600    const LayoutPoint& m_accumulatedOffset;
     601};
     602
     603} // unnamed namespace
     604
     605void RenderInline::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
     606{
     607    generateLineBoxRects(AbsoluteRectsGeneratorContext(rects, accumulatedOffset));
     608
     609    if (continuation()) {
     610        if (continuation()->isBox()) {
     611            RenderBox* box = toRenderBox(continuation());
     612            continuation()->absoluteRects(rects, toLayoutPoint(accumulatedOffset - containingBlock()->location() + box->size()));
     613        } else
     614            continuation()->absoluteRects(rects, toLayoutPoint(accumulatedOffset - containingBlock()->location()));
     615    }
     616}
     617
     618
     619namespace {
     620
     621class AbsoluteQuadsGeneratorContext {
     622public:
     623    AbsoluteQuadsGeneratorContext(const RenderInline* renderer, Vector<FloatQuad>& quads, bool* wasFixed)
     624        : m_renderer(renderer)
     625        , m_quads(quads)
     626        , m_wasFixed(wasFixed) { }
     627
     628    void operator()(const FloatRect& rect)
     629    {
     630        m_quads.append(m_renderer->localToAbsoluteQuad(rect));
     631    }
     632private:
     633    const RenderInline* m_renderer;
     634    Vector<FloatQuad>& m_quads;
     635    bool* m_wasFixed;
     636};
     637
     638} // unnamed namespace
     639
    595640void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
    596641{
    597     if (!alwaysCreateLineBoxes())
    598         culledInlineAbsoluteQuads(this, quads);
    599     else if (InlineFlowBox* curr = firstLineBox()) {
    600         for (; curr; curr = curr->nextLineBox()) {
    601             FloatRect localRect(curr->x(), curr->y(), curr->width(), curr->height());
    602             quads.append(localToAbsoluteQuad(localRect, false, wasFixed));
    603         }
    604     } else
    605         quads.append(localToAbsoluteQuad(FloatRect(), false, wasFixed));
     642    generateLineBoxRects(AbsoluteQuadsGeneratorContext(this, quads, wasFixed));
    606643
    607644    if (continuation())
    608645        continuation()->absoluteQuads(quads, wasFixed);
    609 }
    610 
    611 void RenderInline::culledInlineAbsoluteQuads(const RenderInline* container, Vector<FloatQuad>& quads) const
    612 {
    613     if (!culledInlineFirstLineBox()) {
    614         quads.append(localToAbsoluteQuad(FloatRect()));
    615         return;
    616     }
    617 
    618     bool isHorizontal = style()->isHorizontalWritingMode();
    619     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
    620         if (curr->isFloatingOrPositioned())
    621             continue;
    622            
    623         // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block
    624         // direction (aligned to the root box's baseline).
    625         if (curr->isBox()) {
    626             RenderBox* currBox = toRenderBox(curr);
    627             if (currBox->inlineBoxWrapper()) {
    628                 RootInlineBox* rootBox = currBox->inlineBoxWrapper()->root();
    629                 int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    630                 int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    631                 FloatRect result;
    632                 if (isHorizontal)
    633                     result = FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight);
    634                 else
    635                     result = FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, currBox->height() + currBox->marginHeight());
    636                 quads.append(localToAbsoluteQuad(result));
    637             }
    638         } else if (curr->isRenderInline()) {
    639             // If the child doesn't need line boxes either, then we can recur.
    640             RenderInline* currInline = toRenderInline(curr);
    641             if (!currInline->alwaysCreateLineBoxes())
    642                 currInline->culledInlineAbsoluteQuads(container, quads);
    643             else {
    644                 for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
    645                     RootInlineBox* rootBox = childLine->root();
    646                     int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    647                     int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    648                     FloatRect result;
    649                     if (isHorizontal)
    650                         result = FloatRect(childLine->x() - childLine->marginLogicalLeft(),
    651                             logicalTop,
    652                             childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight(),
    653                             logicalHeight);
    654                     else
    655                         result = FloatRect(logicalTop,
    656                             childLine->y() - childLine->marginLogicalLeft(),
    657                             logicalHeight,
    658                             childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight());
    659                     quads.append(localToAbsoluteQuad(result));
    660                 }
    661             }
    662         } else if (curr->isText()) {
    663             RenderText* currText = toRenderText(curr);
    664             for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) {
    665                 RootInlineBox* rootBox = childText->root();
    666                 int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    667                 int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    668                 FloatRect result;
    669                 if (isHorizontal)
    670                     result = FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight);
    671                 else
    672                     result = FloatRect(logicalTop, childText->y(), logicalHeight, childText->logicalWidth());
    673                 quads.append(localToAbsoluteQuad(result));
    674             }
    675         }
    676     }
    677646}
    678647
     
    786755}
    787756
     757namespace {
     758
     759class LinesBoundingBoxGeneratorContext {
     760public:
     761    LinesBoundingBoxGeneratorContext(FloatRect& rect) : m_rect(rect) { }
     762    void operator()(const FloatRect& rect)
     763    {
     764        m_rect.uniteIfNonZero(rect);
     765    }
     766private:
     767    FloatRect& m_rect;
     768};
     769
     770} // unnamed namespace
     771
    788772IntRect RenderInline::linesBoundingBox() const
    789773{
    790774    if (!alwaysCreateLineBoxes()) {
    791775        ASSERT(!firstLineBox());
    792         return enclosingIntRect(culledInlineBoundingBox(this));
     776        FloatRect floatResult;
     777        generateCulledLineBoxRects(LinesBoundingBoxGeneratorContext(floatResult), this);
     778        return enclosingIntRect(floatResult);
    793779    }
    794780
     
    820806
    821807    return result;
    822 }
    823 
    824 FloatRect RenderInline::culledInlineBoundingBox(const RenderInline* container) const
    825 {
    826     FloatRect result;
    827     bool isHorizontal = style()->isHorizontalWritingMode();
    828     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
    829         if (curr->isFloatingOrPositioned())
    830             continue;
    831            
    832         // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block
    833         // direction (aligned to the root box's baseline).
    834         if (curr->isBox()) {
    835             RenderBox* currBox = toRenderBox(curr);
    836             if (currBox->inlineBoxWrapper()) {
    837                 RootInlineBox* rootBox = currBox->inlineBoxWrapper()->root();
    838                 int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    839                 int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    840                 if (isHorizontal)
    841                     result.uniteIfNonZero(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight));
    842                 else
    843                     result.uniteIfNonZero(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, currBox->height() + currBox->marginHeight()));
    844             }
    845         } else if (curr->isRenderInline()) {
    846             // If the child doesn't need line boxes either, then we can recur.
    847             RenderInline* currInline = toRenderInline(curr);
    848             if (!currInline->alwaysCreateLineBoxes())
    849                 result.uniteIfNonZero(currInline->culledInlineBoundingBox(container));
    850             else {
    851                 for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
    852                     RootInlineBox* rootBox = childLine->root();
    853                     int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    854                     int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    855                     if (isHorizontal)
    856                         result.uniteIfNonZero(FloatRect(childLine->x() - childLine->marginLogicalLeft(),
    857                             logicalTop,
    858                             childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight(),
    859                             logicalHeight));
    860                     else
    861                         result.uniteIfNonZero(FloatRect(logicalTop,
    862                             childLine->y() - childLine->marginLogicalLeft(),
    863                             logicalHeight,
    864                             childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight()));
    865                                      
    866                 }
    867             }
    868         } else if (curr->isText()) {
    869             RenderText* currText = toRenderText(curr);
    870             for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) {
    871                 RootInlineBox* rootBox = childText->root();
    872                 int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
    873                 int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
    874                 if (isHorizontal)
    875                     result.uniteIfNonZero(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));
    876                 else
    877                     result.uniteIfNonZero(FloatRect(logicalTop, childText->y(), logicalHeight, childText->logicalWidth()));
    878             }
    879         }
    880     }
    881     return enclosingLayoutRect(result);
    882808}
    883809
     
    932858LayoutRect RenderInline::culledInlineVisualOverflowBoundingBox() const
    933859{
    934     LayoutRect result(culledInlineBoundingBox(this));
     860    FloatRect floatResult;
     861    generateCulledLineBoxRects(LinesBoundingBoxGeneratorContext(floatResult), this);
     862    LayoutRect result(enclosingLayoutRect(floatResult));
    935863    bool isHorizontal = style()->isHorizontalWritingMode();
    936864    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
     
    13671295void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
    13681296{
    1369     if (!alwaysCreateLineBoxes())
    1370         culledInlineAbsoluteRects(this, rects, toLayoutSize(additionalOffset));
    1371     else {
    1372         for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
    1373             rects.append(enclosingIntRect(FloatRect(additionalOffset.x() + curr->x(), additionalOffset.y() + curr->y(), curr->width(), curr->height())));
    1374     }
     1297    generateLineBoxRects(AbsoluteRectsGeneratorContext(rects, additionalOffset));
    13751298
    13761299    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
  • trunk/Source/WebCore/rendering/RenderInline.h

    r115981 r116718  
    9999    virtual bool isRenderInline() const { return true; }
    100100
    101     FloatRect culledInlineBoundingBox(const RenderInline* container) const;
    102101    LayoutRect culledInlineVisualOverflowBoundingBox() const;
    103102    InlineBox* culledInlineFirstLineBox() const;
    104103    InlineBox* culledInlineLastLineBox() const;
    105     void culledInlineAbsoluteRects(const RenderInline* container, Vector<IntRect>&, const LayoutSize&) const;
    106     void culledInlineAbsoluteQuads(const RenderInline* container, Vector<FloatQuad>&) const;
     104
     105    template<typename GeneratorContext>
     106    void generateLineBoxRects(GeneratorContext yield) const;
     107    template<typename GeneratorContext>
     108    void generateCulledLineBoxRects(GeneratorContext yield, const RenderInline* container) const;
    107109
    108110    void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
Note: See TracChangeset for help on using the changeset viewer.