Changeset 157362 in webkit


Ignore:
Timestamp:
Oct 13, 2013, 2:39:44 AM (12 years ago)
Author:
Antti Koivisto
Message:

Move absoluteRects/Quads to RenderTextLineBoxes
https://bugs.webkit.org/show_bug.cgi?id=122706

Reviewed by Andreas Kling.

  • rendering/RenderTextLineBoxes.cpp:

(WebCore::RenderTextLineBoxes::absoluteRects):
(WebCore::RenderTextLineBoxes::absoluteRectsForRange):
(WebCore::RenderTextLineBoxes::absoluteQuads):
(WebCore::RenderTextLineBoxes::absoluteQuadsForRange):

These move.

(WebCore::RenderTextLineBoxes::selectionRectForRange):
(WebCore::RenderTextLineBoxes::setSelectionState):

Also moved a few smaller functions.

Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r157361 r157362  
     12013-10-12  Antti Koivisto  <antti@apple.com>
     2
     3        Move absoluteRects/Quads to RenderTextLineBoxes
     4        https://bugs.webkit.org/show_bug.cgi?id=122706
     5
     6        Reviewed by Andreas Kling.
     7
     8        * rendering/RenderTextLineBoxes.cpp:
     9        (WebCore::RenderTextLineBoxes::absoluteRects):
     10        (WebCore::RenderTextLineBoxes::absoluteRectsForRange):
     11        (WebCore::RenderTextLineBoxes::absoluteQuads):
     12        (WebCore::RenderTextLineBoxes::absoluteQuadsForRange):
     13       
     14            These move.
     15
     16        (WebCore::RenderTextLineBoxes::selectionRectForRange):
     17        (WebCore::RenderTextLineBoxes::setSelectionState):
     18       
     19            Also moved a few smaller functions.
     20
    1212013-10-13  Andreas Kling  <akling@apple.com>
    222
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r157212 r157362  
    791791#endif
    792792    if (obj->isText())
    793         toRenderText(obj)->absoluteQuads(quads, 0, RenderText::ClipToEllipsis);
     793        toRenderText(obj)->absoluteQuadsClippedToEllipsis(quads);
    794794    else if (isWebArea() || isSeamlessWebArea() || isSVGRoot)
    795795        obj->absoluteQuads(quads);
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r157340 r157362  
    116116}
    117117
    118 LayoutUnit InlineTextBox::selectionTop()
     118LayoutUnit InlineTextBox::selectionTop() const
    119119{
    120120    return root().selectionTop();
    121121}
    122122
    123 LayoutUnit InlineTextBox::selectionBottom()
     123LayoutUnit InlineTextBox::selectionBottom() const
    124124{
    125125    return root().selectionBottom();
    126126}
    127127
    128 LayoutUnit InlineTextBox::selectionHeight()
     128LayoutUnit InlineTextBox::selectionHeight() const
    129129{
    130130    return root().selectionHeight();
     
    201201}
    202202
    203 LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos)
     203LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const
    204204{
    205205    int sPos = max(startPos - m_start, 0);
  • trunk/Source/WebCore/rendering/InlineTextBox.h

    r157015 r157362  
    7474    void offsetRun(int d) { ASSERT(!isDirty()); m_start += d; }
    7575
    76     unsigned short truncation() { return m_truncation; }
     76    unsigned short truncation() const { return m_truncation; }
    7777
    7878    virtual void markDirty(bool dirty = true) OVERRIDE FINAL;
     
    103103
    104104private:
    105     LayoutUnit selectionTop();
    106     LayoutUnit selectionBottom();
    107     LayoutUnit selectionHeight();
     105    LayoutUnit selectionTop() const;
     106    LayoutUnit selectionBottom() const;
     107    LayoutUnit selectionHeight() const;
    108108
    109109    TextRun constructTextRun(const RenderStyle&, const Font&, BufferForAppendingHyphen* = 0) const;
     
    113113    virtual FloatRect calculateBoundaries() const { return FloatRect(x(), y(), width(), height()); }
    114114
    115     virtual LayoutRect localSelectionRect(int startPos, int endPos);
     115    virtual LayoutRect localSelectionRect(int startPos, int endPos) const;
    116116    bool isSelected(int startPos, int endPos) const;
    117117    void selectionStartEnd(int& sPos, int& ePos);
  • trunk/Source/WebCore/rendering/RenderText.cpp

    r157349 r157362  
    265265}
    266266
    267 static FloatRect localQuadForTextBox(InlineTextBox* box, unsigned start, unsigned end, bool useSelectionHeight)
    268 {
    269     unsigned realEnd = min(box->end() + 1, end);
    270     LayoutRect r = box->localSelectionRect(start, realEnd);
    271     if (r.height()) {
    272         if (!useSelectionHeight) {
    273             // Change the height and y position (or width and x for vertical text)
    274             // because selectionRect uses selection-specific values.
    275             if (box->isHorizontal()) {
    276                 r.setHeight(box->height());
    277                 r.setY(box->y());
    278             } else {
    279                 r.setWidth(box->width());
    280                 r.setX(box->x());
    281             }
    282         }
    283         return FloatRect(r);
    284     }
    285     return FloatRect();
    286 }
    287 
    288267void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed)
    289268{
     
    298277    end = min(end, static_cast<unsigned>(INT_MAX));
    299278   
    300     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
    301         // Note: box->end() returns the index of the last character, not the index past it
    302         if (start <= box->start() && box->end() < end) {
    303             FloatRect r = box->calculateBoundaries();
    304             if (useSelectionHeight) {
    305                 LayoutRect selectionRect = box->localSelectionRect(start, end);
    306                 if (box->isHorizontal()) {
    307                     r.setHeight(selectionRect.height());
    308                     r.setY(selectionRect.y());
    309                 } else {
    310                     r.setWidth(selectionRect.width());
    311                     r.setX(selectionRect.x());
    312                 }
    313             }
    314             rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBox());
    315         } else {
    316             // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722
    317             FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
    318             if (!rect.isZero())
    319                 rects.append(localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox());
    320         }
    321     }
    322 }
    323 
    324 static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigned endPos)
    325 {
    326     if (!box)
    327         return IntRect();
    328    
    329     unsigned short truncation = box->truncation();
    330     if (truncation == cNoTruncation)
    331         return IntRect();
    332    
    333     IntRect rect;
    334     if (EllipsisBox* ellipsis = box->root().ellipsisBox()) {
    335         int ellipsisStartPosition = max<int>(startPos - box->start(), 0);
    336         int ellipsisEndPosition = min<int>(endPos - box->start(), box->len());
    337        
    338         // The ellipsis should be considered to be selected if the end of
    339         // the selection is past the beginning of the truncation and the
    340         // beginning of the selection is before or at the beginning of the truncation.
    341         if (ellipsisEndPosition >= truncation && ellipsisStartPosition <= truncation)
    342             return ellipsis->selectionRect();
    343     }
    344    
    345     return IntRect();
    346 }
    347    
    348 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, ClippingOption option) const
    349 {
    350     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
    351         FloatRect boundaries = box->calculateBoundaries();
    352 
    353         // Shorten the width of this text box if it ends in an ellipsis.
    354         // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch.
    355         IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(box, 0, textLength()) : IntRect();
    356         if (!ellipsisRect.isEmpty()) {
    357             if (style()->isHorizontalWritingMode())
    358                 boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
    359             else
    360                 boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
    361         }
    362         quads.append(localToAbsoluteQuad(boundaries, 0, wasFixed));
    363     }
    364 }
    365    
     279    m_lineBoxes.absoluteRectsForRange(*this, rects, start, end, useSelectionHeight, wasFixed);
     280}
     281
     282void RenderText::absoluteQuadsClippedToEllipsis(Vector<FloatQuad>& quads) const
     283{
     284    return m_lineBoxes.absoluteQuads(*this, quads, nullptr, RenderTextLineBoxes::ClipToEllipsis);
     285}
     286
    366287void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
    367288{
    368     absoluteQuads(quads, wasFixed, NoClipping);
     289    return m_lineBoxes.absoluteQuads(*this, quads, wasFixed, RenderTextLineBoxes::NoClipping);
    369290}
    370291
     
    381302    end = min(end, static_cast<unsigned>(INT_MAX));
    382303   
    383     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
    384         // Note: box->end() returns the index of the last character, not the index past it
    385         if (start <= box->start() && box->end() < end) {
    386             FloatRect r = box->calculateBoundaries();
    387             if (useSelectionHeight) {
    388                 LayoutRect selectionRect = box->localSelectionRect(start, end);
    389                 if (box->isHorizontal()) {
    390                     r.setHeight(selectionRect.height());
    391                     r.setY(selectionRect.y());
    392                 } else {
    393                     r.setWidth(selectionRect.width());
    394                     r.setX(selectionRect.x());
    395                 }
    396             }
    397             quads.append(localToAbsoluteQuad(r, 0, wasFixed));
    398         } else {
    399             FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
    400             if (!rect.isZero())
    401                 quads.append(localToAbsoluteQuad(rect, 0, wasFixed));
    402         }
    403     }
     304    m_lineBoxes.absoluteQuadsForRange(*this, quads, start, end, useSelectionHeight, wasFixed);
    404305}
    405306
     
    925826    RenderObject::setSelectionState(state);
    926827
    927     if (canUpdateSelectionOnRootLineBoxes()) {
    928         if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) {
    929             int startPos, endPos;
    930             selectionStartEnd(startPos, endPos);
    931             if (selectionState() == SelectionStart) {
    932                 endPos = textLength();
    933 
    934                 // to handle selection from end of text to end of line
    935                 if (startPos && startPos == endPos)
    936                     startPos = endPos - 1;
    937             } else if (selectionState() == SelectionEnd)
    938                 startPos = 0;
    939 
    940             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
    941                 if (box->isSelected(startPos, endPos))
    942                     box->root().setHasSelectedChildren(true);
    943             }
    944         } else {
    945             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
    946                 box->root().setHasSelectedChildren(state == SelectionInside);
    947             }
    948         }
    949     }
     828    if (canUpdateSelectionOnRootLineBoxes())
     829        m_lineBoxes.setSelectionState(*this, state);
    950830
    951831    // The containing block can be null in case of an orphaned tree.
     
    12341114        return IntRect();
    12351115
    1236     LayoutRect rect;
    1237     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
    1238         rect.unite(box->localSelectionRect(startPos, endPos));
    1239         rect.unite(ellipsisRectForBox(box, startPos, endPos));
    1240     }
     1116    LayoutRect rect = m_lineBoxes.selectionRectForRange(startPos, endPos);
    12411117
    12421118    if (clipToVisibleContent)
  • trunk/Source/WebCore/rendering/RenderText.h

    r157345 r157362  
    6969    void absoluteQuadsForRange(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false, bool* wasFixed = 0);
    7070
    71     enum ClippingOption { NoClipping, ClipToEllipsis };
    72     void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed = 0, ClippingOption = NoClipping) const;
     71    void absoluteQuadsClippedToEllipsis(Vector<FloatQuad>&) const;
    7372
    7473    virtual VisiblePosition positionForPoint(const LayoutPoint&) OVERRIDE;
  • trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp

    r157349 r157362  
    2727#include "RenderTextLineBoxes.h"
    2828
     29#include "EllipsisBox.h"
    2930#include "InlineTextBox.h"
    3031#include "RenderBlock.h"
     
    388389    }
    389390    return renderer.createVisiblePosition(0, DOWNSTREAM);
     391}
     392
     393void RenderTextLineBoxes::setSelectionState(RenderText& renderer, RenderObject::SelectionState state)
     394{
     395    if (state == RenderObject::SelectionInside || state == RenderObject::SelectionNone) {
     396        for (auto box = m_first; box; box = box->nextTextBox())
     397            box->root().setHasSelectedChildren(state == RenderObject::SelectionInside);
     398        return;
     399    }
     400
     401    int start, end;
     402    renderer.selectionStartEnd(start, end);
     403    if (state == RenderObject::SelectionStart) {
     404        end = renderer.textLength();
     405
     406        // to handle selection from end of text to end of line
     407        if (start && start == end)
     408            start = end - 1;
     409    } else if (state == RenderObject::SelectionEnd)
     410        start = 0;
     411
     412    for (auto box = m_first; box; box = box->nextTextBox()) {
     413        if (box->isSelected(start, end))
     414            box->root().setHasSelectedChildren(true);
     415    }
     416}
     417
     418static IntRect ellipsisRectForBox(const InlineTextBox& box, unsigned start, unsigned end)
     419{
     420    unsigned short truncation = box.truncation();
     421    if (truncation == cNoTruncation)
     422        return IntRect();
     423
     424    auto ellipsis = box.root().ellipsisBox();
     425    if (!ellipsis)
     426        return IntRect();
     427   
     428    IntRect rect;
     429    int ellipsisStartPosition = std::max<int>(start - box.start(), 0);
     430    int ellipsisEndPosition = std::min<int>(end - box.start(), box.len());
     431   
     432    // The ellipsis should be considered to be selected if the end of
     433    // the selection is past the beginning of the truncation and the
     434    // beginning of the selection is before or at the beginning of the truncation.
     435    if (ellipsisEndPosition < truncation && ellipsisStartPosition > truncation)
     436        return IntRect();
     437    return ellipsis->selectionRect();
     438}
     439
     440LayoutRect RenderTextLineBoxes::selectionRectForRange(unsigned start, unsigned end)
     441{
     442    LayoutRect rect;
     443    for (auto box = m_first; box; box = box->nextTextBox()) {
     444        rect.unite(box->localSelectionRect(start, end));
     445        rect.unite(ellipsisRectForBox(*box, start, end));
     446    }
     447    return rect;
     448}
     449
     450void RenderTextLineBoxes::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
     451{
     452    for (auto box = m_first; box; box = box->nextTextBox())
     453        rects.append(enclosingIntRect(FloatRect(accumulatedOffset + box->topLeft(), box->size())));
     454}
     455
     456static FloatRect localQuadForTextBox(const InlineTextBox& box, unsigned start, unsigned end, bool useSelectionHeight)
     457{
     458    unsigned realEnd = std::min(box.end() + 1, end);
     459    LayoutRect boxSelectionRect = box.localSelectionRect(start, realEnd);
     460    if (!boxSelectionRect.height())
     461        return FloatRect();
     462    if (useSelectionHeight)
     463        return boxSelectionRect;
     464    // Change the height and y position (or width and x for vertical text)
     465    // because selectionRect uses selection-specific values.
     466    if (box.isHorizontal()) {
     467        boxSelectionRect.setHeight(box.height());
     468        boxSelectionRect.setY(box.y());
     469    } else {
     470        boxSelectionRect.setWidth(box.width());
     471        boxSelectionRect.setX(box.x());
     472    }
     473    return boxSelectionRect;
     474}
     475
     476void RenderTextLineBoxes::absoluteRectsForRange(const RenderText& renderer, Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const
     477{
     478    for (auto box = m_first; box; box = box->nextTextBox()) {
     479        // Note: box->end() returns the index of the last character, not the index past it
     480        if (start <= box->start() && box->end() < end) {
     481            FloatRect boundaries = box->calculateBoundaries();
     482            if (useSelectionHeight) {
     483                LayoutRect selectionRect = box->localSelectionRect(start, end);
     484                if (box->isHorizontal()) {
     485                    boundaries.setHeight(selectionRect.height());
     486                    boundaries.setY(selectionRect.y());
     487                } else {
     488                    boundaries.setWidth(selectionRect.width());
     489                    boundaries.setX(selectionRect.x());
     490                }
     491            }
     492            rects.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed).enclosingBoundingBox());
     493            continue;
     494        }
     495        // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722
     496        FloatRect rect = localQuadForTextBox(*box, start, end, useSelectionHeight);
     497        if (!rect.isZero())
     498            rects.append(renderer.localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox());
     499    }
     500}
     501
     502void RenderTextLineBoxes::absoluteQuads(const RenderText& renderer, Vector<FloatQuad>& quads, bool* wasFixed, ClippingOption option) const
     503{
     504    for (auto box = m_first; box; box = box->nextTextBox()) {
     505        FloatRect boundaries = box->calculateBoundaries();
     506
     507        // Shorten the width of this text box if it ends in an ellipsis.
     508        // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch.
     509        IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(*box, 0, renderer.textLength()) : IntRect();
     510        if (!ellipsisRect.isEmpty()) {
     511            if (renderer.style()->isHorizontalWritingMode())
     512                boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
     513            else
     514                boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
     515        }
     516        quads.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed));
     517    }
     518}
     519
     520void RenderTextLineBoxes::absoluteQuadsForRange(const RenderText& renderer, Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const
     521{
     522    for (auto box = m_first; box; box = box->nextTextBox()) {
     523        // Note: box->end() returns the index of the last character, not the index past it
     524        if (start <= box->start() && box->end() < end) {
     525            FloatRect boundaries = box->calculateBoundaries();
     526            if (useSelectionHeight) {
     527                LayoutRect selectionRect = box->localSelectionRect(start, end);
     528                if (box->isHorizontal()) {
     529                    boundaries.setHeight(selectionRect.height());
     530                    boundaries.setY(selectionRect.y());
     531                } else {
     532                    boundaries.setWidth(selectionRect.width());
     533                    boundaries.setX(selectionRect.x());
     534                }
     535            }
     536            quads.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed));
     537            continue;
     538        }
     539        FloatRect rect = localQuadForTextBox(*box, start, end, useSelectionHeight);
     540        if (!rect.isZero())
     541            quads.append(renderer.localToAbsoluteQuad(rect, 0, wasFixed));
     542    }
    390543}
    391544
  • trunk/Source/WebCore/rendering/RenderTextLineBoxes.h

    r157349 r157362  
    2828
    2929#include "LayoutRect.h"
     30#include "RenderObject.h"
    3031#include "VisiblePosition.h"
    3132
     
    6061    VisiblePosition positionForPoint(const RenderText&, const LayoutPoint&) const;
    6162
     63    void setSelectionState(RenderText&, RenderObject::SelectionState);
     64    LayoutRect selectionRectForRange(unsigned start, unsigned end);
     65
    6266    IntRect boundingBox(const RenderText&) const;
    6367    LayoutRect visualOverflowBoundingBox(const RenderText&) const;
     68
     69    void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
     70    void absoluteRectsForRange(const RenderText&, Vector<IntRect>&, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const;
     71    enum ClippingOption { NoClipping, ClipToEllipsis };
     72    void absoluteQuads(const RenderText&, Vector<FloatQuad>&, bool* wasFixed, ClippingOption) const;
     73    void absoluteQuadsForRange(const RenderText&, Vector<FloatQuad>&, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const;
    6474
    6575    void dirtyAll();
  • trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp

    r157341 r157362  
    107107}
    108108
    109 FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, RenderStyle* style)
     109FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, RenderStyle* style) const
    110110{
    111111    ASSERT_WITH_SECURITY_IMPLICATION(startPosition < endPosition);
     
    133133}
    134134
    135 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPosition)
     135LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPosition) const
    136136{
    137137    int boxStart = start();
  • trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h

    r156094 r157362  
    5151    void paintSelectionBackground(PaintInfo&);
    5252    virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
    53     virtual LayoutRect localSelectionRect(int startPosition, int endPosition);
     53    virtual LayoutRect localSelectionRect(int startPosition, int endPosition) const OVERRIDE;
    5454
    5555    bool mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment&, int& startPosition, int& endPosition) const;
     
    6767
    6868    int offsetForPositionInFragment(const SVGTextFragment&, float position, bool includePartialGlyphs) const;
    69     FloatRect selectionRectForTextFragment(const SVGTextFragment&, int fragmentStartPosition, int fragmentEndPosition, RenderStyle*);
     69    FloatRect selectionRectForTextFragment(const SVGTextFragment&, int fragmentStartPosition, int fragmentEndPosition, RenderStyle*) const;
    7070
    7171private:
Note: See TracChangeset for help on using the changeset viewer.