Commit 34c7902c authored by hyatt@apple.com's avatar hyatt@apple.com

Source/JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=69372

        
[CSS3 Regions] Make sure overflow:visible lets content spill out of regions.
        
Add support for reverse iteration to ListHashSet to support being able to walk them
backwards easily.

Reviewed by Anders Carlsson.

* wtf/ListHashSet.h:
(WTF::ListHashSetReverseIterator::ListHashSetReverseIterator):
(WTF::ListHashSetReverseIterator::get):
(WTF::ListHashSetReverseIterator::operator*):
(WTF::ListHashSetReverseIterator::operator->):
(WTF::ListHashSetReverseIterator::operator++):
(WTF::ListHashSetReverseIterator::operator--):
(WTF::ListHashSetReverseIterator::operator==):
(WTF::ListHashSetReverseIterator::operator!=):
(WTF::ListHashSetReverseIterator::operator const_reverse_iterator):
(WTF::ListHashSetReverseIterator::node):
(WTF::ListHashSetConstReverseIterator::ListHashSetConstReverseIterator):
(WTF::ListHashSetConstReverseIterator::get):
(WTF::ListHashSetConstReverseIterator::operator*):
(WTF::ListHashSetConstReverseIterator::operator->):
(WTF::ListHashSetConstReverseIterator::operator++):
(WTF::ListHashSetConstReverseIterator::operator--):
(WTF::ListHashSetConstReverseIterator::operator==):
(WTF::ListHashSetConstReverseIterator::operator!=):
(WTF::ListHashSetConstReverseIterator::node):
(WTF::::rbegin):
(WTF::::rend):
(WTF::::makeReverseIterator):
(WTF::::makeConstReverseIterator):
(WTF::::makeConstIterator):

Source/WebCore: https://bugs.webkit.org/show_bug.cgi?id=69372
        
[CSS3 Regions] Make sure overflow:visible lets content spill out of regions.

Reviewed by Anders Carlsson.

No new tests, since plenty of results changed.

* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::paintIntoRegion):
(WebCore::RenderFlowThread::hitTestRegion):
(WebCore::RenderFlowThread::repaintRectangleInRegions):
(WebCore::RenderFlowThread::firstRegion):
(WebCore::RenderFlowThread::lastRegion):
* rendering/RenderFlowThread.h:
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::regionOverflowRect):
(WebCore::RenderRegion::isFirstRegion):
(WebCore::RenderRegion::isLastRegion):
(WebCore::RenderRegion::layout):
* rendering/RenderRegion.h:
(WebCore::RenderRegion::setRegionRect):
(WebCore::RenderRegion::regionRect):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=69372
        
[CSS3 Regions] Make sure overflow:visible lets content spill out of regions.

Reviewed by Anders Carlsson.

* platform/mac/fast/regions/content-flowed-into-regions-dynamically-removed-expected.png:
* platform/mac/fast/regions/percentage-margins-mixed-ltr-dominant-regions-expected.png:
* platform/mac/fast/regions/percentage-margins-mixed-rtl-dominant-regions-expected.png:
* platform/mac/fast/regions/percentage-margins-rtl-variable-width-regions-expected.png:
* platform/mac/fast/regions/percentage-margins-variable-width-regions-expected.png:
* platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.png:
* platform/mac/fast/regions/webkit-flow-float-unable-to-push-expected.png:
* platform/mac/fast/regions/webkit-flow-floats-inside-regions-bounds-expected.png:
* platform/mac/fast/regions/webkit-flow-inlines-dynamic-expected.png:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96643 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c65c4700
2011-10-04 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=69372
[CSS3 Regions] Make sure overflow:visible lets content spill out of regions.
Reviewed by Anders Carlsson.
* platform/mac/fast/regions/content-flowed-into-regions-dynamically-removed-expected.png:
* platform/mac/fast/regions/percentage-margins-mixed-ltr-dominant-regions-expected.png:
* platform/mac/fast/regions/percentage-margins-mixed-rtl-dominant-regions-expected.png:
* platform/mac/fast/regions/percentage-margins-rtl-variable-width-regions-expected.png:
* platform/mac/fast/regions/percentage-margins-variable-width-regions-expected.png:
* platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.png:
* platform/mac/fast/regions/webkit-flow-float-unable-to-push-expected.png:
* platform/mac/fast/regions/webkit-flow-floats-inside-regions-bounds-expected.png:
* platform/mac/fast/regions/webkit-flow-inlines-dynamic-expected.png:
2011-10-04 Csaba Osztrogonác <ossy@webkit.org>
[Qt] Unreviewed gardening. Update Qt specific expected results.
2011-10-04 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=69372
[CSS3 Regions] Make sure overflow:visible lets content spill out of regions.
Add support for reverse iteration to ListHashSet to support being able to walk them
backwards easily.
Reviewed by Anders Carlsson.
* wtf/ListHashSet.h:
(WTF::ListHashSetReverseIterator::ListHashSetReverseIterator):
(WTF::ListHashSetReverseIterator::get):
(WTF::ListHashSetReverseIterator::operator*):
(WTF::ListHashSetReverseIterator::operator->):
(WTF::ListHashSetReverseIterator::operator++):
(WTF::ListHashSetReverseIterator::operator--):
(WTF::ListHashSetReverseIterator::operator==):
(WTF::ListHashSetReverseIterator::operator!=):
(WTF::ListHashSetReverseIterator::operator const_reverse_iterator):
(WTF::ListHashSetReverseIterator::node):
(WTF::ListHashSetConstReverseIterator::ListHashSetConstReverseIterator):
(WTF::ListHashSetConstReverseIterator::get):
(WTF::ListHashSetConstReverseIterator::operator*):
(WTF::ListHashSetConstReverseIterator::operator->):
(WTF::ListHashSetConstReverseIterator::operator++):
(WTF::ListHashSetConstReverseIterator::operator--):
(WTF::ListHashSetConstReverseIterator::operator==):
(WTF::ListHashSetConstReverseIterator::operator!=):
(WTF::ListHashSetConstReverseIterator::node):
(WTF::::rbegin):
(WTF::::rend):
(WTF::::makeReverseIterator):
(WTF::::makeConstReverseIterator):
(WTF::::makeConstIterator):
2011-10-04 Gavin Peters <gavinp@chromium.org>
fix gtk breakage caused by changeset 96595
......@@ -49,6 +49,8 @@ namespace WTF {
template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator;
template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator;
template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetReverseIterator;
template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstReverseIterator;
template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode;
template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator;
......@@ -71,11 +73,15 @@ namespace WTF {
public:
typedef ValueArg ValueType;
typedef ListHashSetIterator<ValueType, inlineCapacity, HashArg> iterator;
typedef ListHashSetConstIterator<ValueType, inlineCapacity, HashArg> const_iterator;
friend class ListHashSetConstIterator<ValueType, inlineCapacity, HashArg>;
typedef ListHashSetReverseIterator<ValueType, inlineCapacity, HashArg> reverse_iterator;
typedef ListHashSetConstReverseIterator<ValueType, inlineCapacity, HashArg> const_reverse_iterator;
friend class ListHashSetConstReverseIterator<ValueType, inlineCapacity, HashArg>;
ListHashSet();
ListHashSet(const ListHashSet&);
ListHashSet& operator=(const ListHashSet&);
......@@ -92,6 +98,11 @@ namespace WTF {
const_iterator begin() const;
const_iterator end() const;
reverse_iterator rbegin();
reverse_iterator rend();
const_reverse_iterator rbegin() const;
const_reverse_iterator rend() const;
ValueType& first();
const ValueType& first() const;
......@@ -126,8 +137,11 @@ namespace WTF {
void appendNode(Node*);
void insertNodeBefore(Node* beforeNode, Node* newNode);
void deleteAllNodes();
iterator makeIterator(Node*);
const_iterator makeConstIterator(Node*) const;
reverse_iterator makeReverseIterator(Node*);
const_reverse_iterator makeConstReverseIterator(Node*) const;
friend void deleteAllValues<>(const ListHashSet&);
......@@ -358,6 +372,117 @@ namespace WTF {
Node* m_position;
};
template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetReverseIterator {
private:
typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
typedef ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg> reverse_iterator;
typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_reverse_iterator;
typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
typedef ValueArg ValueType;
typedef ValueType& ReferenceType;
typedef ValueType* PointerType;
friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;
ListHashSetReverseIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { }
public:
ListHashSetReverseIterator() { }
// default copy, assignment and destructor are OK
PointerType get() const { return const_cast<PointerType>(m_iterator.get()); }
ReferenceType operator*() const { return *get(); }
PointerType operator->() const { return get(); }
reverse_iterator& operator++() { ++m_iterator; return *this; }
// postfix ++ intentionally omitted
reverse_iterator& operator--() { --m_iterator; return *this; }
// postfix -- intentionally omitted
// Comparison.
bool operator==(const reverse_iterator& other) const { return m_iterator == other.m_iterator; }
bool operator!=(const reverse_iterator& other) const { return m_iterator != other.m_iterator; }
operator const_reverse_iterator() const { return m_iterator; }
private:
Node* node() { return m_iterator.node(); }
const_reverse_iterator m_iterator;
};
template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstReverseIterator {
private:
typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
typedef ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg> reverse_iterator;
typedef ListHashSetConstReverseIterator<ValueArg, inlineCapacity, HashArg> const_reverse_iterator;
typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
typedef ValueArg ValueType;
typedef const ValueType& ReferenceType;
typedef const ValueType* PointerType;
friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;
friend class ListHashSetConstReverseIterator<ValueArg, inlineCapacity, HashArg>;
ListHashSetConstReverseIterator(const ListHashSetType* set, Node* position)
: m_set(set)
, m_position(position)
{
}
public:
ListHashSetConstReverseIterator()
{
}
PointerType get() const
{
return &m_position->m_value;
}
ReferenceType operator*() const { return *get(); }
PointerType operator->() const { return get(); }
const_reverse_iterator& operator++()
{
ASSERT(m_position != 0);
m_position = m_position->m_prev;
return *this;
}
// postfix ++ intentionally omitted
const_reverse_iterator& operator--()
{
ASSERT(m_position != m_set->m_tail);
if (!m_position)
m_position = m_set->m_head;
else
m_position = m_position->m_next;
return *this;
}
// postfix -- intentionally omitted
// Comparison.
bool operator==(const const_reverse_iterator& other) const
{
return m_position == other.m_position;
}
bool operator!=(const const_reverse_iterator& other) const
{
return m_position != other.m_position;
}
private:
Node* node() { return m_position; }
const ListHashSetType* m_set;
Node* m_position;
};
template<typename ValueType, size_t inlineCapacity, typename HashFunctions>
struct ListHashSetTranslator {
......@@ -457,6 +582,30 @@ namespace WTF {
return makeConstIterator(0);
}
template<typename T, size_t inlineCapacity, typename U>
inline typename ListHashSet<T, inlineCapacity, U>::reverse_iterator ListHashSet<T, inlineCapacity, U>::rbegin()
{
return makeReverseIterator(m_tail);
}
template<typename T, size_t inlineCapacity, typename U>
inline typename ListHashSet<T, inlineCapacity, U>::reverse_iterator ListHashSet<T, inlineCapacity, U>::rend()
{
return makeReverseIterator(0);
}
template<typename T, size_t inlineCapacity, typename U>
inline typename ListHashSet<T, inlineCapacity, U>::const_reverse_iterator ListHashSet<T, inlineCapacity, U>::rbegin() const
{
return makeConstReverseIterator(m_tail);
}
template<typename T, size_t inlineCapacity, typename U>
inline typename ListHashSet<T, inlineCapacity, U>::const_reverse_iterator ListHashSet<T, inlineCapacity, U>::rend() const
{
return makeConstReverseIterator(0);
}
template<typename T, size_t inlineCapacity, typename U>
inline T& ListHashSet<T, inlineCapacity, U>::first()
{
......@@ -675,6 +824,18 @@ namespace WTF {
node->destroy(m_allocator.get());
}
template<typename T, size_t inlineCapacity, typename U>
inline ListHashSetReverseIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeReverseIterator(Node* position)
{
return ListHashSetReverseIterator<T, inlineCapacity, U>(this, position);
}
template<typename T, size_t inlineCapacity, typename U>
inline ListHashSetConstReverseIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstReverseIterator(Node* position) const
{
return ListHashSetConstReverseIterator<T, inlineCapacity, U>(this, position);
}
template<typename T, size_t inlineCapacity, typename U>
inline ListHashSetIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeIterator(Node* position)
{
......@@ -686,7 +847,6 @@ namespace WTF {
{
return ListHashSetConstIterator<T, inlineCapacity, U>(this, position);
}
template<bool, typename ValueType, typename HashTableType>
void deleteAllValues(HashTableType& collection)
{
......
2011-10-04 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=69372
[CSS3 Regions] Make sure overflow:visible lets content spill out of regions.
Reviewed by Anders Carlsson.
No new tests, since plenty of results changed.
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::paintIntoRegion):
(WebCore::RenderFlowThread::hitTestRegion):
(WebCore::RenderFlowThread::repaintRectangleInRegions):
(WebCore::RenderFlowThread::firstRegion):
(WebCore::RenderFlowThread::lastRegion):
* rendering/RenderFlowThread.h:
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::regionOverflowRect):
(WebCore::RenderRegion::isFirstRegion):
(WebCore::RenderRegion::isLastRegion):
(WebCore::RenderRegion::layout):
* rendering/RenderRegion.h:
(WebCore::RenderRegion::setRegionRect):
(WebCore::RenderRegion::regionRect):
2011-10-04 Chris Rogers <crogers@google.com>
Avoid unnecessary ASSERT in AudioDSPKernelProcessor::setNumberOfChannels()
......@@ -420,7 +420,8 @@ void RenderFlowThread::paintIntoRegion(PaintInfo& paintInfo, RenderRegion* regio
// paintOffset contains the offset where the painting should occur
// adjusted with the region padding and border.
LayoutRect regionRect(region->regionRect());
LayoutRect regionClippingRect(paintOffset, regionRect.size());
LayoutRect regionOverflowRect(region->regionOverflowRect());
LayoutRect regionClippingRect(paintOffset, regionOverflowRect.size());
PaintInfo info(paintInfo);
info.rect.intersect(regionClippingRect);
......@@ -452,8 +453,9 @@ void RenderFlowThread::paintIntoRegion(PaintInfo& paintInfo, RenderRegion* regio
bool RenderFlowThread::hitTestRegion(RenderRegion* region, const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
{
LayoutRect regionRect = region->regionRect();
LayoutRect regionClippingRect(accumulatedOffset, regionRect.size());
LayoutRect regionRect(region->regionRect());
LayoutRect regionOverflowRect = region->regionOverflowRect();
LayoutRect regionClippingRect(accumulatedOffset, regionOverflowRect.size());
if (!regionClippingRect.contains(pointInContainer))
return false;
......@@ -504,9 +506,11 @@ void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect,
// We only have to issue a repaint in this region if the region rect intersects the repaint rect.
LayoutRect flippedRegionRect(region->regionRect());
flipForWritingMode(flippedRegionRect); // Put the region rect into physical coordinates.
IntRect clippedRect(flippedRegionRect);
LayoutRect flippedRegionOverflowRect(region->regionOverflowRect());
flipForWritingMode(flippedRegionRect); // Put the region rects into physical coordinates.
flipForWritingMode(flippedRegionOverflowRect);
IntRect clippedRect(flippedRegionOverflowRect);
clippedRect.intersect(repaintRect);
if (clippedRect.isEmpty())
continue;
......@@ -699,4 +703,30 @@ LayoutUnit RenderFlowThread::contentLogicalLeftOfFirstRegion() const
return 0;
}
RenderRegion* RenderFlowThread::firstRegion() const
{
if (!hasValidRegions())
return 0;
for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
RenderRegion* region = *iter;
if (!region->isValid())
continue;
return region;
}
return 0;
}
RenderRegion* RenderFlowThread::lastRegion() const
{
if (!hasValidRegions())
return 0;
for (RenderRegionList::const_reverse_iterator iter = m_regionList.rbegin(); iter != m_regionList.rend(); ++iter) {
RenderRegion* region = *iter;
if (!region->isValid())
continue;
return region;
}
return 0;
}
} // namespace WebCore
......@@ -114,6 +114,9 @@ public:
LayoutUnit contentLogicalHeightOfFirstRegion() const;
LayoutUnit contentLogicalLeftOfFirstRegion() const;
RenderRegion* firstRegion() const;
RenderRegion* lastRegion() const;
private:
virtual const char* renderName() const { return "RenderFlowThread"; }
......
......@@ -53,6 +53,40 @@ RenderRegion::~RenderRegion()
deleteAllRenderBoxRegionInfo();
}
LayoutRect RenderRegion::regionOverflowRect() const
{
if (hasOverflowClip() || !isValid() || !m_flowThread)
return regionRect();
LayoutRect flowThreadOverflow = m_flowThread->visualOverflowRect();
// Only clip along the flow thread axis.
LayoutRect clipRect;
if (m_flowThread->isHorizontalWritingMode()) {
LayoutUnit minY = isFirstRegion() ? flowThreadOverflow.y() : regionRect().y();
LayoutUnit maxY = isLastRegion() ? flowThreadOverflow.maxY() : regionRect().maxY();
clipRect = LayoutRect(flowThreadOverflow.x(), minY, flowThreadOverflow.width(), maxY - minY);
} else {
LayoutUnit minX = isFirstRegion() ? flowThreadOverflow.x() : regionRect().x();
LayoutUnit maxX = isLastRegion() ? flowThreadOverflow.maxX() : regionRect().maxX();
clipRect = LayoutRect(minX, flowThreadOverflow.y(), maxX - minX, flowThreadOverflow.height());
}
return clipRect;
}
bool RenderRegion::isFirstRegion() const
{
ASSERT(isValid() && m_flowThread);
return m_flowThread->firstRegion() == this;
}
bool RenderRegion::isLastRegion() const
{
ASSERT(isValid() && m_flowThread);
return m_flowThread->lastRegion() == this;
}
void RenderRegion::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// Delegate painting of content in region to RenderFlowThread.
......@@ -91,6 +125,17 @@ void RenderRegion::layout()
if (regionRect().width() != contentWidth() || regionRect().height() != contentHeight())
m_flowThread->invalidateRegions();
}
// FIXME: We need to find a way to set up overflow properly. Our flow thread hasn't gotten a layout
// yet, so we can't look to it for correct information. It's possible we could wait until after the RenderFlowThread
// gets a layout, and then try to propagate overflow information back to the region, and then mark for a second layout.
// That second layout would then be able to use the information from the RenderFlowThread to set up overflow.
//
// The big problem though is that overflow needs to be region-specific. We can't simply use the RenderFlowThread's global
// overflow values, since then we'd always think any narrow region had huge overflow (all the way to the width of the
// RenderFlowThread itself).
//
// We'll need to expand RenderBoxRegionInfo to also hold left and right overflow values.
}
void RenderRegion::attachRegion()
......
......@@ -48,8 +48,9 @@ public:
virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
void setRegionRect(const IntRect& rect) { m_regionRect = rect; }
IntRect regionRect() const { return m_regionRect; }
void setRegionRect(const LayoutRect& rect) { m_regionRect = rect; }
LayoutRect regionRect() const { return m_regionRect; }
LayoutRect regionOverflowRect() const;
void attachRegion();
void detachRegion();
......@@ -70,6 +71,9 @@ public:
LayoutUnit offsetFromLogicalTopOfFirstPage() const;
bool isFirstRegion() const;
bool isLastRegion() const;
private:
virtual const char* renderName() const { return "RenderRegion"; }
......@@ -79,7 +83,7 @@ private:
// we need to create a dependency tree, so that layout of the
// regions is always done before the regions themselves.
RenderFlowThread* m_parentFlowThread;
IntRect m_regionRect;
LayoutRect m_regionRect;
// This map holds unique information about a block that is split across regions.
// A RenderBoxRegionInfo* tells us about any layout information for a RenderBox that
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment