Changeset 101755 in webkit


Ignore:
Timestamp:
Dec 2, 2011 12:26:05 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Range sliders and spin buttons don't work with multi-columns.
https://bugs.webkit.org/show_bug.cgi?id=70898

Patch by Yosifumi Inoue <yosin@chromium.org> on 2011-12-02
Reviewed by Dan Bernstein.

Source/WebCore:

This patch makes RenderBlock::hitTestColumns and
RenderBoxModelObject::mapAbsoluteToLocal to handle point
in multi-column same logic.

In multi-column, coordinate of box model rendering object is different
from absolute coordinate.. Columns in box model rendering object spans
vertically rather than horizontally.

When absolute point is represented in (column[i]+dx, column[0]+dy),
it is (column[0]+dx, column[0] + columnHeight + dy) in box model
rendering object coordinate.

Tests: fast/events/document-elementFromPoint.html

fast/events/offsetX-offsetY.html
fast/forms/number/spin-in-multi-column.html
fast/forms/range/slider-in-multi-column.html
fast/forms/select/listbox-in-multi-column.html

  • rendering/RenderBlock.cpp:

(WebCore::ColumnRectIterator::ColumnRectIterator): Added
(WebCore::ColumnRectIterator::advance): Added
(WebCore::ColumnRectIterator::columnRect): Added
(WebCore::ColumnRectIterator::hasMore): Added
(WebCore::ColumnRectIterator::adjust): Added
(WebCore::ColumnRectIterator::update): Added
(WebCore::RenderBlock::hitTestColumns): Use ColumnRectIterator.
(WebCore::RenderBlock::adjustForColumnRect): Added

  • rendering/RenderBlock.h: Add adjustForColumnRect.
  • rendering/RenderBox.cpp:

(WebCore::RenderBox::mapAbsoluteToLocalPoint): Call RenderBoxModelObject::mapAbsoluteToLocalPoint.

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::mapAbsoluteToLocalPoint): Move from RenderInline::mapAbsoluteToLocalPoint and call RenderBlock::adjustForColumnRect.

  • rendering/RenderBoxModelObject.h: add mapAbsoluteToLocalPoint.
  • rendering/RenderInline.cpp: Move mapAbsoluteToLocalPoint to RenderBoxModelObject.
  • rendering/RenderInline.h: remove mapAbsoluteToLocalPoint.

LayoutTests:

  • fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
  • fast/events/offsetX-offsetY.html: Change offset for "in-columns" test.
  • fast/forms/listbox/listbox-in-multi-column-expected.txt: Added.
  • fast/forms/listbox/listbox-in-multi-column.html: Added.
  • fast/forms/number/spin-in-multi-column-expected.txt: Added.
  • fast/forms/number/spin-in-multi-column.html: Added.
  • fast/forms/range/slider-in-multi-column-expected.txt: Added.
  • fast/forms/range/slider-in-multi-column.html: Added.
  • platform/chromium-win/fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
  • platform/efl/fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
  • platform/gtk/fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
Location:
trunk
Files:
8 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r101754 r101755  
     12011-12-02  Yosifumi Inoue  <yosin@chromium.org>
     2
     3        Range sliders and spin buttons don't work with multi-columns.
     4        https://bugs.webkit.org/show_bug.cgi?id=70898
     5
     6        Reviewed by Dan Bernstein.
     7
     8        * fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
     9        * fast/events/offsetX-offsetY.html: Change offset for "in-columns" test.
     10        * fast/forms/listbox/listbox-in-multi-column-expected.txt: Added.
     11        * fast/forms/listbox/listbox-in-multi-column.html: Added.
     12        * fast/forms/number/spin-in-multi-column-expected.txt: Added.
     13        * fast/forms/number/spin-in-multi-column.html: Added.
     14        * fast/forms/range/slider-in-multi-column-expected.txt: Added.
     15        * fast/forms/range/slider-in-multi-column.html: Added.
     16        * platform/chromium-win/fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
     17        * platform/efl/fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
     18        * platform/gtk/fast/events/offsetX-offsetY-expected.txt: Change offset for "in-columns" test.
     19
    1202011-12-02  Pavel Feldman  <pfeldman@google.com>
    221
  • trunk/LayoutTests/fast/events/offsetX-offsetY-expected.txt

    r91479 r101755  
    1919PASS: event at (410, 30) hit fixed-box at offset (10, 10)
    2020PASS: event at (36, 272) hit with-bordertopextra at offset (4, 4)
    21 PASS: event at (639, 207) hit in-columns at offset (173, -189)
     21PASS: event at (639, 207) hit in-columns at offset (35, 5)
    2222PASS: event at (563, 410) hit inside-overflow at offset (7, 6)
    2323PASS: event at (112, 369) hit transformed at offset (11, 16)
  • trunk/LayoutTests/fast/events/offsetX-offsetY.html

    r91479 r101755  
    3838      dispatchEvent(410, 30, 'fixed-box', 10, 10);
    3939      dispatchEvent(36, 272, 'with-bordertopextra', 4, 4);
    40       dispatchEvent(639, 207, 'in-columns', 173, -189);
     40      dispatchEvent(639, 207, 'in-columns', 35, 5);
    4141      dispatchEvent(563, 410, 'inside-overflow', 7, 6);
    4242      dispatchEvent(112, 369, 'transformed', 11, 16);
  • trunk/LayoutTests/platform/chromium-win/fast/events/offsetX-offsetY-expected.txt

    r91490 r101755  
    1919PASS: event at (410, 30) hit fixed-box at offset (10, 10)
    2020FAIL: event at (36, 272) expected to hit with-bordertopextra at (4, 4) but hit filler at (56, 372)
    21 FAIL: event at (639, 207) expected to hit in-columns at (173, -189) but hit in-columns at (173, -205)
     21PASS: event at (639, 207) hit in-columns at offset (35, 5)
    2222FAIL: event at (563, 410) expected to hit inside-overflow at (7, 6) but hit overflow-contents at (178, 112)
    2323FAIL: event at (112, 369) expected to hit transformed at (11, 16) but hit transformed at (7, 2)
  • trunk/LayoutTests/platform/efl/fast/events/offsetX-offsetY-expected.txt

    r97993 r101755  
    1919PASS: event at (410, 30) hit fixed-box at offset (10, 10)
    2020FAIL: event at (36, 272) expected to hit with-bordertopextra at (4, 4) but hit with-bordertopextra at (4, 0)
    21 FAIL: event at (639, 207) expected to hit in-columns at (173, -189) but hit in-columns at (173, -210)
     21PASS: event at (639, 207) hit in-columns at offset (35, 5)
    2222FAIL: event at (563, 410) expected to hit inside-overflow at (7, 6) but hit inside-overflow at (7, 1)
    2323FAIL: event at (112, 369) expected to hit transformed at (11, 16) but hit transformed at (9, 9)
  • trunk/LayoutTests/platform/gtk/fast/events/offsetX-offsetY-expected.txt

    r101368 r101755  
    1919PASS: event at (410, 30) hit fixed-box at offset (10, 10)
    2020PASS: event at (36, 272) hit with-bordertopextra at offset (4, 4)
    21 FAIL: event at (639, 207) expected to hit in-columns at (173, -189) but hit in-columns at (173, -199)
     21PASS: event at (639, 207) hit in-columns at offset (35, 5)
    2222PASS: event at (563, 410) hit inside-overflow at offset (7, 6)
    2323PASS: event at (112, 369) hit transformed at offset (11, 16)
  • trunk/Source/WebCore/ChangeLog

    r101754 r101755  
     12011-12-02  Yosifumi Inoue  <yosin@chromium.org>
     2
     3        Range sliders and spin buttons don't work with multi-columns.
     4        https://bugs.webkit.org/show_bug.cgi?id=70898
     5
     6        Reviewed by Dan Bernstein.
     7
     8        This patch makes RenderBlock::hitTestColumns and
     9        RenderBoxModelObject::mapAbsoluteToLocal to handle point
     10        in multi-column same logic.
     11
     12        In multi-column, coordinate of box model rendering object is different
     13        from absolute coordinate.. Columns in box model rendering object spans
     14        vertically rather than horizontally.
     15
     16        When absolute point is represented in (column[i]+dx, column[0]+dy),
     17        it is (column[0]+dx, column[0] + columnHeight + dy) in box model
     18        rendering object coordinate.
     19
     20        Tests: fast/events/document-elementFromPoint.html
     21               fast/events/offsetX-offsetY.html
     22               fast/forms/number/spin-in-multi-column.html
     23               fast/forms/range/slider-in-multi-column.html
     24               fast/forms/select/listbox-in-multi-column.html
     25
     26        * rendering/RenderBlock.cpp:
     27        (WebCore::ColumnRectIterator::ColumnRectIterator): Added
     28        (WebCore::ColumnRectIterator::advance): Added
     29        (WebCore::ColumnRectIterator::columnRect): Added
     30        (WebCore::ColumnRectIterator::hasMore): Added
     31        (WebCore::ColumnRectIterator::adjust): Added
     32        (WebCore::ColumnRectIterator::update): Added
     33        (WebCore::RenderBlock::hitTestColumns): Use ColumnRectIterator.
     34        (WebCore::RenderBlock::adjustForColumnRect): Added
     35        * rendering/RenderBlock.h: Add adjustForColumnRect.
     36        * rendering/RenderBox.cpp:
     37        (WebCore::RenderBox::mapAbsoluteToLocalPoint): Call RenderBoxModelObject::mapAbsoluteToLocalPoint.
     38        * rendering/RenderBoxModelObject.cpp:
     39        (WebCore::RenderBoxModelObject::mapAbsoluteToLocalPoint): Move from RenderInline::mapAbsoluteToLocalPoint and call RenderBlock::adjustForColumnRect.
     40        * rendering/RenderBoxModelObject.h: add mapAbsoluteToLocalPoint.
     41        * rendering/RenderInline.cpp: Move mapAbsoluteToLocalPoint to RenderBoxModelObject.
     42        * rendering/RenderInline.h: remove mapAbsoluteToLocalPoint.
     43
    1442011-12-02  Pavel Feldman  <pfeldman@google.com>
    245
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r101584 r101755  
    42384238}
    42394239
     4240class ColumnRectIterator {
     4241    WTF_MAKE_NONCOPYABLE(ColumnRectIterator);
     4242public:
     4243    ColumnRectIterator(const RenderBlock& block)
     4244        : m_block(block)
     4245        , m_colInfo(block.columnInfo())
     4246        , m_direction(m_block.style()->isFlippedBlocksWritingMode() ? 1 : -1)
     4247        , m_isHorizontal(block.isHorizontalWritingMode())
     4248        , m_logicalLeft(block.logicalLeftOffsetForContent())
     4249    {
     4250        int colCount = m_colInfo->columnCount();
     4251        m_colIndex = colCount - 1;
     4252        m_currLogicalTopOffset = colCount * m_colInfo->columnHeight() * m_direction;
     4253        update();
     4254    }
     4255
     4256    void advance()
     4257    {
     4258        ASSERT(hasMore());
     4259        m_colIndex--;
     4260        update();
     4261    }
     4262
     4263    LayoutRect columnRect() const { return m_colRect; }
     4264    bool hasMore() const { return m_colIndex >= 0; }
     4265
     4266    void adjust(LayoutSize& offset) const
     4267    {
     4268        LayoutUnit currLogicalLeftOffset = (m_isHorizontal ? m_colRect.x() : m_colRect.y()) - m_logicalLeft;
     4269        offset += m_isHorizontal ? LayoutSize(currLogicalLeftOffset, m_currLogicalTopOffset) : LayoutSize(m_currLogicalTopOffset, currLogicalLeftOffset);
     4270        if (m_colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
     4271            if (m_isHorizontal)
     4272                offset.expand(0, m_colRect.y() - m_block.borderTop() - m_block.paddingTop());
     4273            else
     4274                offset.expand(m_colRect.x() - m_block.borderLeft() - m_block.paddingLeft(), 0);
     4275        }
     4276    }
     4277
     4278private:
     4279    void update()
     4280    {
     4281        if (m_colIndex < 0)
     4282            return;
     4283
     4284        m_colRect = m_block.columnRectAt(const_cast<ColumnInfo*>(m_colInfo), m_colIndex);
     4285        m_block.flipForWritingMode(m_colRect);
     4286        m_currLogicalTopOffset -= (m_isHorizontal ? m_colRect.height() : m_colRect.width()) * m_direction;
     4287    }
     4288
     4289    const RenderBlock& m_block;
     4290    const ColumnInfo* const m_colInfo;
     4291    const int m_direction;
     4292    const bool m_isHorizontal;
     4293    const LayoutUnit m_logicalLeft;
     4294    int m_colIndex;
     4295    LayoutUnit m_currLogicalTopOffset;
     4296    LayoutRect m_colRect;
     4297};
     4298
    42404299bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
    42414300{
    42424301    // We need to do multiple passes, breaking up our hit testing into strips.
    4243     ColumnInfo* colInfo = columnInfo();
    4244     int colCount = columnCount(colInfo);
    4245     if (!colCount)
     4302    if (!hasColumns())
    42464303        return false;
    4247     LayoutUnit logicalLeft = logicalLeftOffsetForContent();
    4248     LayoutUnit currLogicalTopOffset = !style()->isFlippedBlocksWritingMode() ? -colCount * colInfo->columnHeight() : colCount * colInfo->columnHeight();
    4249     bool isHorizontal = isHorizontalWritingMode();
    4250 
    4251     for (int i = colCount - 1; i >= 0; i--) {
    4252         LayoutRect colRect = columnRectAt(colInfo, i);
    4253         flipForWritingMode(colRect);
    4254         LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
    4255         LayoutUnit blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
    4256         if (style()->isFlippedBlocksWritingMode())
    4257             currLogicalTopOffset -= blockDelta;
    4258         else
    4259             currLogicalTopOffset += blockDelta;
     4304
     4305    for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
     4306        LayoutRect hitRect = result.rectForPoint(pointInContainer);
     4307        LayoutRect colRect = it.columnRect();
    42604308        colRect.moveBy(accumulatedOffset);
    4261        
    4262         if (colRect.intersects(result.rectForPoint(pointInContainer))) {
     4309        if (colRect.intersects(hitRect)) {
    42634310            // The point is inside this column.
    42644311            // Adjust accumulatedOffset to change where we hit test.
    4265        
    4266             LayoutSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, currLogicalLeftOffset);
    4267             if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
    4268                 if (isHorizontal)
    4269                     offset.expand(0, colRect.y() - accumulatedOffset.y() - borderTop() - paddingTop());
    4270                 else
    4271                     offset.expand(colRect.x() - accumulatedOffset.x() - borderLeft() - paddingLeft(), 0);
    4272             }
    4273 
     4312            LayoutSize offset;
     4313            it.adjust(offset);
    42744314            LayoutPoint finalLocation = accumulatedOffset + offset;
    4275             if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(pointInContainer)))
    4276                 hitTestContents(request, result, pointInContainer, finalLocation, hitTestAction);
    4277             else
     4315            if (!result.isRectBasedTest() || colRect.contains(hitRect))
    42784316                return hitTestContents(request, result, pointInContainer, finalLocation, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, pointInContainer, finalLocation));
     4317
     4318            hitTestContents(request, result, pointInContainer, finalLocation, hitTestAction);
    42794319        }
    42804320    }
    42814321
    42824322    return false;
     4323}
     4324
     4325void RenderBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& pointInContainer) const
     4326{
     4327    for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
     4328        LayoutRect colRect = it.columnRect();
     4329        if (colRect.contains(pointInContainer)) {
     4330            it.adjust(offset);
     4331            return;
     4332        }
     4333    }
    42834334}
    42844335
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r101574 r101755  
    197197    void adjustRectForColumns(LayoutRect&) const;
    198198    virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const;
     199    void adjustForColumnRect(LayoutSize& offset, const LayoutPoint& pointInContainer) const;
    199200
    200201    void addContinuationWithOutline(RenderInline*);
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r101399 r101755  
    13941394    } else
    13951395        fixed |= isFixedPos;
    1396    
    1397     RenderObject* o = container();
    1398     if (!o)
    1399         return;
    1400 
    1401     o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
    1402 
    1403     LayoutSize containerOffset = offsetFromContainer(o, LayoutPoint());
    1404 
    1405     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
    1406     if (useTransforms && shouldUseTransformFromContainer(o)) {
    1407         TransformationMatrix t;
    1408         getTransformFromContainer(o, containerOffset, t);
    1409         transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
    1410     } else
    1411         transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
     1396
     1397    RenderBoxModelObject::mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
    14121398}
    14131399
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r100528 r101755  
    3838#include "RenderView.h"
    3939#include "Settings.h"
     40#include "TransformState.h"
    4041#include <wtf/CurrentTime.h>
    4142
     
    27182719}
    27192720
     2721void RenderBoxModelObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
     2722{
     2723    // We don't expect absoluteToLocal() to be called during layout (yet)
     2724    ASSERT(!view() || !view()->layoutStateEnabled());
     2725
     2726    RenderObject* o = container();
     2727    if (!o)
     2728        return;
     2729
     2730    o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
     2731
     2732    LayoutSize containerOffset = offsetFromContainer(o, LayoutPoint());
     2733
     2734    if (style()->position() != AbsolutePosition && style()->position() != FixedPosition && o->hasColumns()) {
     2735        RenderBlock* block = static_cast<RenderBlock*>(o);
     2736        LayoutPoint point(roundedLayoutPoint(transformState.mappedPoint()));
     2737        point -= containerOffset;
     2738        block->adjustForColumnRect(containerOffset, point);
     2739    }
     2740
     2741    bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
     2742    if (useTransforms && shouldUseTransformFromContainer(o)) {
     2743        TransformationMatrix t;
     2744        getTransformFromContainer(o, containerOffset, t);
     2745        transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
     2746    } else
     2747        transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
     2748}
     2749
    27202750} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.h

    r99893 r101755  
    125125    virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
    126126    virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
     127
     128    virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const OVERRIDE;
    127129
    128130    // Called by RenderObject::willBeDestroyed() and is the only way layers should ever be destroyed
  • trunk/Source/WebCore/rendering/RenderInline.cpp

    r101342 r101755  
    11621162}
    11631163
    1164 void RenderInline::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
    1165 {
    1166     // We don't expect this function to be called during layout.
    1167     ASSERT(!view() || !view()->layoutStateEnabled());
    1168 
    1169     RenderObject* o = container();
    1170     if (!o)
    1171         return;
    1172 
    1173     o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
    1174 
    1175     LayoutSize containerOffset = offsetFromContainer(o, LayoutPoint());
    1176 
    1177     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
    1178     if (useTransforms && shouldUseTransformFromContainer(o)) {
    1179         TransformationMatrix t;
    1180         getTransformFromContainer(o, containerOffset, t);
    1181         transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
    1182     } else
    1183         transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
    1184 }
    1185 
    11861164void RenderInline::updateDragState(bool dragOn)
    11871165{
  • trunk/Source/WebCore/rendering/RenderInline.h

    r96859 r101755  
    132132
    133133    virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState&, bool* wasFixed = 0) const;
    134     virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
    135134
    136135    virtual VisiblePosition positionForPoint(const LayoutPoint&);
Note: See TracChangeset for help on using the changeset viewer.