Merge from Chromium at DEPS revision r215573
This commit was generated by merge_to_master.py.
Change-Id: I07a9d4f856da71a9fb8fcd4d688596ef141bf5a3
diff --git a/Source/core/rendering/BidiRun.cpp b/Source/core/rendering/BidiRun.cpp
index 8e56a0b..12e83a5 100644
--- a/Source/core/rendering/BidiRun.cpp
+++ b/Source/core/rendering/BidiRun.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/rendering/BidiRun.h"
-#include "core/rendering/RenderArena.h"
+#include "core/platform/Partitions.h"
#include "wtf/RefCountedLeakCounter.h"
#include "wtf/StdLibExtras.h"
@@ -33,42 +33,20 @@
DEFINE_DEBUG_ONLY_GLOBAL(RefCountedLeakCounter, bidiRunCounter, ("BidiRun"));
-#ifndef NDEBUG
-static bool inBidiRunDestroy;
-#endif
-
-void BidiRun::destroy()
-{
-#ifndef NDEBUG
- inBidiRunDestroy = true;
-#endif
- RenderArena* renderArena = m_object->renderArena();
- delete this;
-#ifndef NDEBUG
- inBidiRunDestroy = false;
-#endif
-
- // Recover the size left there for us by operator delete and free the memory.
- renderArena->free(*reinterpret_cast<size_t*>(this), this);
-}
-
-void* BidiRun::operator new(size_t sz, RenderArena* renderArena)
+void* BidiRun::operator new(size_t sz)
{
#ifndef NDEBUG
bidiRunCounter.increment();
#endif
- return renderArena->allocate(sz);
+ return partitionAlloc(Partitions::getRenderingPartition(), sz);
}
-void BidiRun::operator delete(void* ptr, size_t sz)
+void BidiRun::operator delete(void* ptr)
{
#ifndef NDEBUG
bidiRunCounter.decrement();
#endif
- ASSERT(inBidiRunDestroy);
-
- // Stash size where destroy() can find it.
- *(size_t*)ptr = sz;
+ partitionFree(ptr);
}
}
diff --git a/Source/core/rendering/BidiRun.h b/Source/core/rendering/BidiRun.h
index 74f3fad..abfe2d1 100644
--- a/Source/core/rendering/BidiRun.h
+++ b/Source/core/rendering/BidiRun.h
@@ -44,21 +44,13 @@
m_startsSegment = false;
}
- void destroy();
-
- // Overloaded new operator.
- void* operator new(size_t, RenderArena*);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
+ // BidiRuns are allocated out of the rendering partition.
+ void* operator new(size_t);
+ void operator delete(void*);
BidiRun* next() { return static_cast<BidiRun*>(m_next); }
RenderObject* object() { return m_object; }
-private:
- // The normal operator new is disallowed.
- void* operator new(size_t) throw();
-
public:
RenderObject* m_object;
InlineBox* m_box;
diff --git a/Source/core/rendering/InlineBox.cpp b/Source/core/rendering/InlineBox.cpp
index a1bc0b9..bfd9db6 100644
--- a/Source/core/rendering/InlineBox.cpp
+++ b/Source/core/rendering/InlineBox.cpp
@@ -20,10 +20,10 @@
#include "config.h"
#include "core/rendering/InlineBox.h"
+#include "core/platform/Partitions.h"
#include "core/platform/graphics/FontMetrics.h"
#include "core/rendering/InlineFlowBox.h"
#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RootInlineBox.h"
@@ -68,31 +68,14 @@
parent()->removeChild(this);
}
-void InlineBox::destroy(RenderArena* renderArena)
+void* InlineBox::operator new(size_t sz)
{
-#ifndef NDEBUG
- inInlineBoxDetach = true;
-#endif
- delete this;
-#ifndef NDEBUG
- inInlineBoxDetach = false;
-#endif
-
- // Recover the size left there for us by operator delete and free the memory.
- renderArena->free(*(size_t *)this, this);
+ return partitionAlloc(Partitions::getRenderingPartition(), sz);
}
-void* InlineBox::operator new(size_t sz, RenderArena* renderArena)
+void InlineBox::operator delete(void* ptr)
{
- return renderArena->allocate(sz);
-}
-
-void InlineBox::operator delete(void* ptr, size_t sz)
-{
- ASSERT(inInlineBoxDetach);
-
- // Stash size where destroy can find it.
- *(size_t *)ptr = sz;
+ partitionFree(ptr);
}
#ifndef NDEBUG
@@ -183,11 +166,11 @@
curr->markDirty();
}
-void InlineBox::deleteLine(RenderArena* arena)
+void InlineBox::deleteLine()
{
if (!m_bitfields.extracted() && m_renderer->isBox())
toRenderBox(m_renderer)->setInlineBoxWrapper(0);
- destroy(arena);
+ destroy();
}
void InlineBox::extractLine()
diff --git a/Source/core/rendering/InlineBox.h b/Source/core/rendering/InlineBox.h
index b94346c..fdb04d5 100644
--- a/Source/core/rendering/InlineBox.h
+++ b/Source/core/rendering/InlineBox.h
@@ -63,9 +63,9 @@
virtual ~InlineBox();
- virtual void destroy(RenderArena*);
+ virtual void destroy() { delete this; }
- virtual void deleteLine(RenderArena*);
+ virtual void deleteLine();
virtual void extractLine();
virtual void attachLine();
@@ -97,15 +97,9 @@
virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom);
- // Overloaded new operator.
- void* operator new(size_t, RenderArena*);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
-
-private:
- // The normal operator new is disallowed.
- void* operator new(size_t) throw();
+ // InlineBoxes are allocated out of the rendering partition.
+ void* operator new(size_t);
+ void operator delete(void*);
public:
#ifndef NDEBUG
diff --git a/Source/core/rendering/InlineFlowBox.cpp b/Source/core/rendering/InlineFlowBox.cpp
index 8fc9a48..e9890ff 100644
--- a/Source/core/rendering/InlineFlowBox.cpp
+++ b/Source/core/rendering/InlineFlowBox.cpp
@@ -198,7 +198,7 @@
checkConsistency();
}
-void InlineFlowBox::deleteLine(RenderArena* arena)
+void InlineFlowBox::deleteLine()
{
InlineBox* child = firstChild();
InlineBox* next = 0;
@@ -208,7 +208,7 @@
#ifndef NDEBUG
child->setParent(0);
#endif
- child->deleteLine(arena);
+ child->deleteLine();
child = next;
}
#ifndef NDEBUG
@@ -217,7 +217,7 @@
#endif
removeLineBoxFromRenderObject();
- destroy(arena);
+ destroy();
}
void InlineFlowBox::removeLineBoxFromRenderObject()
diff --git a/Source/core/rendering/InlineFlowBox.h b/Source/core/rendering/InlineFlowBox.h
index 8128326..e81e426 100644
--- a/Source/core/rendering/InlineFlowBox.h
+++ b/Source/core/rendering/InlineFlowBox.h
@@ -96,7 +96,7 @@
}
void addToLine(InlineBox* child);
- virtual void deleteLine(RenderArena*) OVERRIDE FINAL;
+ virtual void deleteLine() OVERRIDE FINAL;
virtual void extractLine() OVERRIDE FINAL;
virtual void attachLine() OVERRIDE FINAL;
virtual void adjustPosition(float dx, float dy);
diff --git a/Source/core/rendering/InlineIterator.h b/Source/core/rendering/InlineIterator.h
index 6750b85..eae2dca 100644
--- a/Source/core/rendering/InlineIterator.h
+++ b/Source/core/rendering/InlineIterator.h
@@ -444,7 +444,7 @@
static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolver, RenderObject* obj, unsigned pos)
{
ASSERT(obj);
- BidiRun* isolatedRun = new (obj->renderArena()) BidiRun(pos, 0, obj, resolver.context(), resolver.dir());
+ BidiRun* isolatedRun = new BidiRun(pos, 0, obj, resolver.context(), resolver.dir());
resolver.runs().addRun(isolatedRun);
// FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply
// ASSERT here that we didn't create multiple objects for the same inline.
diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp
index 3a22c0f..e2eeae0 100644
--- a/Source/core/rendering/InlineTextBox.cpp
+++ b/Source/core/rendering/InlineTextBox.cpp
@@ -65,11 +65,11 @@
static const int misspellingLineThickness = 3;
-void InlineTextBox::destroy(RenderArena* arena)
+void InlineTextBox::destroy()
{
if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow)
gTextBoxesWithOverflow->remove(this);
- InlineBox::destroy(arena);
+ InlineBox::destroy();
}
void InlineTextBox::markDirty(bool dirty)
@@ -238,10 +238,10 @@
return LayoutRect(topPoint, LayoutSize(width, height));
}
-void InlineTextBox::deleteLine(RenderArena* arena)
+void InlineTextBox::deleteLine()
{
toRenderText(renderer())->removeTextBox(this);
- destroy(arena);
+ destroy();
}
void InlineTextBox::extractLine()
diff --git a/Source/core/rendering/InlineTextBox.h b/Source/core/rendering/InlineTextBox.h
index 2647d65..8778f97 100644
--- a/Source/core/rendering/InlineTextBox.h
+++ b/Source/core/rendering/InlineTextBox.h
@@ -57,7 +57,7 @@
{
}
- virtual void destroy(RenderArena*) OVERRIDE FINAL;
+ virtual void destroy() OVERRIDE FINAL;
InlineTextBox* prevTextBox() const { return m_prevTextBox; }
InlineTextBox* nextTextBox() const { return m_nextTextBox; }
@@ -125,7 +125,7 @@
RenderText* textRenderer() const;
private:
- virtual void deleteLine(RenderArena*) OVERRIDE FINAL;
+ virtual void deleteLine() OVERRIDE FINAL;
virtual void extractLine() OVERRIDE FINAL;
virtual void attachLine() OVERRIDE FINAL;
diff --git a/Source/core/rendering/LayoutState.cpp b/Source/core/rendering/LayoutState.cpp
index fe30cda..6d1b6fa 100644
--- a/Source/core/rendering/LayoutState.cpp
+++ b/Source/core/rendering/LayoutState.cpp
@@ -26,8 +26,8 @@
#include "config.h"
#include "core/rendering/LayoutState.h"
+#include "core/platform/Partitions.h"
#include "core/rendering/ColumnInfo.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
@@ -161,31 +161,14 @@
}
}
-#ifndef NDEBUG
-static bool inLayoutStateDestroy;
-#endif
-
-void LayoutState::destroy(RenderArena* renderArena)
+void* LayoutState::operator new(size_t sz)
{
-#ifndef NDEBUG
- inLayoutStateDestroy = true;
-#endif
- delete this;
-#ifndef NDEBUG
- inLayoutStateDestroy = false;
-#endif
- renderArena->free(*(size_t*)this, this);
+ return partitionAlloc(Partitions::getRenderingPartition(), sz);
}
-void* LayoutState::operator new(size_t sz, RenderArena* renderArena)
+void LayoutState::operator delete(void* ptr)
{
- return renderArena->allocate(sz);
-}
-
-void LayoutState::operator delete(void* ptr, size_t sz)
-{
- ASSERT(inLayoutStateDestroy);
- *(size_t*)ptr = sz;
+ partitionFree(ptr);
}
void LayoutState::clearPaginationInformation()
diff --git a/Source/core/rendering/LayoutState.h b/Source/core/rendering/LayoutState.h
index 058aa43..1bd336c 100644
--- a/Source/core/rendering/LayoutState.h
+++ b/Source/core/rendering/LayoutState.h
@@ -33,7 +33,6 @@
namespace WebCore {
-class RenderArena;
class RenderBlock;
class RenderBox;
class RenderObject;
@@ -65,13 +64,9 @@
LayoutState(LayoutState*, RenderBox*, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged, ColumnInfo*);
LayoutState(RenderObject*);
- void destroy(RenderArena*);
-
- // Overloaded new operator.
- void* operator new(size_t, RenderArena*);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
+ // LayoutState is allocated out of the rendering partition.
+ void* operator new(size_t);
+ void operator delete(void*);
void clearPaginationInformation();
bool isPaginatingColumns() const { return m_columnInfo && m_columnInfo->paginationUnit() == ColumnInfo::Column; }
@@ -96,9 +91,6 @@
ShapeInsideInfo* shapeInsideInfo() const { return m_shapeInsideInfo; }
private:
- // The normal operator new is disallowed.
- void* operator new(size_t) throw();
-
void propagateLineGridInfo(RenderBox*);
void establishLineGrid(RenderBlock*);
diff --git a/Source/core/rendering/RenderArena.cpp b/Source/core/rendering/RenderArena.cpp
deleted file mode 100644
index 69a4f29..0000000
--- a/Source/core/rendering/RenderArena.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2003 Apple Computer, Inc.
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * Portions are Copyright (C) 1998 Netscape Communications Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#include "config.h"
-#include "core/rendering/RenderArena.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <limits>
-
-#include "wtf/Assertions.h"
-#include "wtf/CryptographicallyRandomNumber.h"
-
-#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
-
-#ifdef NDEBUG
-static void* MaskPtr(void* p, uintptr_t mask)
-{
- return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask);
-}
-#endif
-
-namespace WebCore {
-
-#ifndef NDEBUG
-
-const int signature = 0xDBA00AEA;
-const int signatureDead = 0xDBA00AED;
-
-typedef struct {
- RenderArena* arena;
- size_t size;
- int signature;
-} RenderArenaDebugHeader;
-
-static const size_t debugHeaderSize = ARENA_ALIGN(sizeof(RenderArenaDebugHeader));
-
-#endif
-
-RenderArena::RenderArena(unsigned arenaSize)
- : m_totalSize(0)
- , m_totalAllocated(0)
-{
- ASSERT(arenaSize > sizeof(Arena) + ARENA_ALIGN_MASK);
- // The underlying Arena class allocates some metadata on top of our
- // requested size. Factor this in so that we can get perfect power-of-two
- // allocation sizes passed to the underlying malloc() call.
- arenaSize -= (sizeof(Arena) + ARENA_ALIGN_MASK);
- // Initialize the arena pool
- INIT_ARENA_POOL(&m_pool, "RenderArena", arenaSize);
-
- // Zero out the recyclers array
- memset(m_recyclers, 0, sizeof(m_recyclers));
-
- // Mask freelist pointers to detect corruption and stop freelist spraying.
- // We use an arbitray function and rely on ASLR to randomize it.
- // The first value in RenderObject (or any class) is a vtable pointer, which
- // always overlaps with the next pointer. This change guarantees that the
- // masked vtable/next pointer will never point to valid memory. So, we
- // should immediately crash on the first invalid vtable access for a stale
- // RenderObject pointer.
- // See http://download.crowdstrike.com/papers/hes-exploiting-a-coalmine.pdf.
- WTF::cryptographicallyRandomValues(&m_mask, sizeof(m_mask));
- m_mask |= (static_cast<uintptr_t>(3) << (std::numeric_limits<uintptr_t>::digits - 2)) | 1;
-}
-
-RenderArena::~RenderArena()
-{
- FinishArenaPool(&m_pool);
-}
-
-void* RenderArena::allocate(size_t size)
-{
- ASSERT(size <= gMaxRecycledSize - 32);
- m_totalSize += size;
-
-#ifdef ADDRESS_SANITIZER
- return ::malloc(size);
-#elif !defined(NDEBUG)
- // Use standard malloc so that memory debugging tools work.
- ASSERT(this);
- void* block = ::malloc(debugHeaderSize + size);
- RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block);
- header->arena = this;
- header->size = size;
- header->signature = signature;
- return static_cast<char*>(block) + debugHeaderSize;
-#else
- // Ensure we have correct alignment for pointers. Important for Tru64
- size = ROUNDUP(size, sizeof(void*));
-
- const size_t index = size >> kRecyclerShift;
-
- void* result = m_recyclers[index];
- if (result) {
- // Need to move to the next object
- void* next = MaskPtr(*((void**)result), m_mask);
- m_recyclers[index] = next;
- }
-
- if (!result) {
- // Allocate a new chunk from the arena
- unsigned bytesAllocated = 0;
- ARENA_ALLOCATE(result, &m_pool, size, &bytesAllocated);
- m_totalAllocated += bytesAllocated;
- }
-
- return result;
-#endif
-}
-
-void RenderArena::free(size_t size, void* ptr)
-{
- ASSERT(size <= gMaxRecycledSize - 32);
- m_totalSize -= size;
-
-#ifdef ADDRESS_SANITIZER
- ::free(ptr);
-#elif !defined(NDEBUG)
- // Use standard free so that memory debugging tools work.
- void* block = static_cast<char*>(ptr) - debugHeaderSize;
- RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block);
- ASSERT(header->signature == signature);
- ASSERT_UNUSED(size, header->size == size);
- ASSERT(header->arena == this);
- header->signature = signatureDead;
- ::free(block);
-#else
- // Ensure we have correct alignment for pointers. Important for Tru64
- size = ROUNDUP(size, sizeof(void*));
-
- const size_t index = size >> kRecyclerShift;
- void* currentTop = m_recyclers[index];
- m_recyclers[index] = ptr;
- *((void**)ptr) = MaskPtr(currentTop, m_mask);
-#endif
-}
-
-} // namespace WebCore
diff --git a/Source/core/rendering/RenderArena.h b/Source/core/rendering/RenderArena.h
deleted file mode 100644
index 255509e..0000000
--- a/Source/core/rendering/RenderArena.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2003 Apple Computer, Inc.
- *
- * Portions are Copyright (C) 1998 Netscape Communications Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#ifndef RenderArena_h
-#define RenderArena_h
-
-#include "core/platform/Arena.h"
-#include "wtf/FastAllocBase.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-static const size_t gMaxRecycledSize = 1024;
-
-class RenderArena : public RefCounted<RenderArena> {
-public:
- static PassRefPtr<RenderArena> create() { return adoptRef(new RenderArena); }
- ~RenderArena();
-
- // Memory management functions
- void* allocate(size_t);
- void free(size_t, void*);
-
- size_t totalRenderArenaSize() const { return m_totalSize; }
- size_t totalRenderArenaAllocatedBytes() const { return m_totalAllocated; }
-
-private:
- RenderArena(unsigned arenaSize = 8192);
-
- // Underlying arena pool
- ArenaPool m_pool;
-
- // The mask used to secure the recycled freelist pointers.
- uintptr_t m_mask;
- // The recycler array is sparse with the indices being multiples of the
- // rounding size, sizeof(void*), i.e., 0, 4, 8, 12, 16, 20, ... on 32-bit.
- static const size_t kRecyclerShift = (sizeof(void*) == 8) ? 3 : 2;
- void* m_recyclers[gMaxRecycledSize >> kRecyclerShift];
-
- size_t m_totalSize;
- size_t m_totalAllocated;
-};
-
-} // namespace WebCore
-
-#endif // RenderArena_h
diff --git a/Source/core/rendering/RenderBR.cpp b/Source/core/rendering/RenderBR.cpp
index df38fd9..27fa7c7 100644
--- a/Source/core/rendering/RenderBR.cpp
+++ b/Source/core/rendering/RenderBR.cpp
@@ -23,7 +23,6 @@
#include "core/rendering/RenderBR.h"
#include "core/dom/Document.h"
-#include "core/editing/VisiblePosition.h"
namespace WebCore {
@@ -73,9 +72,9 @@
return 1;
}
-VisiblePosition RenderBR::positionForPoint(const LayoutPoint&)
+PositionWithAffinity RenderBR::positionForPoint(const LayoutPoint&)
{
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
}
} // namespace WebCore
diff --git a/Source/core/rendering/RenderBR.h b/Source/core/rendering/RenderBR.h
index c504a6e..a5ad8ff 100644
--- a/Source/core/rendering/RenderBR.h
+++ b/Source/core/rendering/RenderBR.h
@@ -51,7 +51,7 @@
virtual int caretMinOffset() const;
virtual int caretMaxOffset() const;
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
diff --git a/Source/core/rendering/RenderBlock.cpp b/Source/core/rendering/RenderBlock.cpp
index b969ed8..e456543 100644
--- a/Source/core/rendering/RenderBlock.cpp
+++ b/Source/core/rendering/RenderBlock.cpp
@@ -228,23 +228,17 @@
{
FloatingObjects* floats = floatingObjects();
- // Container map entries are only cleared when the RenderBlock or the float are being destroyed.
- // This means that it might contain obsolete entries, but the performance cost of modifying the
- // container map during layout is very high, and it is much easier to deal with the extra entries
- // when iterating container maps.
- if (beingDestroyed()) {
- FloatingObjectSetIterator end = floats->set().end();
- for (FloatingObjectSetIterator floatIterator = floats->set().begin(); floatIterator != end; ++floatIterator) {
- TrackedContainerMap::iterator it = gFloatingObjectContainerMap->find((*floatIterator)->m_renderer);
- ASSERT(it != gFloatingObjectContainerMap->end());
- if (it == gFloatingObjectContainerMap->end())
- continue;
- HashSet<RenderBlock*>* containerSet = it->value.get();
- ASSERT(containerSet->contains(this));
- containerSet->remove(this);
- if (containerSet->isEmpty())
- gFloatingObjectContainerMap->remove(it);
- }
+ FloatingObjectSetIterator end = floats->set().end();
+ for (FloatingObjectSetIterator floatIterator = floats->set().begin(); floatIterator != end; ++floatIterator) {
+ TrackedContainerMap::iterator it = gFloatingObjectContainerMap->find((*floatIterator)->m_renderer);
+ ASSERT(it != gFloatingObjectContainerMap->end());
+ if (it == gFloatingObjectContainerMap->end())
+ continue;
+ HashSet<RenderBlock*>* containerSet = it->value.get();
+ ASSERT(containerSet->contains(this));
+ containerSet->remove(this);
+ if (containerSet->isEmpty())
+ gFloatingObjectContainerMap->remove(it);
}
if (deleteValues == DeleteAllValues)
deleteAllValues(floats->set());
@@ -269,7 +263,7 @@
RenderBlock* RenderBlock::createAnonymous(Document* document)
{
- RenderBlock* renderer = new (document->renderArena()) RenderBlock(0);
+ RenderBlock* renderer = new RenderBlock(0);
renderer->setDocumentForAnonymous(document);
return renderer;
}
@@ -279,16 +273,6 @@
// Mark as being destroyed to avoid trouble with merges in removeChild().
m_beingDestroyed = true;
- if (!documentBeingDestroyed()) {
- if (firstChild() && firstChild()->isRunIn()) {
- // If we are moving inline children(run-in) from |this| to |parent|, then we need
- // to clear our line box tree.
- if (childrenInline())
- deleteLineBoxTree();
- moveRunInToOriginalPosition(firstChild());
- }
- }
-
// Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
// properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
children()->destroyLeftoverChildren();
@@ -324,10 +308,10 @@
parent()->dirtyLinesFromChangedChild(this);
}
- m_lineBoxes.deleteLineBoxes(renderArena());
+ m_lineBoxes.deleteLineBoxes();
if (lineGridBox())
- lineGridBox()->destroy(renderArena());
+ lineGridBox()->destroy();
if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
gDelayedUpdateScrollInfoSet->remove(this);
@@ -734,9 +718,6 @@
// time in makeChildrenNonInline by just setting this explicitly up front.
newBlockBox->setChildrenInline(false);
- // We delayed adding the newChild until now so that the |newBlockBox| would be fully
- // connected, thus allowing newChild access to a renderArena should it need
- // to wrap itself in additional boxes (e.g., table construction).
newBlockBox->addChild(newChild);
// Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
@@ -786,9 +767,6 @@
// time in makeChildrenNonInline by just setting this explicitly up front.
newBlockBox->setChildrenInline(false);
- // We delayed adding the newChild until now so that the |newBlockBox| would be fully
- // connected, thus allowing newChild access to a renderArena should it need
- // to wrap itself in additional boxes (e.g., table construction).
newBlockBox->addChild(newChild);
// Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
@@ -1026,7 +1004,7 @@
(*it)->m_originatingLine = 0;
}
}
- m_lineBoxes.deleteLineBoxTree(renderArena());
+ m_lineBoxes.deleteLineBoxTree();
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->recomputeIsIgnored(this);
@@ -1034,7 +1012,7 @@
RootInlineBox* RenderBlock::createRootInlineBox()
{
- return new (renderArena()) RootInlineBox(this);
+ return new RootInlineBox(this);
}
RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
@@ -1952,9 +1930,9 @@
RenderBoxModelObject* newRunIn = 0;
if (!runIn->isRenderBlock())
- newRunIn = new (renderArena()) RenderBlock(runIn->node());
+ newRunIn = new RenderBlock(runIn->node());
else
- newRunIn = new (renderArena()) RenderInline(toElement(runIn->node()));
+ newRunIn = new RenderInline(toElement(runIn->node()));
runIn->node()->setRenderer(newRunIn);
newRunIn->setStyle(runIn->style());
@@ -1991,9 +1969,6 @@
if (!curr || !curr->isRenderBlock() || !curr->childrenInline())
return;
- if (toRenderBlock(curr)->beingDestroyed())
- return;
-
// Per CSS3, "A run-in cannot run in to a block that already starts with a
// run-in or that itself is a run-in".
if (curr->isRunIn() || (curr->firstChild() && curr->firstChild()->isRunIn()))
@@ -2880,10 +2855,8 @@
r->layoutIfNeeded();
// Lay out again if our estimate was wrong.
- if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) {
- r->setChildNeedsLayout(true, MarkOnlyThis);
- r->layoutIfNeeded();
- }
+ if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop)
+ r->forceChildLayout();
}
if (hasColumns())
@@ -3919,6 +3892,7 @@
FloatingObjects* floats = floatingObjects();
HashSet<RenderBlock*>* containerSet = gFloatingObjectContainerMap->get(floatingObject->renderer());
+ ASSERT(!containerSet || containerSet->contains(this) == floats->set().contains(floatingObject));
floats->add(floatingObject);
if (!containerSet) {
@@ -3941,11 +3915,13 @@
RenderBlock* container = *it;
TrackedFloatMap::iterator floatIterator = gFloatingObjectMap->find(container);
+ ASSERT(floatIterator != gFloatingObjectMap->end());
if (floatIterator == gFloatingObjectMap->end())
continue;
FloatingObjects* floatingObjects = floatIterator->value.get();
const FloatingObjectSet& floatingObjectSet = floatingObjects->set();
FloatingObjectSetIterator floatIt = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(floatingObject);
+ ASSERT(floatIt != floatingObjectSet.end());
if (floatIt != floatingObjectSet.end())
floatingObjects->remove(*floatIt);
if (floatingObjects->set().isEmpty())
@@ -5271,7 +5247,7 @@
// FIXME: This function should go on RenderObject as an instance method. Then
// all cases in which positionForPoint recurs could call this instead to
// prevent crossing editable boundaries. This would require many tests.
-static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const LayoutPoint& pointInParentCoordinates)
+static PositionWithAffinity positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const LayoutPoint& pointInParentCoordinates)
{
LayoutPoint childLocation = child->location();
if (child->isInFlowPositioned())
@@ -5299,16 +5275,16 @@
LayoutUnit childMiddle = parent->logicalWidthForChild(child) / 2;
LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
if (logicalLeft < childMiddle)
- return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
- return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
+ return ancestor->createPositionWithAffinity(childNode->nodeIndex(), DOWNSTREAM);
+ return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, UPSTREAM);
}
-VisiblePosition RenderBlock::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents)
+PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents)
{
ASSERT(childrenInline());
if (!firstRootBox())
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
bool linesAreFlipped = style()->isFlippedLinesWritingMode();
bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
@@ -5364,7 +5340,7 @@
box = newBox;
}
// y coordinate is above first root line box, so return the start of the first
- return VisiblePosition(positionForBox(box, true), DOWNSTREAM);
+ return PositionWithAffinity(positionForBox(box, true), DOWNSTREAM);
}
}
@@ -5382,13 +5358,13 @@
ASSERT(moveCaretToBoundary);
InlineBox* logicallyLastBox;
if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
- return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
+ return PositionWithAffinity(positionForBox(logicallyLastBox, false), DOWNSTREAM);
}
// Can't reach this. We have a root line box, but it has no kids.
// FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
// seems to hit this code path.
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
}
static inline bool isChildHitTestCandidate(RenderBox* box)
@@ -5396,7 +5372,7 @@
return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrOutOfFlowPositioned();
}
-VisiblePosition RenderBlock::positionForPoint(const LayoutPoint& point)
+PositionWithAffinity RenderBlock::positionForPoint(const LayoutPoint& point)
{
if (isTable())
return RenderBox::positionForPoint(point);
@@ -5407,9 +5383,9 @@
LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
- return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
+ return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
- return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
+ return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM);
}
LayoutPoint pointInContents = point;
@@ -6525,15 +6501,25 @@
// the normal flow. We make an exception for marquees, since their baselines are meaningless
// (the content inside them moves). This matches WinIE as well, which just bottom-aligns them.
// We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
- // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
- // of our content box.
+ // vertically (e.g., an overflow:hidden block that has had scrollTop moved).
+ // inline-block with overflow should use the bottom of margin box as well.
bool ignoreBaseline = (layer() && (isMarquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset())
- : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
+ : (layer()->horizontalScrollbar() || layer()->scrollXOffset())))) || (isWritingModeRoot() && !isRubyRun())
+ || (style()->isDisplayInlineType() && style()->overflowY() != OVISIBLE);
int baselinePos = ignoreBaseline ? -1 : inlineBlockBaseline(direction);
- LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
- if (baselinePos != -1 && baselinePos <= bottomOfContent)
+ if (isDeprecatedFlexibleBox()) {
+ // Historically, we did this check for all baselines. But we can't
+ // remove this code from deprecated flexbox, because it effectively
+ // breaks -webkit-line-clamp, which is used in the wild -- we would
+ // calculate the baseline as if -webkit-line-clamp wasn't used.
+ // For simplicity, we use this for all uses of deprecated flexbox.
+ LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
+ if (baselinePos > bottomOfContent)
+ baselinePos = -1;
+ }
+ if (baselinePos != -1)
return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
@@ -6791,7 +6777,7 @@
// Construct a text fragment for the text after the first letter.
// This text fragment might be empty.
RenderTextFragment* remainingText =
- new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
+ new RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
remainingText->setStyle(textObj->style());
if (remainingText->node())
remainingText->node()->setRenderer(remainingText);
@@ -6803,7 +6789,7 @@
// construct text fragment for the first letter
RenderTextFragment* letter =
- new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
+ new RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
letter->setStyle(pseudoStyle);
firstLetter->addChild(letter);
diff --git a/Source/core/rendering/RenderBlock.h b/Source/core/rendering/RenderBlock.h
index 1ee2475..feca5d0 100644
--- a/Source/core/rendering/RenderBlock.h
+++ b/Source/core/rendering/RenderBlock.h
@@ -227,7 +227,7 @@
LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
LayoutUnit textIndentOffset() const;
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
// Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
virtual LayoutUnit availableLogicalWidth() const OVERRIDE FINAL;
@@ -331,7 +331,7 @@
if (!m_rareData)
m_rareData = adoptPtr(new RenderBlockRareData(this));
if (m_rareData->m_lineGridBox)
- m_rareData->m_lineGridBox->destroy(renderArena());
+ m_rareData->m_lineGridBox->destroy();
m_rareData->m_lineGridBox = box;
}
void layoutLineGridBox();
@@ -965,7 +965,7 @@
void newLine(EClear);
Position positionForBox(InlineBox*, bool start = true) const;
- VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&);
+ PositionWithAffinity positionForPointWithInlineChildren(const LayoutPoint&);
virtual void calcColumnWidth();
void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
diff --git a/Source/core/rendering/RenderBlockLineLayout.cpp b/Source/core/rendering/RenderBlockLineLayout.cpp
index 4d9d6ec..eb77321 100644
--- a/Source/core/rendering/RenderBlockLineLayout.cpp
+++ b/Source/core/rendering/RenderBlockLineLayout.cpp
@@ -23,7 +23,6 @@
#include "config.h"
#include "core/platform/text/BidiResolver.h"
-#include "core/platform/text/Hyphenation.h"
#include "core/rendering/InlineIterator.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderCombineText.h"
@@ -427,7 +426,7 @@
static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
{
- return new (obj->renderArena()) BidiRun(start, end, obj, resolver.context(), resolver.dir());
+ return new BidiRun(start, end, obj, resolver.context(), resolver.dir());
}
void RenderBlock::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
@@ -1203,7 +1202,7 @@
while (BidiContext* parent = baseContext->parent())
baseContext = parent;
- BidiRun* newTrailingRun = new (renderArena()) BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);
+ BidiRun* newTrailingRun = new BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);
trailingSpaceRun->m_stop = firstSpace;
if (direction == LTR)
bidiRuns.addRun(newTrailingRun);
@@ -1481,15 +1480,15 @@
RenderFlowThread* m_flowThread;
};
-static void deleteLineRange(LineLayoutState& layoutState, RenderArena* arena, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
+static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
{
RootInlineBox* boxToDelete = startLine;
while (boxToDelete && boxToDelete != stopLine) {
layoutState.updateRepaintRangeFromBox(boxToDelete);
- // Note: deleteLineRange(renderArena(), firstRootBox()) is not identical to deleteLineBoxTree().
+ // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineBoxTree().
// deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing.
RootInlineBox* next = boxToDelete->nextRootBox();
- boxToDelete->deleteLine(arena);
+ boxToDelete->deleteLine();
boxToDelete = next;
}
}
@@ -1534,7 +1533,7 @@
if (startLine) {
if (!layoutState.usesRepaintBounds())
layoutState.setRepaintRange(logicalHeight());
- deleteLineRange(layoutState, renderArena(), startLine);
+ deleteLineRange(layoutState, startLine);
}
if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithBreak()) {
@@ -1847,7 +1846,7 @@
if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine()) != oldLineWidth) {
// We have to delete this line, remove all floats that got added, and let line layout re-run.
- lineBox->deleteLine(renderArena());
+ lineBox->deleteLine();
end = restartLayoutRunsAndFloatsInRange(oldLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver, oldEnd);
continue;
}
@@ -1987,7 +1986,7 @@
setLogicalHeight(lastRootBox()->lineBottomWithLeading());
} else {
// Delete all the remaining lines.
- deleteLineRange(layoutState, renderArena(), layoutState.endLine());
+ deleteLineRange(layoutState, layoutState.endLine());
}
}
@@ -1998,7 +1997,7 @@
if (layoutState.checkForFloatsFromLastLine()) {
LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
- TrailingFloatsRootInlineBox* trailingFloatsLineBox = new (renderArena()) TrailingFloatsRootInlineBox(this);
+ TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(this);
m_lineBoxes.appendLineBox(trailingFloatsLineBox);
trailingFloatsLineBox->setConstructed();
GlyphOverflowAndFallbackFontsMap textBoxDataMap;
@@ -2061,7 +2060,7 @@
LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom, flowThread);
if (isFullLayout)
- lineBoxes()->deleteLineBoxes(renderArena());
+ lineBoxes()->deleteLineBoxes();
// Text truncation kicks in in two cases:
// 1) If your overflow isn't visible and your text-overflow-mode isn't clip.
@@ -2229,12 +2228,11 @@
if (layoutState.isFullLayout()) {
// FIXME: This should just call deleteLineBoxTree, but that causes
// crashes for fast/repaint tests.
- RenderArena* arena = renderArena();
curr = firstRootBox();
while (curr) {
// Note: This uses nextRootBox() insted of nextLineBox() like deleteLineBoxTree does.
RootInlineBox* next = curr->nextRootBox();
- curr->deleteLine(arena);
+ curr->deleteLine();
curr = next;
}
ASSERT(!firstLineBox() && !lastLineBox());
@@ -2413,7 +2411,7 @@
}
// Now delete the lines that we failed to sync.
- deleteLineRange(layoutState, renderArena(), originalEndLine, result);
+ deleteLineRange(layoutState, originalEndLine, result);
return matched;
}
}
@@ -2565,72 +2563,6 @@
return font.width(run, fallbackFonts, &glyphOverflow);
}
-static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
-{
- // Map 'hyphenate-limit-{before,after}: auto;' to 2.
- unsigned minimumPrefixLength;
- unsigned minimumSuffixLength;
-
- if (minimumPrefixLimit < 0)
- minimumPrefixLength = 2;
- else
- minimumPrefixLength = static_cast<unsigned>(minimumPrefixLimit);
-
- if (minimumSuffixLimit < 0)
- minimumSuffixLength = 2;
- else
- minimumSuffixLength = static_cast<unsigned>(minimumSuffixLimit);
-
- if (pos - lastSpace <= minimumSuffixLength)
- return;
-
- if (consecutiveHyphenatedLinesLimit >= 0 && consecutiveHyphenatedLines >= static_cast<unsigned>(consecutiveHyphenatedLinesLimit))
- return;
-
- int hyphenWidth = measureHyphenWidth(text, font);
-
- float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
- // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
- // that an hyphenation opportunity exists, so do not bother to look for it.
- if (maxPrefixWidth <= font.pixelSize() * 5 / 4)
- return;
-
- TextRun run = RenderBlock::constructTextRun(text, font, text, lastSpace, pos - lastSpace, text->style());
- run.setCharactersLength(text->textLength() - lastSpace);
- ASSERT(run.charactersLength() >= run.length());
-
- run.setTabSize(!collapseWhiteSpace, text->style()->tabSize());
- run.setXPos(xPos + lastSpaceWordSpacing);
-
- unsigned prefixLength = font.offsetForPosition(run, maxPrefixWidth, false);
- if (prefixLength < minimumPrefixLength)
- return;
-
- prefixLength = lastHyphenLocation(text->substring(lastSpace, pos - lastSpace), min(prefixLength, pos - lastSpace - minimumSuffixLength) + 1, localeIdentifier);
- if (!prefixLength || prefixLength < minimumPrefixLength)
- return;
-
- // When lastSapce is a space, which it always is except sometimes at the beginning of a line or after collapsed
- // space, it should not count towards hyphenate-limit-before.
- if (prefixLength == minimumPrefixLength) {
- UChar characterAtLastSpace = text->characterAt(lastSpace);
- if (characterAtLastSpace == ' ' || characterAtLastSpace == '\n' || characterAtLastSpace == '\t' || characterAtLastSpace == noBreakSpace)
- return;
- }
-
- ASSERT(pos - lastSpace - prefixLength >= minimumSuffixLength);
-
-#if !ASSERT_DISABLED
- float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
- ASSERT(xPos + prefixWidth <= availableWidth);
-#else
- UNUSED_PARAM(isFixedPitch);
-#endif
-
- lineBreak.moveTo(text, lastSpace + prefixLength, nextBreakable);
- hyphenated = true;
-}
-
class TrailingObjects {
public:
TrailingObjects();
@@ -3001,7 +2933,6 @@
RenderStyle* style = t->style(lineInfo.isFirstLine());
const Font& f = style->font();
bool isFixedPitch = f.isFixedPitch();
- bool canHyphenate = style->hyphens() == HyphensAuto && WebCore::canHyphenate(style->locale());
unsigned lastSpace = current.m_pos;
float wordSpacing = currentStyle->wordSpacing();
@@ -3056,7 +2987,7 @@
if (!collapseWhiteSpace || !currentCharacterIsSpace)
lineInfo.setEmpty(false, m_block, &width);
- if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphens() != HyphensNone) {
+ if (c == softHyphen && autoWrap && !hyphenWidth) {
hyphenWidth = measureHyphenWidth(t, f);
width.addUncommittedWidth(hyphenWidth);
}
@@ -3070,8 +3001,7 @@
midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth();
}
- bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(renderTextInfo.m_lineBreakIterator, current.m_pos, current.m_nextBreakablePosition)
- && (style->hyphens() != HyphensNone || (current.previousInSameNode() != softHyphen)));
+ bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(renderTextInfo.m_lineBreakIterator, current.m_pos, current.m_nextBreakablePosition));
if (betweenWords || midWordBreak) {
bool stoppedIgnoringSpaces = false;
@@ -3135,11 +3065,6 @@
}
}
if (lineWasTooWide || !width.fitsOnLine()) {
- if (canHyphenate && !width.fitsOnLine()) {
- tryHyphenating(t, f, style->locale(), consecutiveHyphenatedLines, blockStyle->hyphenationLimitLines(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated);
- if (m_hyphenated)
- goto end;
- }
if (lBreak.atTextParagraphSeparator()) {
if (!stoppedIgnoringSpaces && current.m_pos > 0)
ensureCharacterGetsLineBox(lineMidpointState, current);
@@ -3147,7 +3072,7 @@
lineInfo.setPreviousLineBrokeCleanly(true);
wordMeasurement.endOffset = lBreak.m_pos;
}
- if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characterAt(lBreak.m_pos - 1) == softHyphen && style->hyphens() != HyphensNone)
+ if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characterAt(lBreak.m_pos - 1) == softHyphen)
m_hyphenated = true;
if (lBreak.m_pos && lBreak.m_pos != (unsigned)wordMeasurement.endOffset && !wordMeasurement.width) {
if (charWidth) {
@@ -3267,10 +3192,7 @@
includeEndWidth = false;
if (!width.fitsOnLine()) {
- if (canHyphenate)
- tryHyphenating(t, f, style->locale(), consecutiveHyphenatedLines, blockStyle->hyphenationLimitLines(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated);
-
- if (!m_hyphenated && lBreak.previousInSameNode() == softHyphen && style->hyphens() != HyphensNone)
+ if (!m_hyphenated && lBreak.previousInSameNode() == softHyphen)
m_hyphenated = true;
if (m_hyphenated)
@@ -3552,7 +3474,7 @@
setLineGridBox(0);
- RootInlineBox* lineGridBox = new (renderArena()) RootInlineBox(this);
+ RootInlineBox* lineGridBox = new RootInlineBox(this);
lineGridBox->setHasTextChildren(); // Needed to make the line ascent/descent actually be honored in quirks mode.
lineGridBox->setConstructed();
GlyphOverflowAndFallbackFontsMap textBoxDataMap;
diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
index e596013..dde7f3e 100644
--- a/Source/core/rendering/RenderBox.cpp
+++ b/Source/core/rendering/RenderBox.cpp
@@ -47,6 +47,7 @@
#include "core/rendering/RenderFlexibleBox.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
+#include "core/rendering/RenderGrid.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderLayerCompositor.h"
@@ -305,6 +306,7 @@
}
updateShapeOutsideInfoAfterStyleChange(style()->shapeOutside(), oldStyle ? oldStyle->shapeOutside() : 0);
+ updateGridPositionAfterStyleChange(oldStyle);
}
void RenderBox::updateShapeOutsideInfoAfterStyleChange(const ShapeValue* shapeOutside, const ShapeValue* oldShapeOutside)
@@ -321,6 +323,23 @@
}
}
+void RenderBox::updateGridPositionAfterStyleChange(const RenderStyle* oldStyle)
+{
+ if (!oldStyle || !parent() || !parent()->isRenderGrid())
+ return;
+
+ if (oldStyle->gridColumnStart() == style()->gridColumnStart()
+ && oldStyle->gridColumnEnd() == style()->gridColumnEnd()
+ && oldStyle->gridRowStart() == style()->gridRowStart()
+ && oldStyle->gridRowEnd() == style()->gridRowEnd()
+ && oldStyle->order() == style()->order())
+ return;
+
+ // It should be possible to not dirty the grid in some cases (like moving an explicitly placed grid item).
+ // For now, it's more simple to just always recompute the grid.
+ toRenderGrid(parent())->dirtyGrid();
+}
+
void RenderBox::updateFromStyle()
{
RenderBoxModelObject::updateFromStyle();
@@ -580,10 +599,10 @@
rects.append(pixelSnappedIntRect(additionalOffset, size()));
}
-void RenderBox::addLayerHitTestRects(LayerHitTestRects& layerRects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const
+void RenderBox::addLayerHitTestRects(LayerHitTestRects& layerRects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
{
LayoutPoint adjustedLayerOffset = layerOffset + locationOffset();
- RenderBoxModelObject::addLayerHitTestRects(layerRects, currentLayer, adjustedLayerOffset);
+ RenderBoxModelObject::addLayerHitTestRects(layerRects, currentLayer, adjustedLayerOffset, containerRect);
}
void RenderBox::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutPoint& layerOffset) const
@@ -1814,14 +1833,14 @@
InlineBox* RenderBox::createInlineBox()
{
- return new (renderArena()) InlineBox(this);
+ return new InlineBox(this);
}
void RenderBox::dirtyLineBoxes(bool fullLayout)
{
if (m_inlineBoxWrapper) {
if (fullLayout) {
- m_inlineBoxWrapper->destroy(renderArena());
+ m_inlineBoxWrapper->destroy();
m_inlineBoxWrapper = 0;
} else
m_inlineBoxWrapper->dirtyLineBoxes();
@@ -1853,7 +1872,7 @@
// Nuke the box.
box->remove();
- box->destroy(renderArena());
+ box->destroy();
} else if (isReplaced()) {
setLocation(roundedLayoutPoint(box->topLeft()));
setInlineBoxWrapper(box);
@@ -1865,7 +1884,7 @@
if (m_inlineBoxWrapper) {
if (!documentBeingDestroyed())
m_inlineBoxWrapper->remove();
- m_inlineBoxWrapper->destroy(renderArena());
+ m_inlineBoxWrapper->destroy();
m_inlineBoxWrapper = 0;
}
}
@@ -4052,11 +4071,11 @@
return rect;
}
-VisiblePosition RenderBox::positionForPoint(const LayoutPoint& point)
+PositionWithAffinity RenderBox::positionForPoint(const LayoutPoint& point)
{
// no children...return this render object's element, if there is one, and offset 0
if (!firstChild())
- return createVisiblePosition(nonPseudoNode() ? firstPositionInOrBeforeNode(nonPseudoNode()) : Position());
+ return createPositionWithAffinity(nonPseudoNode() ? firstPositionInOrBeforeNode(nonPseudoNode()) : Position());
if (isTable() && nonPseudoNode()) {
LayoutUnit right = contentWidth() + borderAndPaddingWidth();
@@ -4064,8 +4083,8 @@
if (point.x() < 0 || point.x() > right || point.y() < 0 || point.y() > bottom) {
if (point.x() <= right / 2)
- return createVisiblePosition(firstPositionInOrBeforeNode(nonPseudoNode()));
- return createVisiblePosition(lastPositionInOrAfterNode(nonPseudoNode()));
+ return createPositionWithAffinity(firstPositionInOrBeforeNode(nonPseudoNode()));
+ return createPositionWithAffinity(lastPositionInOrAfterNode(nonPseudoNode()));
}
}
@@ -4132,8 +4151,7 @@
if (closestRenderer)
return closestRenderer->positionForPoint(adjustedPoint - closestRenderer->locationOffset());
-
- return createVisiblePosition(firstPositionInOrBeforeNode(nonPseudoNode()));
+ return createPositionWithAffinity(firstPositionInOrBeforeNode(nonPseudoNode()));
}
bool RenderBox::shrinkToAvoidFloats() const
@@ -4286,13 +4304,12 @@
if (!m_overflow)
return;
- LayoutRect noOverflowRect = this->noOverflowRect();
- if (visualOverflowRect() == noOverflowRect) {
+ if (!hasVisualOverflow()) {
m_overflow.clear();
return;
}
- m_overflow->setLayoutOverflow(noOverflowRect);
+ m_overflow->setLayoutOverflow(noOverflowRect());
}
inline static bool percentageLogicalHeightIsResolvable(const RenderBox* box)
diff --git a/Source/core/rendering/RenderBox.h b/Source/core/rendering/RenderBox.h
index 105f91f..24562dc 100644
--- a/Source/core/rendering/RenderBox.h
+++ b/Source/core/rendering/RenderBox.h
@@ -493,7 +493,7 @@
LayoutRect maskClipRect();
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
void removeFloatingOrPositionedChildFromBlockLists();
@@ -555,8 +555,8 @@
return false;
LayoutRect layoutOverflowRect = m_overflow->layoutOverflowRect();
- flipForWritingMode(layoutOverflowRect);
- return layoutOverflowRect.x() < x() || layoutOverflowRect.maxX() > x() + logicalWidth();
+ LayoutRect noOverflowRect = this->noOverflowRect();
+ return layoutOverflowRect.x() < noOverflowRect.x() || layoutOverflowRect.maxX() > noOverflowRect.maxX();
}
bool hasVerticalLayoutOverflow() const
@@ -565,8 +565,8 @@
return false;
LayoutRect layoutOverflowRect = m_overflow->layoutOverflowRect();
- flipForWritingMode(layoutOverflowRect);
- return layoutOverflowRect.y() < y() || layoutOverflowRect.maxY() > y() + logicalHeight();
+ LayoutRect noOverflowRect = this->noOverflowRect();
+ return layoutOverflowRect.y() < noOverflowRect.y() || layoutOverflowRect.maxY() > noOverflowRect.maxY();
}
virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject*) const
@@ -617,11 +617,12 @@
RenderObject* splitAnonymousBoxesAroundChild(RenderObject* beforeChild);
- virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset) const OVERRIDE;
+ virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE;
virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE;
private:
void updateShapeOutsideInfoAfterStyleChange(const ShapeValue* shapeOutside, const ShapeValue* oldShapeOutside);
+ void updateGridPositionAfterStyleChange(const RenderStyle*);
bool includeVerticalScrollbarSize() const;
bool includeHorizontalScrollbarSize() const;
diff --git a/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
index ded6ea3..8135893 100644
--- a/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
+++ b/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
@@ -142,7 +142,7 @@
RenderDeprecatedFlexibleBox* RenderDeprecatedFlexibleBox::createAnonymous(Document* document)
{
- RenderDeprecatedFlexibleBox* renderer = new (document->renderArena()) RenderDeprecatedFlexibleBox(0);
+ RenderDeprecatedFlexibleBox* renderer = new RenderDeprecatedFlexibleBox(0);
renderer->setDocumentForAnonymous(document);
return renderer;
}
@@ -899,6 +899,8 @@
void RenderDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutChildren)
{
+ UseCounter::count(document(), UseCounter::LineClamp);
+
int maxLineCount = 0;
for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
if (childDoesNotAffectWidthOrFlexing(child))
@@ -940,9 +942,8 @@
if (newHeight == child->height())
continue;
- child->setChildNeedsLayout(true, MarkOnlyThis);
child->setOverrideLogicalContentHeight(newHeight - child->borderAndPaddingHeight());
- child->layoutIfNeeded();
+ child->forceChildLayout();
// FIXME: For now don't support RTL.
if (style()->direction() != LTR)
diff --git a/Source/core/rendering/RenderEmbeddedObject.cpp b/Source/core/rendering/RenderEmbeddedObject.cpp
index b3d6e27..de41af3 100644
--- a/Source/core/rendering/RenderEmbeddedObject.cpp
+++ b/Source/core/rendering/RenderEmbeddedObject.cpp
@@ -253,8 +253,7 @@
childBox->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
childBox->style()->setHeight(Length(newSize.height(), Fixed));
childBox->style()->setWidth(Length(newSize.width(), Fixed));
- childBox->setNeedsLayout(true, MarkOnlyThis);
- childBox->layout();
+ childBox->forceLayout();
setChildNeedsLayout(false);
statePusher.pop();
diff --git a/Source/core/rendering/RenderFileUploadControl.cpp b/Source/core/rendering/RenderFileUploadControl.cpp
index 7228e4b..0a6e67b 100644
--- a/Source/core/rendering/RenderFileUploadControl.cpp
+++ b/Source/core/rendering/RenderFileUploadControl.cpp
@@ -25,7 +25,6 @@
#include "HTMLNames.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/editing/VisiblePosition.h"
#include "core/fileapi/FileList.h"
#include "core/html/HTMLInputElement.h"
#include "core/platform/graphics/Font.h"
@@ -204,9 +203,9 @@
setPreferredLogicalWidthsDirty(false);
}
-VisiblePosition RenderFileUploadControl::positionForPoint(const LayoutPoint&)
+PositionWithAffinity RenderFileUploadControl::positionForPoint(const LayoutPoint&)
{
- return VisiblePosition();
+ return PositionWithAffinity();
}
HTMLInputElement* RenderFileUploadControl::uploadButton() const
diff --git a/Source/core/rendering/RenderFileUploadControl.h b/Source/core/rendering/RenderFileUploadControl.h
index acfa504..3a9e343 100644
--- a/Source/core/rendering/RenderFileUploadControl.h
+++ b/Source/core/rendering/RenderFileUploadControl.h
@@ -54,7 +54,7 @@
int maxFilenameWidth() const;
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
HTMLInputElement* uploadButton() const;
diff --git a/Source/core/rendering/RenderFlexibleBox.cpp b/Source/core/rendering/RenderFlexibleBox.cpp
index b91e99d..40c26e0 100644
--- a/Source/core/rendering/RenderFlexibleBox.cpp
+++ b/Source/core/rendering/RenderFlexibleBox.cpp
@@ -80,7 +80,7 @@
RenderFlexibleBox* RenderFlexibleBox::createAnonymous(Document* document)
{
- RenderFlexibleBox* renderer = new (document->renderArena()) RenderFlexibleBox(0);
+ RenderFlexibleBox* renderer = new RenderFlexibleBox(0);
renderer->setDocumentForAnonymous(document);
return renderer;
}
@@ -1338,8 +1338,7 @@
if (desiredLogicalHeight != child->logicalHeight()) {
child->setOverrideLogicalContentHeight(desiredLogicalHeight - child->borderAndPaddingLogicalHeight());
child->setLogicalHeight(0);
- child->setChildNeedsLayout(true, MarkOnlyThis);
- child->layout();
+ child->forceChildLayout();
}
}
} else if (isColumnFlow() && child->style()->logicalWidth().isAuto()) {
@@ -1350,8 +1349,7 @@
if (childWidth != child->logicalWidth()) {
child->setOverrideLogicalContentWidth(childWidth - child->borderAndPaddingLogicalWidth());
- child->setChildNeedsLayout(true, MarkOnlyThis);
- child->layout();
+ child->forceChildLayout();
}
}
}
diff --git a/Source/core/rendering/RenderFlowThread.cpp b/Source/core/rendering/RenderFlowThread.cpp
index 45d89f4..a6b3ae8 100644
--- a/Source/core/rendering/RenderFlowThread.cpp
+++ b/Source/core/rendering/RenderFlowThread.cpp
@@ -161,12 +161,12 @@
region->deleteAllRenderBoxRegionInfo();
- // In the normal layout phase we need to initialize the overrideLogicalContentHeight for auto-height regions.
- // See initializeRegionsOverrideLogicalContentHeight for the explanation.
+ // In the normal layout phase we need to initialize the computedAutoHeight for auto-height regions.
+ // See initializeRegionsComputedAutoHeight for the explanation.
// Also, if we have auto-height regions we can't assume m_regionsHaveUniformLogicalHeight to be true in the first phase
// because the auto-height regions don't have their height computed yet.
if (!inConstrainedLayoutPhase() && region->hasAutoLogicalHeight()) {
- region->setOverrideLogicalContentHeight(region->maxPageLogicalHeight());
+ region->setComputedAutoHeight(region->maxPageLogicalHeight());
m_regionsHaveUniformLogicalHeight = false;
}
@@ -200,7 +200,7 @@
// In case this is the second pass of the normal phase we need to update the auto-height regions to their initial value.
// If the region chain was invalidated this will happen anyway.
if (!m_regionsInvalidated && !inConstrainedLayoutPhase())
- initializeRegionsOverrideLogicalContentHeight();
+ initializeRegionsComputedAutoHeight();
validateRegions();
@@ -729,7 +729,7 @@
void RenderFlowThread::applyBreakAfterContent(LayoutUnit clientHeight)
{
// Simulate a region break at height. If it points inside an auto logical height region,
- // then it may determine the region override logical content height.
+ // then it may determine the region computed autoheight.
addForcedRegionBreak(clientHeight, this, false);
}
@@ -824,7 +824,7 @@
// During the normal layout phase of the named flow the regions are initialized with a height equal to their max-height.
// This way unforced breaks are automatically placed when a region is full and the content height/position correctly estimated.
// Also, the region where a forced break falls is exactly the region found at the forced break offset inside the flow content.
-void RenderFlowThread::initializeRegionsOverrideLogicalContentHeight(RenderRegion* startRegion)
+void RenderFlowThread::initializeRegionsComputedAutoHeight(RenderRegion* startRegion)
{
ASSERT(!inConstrainedLayoutPhase());
if (!hasAutoLogicalHeightRegions())
@@ -834,7 +834,7 @@
for (; regionIter != m_regionList.end(); ++regionIter) {
RenderRegion* region = *regionIter;
if (region->hasAutoLogicalHeight())
- region->setOverrideLogicalContentHeight(region->maxPageLogicalHeight());
+ region->setComputedAutoHeight(region->maxPageLogicalHeight());
}
}
@@ -864,9 +864,9 @@
for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
RenderRegion* region = *iter;
- // If we find an empty auto-height region, clear the overrideLogicalContentHeight value.
+ // If we find an empty auto-height region, clear the computedAutoHeight value.
if (emptyRegionsSegment && region->hasAutoLogicalHeight())
- region->clearOverrideLogicalContentHeight();
+ region->clearComputedAutoHeight();
LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
LayoutUnit regionLogicalHeight = std::min<LayoutUnit>(LayoutUnit::max() / 2 - logicalHeight, region->logicalHeightOfAllFlowThreadContent());
@@ -894,7 +894,7 @@
{
// We take breaks into account for height computation for auto logical height regions
// only in the layout phase in which we lay out the flows threads unconstrained
- // and we use the content breaks to determine the overrideContentLogicalHeight for
+ // and we use the content breaks to determine the computedAutoHeight for
// auto logical height regions.
if (inConstrainedLayoutPhase())
return false;
@@ -908,7 +908,7 @@
RenderRegionList::iterator regionIter = m_regionList.find(iter->value);
ASSERT(regionIter != m_regionList.end());
ASSERT((*regionIter)->hasAutoLogicalHeight());
- initializeRegionsOverrideLogicalContentHeight(*regionIter);
+ initializeRegionsComputedAutoHeight(*regionIter);
// We need to update the regions flow thread portion rect because we are going to process
// a break on these regions.
@@ -916,13 +916,13 @@
}
// Simulate a region break at offsetBreakInFlowThread. If it points inside an auto logical height region,
- // then it determines the region override logical content height.
+ // then it determines the region computed auto height.
RenderRegion* region = regionAtBlockOffset(offsetBreakInFlowThread);
if (!region)
return false;
bool lastBreakAfterContent = breakChild == this;
- bool overrideLogicalContentHeightComputed = false;
+ bool hasComputedAutoHeight = false;
LayoutUnit currentRegionOffsetInFlowThread = isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x();
LayoutUnit offsetBreakInCurrentRegion = offsetBreakInFlowThread - currentRegionOffsetInFlowThread;
@@ -930,36 +930,36 @@
if (region->hasAutoLogicalHeight()) {
// A forced break can appear only in an auto-height region that didn't have a forced break before.
// This ASSERT is a good-enough heuristic to verify the above condition.
- ASSERT(region->maxPageLogicalHeight() == region->overrideLogicalContentHeight());
+ ASSERT(region->maxPageLogicalHeight() == region->computedAutoHeight());
mapToUse.set(breakChild, region);
- overrideLogicalContentHeightComputed = true;
+ hasComputedAutoHeight = true;
// Compute the region height pretending that the offsetBreakInCurrentRegion is the logicalHeight for the auto-height region.
- LayoutUnit regionOverrideLogicalContentHeight = region->constrainContentBoxLogicalHeightByMinMax(offsetBreakInCurrentRegion, -1);
+ LayoutUnit regionComputedAutoHeight = region->constrainContentBoxLogicalHeightByMinMax(offsetBreakInCurrentRegion, -1);
// The new height of this region needs to be smaller than the initial value, the max height. A forced break is the only way to change the initial
// height of an auto-height region besides content ending.
- ASSERT(regionOverrideLogicalContentHeight <= region->maxPageLogicalHeight());
+ ASSERT(regionComputedAutoHeight <= region->maxPageLogicalHeight());
- region->setOverrideLogicalContentHeight(regionOverrideLogicalContentHeight);
+ region->setComputedAutoHeight(regionComputedAutoHeight);
- currentRegionOffsetInFlowThread += regionOverrideLogicalContentHeight;
+ currentRegionOffsetInFlowThread += regionComputedAutoHeight;
} else
currentRegionOffsetInFlowThread += isHorizontalWritingMode() ? region->flowThreadPortionRect().height() : region->flowThreadPortionRect().width();
// If the break was found inside an auto-height region its size changed so we need to recompute the flow thread portion rectangles.
- // Also, if this is the last break after the content we need to clear the overrideLogicalContentHeight value on the last empty regions.
+ // Also, if this is the last break after the content we need to clear the computedAutoHeight value on the last empty regions.
if (hasAutoLogicalHeightRegions() && lastBreakAfterContent)
updateRegionsFlowThreadPortionRect(region);
- else if (overrideLogicalContentHeightComputed)
+ else if (hasComputedAutoHeight)
updateRegionsFlowThreadPortionRect();
if (offsetBreakAdjustment)
*offsetBreakAdjustment = max<LayoutUnit>(0, currentRegionOffsetInFlowThread - offsetBreakInFlowThread);
- return overrideLogicalContentHeightComputed;
+ return hasComputedAutoHeight;
}
void RenderFlowThread::incrementAutoLogicalHeightRegions()
diff --git a/Source/core/rendering/RenderFlowThread.h b/Source/core/rendering/RenderFlowThread.h
index 27ea3ac..18fb7db 100644
--- a/Source/core/rendering/RenderFlowThread.h
+++ b/Source/core/rendering/RenderFlowThread.h
@@ -191,7 +191,7 @@
virtual void dispatchRegionLayoutUpdateEvent() { m_dispatchRegionLayoutUpdateEvent = false; }
virtual void dispatchRegionOversetChangeEvent() { m_dispatchRegionOversetChangeEvent = false; }
- void initializeRegionsOverrideLogicalContentHeight(RenderRegion* = 0);
+ void initializeRegionsComputedAutoHeight(RenderRegion* = 0);
virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) { };
diff --git a/Source/core/rendering/RenderFullScreen.cpp b/Source/core/rendering/RenderFullScreen.cpp
index dea4e45..b98c229 100644
--- a/Source/core/rendering/RenderFullScreen.cpp
+++ b/Source/core/rendering/RenderFullScreen.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/rendering/RenderFullScreen.h"
-#include "core/dom/FullscreenController.h"
+#include "core/dom/FullscreenElementStack.h"
using namespace WebCore;
@@ -58,7 +58,7 @@
RenderFullScreen* RenderFullScreen::createAnonymous(Document* document)
{
- RenderFullScreen* renderer = new (document->renderArena()) RenderFullScreen();
+ RenderFullScreen* renderer = new RenderFullScreen();
renderer->setDocumentForAnonymous(document);
return renderer;
}
@@ -75,7 +75,7 @@
// RenderObjects are unretained, so notify the document (which holds a pointer to a RenderFullScreen)
// if it's RenderFullScreen is destroyed.
if (document()) {
- FullscreenController* controller = FullscreenController::from(document());
+ FullscreenElementStack* controller = FullscreenElementStack::from(document());
if (controller->fullScreenRenderer() == this)
controller->fullScreenRendererDestroyed();
}
@@ -140,7 +140,7 @@
fullscreenRenderer->setNeedsLayoutAndPrefWidthsRecalc();
}
- FullscreenController::from(document)->setFullScreenRenderer(fullscreenRenderer);
+ FullscreenElementStack::from(document)->setFullScreenRenderer(fullscreenRenderer);
return fullscreenRenderer;
}
@@ -162,7 +162,7 @@
if (placeholder())
placeholder()->remove();
remove();
- FullscreenController::from(document())->setFullScreenRenderer(0);
+ FullscreenElementStack::from(document())->setFullScreenRenderer(0);
}
void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
@@ -178,7 +178,7 @@
style->setHeight(Length(frameRect.height(), Fixed));
if (!m_placeholder) {
- m_placeholder = new (document()->renderArena()) RenderFullScreenPlaceholder(this);
+ m_placeholder = new RenderFullScreenPlaceholder(this);
m_placeholder->setStyle(style);
if (parent()) {
parent()->addChild(m_placeholder, this);
diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp
index 837e189..041dd4e 100644
--- a/Source/core/rendering/RenderGrid.cpp
+++ b/Source/core/rendering/RenderGrid.cpp
@@ -150,6 +150,7 @@
RenderGrid::RenderGrid(Element* element)
: RenderBlock(element)
+ , m_gridIsDirty(true)
, m_orderIterator(this)
{
// All of our children must be block level.
@@ -160,6 +161,70 @@
{
}
+void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+ RenderBlock::addChild(newChild, beforeChild);
+
+ if (gridIsDirty())
+ return;
+
+ RenderBox* newChildBox = toRenderBox(newChild);
+ OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, ForRows);
+ OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox, ForColumns);
+ if (!rowPositions || !columnPositions) {
+ // The new child requires the auto-placement algorithm to run so we need to recompute the grid fully.
+ dirtyGrid();
+ } else {
+ if (gridRowCount() <= rowPositions->finalPositionIndex || gridColumnCount() <= columnPositions->finalPositionIndex) {
+ // FIXME: We could just insert the new child provided we had a primitive to arbitrarily grow the grid.
+ dirtyGrid();
+ } else {
+ insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPositions));
+ }
+ }
+}
+
+void RenderGrid::removeChild(RenderObject* child)
+{
+ RenderBlock::removeChild(child);
+
+ if (gridIsDirty())
+ return;
+
+ ASSERT(child->isBox());
+ // FIXME: We could avoid dirtying the grid in some cases (e.g. if it's an explicitly positioned element).
+ dirtyGrid();
+}
+
+void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderBlock::styleDidChange(diff, oldStyle);
+ if (!oldStyle)
+ return;
+
+ // FIXME: The following checks could be narrowed down if we kept track of which type of grid items we have:
+ // - explicit grid size changes impact negative explicitely positioned and auto-placed grid items.
+ // - named grid lines only impact grid items with named grid lines.
+ // - auto-flow changes only impacts auto-placed children.
+
+ if (explicitGridDidResize(oldStyle)
+ || namedGridLinesDefinitionDidChange(oldStyle)
+ || oldStyle->gridAutoFlow() != style()->gridAutoFlow())
+ dirtyGrid();
+}
+
+bool RenderGrid::explicitGridDidResize(const RenderStyle* oldStyle) const
+{
+ return oldStyle->gridDefinitionColumns().size() != style()->gridDefinitionColumns().size()
+ || oldStyle->gridDefinitionRows().size() != style()->gridDefinitionRows().size();
+}
+
+bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle) const
+{
+ return oldStyle->namedGridRowLines() != style()->namedGridRowLines()
+ || oldStyle->namedGridColumnLines() != style()->namedGridColumnLines();
+}
+
void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
{
ASSERT(needsLayout());
@@ -229,8 +294,6 @@
// FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexibleBox).
}
-
- const_cast<RenderGrid*>(this)->clearGrid();
}
void RenderGrid::computePreferredLogicalWidths()
@@ -621,11 +684,17 @@
void RenderGrid::placeItemsOnGrid()
{
- ASSERT(!gridWasPopulated());
+ if (!gridIsDirty())
+ return;
+
ASSERT(m_gridItemCoordinate.isEmpty());
populateExplicitGridAndOrderIterator();
+ // We clear the dirty bit here as the grid sizes have been updated, this means
+ // that we can safely call gridRowCount() / gridColumnCount().
+ m_gridIsDirty = false;
+
Vector<RenderBox*> autoMajorAxisAutoGridItems;
Vector<RenderBox*> specifiedMajorAxisAutoGridItems;
GridAutoFlow autoFlow = style()->gridAutoFlow();
@@ -657,6 +726,8 @@
placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems);
placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems);
+
+ m_grid.shrinkToFit();
}
void RenderGrid::populateExplicitGridAndOrderIterator()
@@ -753,10 +824,11 @@
return (flow == AutoFlowColumn) ? ForRows : ForColumns;
}
-void RenderGrid::clearGrid()
+void RenderGrid::dirtyGrid()
{
- m_grid.clear();
+ m_grid.resize(0);
m_gridItemCoordinate.clear();
+ m_gridIsDirty = true;
}
void RenderGrid::layoutGridItems()
@@ -811,7 +883,6 @@
// FIXME: We should handle min / max logical height.
setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight());
- clearGrid();
}
GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const
@@ -837,7 +908,7 @@
// We should NEVER see both spans as they should have been handled during style resolve.
ASSERT(!initialPosition.isSpan() || !finalPosition.isSpan());
- if (initialPosition.isAuto() && finalPosition.isAuto()) {
+ if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) {
if (style()->gridAutoFlow() == AutoFlowNone)
return adoptPtr(new GridSpan(0, 0));
diff --git a/Source/core/rendering/RenderGrid.h b/Source/core/rendering/RenderGrid.h
index eddf270..0966ec3 100644
--- a/Source/core/rendering/RenderGrid.h
+++ b/Source/core/rendering/RenderGrid.h
@@ -54,11 +54,21 @@
virtual bool avoidsFloats() const OVERRIDE { return true; }
virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
+ void dirtyGrid();
+
private:
virtual bool isRenderGrid() const OVERRIDE { return true; }
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject*) OVERRIDE;
+
+ virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
+
+ bool explicitGridDidResize(const RenderStyle*) const;
+ bool namedGridLinesDefinitionDidChange(const RenderStyle*) const;
+
LayoutUnit computePreferredTrackWidth(const GridLength&, size_t) const;
class GridIterator;
@@ -81,7 +91,6 @@
TrackSizingDirection autoPlacementMinorAxisDirection() const;
void layoutGridItems();
- void clearGrid();
typedef LayoutUnit (RenderGrid::* SizingFunction)(RenderBox*, TrackSizingDirection, Vector<GridTrack>&);
typedef LayoutUnit (GridTrack::* AccumulatorGetter)() const;
@@ -116,27 +125,44 @@
virtual void paintChildren(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
+ bool gridIsDirty() const { return m_gridIsDirty; }
+
#ifndef NDEBUG
bool tracksAreWiderThanMinTrackBreadth(TrackSizingDirection, const Vector<GridTrack>&);
- bool gridWasPopulated() const { return !m_grid.isEmpty() && !m_grid[0].isEmpty(); }
#endif
size_t gridColumnCount() const
{
- ASSERT(gridWasPopulated());
+ ASSERT(!gridIsDirty());
return m_grid[0].size();
}
size_t gridRowCount() const
{
- ASSERT(gridWasPopulated());
+ ASSERT(!gridIsDirty());
return m_grid.size();
}
Vector<Vector<Vector<RenderBox*, 1> > > m_grid;
+ bool m_gridIsDirty;
HashMap<const RenderBox*, GridCoordinate> m_gridItemCoordinate;
OrderIterator m_orderIterator;
};
+inline RenderGrid* toRenderGrid(RenderObject* object)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderGrid());
+ return static_cast<RenderGrid*>(object);
+}
+
+inline const RenderGrid* toRenderGrid(const RenderObject* object)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderGrid());
+ return static_cast<const RenderGrid*>(object);
+}
+
+// Catch unneeded cast.
+void toRenderGrid(const RenderGrid*);
+
} // namespace WebCore
#endif // RenderGrid_h
diff --git a/Source/core/rendering/RenderImage.cpp b/Source/core/rendering/RenderImage.cpp
index 8179918..d1ac1ea 100644
--- a/Source/core/rendering/RenderImage.cpp
+++ b/Source/core/rendering/RenderImage.cpp
@@ -64,7 +64,7 @@
RenderImage* RenderImage::createAnonymous(Document* document)
{
- RenderImage* image = new (document->renderArena()) RenderImage(0);
+ RenderImage* image = new RenderImage(0);
image->setDocumentForAnonymous(document);
return image;
}
@@ -159,7 +159,7 @@
if (!m_imageResource)
return;
- if (newImage != m_imageResource->imagePtr() || !newImage)
+ if (newImage != m_imageResource->imagePtr())
return;
if (!m_didIncrementVisuallyNonEmptyPixelCount) {
@@ -171,7 +171,7 @@
bool imageSizeChanged = false;
// Set image dimensions, taking into account the size of the alt text.
- if (m_imageResource->errorOccurred()) {
+ if (m_imageResource->errorOccurred() || !newImage) {
if (!m_altText.isEmpty() && document()->hasPendingStyleRecalc()) {
ASSERT(node());
if (node()) {
@@ -190,7 +190,7 @@
{
if (newSize == intrinsicSize() && !imageSizeChanged)
return false;
- if (m_imageResource->errorOccurred())
+ if (m_imageResource->errorOccurred() || !m_imageResource->hasImage())
return imageSizeChanged;
setIntrinsicSize(newSize);
return true;
diff --git a/Source/core/rendering/RenderImageResource.cpp b/Source/core/rendering/RenderImageResource.cpp
index d6504f7..9ac02de 100644
--- a/Source/core/rendering/RenderImageResource.cpp
+++ b/Source/core/rendering/RenderImageResource.cpp
@@ -73,6 +73,8 @@
m_cachedImage->addClient(m_renderer);
if (m_cachedImage->errorOccurred())
m_renderer->imageChanged(m_cachedImage.get());
+ } else {
+ m_renderer->imageChanged(m_cachedImage.get());
}
}
diff --git a/Source/core/rendering/RenderInline.cpp b/Source/core/rendering/RenderInline.cpp
index ea48c87..9aa9940 100644
--- a/Source/core/rendering/RenderInline.cpp
+++ b/Source/core/rendering/RenderInline.cpp
@@ -23,8 +23,7 @@
#include "config.h"
#include "core/rendering/RenderInline.h"
-#include "core/dom/FullscreenController.h"
-#include "core/editing/VisiblePosition.h"
+#include "core/dom/FullscreenElementStack.h"
#include "core/page/Chrome.h"
#include "core/page/Frame.h"
#include "core/page/Page.h"
@@ -33,7 +32,6 @@
#include "core/platform/graphics/transforms/TransformState.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineTextBox.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderFullScreen.h"
@@ -56,7 +54,7 @@
RenderInline* RenderInline::createAnonymous(Document* document)
{
- RenderInline* renderer = new (document->renderArena()) RenderInline(0);
+ RenderInline* renderer = new RenderInline(0);
renderer->setDocumentForAnonymous(document);
return renderer;
}
@@ -111,7 +109,7 @@
parent()->dirtyLinesFromChangedChild(this);
}
- m_lineBoxes.deleteLineBoxes(renderArena());
+ m_lineBoxes.deleteLineBoxes();
RenderBoxModelObject::willBeDestroyed();
}
@@ -332,7 +330,7 @@
RenderInline* RenderInline::clone() const
{
- RenderInline* cloneInline = new (renderArena()) RenderInline(node());
+ RenderInline* cloneInline = new RenderInline(node());
cloneInline->setStyle(style());
cloneInline->setFlowThreadState(flowThreadState());
return cloneInline;
@@ -351,7 +349,7 @@
// that renderer is wrapped in a RenderFullScreen, so |this| is not its
// parent. Since the splitting logic expects |this| to be the parent, set
// |beforeChild| to be the RenderFullScreen.
- if (FullscreenController* fullscreen = FullscreenController::fromIfExists(document())) {
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document())) {
const Element* fullScreenElement = fullscreen->webkitCurrentFullScreenElement();
if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement)
beforeChild = fullscreen->fullScreenRenderer();
@@ -475,9 +473,6 @@
// time in makeChildrenNonInline by just setting this explicitly up front.
newBlockBox->setChildrenInline(false);
- // We delayed adding the newChild until now so that the |newBlockBox| would be fully
- // connected, thus allowing newChild access to a renderArena should it need
- // to wrap itself in additional boxes (e.g., table construction).
newBlockBox->addChild(newChild);
// Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
@@ -807,7 +802,7 @@
return false;
}
-VisiblePosition RenderInline::positionForPoint(const LayoutPoint& point)
+PositionWithAffinity RenderInline::positionForPoint(const LayoutPoint& point)
{
// FIXME: Does not deal with relative or sticky positioned inlines (should it?)
RenderBlock* cb = containingBlock();
@@ -1244,7 +1239,7 @@
void RenderInline::dirtyLineBoxes(bool fullLayout)
{
if (fullLayout) {
- m_lineBoxes.deleteLineBoxes(renderArena());
+ m_lineBoxes.deleteLineBoxes();
return;
}
@@ -1275,12 +1270,12 @@
void RenderInline::deleteLineBoxTree()
{
- m_lineBoxes.deleteLineBoxTree(renderArena());
+ m_lineBoxes.deleteLineBoxTree();
}
InlineFlowBox* RenderInline::createInlineFlowBox()
{
- return new (renderArena()) InlineFlowBox(this);
+ return new InlineFlowBox(this);
}
InlineFlowBox* RenderInline::createAndAppendInlineFlowBox()
diff --git a/Source/core/rendering/RenderInline.h b/Source/core/rendering/RenderInline.h
index dfa2889..6e2e7f9 100644
--- a/Source/core/rendering/RenderInline.h
+++ b/Source/core/rendering/RenderInline.h
@@ -148,7 +148,7 @@
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
- virtual VisiblePosition positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
virtual LayoutRect frameRectForStickyPositioning() const OVERRIDE FINAL { return linesBoundingBox(); }
diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp
index 19e1a9b..a228494 100644
--- a/Source/core/rendering/RenderLayer.cpp
+++ b/Source/core/rendering/RenderLayer.cpp
@@ -66,6 +66,7 @@
#include "core/page/animation/AnimationController.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/platform/HistogramSupport.h"
+#include "core/platform/Partitions.h"
#include "core/platform/PlatformGestureEvent.h"
#include "core/platform/PlatformMouseEvent.h"
#include "core/platform/ScrollAnimator.h"
@@ -90,7 +91,6 @@
#include "core/rendering/HitTestResult.h"
#include "core/rendering/HitTestingTransformState.h"
#include "core/rendering/OverlapTestRequestClient.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderInline.h"
@@ -1318,6 +1318,29 @@
return renderer()->absoluteBoundingBoxRect();
}
+bool RenderLayer::userInputScrollable(ScrollbarOrientation orientation) const
+{
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
+ EOverflow overflowStyle = (orientation == HorizontalScrollbar) ?
+ renderer()->style()->overflowX() : renderer()->style()->overflowY();
+ return (overflowStyle == OSCROLL || overflowStyle == OAUTO);
+}
+
+int RenderLayer::pageStep(ScrollbarOrientation orientation) const
+{
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
+ int length = (orientation == HorizontalScrollbar) ?
+ box->pixelSnappedClientWidth() : box->pixelSnappedClientHeight();
+ int minPageStep = static_cast<float>(length) * ScrollableArea::minFractionToStepWhenPaging();
+ int pageStep = max(minPageStep, length - ScrollableArea::maxOverlapBetweenPages());
+
+ return max(pageStep, 1);
+}
+
RenderLayer* RenderLayer::enclosingTransformedAncestor() const
{
RenderLayer* curr = parent();
@@ -1616,23 +1639,14 @@
}
}
-void* RenderLayer::operator new(size_t sz, RenderArena* renderArena)
+void* RenderLayer::operator new(size_t sz)
{
- return renderArena->allocate(sz);
+ return partitionAlloc(Partitions::getRenderingPartition(), sz);
}
-void RenderLayer::operator delete(void* ptr, size_t sz)
+void RenderLayer::operator delete(void* ptr)
{
- // Stash size where destroy can find it.
- *(size_t *)ptr = sz;
-}
-
-void RenderLayer::destroy(RenderArena* renderArena)
-{
- delete this;
-
- // Recover the size left there for us by operator delete and free the memory.
- renderArena->free(*(size_t *)this, this);
+ partitionFree(ptr);
}
void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
@@ -2472,17 +2486,8 @@
int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
{
- Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
- return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
-}
-
-int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
-{
- if (scrollbar->orientation() == HorizontalScrollbar)
- return scrollXOffset();
- if (scrollbar->orientation() == VerticalScrollbar)
- return scrollYOffset();
- return 0;
+ IntSize scrollDimensions = maximumScrollPosition() - minimumScrollPosition();
+ return (orientation == HorizontalScrollbar) ? scrollDimensions.width() : scrollDimensions.height();
}
IntPoint RenderLayer::scrollPosition() const
@@ -2501,9 +2506,7 @@
if (!box || !box->hasOverflowClip())
return -scrollOrigin();
- LayoutRect overflowRect(box->layoutOverflowRect());
- box->flipForWritingMode(overflowRect);
- return -scrollOrigin() + enclosingIntRect(overflowRect).size() - enclosingIntRect(box->clientBoxRect()).size();
+ return -scrollOrigin() + enclosingIntRect(m_overflowRect).size() - enclosingIntRect(box->clientBoxRect()).size();
}
IntRect RenderLayer::visibleContentRect(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
@@ -2843,14 +2846,6 @@
scrollbar = 0;
}
-bool RenderLayer::scrollsOverflow() const
-{
- if (!renderer()->isBox())
- return false;
-
- return toRenderBox(renderer())->scrollsOverflow();
-}
-
void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
{
if (hasScrollbar == hasHorizontalScrollbar())
@@ -2972,7 +2967,7 @@
ASSERT(renderBox());
if (m_scrollDimensionsDirty)
const_cast<RenderLayer*>(this)->computeScrollDimensions();
- return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft() + renderBox()->x());
+ return snapSizeToPixel(m_overflowRect.width(), renderBox()->clientLeft() + renderBox()->x());
}
int RenderLayer::scrollHeight() const
@@ -2980,39 +2975,7 @@
ASSERT(renderBox());
if (m_scrollDimensionsDirty)
const_cast<RenderLayer*>(this)->computeScrollDimensions();
- return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop() + renderBox()->y());
-}
-
-LayoutUnit RenderLayer::overflowTop() const
-{
- RenderBox* box = renderBox();
- LayoutRect overflowRect(box->layoutOverflowRect());
- box->flipForWritingMode(overflowRect);
- return overflowRect.y();
-}
-
-LayoutUnit RenderLayer::overflowBottom() const
-{
- RenderBox* box = renderBox();
- LayoutRect overflowRect(box->layoutOverflowRect());
- box->flipForWritingMode(overflowRect);
- return overflowRect.maxY();
-}
-
-LayoutUnit RenderLayer::overflowLeft() const
-{
- RenderBox* box = renderBox();
- LayoutRect overflowRect(box->layoutOverflowRect());
- box->flipForWritingMode(overflowRect);
- return overflowRect.x();
-}
-
-LayoutUnit RenderLayer::overflowRight() const
-{
- RenderBox* box = renderBox();
- LayoutRect overflowRect(box->layoutOverflowRect());
- box->flipForWritingMode(overflowRect);
- return overflowRect.maxX();
+ return snapSizeToPixel(m_overflowRect.height(), renderBox()->clientTop() + renderBox()->y());
}
void RenderLayer::computeScrollDimensions()
@@ -3022,11 +2985,11 @@
m_scrollDimensionsDirty = false;
- m_scrollSize.setWidth(overflowRight() - overflowLeft());
- m_scrollSize.setHeight(overflowBottom() - overflowTop());
+ m_overflowRect = box->layoutOverflowRect();
+ box->flipForWritingMode(m_overflowRect);
- int scrollableLeftOverflow = overflowLeft() - box->borderLeft();
- int scrollableTopOverflow = overflowTop() - box->borderTop();
+ int scrollableLeftOverflow = m_overflowRect.x() - box->borderLeft();
+ int scrollableTopOverflow = m_overflowRect.y() - box->borderTop();
setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
}
@@ -3109,15 +3072,11 @@
// Set up the range (and page step/line step).
if (m_hBar) {
int clientWidth = box->pixelSnappedClientWidth();
- int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
- m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
- m_hBar->setProportion(clientWidth, m_scrollSize.width());
+ m_hBar->setProportion(clientWidth, m_overflowRect.width());
}
if (m_vBar) {
int clientHeight = box->pixelSnappedClientHeight();
- int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
- m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
- m_vBar->setProportion(clientHeight, m_scrollSize.height());
+ m_vBar->setProportion(clientHeight, m_overflowRect.height());
}
updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
@@ -3598,9 +3557,9 @@
void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
{
ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
+ ASSERT(!(paintFlags & PaintLayerAppliedTransform));
- PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
- bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
+ bool haveTransparency = paintFlags & PaintLayerHaveTransparency;
bool isSelfPaintingLayer = this->isSelfPaintingLayer();
bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase;
@@ -3623,7 +3582,7 @@
GraphicsContext* transparencyLayerContext = context;
- if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot())
+ if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot())
return;
// Ensure our lists are up-to-date.
@@ -3726,12 +3685,12 @@
bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent;
bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground;
bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars;
- bool shouldPaintMask = (localPaintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly;
+ bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly;
PaintBehavior paintBehavior = PaintBehaviorNormal;
- if (localPaintFlags & PaintLayerPaintingSkipRootBackground)
+ if (paintFlags & PaintLayerPaintingSkipRootBackground)
paintBehavior |= PaintBehaviorSkipRootBackground;
- else if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly)
+ else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
paintBehavior |= PaintBehaviorRootBackgroundOnly;
LayerFragments layerFragments;
@@ -3739,9 +3698,9 @@
// Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
// fragment should paint.
collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.region, localPaintingInfo.paintDirtyRect,
- (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
+ (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
(isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot);
- updatePaintingInfoForFragments(layerFragments, localPaintingInfo, localPaintFlags, shouldPaintContent, &offsetFromRoot);
+ updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
}
if (shouldPaintBackground)
@@ -3749,7 +3708,7 @@
localPaintingInfo, paintBehavior, paintingRootForRenderer);
if (shouldPaintNegZOrderList)
- paintList(negZOrderList(), context, localPaintingInfo, localPaintFlags);
+ paintList(negZOrderList(), context, localPaintingInfo, paintFlags);
if (shouldPaintOwnContents)
paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
@@ -3759,10 +3718,10 @@
paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer);
if (shouldPaintNormalFlowAndPosZOrderLists)
- paintList(m_normalFlowList.get(), context, localPaintingInfo, localPaintFlags);
+ paintList(m_normalFlowList.get(), context, localPaintingInfo, paintFlags);
if (shouldPaintNormalFlowAndPosZOrderLists)
- paintList(posZOrderList(), context, localPaintingInfo, localPaintFlags);
+ paintList(posZOrderList(), context, localPaintingInfo, paintFlags);
if (shouldPaintOverlayScrollbars)
paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo);
diff --git a/Source/core/rendering/RenderLayer.h b/Source/core/rendering/RenderLayer.h
index c71c757..db8fd09 100644
--- a/Source/core/rendering/RenderLayer.h
+++ b/Source/core/rendering/RenderLayer.h
@@ -407,14 +407,6 @@
LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
- bool scrollsOverflow() const;
- bool hasScrollbars() const { return m_hBar || m_vBar; }
- void setHasHorizontalScrollbar(bool);
- void setHasVerticalScrollbar(bool);
-
- PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
- void destroyScrollbar(ScrollbarOrientation);
-
bool hasHorizontalScrollbar() const { return horizontalScrollbar(); }
bool hasVerticalScrollbar() const { return verticalScrollbar(); }
@@ -426,7 +418,6 @@
int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
- bool hasOverflowControls() const;
// isPointInResizeControl() is used for testing if a pointer/touch position is in the resize control
// area.
bool isPointInResizeControl(const IntPoint& absolutePoint, ResizerHitTestType resizerHitTestType) const;
@@ -729,12 +720,9 @@
bool hasBlendMode() const;
- // Overloaded new operator. Derived classes must override operator new
- // in order to allocate out of the RenderArena.
- void* operator new(size_t, RenderArena*);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
+ void* operator new(size_t);
+ // Only safe to call from RenderLayerModelObject::destroyLayer()
+ void operator delete(void*);
bool isComposited() const { return m_backing != 0; }
bool hasCompositedMask() const;
@@ -830,6 +818,14 @@
OnlyStackingContextsCanBeStackingContainers
};
+ void setHasHorizontalScrollbar(bool);
+ void setHasVerticalScrollbar(bool);
+
+ PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
+ void destroyScrollbar(ScrollbarOrientation);
+
+ bool hasOverflowControls() const;
+
void updateZOrderLists();
void rebuildZOrderLists();
// See the comment for collectLayers for information about the layerToForceAsStackingContainer parameter.
@@ -903,9 +899,6 @@
IntSize clampScrollOffset(const IntSize&) const;
- // The normal operator new is disallowed on all render objects.
- void* operator new(size_t) throw();
-
void setNextSibling(RenderLayer* next) { m_next = next; }
void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
void setParent(RenderLayer* parent);
@@ -1006,8 +999,6 @@
bool shouldBeSelfPaintingLayer() const;
- int scrollPosition(Scrollbar*) const;
-
// ScrollableArea interface
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
virtual void invalidateScrollCornerRect(const IntRect&);
@@ -1032,6 +1023,8 @@
virtual bool shouldSuspendScrollAnimations() const;
virtual bool scrollbarsCanBeActive() const;
virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
+ virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE;
+ virtual int pageStep(ScrollbarOrientation) const OVERRIDE;
// Rectangle encompassing the scroll corner and resizer rect.
IntRect scrollCornerAndResizerRect() const;
@@ -1100,14 +1093,6 @@
friend class RenderLayerCompositor;
friend class RenderLayerModelObject;
- // Only safe to call from RenderLayerModelObject::destroyLayer(RenderArena*)
- void destroy(RenderArena*);
-
- LayoutUnit overflowTop() const;
- LayoutUnit overflowBottom() const;
- LayoutUnit overflowLeft() const;
- LayoutUnit overflowRight() const;
-
IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const;
IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const;
@@ -1210,7 +1195,7 @@
IntSize m_scrollOffset;
// The width/height of our scrolled area.
- LayoutSize m_scrollSize;
+ LayoutRect m_overflowRect;
// For layers with overflow, we have a pair of scrollbars.
RefPtr<Scrollbar> m_hBar;
diff --git a/Source/core/rendering/RenderLayerBacking.cpp b/Source/core/rendering/RenderLayerBacking.cpp
index bf8bfed..2bc2a70 100644
--- a/Source/core/rendering/RenderLayerBacking.cpp
+++ b/Source/core/rendering/RenderLayerBacking.cpp
@@ -1543,9 +1543,8 @@
}
}
-void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, GraphicsContext* context,
- const IntRect& paintDirtyRect, // In the coords of rootLayer.
- PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase)
+void RenderLayerBacking::doPaintTask(GraphicsLayerPaintInfo& paintInfo, GraphicsContext* context,
+ const IntRect& clip) // In the coords of rootLayer.
{
if (paintsIntoCompositedAncestor()) {
ASSERT_NOT_REACHED();
@@ -1555,32 +1554,48 @@
FontCachePurgePreventer fontCachePurgePreventer;
RenderLayer::PaintLayerFlags paintFlags = 0;
- if (paintingPhase & GraphicsLayerPaintBackground)
+ if (paintInfo.paintingPhase & GraphicsLayerPaintBackground)
paintFlags |= RenderLayer::PaintLayerPaintingCompositingBackgroundPhase;
- if (paintingPhase & GraphicsLayerPaintForeground)
+ if (paintInfo.paintingPhase & GraphicsLayerPaintForeground)
paintFlags |= RenderLayer::PaintLayerPaintingCompositingForegroundPhase;
- if (paintingPhase & GraphicsLayerPaintMask)
+ if (paintInfo.paintingPhase & GraphicsLayerPaintMask)
paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
- if (paintingPhase & GraphicsLayerPaintOverflowContents)
+ if (paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents)
paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
- if (paintingPhase & GraphicsLayerPaintCompositedScroll)
+ if (paintInfo.paintingPhase & GraphicsLayerPaintCompositedScroll)
paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
- if (graphicsLayer == m_backgroundLayer)
+ if (paintInfo.isBackgroundLayer)
paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
else if (compositor()->fixedRootBackgroundLayer())
paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
+ InspectorInstrumentation::willPaint(paintInfo.renderLayer->renderer());
+ context->save();
+
+ LayoutSize offset = paintInfo.offsetFromRenderer;
+ context->translate(-offset);
+ LayoutRect relativeClip(clip);
+ relativeClip.move(offset);
+
+ // The dirtyRect is in the coords of the painting root.
+ IntRect dirtyRect = pixelSnappedIntRect(relativeClip);
+ if (!(paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents))
+ dirtyRect.intersect(paintInfo.compositedBounds);
+
// FIXME: GraphicsLayers need a way to split for RenderRegions.
- RenderLayer::LayerPaintingInfo paintingInfo(m_owningLayer, paintDirtyRect, paintBehavior, LayoutSize());
- m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags);
+ RenderLayer::LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize());
+ paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags);
- ASSERT(graphicsLayer != m_backgroundLayer || paintFlags & RenderLayer::PaintLayerPaintingRootBackgroundOnly);
+ ASSERT(!paintInfo.isBackgroundLayer || paintFlags & RenderLayer::PaintLayerPaintingRootBackgroundOnly);
- if (m_owningLayer->containsDirtyOverlayScrollbars())
- m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
+ if (paintInfo.renderLayer->containsDirtyOverlayScrollbars())
+ paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
- ASSERT(!m_owningLayer->m_usedTransparency);
+ ASSERT(!paintInfo.renderLayer->m_usedTransparency);
+
+ context->restore();
+ InspectorInstrumentation::didPaint(paintInfo.renderLayer->renderer(), context, clip);
}
static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
@@ -1610,17 +1625,16 @@
|| graphicsLayer == m_backgroundLayer.get()
|| graphicsLayer == m_maskLayer.get()
|| graphicsLayer == m_scrollingContentsLayer.get()) {
- InspectorInstrumentation::willPaint(renderer());
- // The dirtyRect is in the coords of the painting root.
- IntRect dirtyRect = clip;
- if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
- dirtyRect.intersect(compositedBounds());
+ GraphicsLayerPaintInfo paintInfo;
+ paintInfo.renderLayer = m_owningLayer;
+ paintInfo.compositedBounds = compositedBounds();
+ paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer();
+ paintInfo.paintingPhase = paintingPhase;
+ paintInfo.isBackgroundLayer = (graphicsLayer == m_backgroundLayer);
// We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
- paintIntoLayer(graphicsLayer, &context, dirtyRect, PaintBehaviorNormal, paintingPhase);
-
- InspectorInstrumentation::didPaint(renderer(), &context, clip);
+ doPaintTask(paintInfo, &context, clip);
} else if (graphicsLayer == layerForHorizontalScrollbar()) {
paintScrollbar(m_owningLayer->horizontalScrollbar(), context, clip);
} else if (graphicsLayer == layerForVerticalScrollbar()) {
diff --git a/Source/core/rendering/RenderLayerBacking.h b/Source/core/rendering/RenderLayerBacking.h
index 1df576f..7a62c3c 100644
--- a/Source/core/rendering/RenderLayerBacking.h
+++ b/Source/core/rendering/RenderLayerBacking.h
@@ -44,6 +44,20 @@
ContainerCompositingLayer // layer with no backing store
};
+
+// A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer.
+struct GraphicsLayerPaintInfo {
+ RenderLayer* renderLayer;
+
+ IntRect compositedBounds;
+
+ IntSize offsetFromRenderer;
+
+ GraphicsLayerPaintingPhase paintingPhase;
+
+ bool isBackgroundLayer;
+};
+
// RenderLayerBacking controls the compositing behavior for a single RenderLayer.
// It holds the various GraphicsLayers, and makes decisions about intra-layer rendering
// optimizations.
@@ -224,7 +238,7 @@
bool shouldClipCompositedBounds() const;
- void paintIntoLayer(const GraphicsLayer*, GraphicsContext*, const IntRect& paintDirtyRect, PaintBehavior, GraphicsLayerPaintingPhase);
+ void doPaintTask(GraphicsLayerPaintInfo&, GraphicsContext*, const IntRect& clip);
static CSSPropertyID graphicsLayerToCSSProperty(AnimatedPropertyID);
static AnimatedPropertyID cssToGraphicsLayerProperty(CSSPropertyID);
diff --git a/Source/core/rendering/RenderLayerCompositor.cpp b/Source/core/rendering/RenderLayerCompositor.cpp
index ed3aa8f..bedb7b5 100644
--- a/Source/core/rendering/RenderLayerCompositor.cpp
+++ b/Source/core/rendering/RenderLayerCompositor.cpp
@@ -116,17 +116,17 @@
OverlapMap()
: m_geometryMap(UseTransforms)
{
- // Begin assuming the root layer will be composited so that there is
- // something on the stack. The root layer should also never get an
- // popCompositingContainer call.
- pushCompositingContainer();
+ // Begin by assuming the root layer will be composited so that there
+ // is something on the stack. The root layer should also never get a
+ // finishCurrentOverlapTestingContext() call.
+ beginNewOverlapTestingContext();
}
void add(const RenderLayer* layer, const IntRect& bounds)
{
// Layers do not contribute to overlap immediately--instead, they will
- // contribute to overlap as soon as their composited ancestor has been
- // recursively processed and popped off the stack.
+ // contribute to overlap as soon as they have been recursively processed
+ // and popped off the stack.
ASSERT(m_overlapStack.size() >= 2);
m_overlapStack[m_overlapStack.size() - 2].add(bounds);
m_layers.add(layer);
@@ -147,13 +147,23 @@
return m_layers.isEmpty();
}
- void pushCompositingContainer()
+ void beginNewOverlapTestingContext()
{
+ // This effectively creates a new "clean slate" for overlap state.
+ // This is used when we know that a subtree or remaining set of
+ // siblings does not need to check overlap with things behind it.
m_overlapStack.append(OverlapMapContainer());
}
- void popCompositingContainer()
+ void finishCurrentOverlapTestingContext()
{
+ // The overlap information on the top of the stack is still necessary
+ // for checking overlap of any layers outside this context that may
+ // overlap things from inside this context. Therefore, we must merge
+ // the information from the top of the stack before popping the stack.
+ //
+ // FIXME: we may be able to avoid this deep copy by rearranging how
+ // overlapMap state is managed.
m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
m_overlapStack.removeLast();
}
@@ -820,8 +830,11 @@
// This layer now acts as the ancestor for kids.
childState.m_compositingAncestor = layer;
+ // Here we know that all children and the layer's own contents can blindly paint into
+ // this layer's backing, until a descendant is composited. So, we don't need to check
+ // for overlap with anything behind this layer.
if (overlapMap)
- overlapMap->pushCompositingContainer();
+ overlapMap->beginNewOverlapTestingContext();
// This layer is going to be composited, so children can safely ignore the fact that there's an
// animation running behind this layer, meaning they can rely on the overlap map testing again.
childState.m_testingOverlap = true;
@@ -832,6 +845,7 @@
#endif
bool anyDescendantHas3DTransform = false;
+ bool willHaveForegroundLayer = false;
if (layer->isStackingContainer()) {
if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
@@ -848,18 +862,23 @@
if (!willBeComposited) {
// make layer compositing
childState.m_compositingAncestor = layer;
- if (overlapMap)
- overlapMap->pushCompositingContainer();
- // This layer is going to be composited, so children can safely ignore the fact that there's an
- // animation running behind this layer, meaning they can rely on the overlap map testing again
- childState.m_testingOverlap = true;
willBeComposited = true;
+ willHaveForegroundLayer = true;
}
}
}
}
}
+ if (overlapMap && willHaveForegroundLayer) {
+ // A foreground layer effectively is a new backing for all subsequent children, so
+ // we don't need to test for overlap with anything behind this.
+ overlapMap->beginNewOverlapTestingContext();
+ // This layer is going to be composited, so children can safely ignore the fact that there's an
+ // animation running behind this layer, meaning they can rely on the overlap map testing again
+ childState.m_testingOverlap = true;
+ }
+
if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
@@ -898,7 +917,10 @@
if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtreeCompositingReasons)) {
childState.m_compositingAncestor = layer;
if (overlapMap) {
- overlapMap->pushCompositingContainer();
+ // FIXME: this context push is effectively a no-op but needs to exist for
+ // now, because the code is designed to push overlap information to the
+ // second-from-top context of the stack.
+ overlapMap->beginNewOverlapTestingContext();
addToOverlapMapRecursive(*overlapMap, layer);
}
willBeComposited = true;
@@ -927,7 +949,7 @@
compositingState.m_testingOverlap = false;
if (overlapMap && childState.m_compositingAncestor == layer && !layer->isRootLayer())
- overlapMap->popCompositingContainer();
+ overlapMap->finishCurrentOverlapTestingContext();
// If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
// to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
@@ -1853,12 +1875,8 @@
if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
return false;
- if (AnimationController* animController = renderer->animation()) {
- return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
- // <rdar://problem/10907251> - WebKit2 doesn't support CA animations of CI filters on Lion and below
- || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter)
- || animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
- }
+ if (AnimationController* animController = renderer->animation())
+ return animController->isRunningAcceleratableAnimationOnRenderer(renderer);
return false;
}
@@ -2195,7 +2213,7 @@
return false;
// We do want a layer if we have a scrolling coordinator and can scroll.
- if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground() && !m_renderView->frameView()->prohibitsScrolling())
+ if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground())
return true;
// Chromium always wants a layer.
diff --git a/Source/core/rendering/RenderLayerModelObject.cpp b/Source/core/rendering/RenderLayerModelObject.cpp
index d5a20c6..c5aecec 100644
--- a/Source/core/rendering/RenderLayerModelObject.cpp
+++ b/Source/core/rendering/RenderLayerModelObject.cpp
@@ -54,7 +54,7 @@
{
ASSERT(!hasLayer()); // Callers should have already called setHasLayer(false)
ASSERT(m_layer);
- m_layer->destroy(renderArena());
+ delete m_layer;
m_layer = 0;
}
@@ -63,7 +63,7 @@
if (m_layer)
return;
- m_layer = new (renderArena()) RenderLayer(this);
+ m_layer = new RenderLayer(this);
setHasLayer(true);
m_layer->insertOnlyThisLayer();
}
@@ -182,16 +182,18 @@
}
}
-void RenderLayerModelObject::addLayerHitTestRects(LayerHitTestRects& rects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const
+void RenderLayerModelObject::addLayerHitTestRects(LayerHitTestRects& rects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
{
// If we have a new layer then our current layer/offset is irrelevant.
LayoutPoint adjustedLayerOffset = layerOffset;
+ LayoutRect adjustedContainerRect = containerRect;
if (hasLayer()) {
currentLayer = layer();
adjustedLayerOffset = LayoutPoint();
+ adjustedContainerRect = LayoutRect();
}
- RenderObject::addLayerHitTestRects(rects, currentLayer, adjustedLayerOffset);
+ RenderObject::addLayerHitTestRects(rects, currentLayer, adjustedLayerOffset, adjustedContainerRect);
}
} // namespace WebCore
diff --git a/Source/core/rendering/RenderLayerModelObject.h b/Source/core/rendering/RenderLayerModelObject.h
index 034c052..42f1183 100644
--- a/Source/core/rendering/RenderLayerModelObject.h
+++ b/Source/core/rendering/RenderLayerModelObject.h
@@ -58,7 +58,7 @@
virtual void willBeDestroyed() OVERRIDE;
- virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* = 0, const LayoutPoint& = LayoutPoint()) const OVERRIDE;
+ virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer*, const LayoutPoint&, const LayoutRect&) const OVERRIDE;
private:
virtual bool isLayerModelObject() const OVERRIDE FINAL { return true; }
diff --git a/Source/core/rendering/RenderLineBoxList.cpp b/Source/core/rendering/RenderLineBoxList.cpp
index 1205f19..6613173 100644
--- a/Source/core/rendering/RenderLineBoxList.cpp
+++ b/Source/core/rendering/RenderLineBoxList.cpp
@@ -32,7 +32,6 @@
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RootInlineBox.h"
@@ -63,13 +62,13 @@
checkConsistency();
}
-void RenderLineBoxList::deleteLineBoxTree(RenderArena* arena)
+void RenderLineBoxList::deleteLineBoxTree()
{
InlineFlowBox* line = m_firstLineBox;
InlineFlowBox* nextLine;
while (line) {
nextLine = line->nextLineBox();
- line->deleteLine(arena);
+ line->deleteLine();
line = nextLine;
}
m_firstLineBox = m_lastLineBox = 0;
@@ -126,13 +125,13 @@
checkConsistency();
}
-void RenderLineBoxList::deleteLineBoxes(RenderArena* arena)
+void RenderLineBoxList::deleteLineBoxes()
{
if (m_firstLineBox) {
InlineFlowBox* next;
for (InlineFlowBox* curr = m_firstLineBox; curr; curr = next) {
next = curr->nextLineBox();
- curr->destroy(arena);
+ curr->destroy();
}
m_firstLineBox = 0;
m_lastLineBox = 0;
diff --git a/Source/core/rendering/RenderLineBoxList.h b/Source/core/rendering/RenderLineBoxList.h
index d0c1afd..b57a4a0 100644
--- a/Source/core/rendering/RenderLineBoxList.h
+++ b/Source/core/rendering/RenderLineBoxList.h
@@ -53,8 +53,8 @@
void appendLineBox(InlineFlowBox*);
- void deleteLineBoxTree(RenderArena*);
- void deleteLineBoxes(RenderArena*);
+ void deleteLineBoxTree();
+ void deleteLineBoxes();
void extractLineBox(InlineFlowBox*);
void attachLineBox(InlineFlowBox*);
diff --git a/Source/core/rendering/RenderListBox.cpp b/Source/core/rendering/RenderListBox.cpp
index 1771c60..a2b87f8 100644
--- a/Source/core/rendering/RenderListBox.cpp
+++ b/Source/core/rendering/RenderListBox.cpp
@@ -176,7 +176,6 @@
if (m_vBar) {
bool enabled = numVisibleItems() < numItems();
m_vBar->setEnabled(enabled);
- m_vBar->setSteps(1, max(1, numVisibleItems() - 1), itemHeight());
m_vBar->setProportion(numVisibleItems(), numItems());
if (!enabled) {
scrollToOffsetWithoutAnimation(VerticalScrollbar, 0);
@@ -625,12 +624,12 @@
int RenderListBox::scrollSize(ScrollbarOrientation orientation) const
{
- return ((orientation == VerticalScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
+ return orientation == VerticalScrollbar ? (numItems() - numVisibleItems()) : 0;
}
-int RenderListBox::scrollPosition(Scrollbar*) const
+IntPoint RenderListBox::scrollPosition() const
{
- return m_indexOffset;
+ return IntPoint(0, m_indexOffset);
}
void RenderListBox::setScrollOffset(const IntPoint& offset)
@@ -835,11 +834,36 @@
return view->frameView()->scrollbarsCanBeActive();
}
+IntPoint RenderListBox::minimumScrollPosition() const
+{
+ return IntPoint();
+}
+
IntPoint RenderListBox::maximumScrollPosition() const
{
return IntPoint(0, numItems() - numVisibleItems());
}
+bool RenderListBox::userInputScrollable(ScrollbarOrientation orientation) const
+{
+ return orientation == VerticalScrollbar;
+}
+
+int RenderListBox::lineStep(ScrollbarOrientation) const
+{
+ return 1;
+}
+
+int RenderListBox::pageStep(ScrollbarOrientation orientation) const
+{
+ return max(1, numVisibleItems() - 1);
+}
+
+float RenderListBox::pixelStep(ScrollbarOrientation) const
+{
+ return 1.0f / itemHeight();
+}
+
ScrollableArea* RenderListBox::enclosingScrollableArea() const
{
// FIXME: Return a RenderLayer that's scrollable.
diff --git a/Source/core/rendering/RenderListBox.h b/Source/core/rendering/RenderListBox.h
index 97e73d3..f039edb 100644
--- a/Source/core/rendering/RenderListBox.h
+++ b/Source/core/rendering/RenderListBox.h
@@ -103,7 +103,7 @@
// ScrollableArea interface.
virtual int scrollSize(ScrollbarOrientation) const OVERRIDE;
- virtual int scrollPosition(Scrollbar*) const OVERRIDE;
+ virtual IntPoint scrollPosition() const OVERRIDE;
virtual void setScrollOffset(const IntPoint&) OVERRIDE;
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
virtual bool isActive() const OVERRIDE;
@@ -121,7 +121,13 @@
virtual IntPoint lastKnownMousePosition() const OVERRIDE;
virtual bool shouldSuspendScrollAnimations() const OVERRIDE;
virtual bool scrollbarsCanBeActive() const OVERRIDE;
+ virtual IntPoint minimumScrollPosition() const OVERRIDE;
virtual IntPoint maximumScrollPosition() const OVERRIDE;
+ virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE;
+ virtual int lineStep(ScrollbarOrientation) const;
+ virtual int pageStep(ScrollbarOrientation) const;
+ virtual float pixelStep(ScrollbarOrientation) const;
+
virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
diff --git a/Source/core/rendering/RenderListMarker.cpp b/Source/core/rendering/RenderListMarker.cpp
index f965338..bc4aaad 100644
--- a/Source/core/rendering/RenderListMarker.cpp
+++ b/Source/core/rendering/RenderListMarker.cpp
@@ -1071,7 +1071,7 @@
RenderListMarker* RenderListMarker::createAnonymous(RenderListItem* item)
{
Document* document = item->document();
- RenderListMarker* renderer = new (document->renderArena()) RenderListMarker(item);
+ RenderListMarker* renderer = new RenderListMarker(item);
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderMedia.cpp b/Source/core/rendering/RenderMedia.cpp
index 6c7cd51..48246c9 100644
--- a/Source/core/rendering/RenderMedia.cpp
+++ b/Source/core/rendering/RenderMedia.cpp
@@ -87,8 +87,7 @@
controlsRenderer->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed));
- controlsRenderer->setNeedsLayout(true, MarkOnlyThis);
- controlsRenderer->layout();
+ controlsRenderer->forceLayout();
setChildNeedsLayout(false);
statePusher.pop();
diff --git a/Source/core/rendering/RenderMenuList.cpp b/Source/core/rendering/RenderMenuList.cpp
index 571e49e..e0856e7 100644
--- a/Source/core/rendering/RenderMenuList.cpp
+++ b/Source/core/rendering/RenderMenuList.cpp
@@ -236,7 +236,7 @@
if (!m_buttonText || !m_buttonText->isBR()) {
if (m_buttonText)
m_buttonText->destroy();
- m_buttonText = new (renderArena()) RenderBR(document());
+ m_buttonText = new RenderBR(document());
m_buttonText->setStyle(style());
addChild(m_buttonText);
}
@@ -246,7 +246,7 @@
else {
if (m_buttonText)
m_buttonText->destroy();
- m_buttonText = new (renderArena()) RenderText(document(), s.impl());
+ m_buttonText = new RenderText(document(), s.impl());
m_buttonText->setStyle(style());
// We need to set the text explicitly though it was specified in the
// constructor because RenderText doesn't refer to the text
diff --git a/Source/core/rendering/RenderMultiColumnFlowThread.cpp b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
index 53bf05a..1a2fc6f 100644
--- a/Source/core/rendering/RenderMultiColumnFlowThread.cpp
+++ b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
@@ -42,7 +42,7 @@
RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Document* document)
{
- RenderMultiColumnFlowThread* renderer = new (document->renderArena()) RenderMultiColumnFlowThread();
+ RenderMultiColumnFlowThread* renderer = new RenderMultiColumnFlowThread();
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderMultiColumnSet.cpp b/Source/core/rendering/RenderMultiColumnSet.cpp
index 2c0175b..f53e156 100644
--- a/Source/core/rendering/RenderMultiColumnSet.cpp
+++ b/Source/core/rendering/RenderMultiColumnSet.cpp
@@ -52,7 +52,7 @@
RenderMultiColumnSet* RenderMultiColumnSet::createAnonymous(RenderFlowThread* flowThread)
{
Document* document = flowThread->document();
- RenderMultiColumnSet* renderer = new (document->renderArena()) RenderMultiColumnSet(flowThread);
+ RenderMultiColumnSet* renderer = new RenderMultiColumnSet(flowThread);
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderNamedFlowThread.cpp b/Source/core/rendering/RenderNamedFlowThread.cpp
index 5537e81..b7e7388 100644
--- a/Source/core/rendering/RenderNamedFlowThread.cpp
+++ b/Source/core/rendering/RenderNamedFlowThread.cpp
@@ -47,7 +47,7 @@
RenderNamedFlowThread* RenderNamedFlowThread::createAnonymous(Document* document, PassRefPtr<NamedFlow> namedFlow)
{
ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- RenderNamedFlowThread* renderer = new (document->renderArena()) RenderNamedFlowThread(namedFlow);
+ RenderNamedFlowThread* renderer = new RenderNamedFlowThread(namedFlow);
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
index 376a739..a41e491 100644
--- a/Source/core/rendering/RenderObject.cpp
+++ b/Source/core/rendering/RenderObject.cpp
@@ -30,6 +30,7 @@
#include "HTMLNames.h"
#include "RuntimeEnabledFeatures.h"
#include "core/accessibility/AXObjectCache.h"
+#include "core/animation/ActiveAnimations.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/editing/EditingBoundary.h"
#include "core/editing/FrameSelection.h"
@@ -43,13 +44,14 @@
#include "core/page/FrameView.h"
#include "core/page/Page.h"
#include "core/page/Settings.h"
+#include "core/page/UseCounter.h"
#include "core/page/animation/AnimationController.h"
+#include "core/platform/Partitions.h"
#include "core/platform/graphics/FloatQuad.h"
#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/transforms/TransformState.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderCounter.h"
#include "core/rendering/RenderDeprecatedFlexibleBox.h"
#include "core/rendering/RenderFlexibleBox.h"
@@ -91,7 +93,6 @@
using namespace HTMLNames;
#ifndef NDEBUG
-static void* baseOfRenderObjectBeingDeleted;
RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject* renderObject, bool isForbidden)
: m_renderObject(renderObject)
@@ -121,30 +122,26 @@
RenderObjectAncestorLineboxDirtySet* RenderObject::s_ancestorLineboxDirtySet = 0;
-void* RenderObject::operator new(size_t sz, RenderArena* renderArena)
+void* RenderObject::operator new(size_t sz)
{
- return renderArena->allocate(sz);
+ return partitionAlloc(Partitions::getRenderingPartition(), sz);
}
-void RenderObject::operator delete(void* ptr, size_t sz)
+void RenderObject::operator delete(void* ptr)
{
- ASSERT(baseOfRenderObjectBeingDeleted == ptr);
-
- // Stash size where destroy can find it.
- *(size_t *)ptr = sz;
+ partitionFree(ptr);
}
RenderObject* RenderObject::createObject(Element* element, RenderStyle* style)
{
Document* doc = element->document();
- RenderArena* arena = doc->renderArena();
// Minimal support for content properties replacing an entire element.
// Works only if we have exactly one piece of content and it's a URL.
// Otherwise acts as if we didn't support this feature.
const ContentData* contentData = style->contentData();
if (contentData && !contentData->next() && contentData->isImage() && !element->isPseudoElement()) {
- RenderImage* image = new (arena) RenderImage(element);
+ RenderImage* image = new RenderImage(element);
// RenderImageResourceStyleImage requires a style being present on the image but we don't want to
// trigger a style change now as the node is not fully attached. Moving this code to style change
// doesn't make sense as it should be run once at renderer creation.
@@ -160,56 +157,62 @@
if (element->hasTagName(rubyTag)) {
if (style->display() == INLINE)
- return new (arena) RenderRubyAsInline(element);
+ return new RenderRubyAsInline(element);
else if (style->display() == BLOCK)
- return new (arena) RenderRubyAsBlock(element);
+ return new RenderRubyAsBlock(element);
}
// treat <rt> as ruby text ONLY if it still has its default treatment of block
if (element->hasTagName(rtTag) && style->display() == BLOCK)
- return new (arena) RenderRubyText(element);
+ return new RenderRubyText(element);
if (RuntimeEnabledFeatures::cssRegionsEnabled() && style->isDisplayRegionType() && !style->regionThread().isEmpty() && doc->renderView())
- return new (arena) RenderRegion(element, 0);
+ return new RenderRegion(element, 0);
+
+ if (style->display() == RUN_IN)
+ UseCounter::count(doc, UseCounter::CSSDisplayRunIn);
+ else if (style->display() == COMPACT)
+ UseCounter::count(doc, UseCounter::CSSDisplayCompact);
+
switch (style->display()) {
case NONE:
return 0;
case INLINE:
- return new (arena) RenderInline(element);
+ return new RenderInline(element);
case BLOCK:
case INLINE_BLOCK:
case RUN_IN:
case COMPACT:
if ((!style->hasAutoColumnCount() || !style->hasAutoColumnWidth()) && doc->regionBasedColumnsEnabled())
- return new (arena) RenderMultiColumnBlock(element);
- return new (arena) RenderBlock(element);
+ return new RenderMultiColumnBlock(element);
+ return new RenderBlock(element);
case LIST_ITEM:
- return new (arena) RenderListItem(element);
+ return new RenderListItem(element);
case TABLE:
case INLINE_TABLE:
- return new (arena) RenderTable(element);
+ return new RenderTable(element);
case TABLE_ROW_GROUP:
case TABLE_HEADER_GROUP:
case TABLE_FOOTER_GROUP:
- return new (arena) RenderTableSection(element);
+ return new RenderTableSection(element);
case TABLE_ROW:
- return new (arena) RenderTableRow(element);
+ return new RenderTableRow(element);
case TABLE_COLUMN_GROUP:
case TABLE_COLUMN:
- return new (arena) RenderTableCol(element);
+ return new RenderTableCol(element);
case TABLE_CELL:
- return new (arena) RenderTableCell(element);
+ return new RenderTableCell(element);
case TABLE_CAPTION:
- return new (arena) RenderTableCaption(element);
+ return new RenderTableCaption(element);
case BOX:
case INLINE_BOX:
- return new (arena) RenderDeprecatedFlexibleBox(element);
+ return new RenderDeprecatedFlexibleBox(element);
case FLEX:
case INLINE_FLEX:
- return new (arena) RenderFlexibleBox(element);
+ return new RenderFlexibleBox(element);
case GRID:
case INLINE_GRID:
- return new (arena) RenderGrid(element);
+ return new RenderGrid(element);
case LAZY_BLOCK:
- return new (arena) RenderLazyBlock(element);
+ return new RenderLazyBlock(element);
}
return 0;
@@ -684,6 +687,10 @@
// calling setNeedsLayout during preferred width computation.
SetLayoutNeededForbiddenScope layoutForbiddenScope(object, isSetNeedsLayoutForbidden());
#endif
+
+ if (object->selfNeedsLayout())
+ return;
+
// Don't mark the outermost object of an unrooted subtree. That object will be
// marked when the subtree is added to the document.
RenderObject* container = object->container();
@@ -1725,10 +1732,18 @@
void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
{
- if (!isText() && style && !RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- setStyle(animation()->updateAnimations(this, style.get()));
- else
+ if (!isText() && style) {
+ if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() && node() && node()->isElementNode()) {
+ Element* element = toElement(node());
+ if (CSSAnimations::needsUpdate(element, style.get()))
+ element->ensureActiveAnimations()->cssAnimations()->update(element, style.get());
+ setStyle(style);
+ } else {
+ setStyle(animation()->updateAnimations(this, style.get()));
+ }
+ } else {
setStyle(style);
+ }
}
StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
@@ -2289,14 +2304,34 @@
return;
}
- this->addLayerHitTestRects(layerRects, currentLayer, layerOffset);
+ this->addLayerHitTestRects(layerRects, currentLayer, layerOffset, LayoutRect());
}
-void RenderObject::addLayerHitTestRects(LayerHitTestRects& layerRects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const
+void RenderObject::addLayerHitTestRects(LayerHitTestRects& layerRects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
{
ASSERT(currentLayer);
ASSERT(currentLayer == this->enclosingLayer());
+ // Compute the rects for this renderer only and add them to the results.
+ // Note that we could avoid passing the offset and instead adjust each result, but this
+ // seems slightly simpler.
+ Vector<LayoutRect> ownRects;
+ LayoutRect newContainerRect;
+ computeSelfHitTestRects(ownRects, layerOffset);
+
+ LayerHitTestRects::iterator iter = layerRects.find(currentLayer);
+ if (iter == layerRects.end())
+ iter = layerRects.add(currentLayer, Vector<LayoutRect>()).iterator;
+ for (size_t i = 0; i < ownRects.size(); i++) {
+ if (!containerRect.contains(ownRects[i])) {
+ iter->value.append(ownRects[i]);
+ if (newContainerRect.isEmpty())
+ newContainerRect = ownRects[i];
+ }
+ }
+ if (newContainerRect.isEmpty())
+ newContainerRect = containerRect;
+
// If it's possible for children to have rects outside our bounds, then we need to descend into
// the children and compute them.
// Ideally there would be other cases where we could detect that children couldn't have rects
@@ -2306,21 +2341,9 @@
// rewrite Region to be more efficient. See https://bugs.webkit.org/show_bug.cgi?id=100814.
if (!isRenderView()) {
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
- curr->addLayerHitTestRects(layerRects, currentLayer, layerOffset);
+ curr->addLayerHitTestRects(layerRects, currentLayer, layerOffset, newContainerRect);
}
}
-
- // Compute the rects for this renderer only and add them to the results.
- // Note that we could avoid passing the offset and instead adjust each result, but this
- // seems slightly simpler.
- Vector<LayoutRect> ownRects;
- computeSelfHitTestRects(ownRects, layerOffset);
-
- LayerHitTestRects::iterator iter = layerRects.find(currentLayer);
- if (iter == layerRects.end())
- layerRects.add(currentLayer, ownRects);
- else
- iter->value.append(ownRects);
}
bool RenderObject::isRooted(RenderView** view) const
@@ -2634,11 +2657,12 @@
void RenderObject::destroy()
{
willBeDestroyed();
- arenaDelete(renderArena(), this);
+ postDestroy();
}
-void RenderObject::arenaDelete(RenderArena* arena, void* base)
+void RenderObject::postDestroy()
{
+ // It seems ugly that this is not in willBeDestroyed().
if (m_style) {
for (const FillLayer* bgLayer = m_style->backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
if (StyleImage* backgroundImage = bgLayer->image())
@@ -2657,22 +2681,12 @@
maskBoxImage->removeClient(this);
}
-#ifndef NDEBUG
- void* savedBase = baseOfRenderObjectBeingDeleted;
- baseOfRenderObjectBeingDeleted = base;
-#endif
delete this;
-#ifndef NDEBUG
- baseOfRenderObjectBeingDeleted = savedBase;
-#endif
-
- // Recover the size left there for us by operator delete and free the memory.
- arena->free(*(size_t*)base, base);
}
-VisiblePosition RenderObject::positionForPoint(const LayoutPoint&)
+PositionWithAffinity RenderObject::positionForPoint(const LayoutPoint&)
{
- return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
+ return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
}
void RenderObject::updateDragState(bool dragOn)
@@ -2769,6 +2783,24 @@
setNeedsLayout(false);
}
+// FIXME: Do we need this method at all? If setNeedsLayout early returns in all the right places,
+// then MarkOnlyThis is not needed for performance or correctness.
+void RenderObject::forceLayout()
+{
+ // This is the only way it's safe to use MarkOnlyThis (i.e. if we're immediately going to call layout).
+ // FIXME: Add asserts that we only ever do the MarkOnlyThis behavior from here.
+ setNeedsLayout(true, MarkOnlyThis);
+ layout();
+}
+
+// FIXME: Does this do anything different than forceLayout given that we're passing MarkOnlyThis.
+// I don't think it does and we should change all callers to use forceLayout.
+void RenderObject::forceChildLayout()
+{
+ setChildNeedsLayout(true, MarkOnlyThis);
+ forceLayout();
+}
+
enum StyleCacheState {
Cached,
Uncached
@@ -3113,7 +3145,7 @@
return node && node->isElementNode() ? toElement(node) : 0;
}
-VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
+PositionWithAffinity RenderObject::createPositionWithAffinity(int offset, EAffinity affinity)
{
// If this is a non-anonymous renderer in an editable area, then it's simple.
if (Node* node = nonPseudoNode()) {
@@ -3122,13 +3154,13 @@
Position position = createLegacyEditingPosition(node, offset);
Position candidate = position.downstream(CanCrossEditingBoundary);
if (candidate.deprecatedNode()->rendererIsEditable())
- return VisiblePosition(candidate, affinity);
+ return PositionWithAffinity(candidate, affinity);
candidate = position.upstream(CanCrossEditingBoundary);
if (candidate.deprecatedNode()->rendererIsEditable())
- return VisiblePosition(candidate, affinity);
+ return PositionWithAffinity(candidate, affinity);
}
// FIXME: Eliminate legacy editing positions
- return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
+ return PositionWithAffinity(createLegacyEditingPosition(node, offset), affinity);
}
// We don't want to cross the boundary between editable and non-editable
@@ -3143,7 +3175,7 @@
RenderObject* renderer = child;
while ((renderer = renderer->nextInPreOrder(parent))) {
if (Node* node = renderer->nonPseudoNode())
- return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
+ return PositionWithAffinity(firstPositionInOrBeforeNode(node), DOWNSTREAM);
}
// Find non-anonymous content before.
@@ -3152,28 +3184,28 @@
if (renderer == parent)
break;
if (Node* node = renderer->nonPseudoNode())
- return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
+ return PositionWithAffinity(lastPositionInOrAfterNode(node), DOWNSTREAM);
}
// Use the parent itself unless it too is anonymous.
if (Node* node = parent->nonPseudoNode())
- return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
+ return PositionWithAffinity(firstPositionInOrBeforeNode(node), DOWNSTREAM);
// Repeat at the next level up.
child = parent;
}
// Everything was anonymous. Give up.
- return VisiblePosition();
+ return PositionWithAffinity();
}
-VisiblePosition RenderObject::createVisiblePosition(const Position& position)
+PositionWithAffinity RenderObject::createPositionWithAffinity(const Position& position)
{
if (position.isNotNull())
- return VisiblePosition(position);
+ return PositionWithAffinity(position);
ASSERT(!node());
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
}
CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
diff --git a/Source/core/rendering/RenderObject.h b/Source/core/rendering/RenderObject.h
index d85358c..85d43f1 100644
--- a/Source/core/rendering/RenderObject.h
+++ b/Source/core/rendering/RenderObject.h
@@ -28,7 +28,7 @@
#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/Element.h"
-#include "core/editing/TextAffinity.h"
+#include "core/dom/Position.h"
#include "core/loader/cache/CachedImageClient.h"
#include "core/platform/graphics/FloatQuad.h"
#include "core/platform/graphics/LayoutRect.h"
@@ -68,7 +68,6 @@
class RenderTable;
class RenderTheme;
class TransformState;
-class VisiblePosition;
struct PaintInfo;
@@ -301,20 +300,11 @@
static RenderObject* createObject(Element*, RenderStyle*);
- // Overloaded new operator. Derived classes must override operator new
- // in order to allocate out of the RenderArena.
- void* operator new(size_t, RenderArena*);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
-
-private:
- // The normal operator new is disallowed on all render objects.
- void* operator new(size_t) throw();
+ // RenderObjects are allocated out of the rendering partition.
+ void* operator new(size_t);
+ void operator delete(void*);
public:
- RenderArena* renderArena() const { return document()->renderArena(); }
-
bool isPseudoElement() const { return node() && node()->isPseudoElement(); }
virtual bool isBR() const { return false; }
@@ -682,6 +672,9 @@
/* This function performs a layout only if one is needed. */
void layoutIfNeeded() { if (needsLayout()) layout(); }
+ void forceLayout();
+ void forceChildLayout();
+
// used for element state updates that cannot be fixed with a
// repaint and do not need a relayout
virtual void updateFromElement() { }
@@ -695,9 +688,9 @@
virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
- VisiblePosition createVisiblePosition(int offset, EAffinity);
- VisiblePosition createVisiblePosition(const Position&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&);
+ PositionWithAffinity createPositionWithAffinity(int offset, EAffinity);
+ PositionWithAffinity createPositionWithAffinity(const Position&);
virtual void dirtyLinesFromChangedChild(RenderObject*);
@@ -1019,7 +1012,7 @@
void clearLayoutRootIfNeeded() const;
virtual void willBeDestroyed();
- void arenaDelete(RenderArena*, void* objectBase);
+ void postDestroy();
virtual bool canBeReplacedWithInlineRunIn() const;
@@ -1029,11 +1022,14 @@
void setDocumentForAnonymous(Document* document) { ASSERT(isAnonymous()); m_node = document; }
// Add hit-test rects for the render tree rooted at this node to the provided collection on a
- // per-RenderLayer basis. CurrentLayer must be the enclosing layer,
- // and layerOffset is the current offset within this layer. Subclass implementations will add
- // any offset for this renderer within it's container, so callers should provide only the
- // offset of the container within it's layer.
- virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const;
+ // per-RenderLayer basis.
+ // currentLayer must be the enclosing layer, and layerOffset is the current offset within
+ // this layer. Subclass implementations will add any offset for this renderer within it's
+ // container, so callers should provide only the offset of the container within it's layer.
+ // containerRect is a rect that has already been added for the currentLayer which is likely to
+ // be a container for child elements. Any rect wholly contained by containerRect can be
+ // skipped.
+ virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const;
// Add hit-test rects for this renderer only to the provided list. layerOffset is the offset
// of this renderer within the current layer that should be used for each result.
diff --git a/Source/core/rendering/RenderQuote.cpp b/Source/core/rendering/RenderQuote.cpp
index 461b9ed..22623c6 100644
--- a/Source/core/rendering/RenderQuote.cpp
+++ b/Source/core/rendering/RenderQuote.cpp
@@ -266,7 +266,7 @@
while (RenderObject* child = lastChild())
child->destroy();
- RenderTextFragment* fragment = new (renderArena()) RenderTextFragment(document(), m_text.impl());
+ RenderTextFragment* fragment = new RenderTextFragment(document(), m_text.impl());
fragment->setStyle(style());
addChild(fragment);
}
diff --git a/Source/core/rendering/RenderRegion.cpp b/Source/core/rendering/RenderRegion.cpp
index 1952abe..203d207 100644
--- a/Source/core/rendering/RenderRegion.cpp
+++ b/Source/core/rendering/RenderRegion.cpp
@@ -45,6 +45,7 @@
: RenderBlock(element)
, m_flowThread(flowThread)
, m_parentNamedFlowThread(0)
+ , m_computedAutoHeight(-1)
, m_isValid(false)
, m_hasCustomRegionStyle(false)
, m_hasAutoLogicalHeight(false)
@@ -60,9 +61,9 @@
LayoutUnit RenderRegion::pageLogicalHeight() const
{
ASSERT(m_flowThread);
- if (hasOverrideHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
+ if (hasComputedAutoHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
ASSERT(hasAutoLogicalHeight());
- return overrideLogicalContentHeight();
+ return computedAutoHeight();
}
return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWidth();
}
@@ -79,9 +80,9 @@
LayoutUnit RenderRegion::logicalHeightOfAllFlowThreadContent() const
{
ASSERT(m_flowThread);
- if (hasOverrideHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
+ if (hasComputedAutoHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
ASSERT(hasAutoLogicalHeight());
- return overrideLogicalContentHeight();
+ return computedAutoHeight();
}
return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWidth();
}
@@ -242,7 +243,7 @@
if (m_hasAutoLogicalHeight)
incrementAutoLogicalHeightCount();
else {
- clearOverrideLogicalContentHeight();
+ clearComputedAutoHeight();
decrementAutoLogicalHeightCount();
}
}
@@ -283,7 +284,7 @@
if (hasAutoLogicalHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
m_flowThread->invalidateRegions();
- clearOverrideLogicalContentHeight();
+ clearComputedAutoHeight();
return;
}
@@ -626,20 +627,22 @@
if (!hasAutoLogicalHeight())
return;
- // We want to update the logical height based on the computed override logical
- // content height only if the view is in the layout phase
- // in which all the auto logical height regions have their override logical height set.
+ // We want to update the logical height based on the computed auto-height
+ // only if the view is in the layout phase in which all the
+ // auto logical height regions have a computed auto-height.
if (!m_flowThread->inConstrainedLayoutPhase())
return;
// There may be regions with auto logical height that during the prerequisite layout phase
// did not have the chance to layout flow thread content. Because of that, these regions do not
- // have an overrideLogicalContentHeight computed and they will not be able to fragment any flow
+ // have a computedAutoHeight and they will not be able to fragment any flow
// thread content.
- if (!hasOverrideHeight())
+ if (!hasComputedAutoHeight())
return;
- LayoutUnit newLogicalHeight = overrideLogicalContentHeight() + borderAndPaddingLogicalHeight();
+ LayoutUnit autoHeight = hasOverrideHeight() ? overrideLogicalContentHeight() : computedAutoHeight();
+
+ LayoutUnit newLogicalHeight = autoHeight + borderAndPaddingLogicalHeight();
ASSERT(newLogicalHeight < LayoutUnit::max() / 2);
if (newLogicalHeight > logicalHeight())
setLogicalHeight(newLogicalHeight);
diff --git a/Source/core/rendering/RenderRegion.h b/Source/core/rendering/RenderRegion.h
index 2e5d431..052c059 100644
--- a/Source/core/rendering/RenderRegion.h
+++ b/Source/core/rendering/RenderRegion.h
@@ -108,6 +108,25 @@
bool hasAutoLogicalHeight() const { return m_hasAutoLogicalHeight; }
+ const LayoutUnit& computedAutoHeight() const
+ {
+ ASSERT(hasComputedAutoHeight());
+ return m_computedAutoHeight;
+ }
+
+ void setComputedAutoHeight(LayoutUnit computedAutoHeight)
+ {
+ ASSERT(computedAutoHeight >= 0);
+ m_computedAutoHeight = computedAutoHeight;
+ }
+
+ void clearComputedAutoHeight()
+ {
+ m_computedAutoHeight = -1;
+ }
+
+ bool hasComputedAutoHeight() const { return (m_computedAutoHeight >= 0); }
+
virtual void updateLogicalHeight() OVERRIDE;
// The top of the nearest page inside the region. For RenderRegions, this is just the logical top of the
@@ -189,6 +208,8 @@
typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap;
RenderObjectRegionStyleMap m_renderObjectRegionStyle;
+ LayoutUnit m_computedAutoHeight;
+
bool m_isValid : 1;
bool m_hasCustomRegionStyle : 1;
bool m_hasAutoLogicalHeight : 1;
diff --git a/Source/core/rendering/RenderReplaced.cpp b/Source/core/rendering/RenderReplaced.cpp
index 4f47b3d..ff3d191 100644
--- a/Source/core/rendering/RenderReplaced.cpp
+++ b/Source/core/rendering/RenderReplaced.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "core/rendering/RenderReplaced.h"
-#include "core/editing/VisiblePosition.h"
#include "core/platform/graphics/GraphicsContext.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderBlock.h"
@@ -465,7 +464,7 @@
setPreferredLogicalWidthsDirty(false);
}
-VisiblePosition RenderReplaced::positionForPoint(const LayoutPoint& point)
+PositionWithAffinity RenderReplaced::positionForPoint(const LayoutPoint& point)
{
// FIXME: This code is buggy if the replaced element is relative positioned.
InlineBox* box = inlineBoxWrapper();
@@ -478,15 +477,15 @@
LayoutUnit lineDirectionPosition = isHorizontalWritingMode() ? point.x() + x() : point.y() + y();
if (blockDirectionPosition < top)
- return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above
+ return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM); // coordinates are above
if (blockDirectionPosition >= bottom)
- return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); // coordinates are below
+ return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM); // coordinates are below
if (node()) {
if (lineDirectionPosition <= logicalLeft() + (logicalWidth() / 2))
- return createVisiblePosition(0, DOWNSTREAM);
- return createVisiblePosition(1, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
+ return createPositionWithAffinity(1, DOWNSTREAM);
}
return RenderBox::positionForPoint(point);
diff --git a/Source/core/rendering/RenderReplaced.h b/Source/core/rendering/RenderReplaced.h
index 43775ad..9b04219 100644
--- a/Source/core/rendering/RenderReplaced.h
+++ b/Source/core/rendering/RenderReplaced.h
@@ -77,7 +77,7 @@
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual VisiblePosition positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
virtual bool canBeSelectionLeaf() const { return true; }
diff --git a/Source/core/rendering/RenderReplica.cpp b/Source/core/rendering/RenderReplica.cpp
index c5831f6..3c6e78d 100644
--- a/Source/core/rendering/RenderReplica.cpp
+++ b/Source/core/rendering/RenderReplica.cpp
@@ -45,7 +45,7 @@
RenderReplica* RenderReplica::createAnonymous(Document* document)
{
- RenderReplica* renderer = new (document->renderArena()) RenderReplica();
+ RenderReplica* renderer = new RenderReplica();
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderRubyBase.cpp b/Source/core/rendering/RenderRubyBase.cpp
index 503a9f5..2de4aeb 100644
--- a/Source/core/rendering/RenderRubyBase.cpp
+++ b/Source/core/rendering/RenderRubyBase.cpp
@@ -49,7 +49,7 @@
RenderRubyBase* RenderRubyBase::createAnonymous(Document* document)
{
- RenderRubyBase* renderer = new (document->renderArena()) RenderRubyBase();
+ RenderRubyBase* renderer = new RenderRubyBase();
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderRubyRun.cpp b/Source/core/rendering/RenderRubyRun.cpp
index 5890d2a..80b4cbd 100644
--- a/Source/core/rendering/RenderRubyRun.cpp
+++ b/Source/core/rendering/RenderRubyRun.cpp
@@ -207,7 +207,7 @@
RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby)
{
ASSERT(parentRuby && parentRuby->isRuby());
- RenderRubyRun* rr = new (parentRuby->renderArena()) RenderRubyRun();
+ RenderRubyRun* rr = new RenderRubyRun();
rr->setDocumentForAnonymous(parentRuby->document());
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parentRuby->style(), INLINE_BLOCK);
rr->setStyle(newStyle.release());
diff --git a/Source/core/rendering/RenderScrollbarPart.cpp b/Source/core/rendering/RenderScrollbarPart.cpp
index 9d36cce..5d1dac3 100644
--- a/Source/core/rendering/RenderScrollbarPart.cpp
+++ b/Source/core/rendering/RenderScrollbarPart.cpp
@@ -48,7 +48,7 @@
RenderScrollbarPart* RenderScrollbarPart::createAnonymous(Document* document, RenderScrollbar* scrollbar, ScrollbarPart part)
{
- RenderScrollbarPart* renderer = new (document->renderArena()) RenderScrollbarPart(scrollbar, part);
+ RenderScrollbarPart* renderer = new RenderScrollbarPart(scrollbar, part);
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderTable.cpp b/Source/core/rendering/RenderTable.cpp
index aaea9fb..f086f2a 100644
--- a/Source/core/rendering/RenderTable.cpp
+++ b/Source/core/rendering/RenderTable.cpp
@@ -1421,7 +1421,7 @@
RenderTable* RenderTable::createAnonymousWithParentRenderer(const RenderObject* parent)
{
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), TABLE);
- RenderTable* newTable = new (parent->renderArena()) RenderTable(0);
+ RenderTable* newTable = new RenderTable(0);
newTable->setDocumentForAnonymous(parent->document());
newTable->setStyle(newStyle.release());
return newTable;
diff --git a/Source/core/rendering/RenderTableCell.cpp b/Source/core/rendering/RenderTableCell.cpp
index b612c20..44316f7 100644
--- a/Source/core/rendering/RenderTableCell.cpp
+++ b/Source/core/rendering/RenderTableCell.cpp
@@ -1251,7 +1251,7 @@
RenderTableCell* RenderTableCell::createAnonymous(Document* document)
{
- RenderTableCell* renderer = new (document->renderArena()) RenderTableCell(0);
+ RenderTableCell* renderer = new RenderTableCell(0);
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderTableRow.cpp b/Source/core/rendering/RenderTableRow.cpp
index 2584b37..f6831b2 100644
--- a/Source/core/rendering/RenderTableRow.cpp
+++ b/Source/core/rendering/RenderTableRow.cpp
@@ -267,7 +267,7 @@
RenderTableRow* RenderTableRow::createAnonymous(Document* document)
{
- RenderTableRow* renderer = new (document->renderArena()) RenderTableRow(0);
+ RenderTableRow* renderer = new RenderTableRow(0);
renderer->setDocumentForAnonymous(document);
return renderer;
}
diff --git a/Source/core/rendering/RenderTableSection.cpp b/Source/core/rendering/RenderTableSection.cpp
index 765b35e..7bd4433 100644
--- a/Source/core/rendering/RenderTableSection.cpp
+++ b/Source/core/rendering/RenderTableSection.cpp
@@ -369,12 +369,32 @@
extraRowSpanningHeight -= accumulatedPositionIncrease;
}
+// To avoid unneeded extra height distributions, we apply the following sorting algorithm:
+// 1. We sort by increasing start row but decreasing last row (ie the top-most, shortest cells first).
+// 2. For cells spanning the same rows, we sort by intrinsic size.
+static bool compareRowSpanCellsInHeightDistributionOrder(const RenderTableCell* cell2, const RenderTableCell* cell1)
+{
+ unsigned cellRowIndex1 = cell1->rowIndex();
+ unsigned cellRowSpan1 = cell1->rowSpan();
+ unsigned cellRowIndex2 = cell2->rowIndex();
+ unsigned cellRowSpan2 = cell2->rowSpan();
+
+ if (cellRowIndex1 == cellRowIndex2 && cellRowSpan1 == cellRowSpan2)
+ return (cell2->logicalHeightForRowSizing() > cell1->logicalHeightForRowSizing());
+
+ return (cellRowIndex2 >= cellRowIndex1 && (cellRowIndex2 + cellRowSpan2) <= (cellRowIndex1 + cellRowSpan1));
+}
+
// Distribute rowSpan cell height in rows those comes in rowSpan cell based on the ratio of row's height if
// 1. RowSpan cell height is greater then the total height of rows in rowSpan cell
void RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells& rowSpanCells)
{
ASSERT(rowSpanCells.size());
+ // 'rowSpanCells' list is already sorted based on the cells rowIndex in ascending order
+ // Arrange row spanning cell in the order in which we need to process first.
+ std::sort(rowSpanCells.begin(), rowSpanCells.end(), compareRowSpanCellsInHeightDistributionOrder);
+
unsigned extraHeightToPropagate = 0;
unsigned lastRowIndex = 0;
unsigned lastRowSpan = 0;
@@ -384,12 +404,13 @@
unsigned rowIndex = cell->rowIndex();
- // FIXME: For now, we are handling only rowspan cells those are not overlapping with other
- // rowspan cells but this is wrong.
- if (rowIndex < lastRowIndex + lastRowSpan)
+ unsigned rowSpan = cell->rowSpan();
+
+ // Only heightest spanning cell will distribute it's extra height in row if more then one spanning cells
+ // present at same level.
+ if (rowIndex == lastRowIndex && rowSpan == lastRowSpan)
continue;
- unsigned rowSpan = cell->rowSpan();
int originalBeforePosition = m_rowPos[rowIndex + rowSpan];
if (extraHeightToPropagate) {
@@ -411,6 +432,9 @@
int totalAutoRowsHeight = 0;
int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight;
+ // FIXME: Inner spanning cell height should not change if it have fixed height when it's parent spanning cell
+ // is distributing it's extra height in rows.
+
// Calculate total percentage, total auto rows height and total rows height except percent rows.
for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
if (m_grid[row].logicalHeight.isPercent()) {
@@ -525,8 +549,7 @@
}
cell->clearIntrinsicPadding();
cell->clearOverrideSize();
- cell->setChildNeedsLayout(true, MarkOnlyThis);
- cell->layoutIfNeeded();
+ cell->forceChildLayout();
}
if (RuntimeEnabledFeatures::rowSpanLogicalHeightSpreadingEnabled()) {
@@ -792,12 +815,11 @@
}
if (cellChildrenFlex) {
- cell->setChildNeedsLayout(true, MarkOnlyThis);
// Alignment within a cell is based off the calculated
// height, which becomes irrelevant once the cell has
// been resized based off its percentage.
cell->setOverrideLogicalContentHeightFromRowHeight(rHeight);
- cell->layoutIfNeeded();
+ cell->forceChildLayout();
// If the baseline moved, we may have to update the data for our row. Find out the new baseline.
if (cell->isBaselineAligned()) {
@@ -1635,7 +1657,7 @@
RenderTableSection* RenderTableSection::createAnonymousWithParentRenderer(const RenderObject* parent)
{
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), TABLE_ROW_GROUP);
- RenderTableSection* newSection = new (parent->renderArena()) RenderTableSection(0);
+ RenderTableSection* newSection = new RenderTableSection(0);
newSection->setDocumentForAnonymous(parent->document());
newSection->setStyle(newStyle.release());
return newSection;
diff --git a/Source/core/rendering/RenderText.cpp b/Source/core/rendering/RenderText.cpp
index cf91399..94a73bf 100644
--- a/Source/core/rendering/RenderText.cpp
+++ b/Source/core/rendering/RenderText.cpp
@@ -27,12 +27,10 @@
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Text.h"
-#include "core/editing/VisiblePosition.h"
#include "core/loader/TextResourceDecoder.h"
#include "core/page/FrameView.h"
#include "core/page/Settings.h"
#include "core/platform/graphics/FloatQuad.h"
-#include "core/platform/text/Hyphenation.h"
#include "core/platform/text/TextBreakIterator.h"
#include "core/platform/text/transcoder/FontTranscoder.h"
#include "core/rendering/EllipsisBox.h"
@@ -298,11 +296,10 @@
void RenderText::deleteTextBoxes()
{
if (firstTextBox()) {
- RenderArena* arena = renderArena();
InlineTextBox* next;
for (InlineTextBox* curr = firstTextBox(); curr; curr = next) {
next = curr->nextTextBox();
- curr->destroy(arena);
+ curr->destroy();
}
m_firstTextBox = m_lastTextBox = 0;
}
@@ -517,7 +514,7 @@
return false;
}
-static VisiblePosition createVisiblePositionForBox(const InlineBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
+static PositionWithAffinity createPositionWithAffinityForBox(const InlineBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
{
EAffinity affinity = VP_DEFAULT_AFFINITY;
switch (shouldAffinityBeDownstream) {
@@ -531,17 +528,17 @@
affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM;
break;
}
- return box->renderer()->createVisiblePosition(offset, affinity);
+ return box->renderer()->createPositionWithAffinity(offset, affinity);
}
-static VisiblePosition createVisiblePositionAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
+static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
{
ASSERT(box);
ASSERT(box->renderer());
ASSERT(offset >= 0);
if (offset && static_cast<unsigned>(offset) < box->len())
- return createVisiblePositionForBox(box, box->start() + offset, shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(box, box->start() + offset, shouldAffinityBeDownstream);
bool positionIsAtStartOfBox = !offset;
if (positionIsAtStartOfBox == box->isLeftToRightDirection()) {
@@ -550,7 +547,7 @@
const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak();
if ((prevBox && prevBox->bidiLevel() == box->bidiLevel())
|| box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
- return createVisiblePositionForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) {
// e.g. left of B in aDC12BAb
@@ -559,7 +556,7 @@
leftmostBox = prevBox;
prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
} while (prevBox && prevBox->bidiLevel() > box->bidiLevel());
- return createVisiblePositionForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream);
}
if (!prevBox || prevBox->bidiLevel() < box->bidiLevel()) {
@@ -570,17 +567,17 @@
rightmostBox = nextBox;
nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
} while (nextBox && nextBox->bidiLevel() >= box->bidiLevel());
- return createVisiblePositionForBox(rightmostBox,
+ return createPositionWithAffinityForBox(rightmostBox,
box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream);
}
- return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
}
const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak();
if ((nextBox && nextBox->bidiLevel() == box->bidiLevel())
|| box->renderer()->containingBlock()->style()->direction() == box->direction())
- return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
// offset is on the right edge
if (nextBox && nextBox->bidiLevel() > box->bidiLevel()) {
@@ -590,7 +587,7 @@
rightmostBox = nextBox;
nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
} while (nextBox && nextBox->bidiLevel() > box->bidiLevel());
- return createVisiblePositionForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream);
}
if (!nextBox || nextBox->bidiLevel() < box->bidiLevel()) {
@@ -601,17 +598,17 @@
leftmostBox = prevBox;
prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
} while (prevBox && prevBox->bidiLevel() >= box->bidiLevel());
- return createVisiblePositionForBox(leftmostBox,
+ return createPositionWithAffinityForBox(leftmostBox,
box->isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream);
}
- return createVisiblePositionForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
}
-VisiblePosition RenderText::positionForPoint(const LayoutPoint& point)
+PositionWithAffinity RenderText::positionForPoint(const LayoutPoint& point)
{
if (!firstTextBox() || textLength() == 0)
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y();
LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x();
@@ -632,7 +629,7 @@
if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream))
- return createVisiblePositionAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
}
}
lastBox = box;
@@ -641,9 +638,9 @@
if (lastBox) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream);
- return createVisiblePositionAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
}
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
}
LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
@@ -889,50 +886,6 @@
return font.width(RenderBlock::constructTextRun(renderer, font, style->hyphenString().string(), style));
}
-static float maxWordFragmentWidth(RenderText* renderer, RenderStyle* style, const Font& font, int wordOffset, int wordLength, int minimumPrefixLength, int minimumSuffixLength, int& suffixStart)
-{
- suffixStart = 0;
- if (wordLength <= minimumSuffixLength)
- return 0;
-
- Vector<int, 8> hyphenLocations;
- int hyphenLocation = wordLength - minimumSuffixLength;
- String word = renderer->substring(wordOffset, wordLength);
- while ((hyphenLocation = lastHyphenLocation(word, hyphenLocation, style->locale())) >= minimumPrefixLength)
- hyphenLocations.append(hyphenLocation);
-
- if (hyphenLocations.isEmpty())
- return 0;
-
- hyphenLocations.reverse();
-
- float minimumFragmentWidthToConsider = font.pixelSize() * 5 / 4 + hyphenWidth(renderer, font);
- float maxFragmentWidth = 0;
- for (size_t k = 0; k < hyphenLocations.size(); ++k) {
- int fragmentLength = hyphenLocations[k] - suffixStart;
- StringBuilder fragmentWithHyphen;
- if (renderer->is8Bit())
- fragmentWithHyphen.append(renderer->characters8() + wordOffset + suffixStart, fragmentLength);
- else
- fragmentWithHyphen.append(renderer->characters16() + wordOffset + suffixStart, fragmentLength);
- fragmentWithHyphen.append(style->hyphenString());
-
- TextRun run = RenderBlock::constructTextRun(renderer, font, fragmentWithHyphen.toString(), style);
- run.setCharactersLength(fragmentWithHyphen.length());
- run.setCharacterScanForCodePath(!renderer->canUseSimpleFontCodePath());
- float fragmentWidth = font.width(run);
-
- // Narrow prefixes are ignored. See tryHyphenating in RenderBlockLineLayout.cpp.
- if (fragmentWidth <= minimumFragmentWidthToConsider)
- continue;
-
- suffixStart += fragmentLength;
- maxFragmentWidth = max(maxFragmentWidth, fragmentWidth);
- }
-
- return maxFragmentWidth;
-}
-
void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
{
ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts);
@@ -976,19 +929,6 @@
float maxWordWidth = numeric_limits<float>::max();
int minimumPrefixLength = 0;
int minimumSuffixLength = 0;
- if (styleToUse->hyphens() == HyphensAuto && canHyphenate(styleToUse->locale())) {
- maxWordWidth = 0;
-
- // Map 'hyphenate-limit-{before,after}: auto;' to 2.
- minimumPrefixLength = styleToUse->hyphenationLimitBefore();
- if (minimumPrefixLength < 0)
- minimumPrefixLength = 2;
-
- minimumSuffixLength = styleToUse->hyphenationLimitAfter();
- if (minimumSuffixLength < 0)
- minimumSuffixLength = 2;
- }
-
int firstGlyphLeftOverflow = -1;
bool breakAll = (styleToUse->wordBreak() == BreakAllWordBreak || styleToUse->wordBreak() == BreakWordBreak) && styleToUse->autoWrap();
@@ -1034,7 +974,7 @@
ASSERT(lastWordBoundary == i);
lastWordBoundary++;
continue;
- } else if (c == softHyphen && styleToUse->hyphens() != HyphensNone) {
+ } else if (c == softHyphen) {
currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
if (firstGlyphLeftOverflow < 0)
firstGlyphLeftOverflow = glyphOverflow.left;
@@ -1045,7 +985,7 @@
bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable);
bool betweenWords = true;
int j = i;
- while (c != '\n' && c != ' ' && c != '\t' && (c != softHyphen || styleToUse->hyphens() == HyphensNone)) {
+ while (c != '\n' && c != ' ' && c != '\t' && (c != softHyphen)) {
j++;
if (j == len)
break;
@@ -1066,28 +1006,11 @@
w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth;
else {
w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
- if (c == softHyphen && styleToUse->hyphens() != HyphensNone)
+ if (c == softHyphen)
currMinWidth += hyphenWidth(this, f);
}
- if (w > maxWordWidth) {
- int suffixStart;
- float maxFragmentWidth = maxWordFragmentWidth(this, styleToUse, f, i, wordLen, minimumPrefixLength, minimumSuffixLength, suffixStart);
-
- if (suffixStart) {
- float suffixWidth;
- if (wordTrailingSpaceWidth && isSpace)
- suffixWidth = widthFromCache(f, i + suffixStart, wordLen - suffixStart + 1, leadWidth + currMaxWidth, 0, 0) - wordTrailingSpaceWidth;
- else
- suffixWidth = widthFromCache(f, i + suffixStart, wordLen - suffixStart, leadWidth + currMaxWidth, 0, 0);
-
- maxFragmentWidth = max(maxFragmentWidth, suffixWidth);
-
- currMinWidth += maxFragmentWidth - w;
- maxWordWidth = max(maxWordWidth, maxFragmentWidth);
- } else
- maxWordWidth = w;
- }
+ maxWordWidth = max(maxWordWidth, w);
if (firstGlyphLeftOverflow < 0)
firstGlyphLeftOverflow = glyphOverflow.left;
@@ -1372,7 +1295,7 @@
return prev;
}
-void RenderText::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const
+void RenderText::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
{
// Text nodes aren't event targets, so don't descend any further.
}
@@ -1496,7 +1419,7 @@
InlineTextBox* RenderText::createTextBox()
{
- return new (renderArena()) InlineTextBox(this);
+ return new InlineTextBox(this);
}
InlineTextBox* RenderText::createInlineTextBox()
@@ -1529,7 +1452,7 @@
m_lastTextBox = s->prevTextBox();
else
s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
- s->destroy(renderArena());
+ s->destroy();
return;
}
diff --git a/Source/core/rendering/RenderText.h b/Source/core/rendering/RenderText.h
index 4aa1d4c..7579704 100644
--- a/Source/core/rendering/RenderText.h
+++ b/Source/core/rendering/RenderText.h
@@ -67,7 +67,7 @@
enum ClippingOption { NoClipping, ClipToEllipsis };
void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed = 0, ClippingOption = NoClipping) const;
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
bool is8Bit() const { return m_text.is8Bit(); }
const LChar* characters8() const { return m_text.impl()->characters8(); }
@@ -152,7 +152,7 @@
virtual void setTextInternal(PassRefPtr<StringImpl>);
virtual UChar previousCharacter() const;
- virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const OVERRIDE;
+ virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE;
virtual InlineTextBox* createTextBox(); // Subclassed by SVG.
diff --git a/Source/core/rendering/RenderView.cpp b/Source/core/rendering/RenderView.cpp
index 8bfcbf2..12b102b 100644
--- a/Source/core/rendering/RenderView.cpp
+++ b/Source/core/rendering/RenderView.cpp
@@ -216,7 +216,7 @@
// inner flows have the necessary information to correctly fragment the content.
// 2. The flows are laid out from the inner flow to the outer flow. After an inner flow is laid out it goes into the constrained layout phase
// and marks the auto-height regions they need layout. This means the outer flows will relayout if they depend on regions with auto-height regions
-// belonging to inner flows. This step will correctly compute the overrideLogicalHeights for the auto-height regions. It's possible for non-auto-height
+// belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height
// regions to relayout if they depend on auto-height regions. This will invalidate the inner flow threads and mark them as needing layout.
// 3. The last step is to do one last layout if there are pathological dependencies between non-auto-height regions and auto-height regions
// as detected in the previous step.
@@ -893,7 +893,7 @@
size_t size = renderWidgets.size();
for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->deref(renderArena());
+ renderWidgets[i]->deref();
}
void RenderView::updateWidgetPositions()
@@ -1015,7 +1015,7 @@
ASSERT(m_layoutStateDisableCount == 0);
ASSERT(m_layoutState == 0);
- m_layoutState = new (renderArena()) LayoutState(root);
+ m_layoutState = new LayoutState(root);
}
bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
diff --git a/Source/core/rendering/RenderView.h b/Source/core/rendering/RenderView.h
index 33846ef..80061e0 100644
--- a/Source/core/rendering/RenderView.h
+++ b/Source/core/rendering/RenderView.h
@@ -225,7 +225,7 @@
|| (renderer->isRenderBlock() && toRenderBlock(renderer)->shapeInsideInfo())
|| (m_layoutState->shapeInsideInfo() && renderer->isRenderBlock() && !toRenderBlock(renderer)->allowsShapeInsideInfoSharing())
) {
- m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
+ m_layoutState = new LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
return true;
}
return false;
@@ -235,7 +235,7 @@
{
LayoutState* state = m_layoutState;
m_layoutState = state->m_next;
- state->destroy(renderArena());
+ delete state;
}
// Suspends the LayoutState optimization. Used under transforms that cannot be represented by
diff --git a/Source/core/rendering/RenderWidget.cpp b/Source/core/rendering/RenderWidget.cpp
index 99e30dd..2c8d271 100644
--- a/Source/core/rendering/RenderWidget.cpp
+++ b/Source/core/rendering/RenderWidget.cpp
@@ -31,7 +31,6 @@
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderLayerBacking.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidgetProtector.h"
using namespace std;
@@ -111,12 +110,8 @@
void RenderWidget::destroy()
{
willBeDestroyed();
-
- // Grab the arena from node()->document()->renderArena() before clearing the node pointer.
- // Clear the node before deref-ing, as this may be deleted when deref is called.
- RenderArena* arena = renderArena();
clearNode();
- deref(arena);
+ deref();
}
RenderWidget::~RenderWidget()
@@ -148,7 +143,7 @@
m_clipRect = clipRect;
- RenderWidgetProtector protector(this);
+ RefPtr<RenderWidget> protector(this);
RefPtr<Node> protectedNode(node());
m_widget->setFrameRect(newFrame);
@@ -318,10 +313,10 @@
toFrameView(m_widget.get())->setIsOverlapped(isOverlapped);
}
-void RenderWidget::deref(RenderArena *arena)
+void RenderWidget::deref()
{
if (--m_refCount <= 0)
- arenaDelete(arena, this);
+ postDestroy();
}
void RenderWidget::updateWidgetPosition()
diff --git a/Source/core/rendering/RenderWidget.h b/Source/core/rendering/RenderWidget.h
index 3f4e572..3e4eeb2 100644
--- a/Source/core/rendering/RenderWidget.h
+++ b/Source/core/rendering/RenderWidget.h
@@ -67,8 +67,8 @@
void widgetPositionsUpdated();
IntRect windowClipRect() const;
- RenderArena* ref() { ++m_refCount; return renderArena(); }
- void deref(RenderArena*);
+ void ref() { ++m_refCount; }
+ void deref();
protected:
RenderWidget(Element*);
diff --git a/Source/core/rendering/RenderWidgetProtector.h b/Source/core/rendering/RenderWidgetProtector.h
deleted file mode 100644
index 2a65ab4..0000000
--- a/Source/core/rendering/RenderWidgetProtector.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RenderWidgetProtector_h
-#define RenderWidgetProtector_h
-
-#include "core/rendering/RenderWidget.h"
-
-namespace WebCore {
-
-class RenderWidgetProtector {
- WTF_MAKE_NONCOPYABLE(RenderWidgetProtector);
-public:
- explicit RenderWidgetProtector(RenderWidget* object)
- : m_object(object)
- , m_arena(object->ref())
- {
- }
-
- ~RenderWidgetProtector()
- {
- m_object->deref(m_arena);
- }
-
-private:
- RenderWidget* m_object;
- RenderArena* m_arena;
-};
-
-}
-
-#endif // RenderWidgetProtector_h
diff --git a/Source/core/rendering/RootInlineBox.cpp b/Source/core/rendering/RootInlineBox.cpp
index fa1def2..bd816bb 100644
--- a/Source/core/rendering/RootInlineBox.cpp
+++ b/Source/core/rendering/RootInlineBox.cpp
@@ -31,7 +31,6 @@
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderArena.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderView.h"
@@ -65,18 +64,18 @@
}
-void RootInlineBox::destroy(RenderArena* arena)
+void RootInlineBox::destroy()
{
- detachEllipsisBox(arena);
- InlineFlowBox::destroy(arena);
+ detachEllipsisBox();
+ InlineFlowBox::destroy();
}
-void RootInlineBox::detachEllipsisBox(RenderArena* arena)
+void RootInlineBox::detachEllipsisBox()
{
if (hasEllipsisBox()) {
EllipsisBox* box = gEllipsisBoxMap->take(this);
box->setParent(0);
- box->destroy(arena);
+ box->destroy();
setHasEllipsisBox(false);
}
}
@@ -89,7 +88,7 @@
void RootInlineBox::clearTruncation()
{
if (hasEllipsisBox()) {
- detachEllipsisBox(renderer()->renderArena());
+ detachEllipsisBox();
InlineFlowBox::clearTruncation();
}
}
@@ -132,9 +131,9 @@
InlineBox* markupBox)
{
// Create an ellipsis box.
- EllipsisBox* ellipsisBox = new (renderer()->renderArena()) EllipsisBox(renderer(), ellipsisStr, this,
- ellipsisWidth - (markupBox ? markupBox->logicalWidth() : 0), logicalHeight(),
- y(), !prevRootBox(), isHorizontal(), markupBox);
+ EllipsisBox* ellipsisBox = new EllipsisBox(renderer(), ellipsisStr, this,
+ ellipsisWidth - (markupBox ? markupBox->logicalWidth() : 0), logicalHeight(),
+ y(), !prevRootBox(), isHorizontal(), markupBox);
if (!gEllipsisBoxMap)
gEllipsisBoxMap = new EllipsisBoxMap();
diff --git a/Source/core/rendering/RootInlineBox.h b/Source/core/rendering/RootInlineBox.h
index 5cf5e68..f6ddc5f 100644
--- a/Source/core/rendering/RootInlineBox.h
+++ b/Source/core/rendering/RootInlineBox.h
@@ -37,11 +37,11 @@
public:
explicit RootInlineBox(RenderBlock*);
- virtual void destroy(RenderArena*) OVERRIDE FINAL;
+ virtual void destroy() OVERRIDE FINAL;
virtual bool isRootInlineBox() const OVERRIDE FINAL { return true; }
- void detachEllipsisBox(RenderArena*);
+ void detachEllipsisBox();
RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLineBox); }
RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLineBox); }
diff --git a/Source/core/rendering/style/ContentData.cpp b/Source/core/rendering/style/ContentData.cpp
index dd052ba..828568f 100644
--- a/Source/core/rendering/style/ContentData.cpp
+++ b/Source/core/rendering/style/ContentData.cpp
@@ -79,21 +79,21 @@
RenderObject* TextContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const
{
- RenderObject* renderer = new (doc->renderArena()) RenderTextFragment(doc, m_text.impl());
+ RenderObject* renderer = new RenderTextFragment(doc, m_text.impl());
renderer->setPseudoStyle(pseudoStyle);
return renderer;
}
RenderObject* CounterContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const
{
- RenderObject* renderer = new (doc->renderArena()) RenderCounter(doc, *m_counter);
+ RenderObject* renderer = new RenderCounter(doc, *m_counter);
renderer->setPseudoStyle(pseudoStyle);
return renderer;
}
RenderObject* QuoteContentData::createRenderer(Document* doc, RenderStyle* pseudoStyle) const
{
- RenderObject* renderer = new (doc->renderArena()) RenderQuote(doc, m_quote);
+ RenderObject* renderer = new RenderQuote(doc, m_quote);
renderer->setPseudoStyle(pseudoStyle);
return renderer;
}
diff --git a/Source/core/rendering/style/FillLayer.cpp b/Source/core/rendering/style/FillLayer.cpp
index 0a3cf36..e93d0a1 100644
--- a/Source/core/rendering/style/FillLayer.cpp
+++ b/Source/core/rendering/style/FillLayer.cpp
@@ -351,6 +351,9 @@
if (m_composite == CompositeClear || m_composite == CompositeCopy)
return true;
+ if (m_blendMode != BlendModeNormal)
+ return false;
+
if (m_composite == CompositeSourceOver)
return m_image->knownToBeOpaque(renderer);
diff --git a/Source/core/rendering/style/GridCoordinate.h b/Source/core/rendering/style/GridCoordinate.h
index a55b7fb..ec0d890 100644
--- a/Source/core/rendering/style/GridCoordinate.h
+++ b/Source/core/rendering/style/GridCoordinate.h
@@ -31,7 +31,9 @@
#ifndef GridCoordinate_h
#define GridCoordinate_h
+#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -51,6 +53,11 @@
ASSERT(initialPositionIndex <= finalPositionIndex);
}
+ bool operator==(const GridSpan& o) const
+ {
+ return initialPositionIndex == o.initialPositionIndex && finalPositionIndex == o.finalPositionIndex;
+ }
+
size_t initialPositionIndex;
size_t finalPositionIndex;
};
@@ -70,10 +77,22 @@
{
}
+ bool operator==(const GridCoordinate& o) const
+ {
+ return columns == o.columns && rows == o.rows;
+ }
+
+ bool operator!=(const GridCoordinate& o) const
+ {
+ return !(*this == o);
+ }
+
GridSpan columns;
GridSpan rows;
};
+typedef HashMap<String, GridCoordinate> NamedGridAreaMap;
+
} // namespace WebCore
#endif // GridCoordinate_h
diff --git a/Source/core/rendering/style/KeyframeList.cpp b/Source/core/rendering/style/KeyframeList.cpp
index 634699e..9d20a1c 100644
--- a/Source/core/rendering/style/KeyframeList.cpp
+++ b/Source/core/rendering/style/KeyframeList.cpp
@@ -20,11 +20,27 @@
*/
#include "config.h"
-#include "core/rendering/RenderObject.h"
#include "core/rendering/style/KeyframeList.h"
+#include "core/css/StylePropertySet.h"
+#include "core/rendering/RenderObject.h"
+
namespace WebCore {
+void KeyframeValue::addProperties(const StylePropertySet* propertySet)
+{
+ if (!propertySet)
+ return;
+ unsigned propertyCount = propertySet->propertyCount();
+ for (unsigned i = 0; i < propertyCount; ++i) {
+ CSSPropertyID property = propertySet->propertyAt(i).id();
+ // Timing-function within keyframes is special, because it is not animated; it just
+ // describes the timing function between this keyframe and the next.
+ if (property != CSSPropertyWebkitAnimationTimingFunction)
+ addProperty(property);
+ }
+}
+
KeyframeList::~KeyframeList()
{
clear();
diff --git a/Source/core/rendering/style/KeyframeList.h b/Source/core/rendering/style/KeyframeList.h
index adab92f..5a5cf92 100644
--- a/Source/core/rendering/style/KeyframeList.h
+++ b/Source/core/rendering/style/KeyframeList.h
@@ -36,6 +36,7 @@
class RenderObject;
class RenderStyle;
+class StylePropertySet;
class KeyframeValue {
public:
@@ -45,6 +46,7 @@
{
}
+ void addProperties(const StylePropertySet*);
void addProperty(CSSPropertyID prop) { m_properties.add(prop); }
bool containsProperty(CSSPropertyID prop) const { return m_properties.contains(prop); }
const HashSet<CSSPropertyID>& properties() const { return m_properties; }
diff --git a/Source/core/rendering/style/RenderStyle.cpp b/Source/core/rendering/style/RenderStyle.cpp
index 2e89c6a..929b894 100644
--- a/Source/core/rendering/style/RenderStyle.cpp
+++ b/Source/core/rendering/style/RenderStyle.cpp
@@ -1006,8 +1006,6 @@
const AtomicString& RenderStyle::hyphenString() const
{
- ASSERT(hyphens() != HyphensNone);
-
const AtomicString& hyphenationString = rareInheritedData.get()->hyphenationString;
if (!hyphenationString.isNull())
return hyphenationString;
diff --git a/Source/core/rendering/style/RenderStyle.h b/Source/core/rendering/style/RenderStyle.h
index 286ea49..b4c6a66 100644
--- a/Source/core/rendering/style/RenderStyle.h
+++ b/Source/core/rendering/style/RenderStyle.h
@@ -737,6 +737,9 @@
const Vector<GridTrackSize>& gridDefinitionRows() const { return rareNonInheritedData->m_grid->m_gridDefinitionRows; }
const NamedGridLinesMap& namedGridColumnLines() const { return rareNonInheritedData->m_grid->m_namedGridColumnLines; }
const NamedGridLinesMap& namedGridRowLines() const { return rareNonInheritedData->m_grid->m_namedGridRowLines; }
+ const NamedGridAreaMap& namedGridArea() const { return rareNonInheritedData->m_grid->m_namedGridArea; }
+ size_t namedGridAreaRowCount() const { return rareNonInheritedData->m_grid->m_namedGridAreaRowCount; }
+ size_t namedGridAreaColumnCount() const { return rareNonInheritedData->m_grid->m_namedGridAreaColumnCount; }
GridAutoFlow gridAutoFlow() const { return rareNonInheritedData->m_grid->m_gridAutoFlow; }
const GridTrackSize& gridAutoColumns() const { return rareNonInheritedData->m_grid->m_gridAutoColumns; }
const GridTrackSize& gridAutoRows() const { return rareNonInheritedData->m_grid->m_gridAutoRows; }
@@ -772,10 +775,6 @@
EOverflowWrap overflowWrap() const { return static_cast<EOverflowWrap>(rareInheritedData->overflowWrap); }
LineBreak lineBreak() const { return static_cast<LineBreak>(rareInheritedData->lineBreak); }
const AtomicString& highlight() const { return rareInheritedData->highlight; }
- Hyphens hyphens() const { return static_cast<Hyphens>(rareInheritedData->hyphens); }
- short hyphenationLimitBefore() const { return rareInheritedData->hyphenationLimitBefore; }
- short hyphenationLimitAfter() const { return rareInheritedData->hyphenationLimitAfter; }
- short hyphenationLimitLines() const { return rareInheritedData->hyphenationLimitLines; }
const AtomicString& hyphenationString() const { return rareInheritedData->hyphenationString; }
const AtomicString& locale() const { return rareInheritedData->locale; }
EBorderFit borderFit() const { return static_cast<EBorderFit>(rareNonInheritedData->m_borderFit); }
@@ -1187,6 +1186,9 @@
void setGridDefinitionRows(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridDefinitionRows, lengths); }
void setNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridColumnLines, namedGridColumnLines); }
void setNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridRowLines, namedGridRowLines); }
+ void setNamedGridArea(const NamedGridAreaMap& namedGridArea) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridArea, namedGridArea); }
+ void setNamedGridAreaRowCount(size_t rowCount) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridAreaRowCount, rowCount); }
+ void setNamedGridAreaColumnCount(size_t columnCount) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridAreaColumnCount, columnCount); }
void setGridAutoFlow(GridAutoFlow flow) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoFlow, flow); }
void setGridColumnStart(const GridPosition& columnStartPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridColumnStart, columnStartPosition); }
@@ -1210,9 +1212,6 @@
void setLineBreak(LineBreak b) { SET_VAR(rareInheritedData, lineBreak, b); }
void setHighlight(const AtomicString& h) { SET_VAR(rareInheritedData, highlight, h); }
void setHyphens(Hyphens h) { SET_VAR(rareInheritedData, hyphens, h); }
- void setHyphenationLimitBefore(short limit) { SET_VAR(rareInheritedData, hyphenationLimitBefore, limit); }
- void setHyphenationLimitAfter(short limit) { SET_VAR(rareInheritedData, hyphenationLimitAfter, limit); }
- void setHyphenationLimitLines(short limit) { SET_VAR(rareInheritedData, hyphenationLimitLines, limit); }
void setHyphenationString(const AtomicString& h) { SET_VAR(rareInheritedData, hyphenationString, h); }
void setLocale(const AtomicString& locale) { SET_VAR(rareInheritedData, locale, locale); }
void setBorderFit(EBorderFit b) { SET_VAR(rareNonInheritedData, m_borderFit, b); }
@@ -1539,10 +1538,6 @@
static LineBreak initialLineBreak() { return LineBreakAuto; }
static const AtomicString& initialHighlight() { return nullAtom; }
static ESpeak initialSpeak() { return SpeakNormal; }
- static Hyphens initialHyphens() { return HyphensManual; }
- static short initialHyphenationLimitBefore() { return -1; }
- static short initialHyphenationLimitAfter() { return -1; }
- static short initialHyphenationLimitLines() { return -1; }
static const AtomicString& initialHyphenationString() { return nullAtom; }
static const AtomicString& initialLocale() { return nullAtom; }
static EBorderFit initialBorderFit() { return BorderFitBorder; }
@@ -1595,6 +1590,9 @@
static NamedGridLinesMap initialNamedGridColumnLines() { return NamedGridLinesMap(); }
static NamedGridLinesMap initialNamedGridRowLines() { return NamedGridLinesMap(); }
+ static NamedGridAreaMap initialNamedGridArea() { return NamedGridAreaMap(); }
+ static size_t initialNamedGridAreaCount() { return 0; }
+
// 'auto' is the default.
static GridPosition initialGridColumnStart() { return GridPosition(); }
static GridPosition initialGridColumnEnd() { return GridPosition(); }
diff --git a/Source/core/rendering/style/StyleGridData.cpp b/Source/core/rendering/style/StyleGridData.cpp
index 5a11326..8ecde3c 100644
--- a/Source/core/rendering/style/StyleGridData.cpp
+++ b/Source/core/rendering/style/StyleGridData.cpp
@@ -33,11 +33,14 @@
StyleGridData::StyleGridData()
: m_gridDefinitionColumns(RenderStyle::initialGridDefinitionColumns())
, m_gridDefinitionRows(RenderStyle::initialGridDefinitionRows())
+ , m_namedGridColumnLines(RenderStyle::initialNamedGridColumnLines())
+ , m_namedGridRowLines(RenderStyle::initialNamedGridRowLines())
, m_gridAutoFlow(RenderStyle::initialGridAutoFlow())
, m_gridAutoRows(RenderStyle::initialGridAutoRows())
, m_gridAutoColumns(RenderStyle::initialGridAutoColumns())
- , m_namedGridColumnLines(RenderStyle::initialNamedGridColumnLines())
- , m_namedGridRowLines(RenderStyle::initialNamedGridRowLines())
+ , m_namedGridArea(RenderStyle::initialNamedGridArea())
+ , m_namedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount())
+ , m_namedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount())
{
}
@@ -50,6 +53,9 @@
, m_gridAutoFlow(o.m_gridAutoFlow)
, m_gridAutoRows(o.m_gridAutoRows)
, m_gridAutoColumns(o.m_gridAutoColumns)
+ , m_namedGridArea(o.m_namedGridArea)
+ , m_namedGridAreaRowCount(o.m_namedGridAreaRowCount)
+ , m_namedGridAreaColumnCount(o.m_namedGridAreaColumnCount)
{
}
diff --git a/Source/core/rendering/style/StyleGridData.h b/Source/core/rendering/style/StyleGridData.h
index 96f1ca5..21d9b01 100644
--- a/Source/core/rendering/style/StyleGridData.h
+++ b/Source/core/rendering/style/StyleGridData.h
@@ -26,6 +26,7 @@
#ifndef StyleGridData_h
#define StyleGridData_h
+#include "core/rendering/style/GridCoordinate.h"
#include "core/rendering/style/GridTrackSize.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "wtf/PassRefPtr.h"
@@ -44,7 +45,7 @@
bool operator==(const StyleGridData& o) const
{
- return m_gridDefinitionColumns == o.m_gridDefinitionColumns && m_gridDefinitionRows == o.m_gridDefinitionRows && m_gridAutoFlow == o.m_gridAutoFlow && m_gridAutoRows == o.m_gridAutoRows && m_gridAutoColumns == o.m_gridAutoColumns && m_namedGridColumnLines == o.m_namedGridColumnLines && m_namedGridRowLines == o.m_namedGridRowLines;
+ return m_gridDefinitionColumns == o.m_gridDefinitionColumns && m_gridDefinitionRows == o.m_gridDefinitionRows && m_gridAutoFlow == o.m_gridAutoFlow && m_gridAutoRows == o.m_gridAutoRows && m_gridAutoColumns == o.m_gridAutoColumns && m_namedGridColumnLines == o.m_namedGridColumnLines && m_namedGridRowLines == o.m_namedGridRowLines && m_namedGridArea == o.m_namedGridArea && m_namedGridArea == o.m_namedGridArea && m_namedGridAreaRowCount == o.m_namedGridAreaRowCount && m_namedGridAreaColumnCount == o.m_namedGridAreaColumnCount;
}
bool operator!=(const StyleGridData& o) const
@@ -63,6 +64,12 @@
GridTrackSize m_gridAutoRows;
GridTrackSize m_gridAutoColumns;
+ NamedGridAreaMap m_namedGridArea;
+ // Because m_namedGridArea doesn't store the unnamed grid areas, we need to keep track
+ // of the explicit grid size defined by both named and unnamed grid areas.
+ size_t m_namedGridAreaRowCount;
+ size_t m_namedGridAreaColumnCount;
+
private:
StyleGridData();
StyleGridData(const StyleGridData&);
diff --git a/Source/core/rendering/svg/ReferenceFilterBuilder.cpp b/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
index b78922a..11ce00e 100644
--- a/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
+++ b/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
@@ -44,13 +44,13 @@
namespace WebCore {
-// Returns whether or not the SVGStyledElement object contains a valid color-interpolation-filters attribute
-static bool getSVGStyledElementColorSpace(SVGStyledElement* svgStyledElement, ColorSpace& cs)
+// Returns whether or not the SVGElement object contains a valid color-interpolation-filters attribute
+static bool getSVGElementColorSpace(SVGElement* svgElement, ColorSpace& cs)
{
- if (!svgStyledElement)
+ if (!svgElement)
return false;
- const RenderObject* renderer = svgStyledElement->renderer();
+ const RenderObject* renderer = svgElement->renderer();
const RenderStyle* style = renderer ? renderer->style() : 0;
const SVGRenderStyle* svgStyle = style ? style->svgStyle() : 0;
EColorInterpolation eColorInterpolation = CI_AUTO;
@@ -59,7 +59,7 @@
eColorInterpolation = svgStyle->colorInterpolationFilters();
} else {
// Otherwise, use the slow path by using string comparison (used by external svg files)
- RefPtr<CSSValue> cssValue = svgStyledElement->getPresentationAttribute(
+ RefPtr<CSSValue> cssValue = svgElement->getPresentationAttribute(
SVGNames::color_interpolation_filtersAttr.toString());
if (cssValue.get() && cssValue->isPrimitiveValue()) {
const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssValue.get());
@@ -125,7 +125,7 @@
RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(parentFilter));
ColorSpace filterColorSpace = ColorSpaceDeviceRGB;
- bool useFilterColorSpace = getSVGStyledElementColorSpace(filterElement, filterColorSpace);
+ bool useFilterColorSpace = getSVGElementColorSpace(filterElement, filterColorSpace);
for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
if (!node->isSVGElement())
@@ -144,7 +144,7 @@
effectElement->setStandardAttributes(effect.get());
effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnitsCurrentValue(), parentFilter->sourceImageRect()));
ColorSpace colorSpace = filterColorSpace;
- if (useFilterColorSpace || getSVGStyledElementColorSpace(effectElement, colorSpace))
+ if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorSpace))
effect->setOperatingColorSpace(colorSpace);
builder->add(effectElement->resultCurrentValue(), effect);
}
diff --git a/Source/core/rendering/svg/RenderSVGContainer.cpp b/Source/core/rendering/svg/RenderSVGContainer.cpp
index 7b1bf66..d64aec4 100644
--- a/Source/core/rendering/svg/RenderSVGContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGContainer.cpp
@@ -34,7 +34,7 @@
namespace WebCore {
-RenderSVGContainer::RenderSVGContainer(SVGStyledElement* node)
+RenderSVGContainer::RenderSVGContainer(SVGElement* node)
: RenderSVGModelObject(node)
, m_objectBoundingBoxValid(false)
, m_needsBoundariesUpdate(true)
diff --git a/Source/core/rendering/svg/RenderSVGContainer.h b/Source/core/rendering/svg/RenderSVGContainer.h
index f5a40fa..b25932b 100644
--- a/Source/core/rendering/svg/RenderSVGContainer.h
+++ b/Source/core/rendering/svg/RenderSVGContainer.h
@@ -31,7 +31,7 @@
class RenderSVGContainer : public RenderSVGModelObject {
public:
- explicit RenderSVGContainer(SVGStyledElement*);
+ explicit RenderSVGContainer(SVGElement*);
virtual ~RenderSVGContainer();
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
diff --git a/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp b/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp
index 7f02252..9fc703e 100644
--- a/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp
@@ -23,7 +23,7 @@
namespace WebCore {
-RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGStyledElement* element)
+RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGElement* element)
: RenderSVGContainer(element)
{
}
diff --git a/Source/core/rendering/svg/RenderSVGHiddenContainer.h b/Source/core/rendering/svg/RenderSVGHiddenContainer.h
index ee2b992..f8e57d3 100644
--- a/Source/core/rendering/svg/RenderSVGHiddenContainer.h
+++ b/Source/core/rendering/svg/RenderSVGHiddenContainer.h
@@ -24,13 +24,13 @@
namespace WebCore {
-class SVGStyledElement;
+class SVGElement;
// This class is for containers which are never drawn, but do need to support style
// <defs>, <linearGradient>, <radialGradient> are all good examples
class RenderSVGHiddenContainer : public RenderSVGContainer {
public:
- explicit RenderSVGHiddenContainer(SVGStyledElement*);
+ explicit RenderSVGHiddenContainer(SVGElement*);
virtual const char* renderName() const { return "RenderSVGHiddenContainer"; }
diff --git a/Source/core/rendering/svg/RenderSVGInline.cpp b/Source/core/rendering/svg/RenderSVGInline.cpp
index bec0c50..917ea33 100644
--- a/Source/core/rendering/svg/RenderSVGInline.cpp
+++ b/Source/core/rendering/svg/RenderSVGInline.cpp
@@ -30,6 +30,14 @@
namespace WebCore {
+bool RenderSVGInline::isChildAllowed(RenderObject* child, RenderStyle* style) const
+{
+ if (SVGRenderSupport::isEmptySVGInlineText(child))
+ return false;
+
+ return RenderInline::isChildAllowed(child, style);
+}
+
RenderSVGInline::RenderSVGInline(Element* element)
: RenderInline(element)
{
@@ -38,7 +46,7 @@
InlineFlowBox* RenderSVGInline::createInlineFlowBox()
{
- InlineFlowBox* box = new (renderArena()) SVGInlineFlowBox(this);
+ InlineFlowBox* box = new SVGInlineFlowBox(this);
box->setHasVirtualLogicalHeight();
return box;
}
diff --git a/Source/core/rendering/svg/RenderSVGInline.h b/Source/core/rendering/svg/RenderSVGInline.h
index 5a01988..4cc390f 100644
--- a/Source/core/rendering/svg/RenderSVGInline.h
+++ b/Source/core/rendering/svg/RenderSVGInline.h
@@ -33,6 +33,8 @@
virtual bool requiresLayer() const OVERRIDE FINAL { return false; }
virtual bool isSVGInline() const OVERRIDE FINAL { return true; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+
// Chapter 10.4 of the SVG Specification say that we should use the
// object bounding box of the parent text element.
// We search for the root text element and take its bounding box.
diff --git a/Source/core/rendering/svg/RenderSVGInlineText.cpp b/Source/core/rendering/svg/RenderSVGInlineText.cpp
index f81b3e1..1141a56 100644
--- a/Source/core/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/core/rendering/svg/RenderSVGInlineText.cpp
@@ -100,7 +100,7 @@
InlineTextBox* RenderSVGInlineText::createTextBox()
{
- InlineTextBox* box = new (renderArena()) SVGInlineTextBox(this);
+ InlineTextBox* box = new SVGInlineTextBox(this);
box->setHasVirtualLogicalHeight();
return box;
}
@@ -155,10 +155,10 @@
return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y != SVGTextLayoutAttributes::emptyValue();
}
-VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point)
+PositionWithAffinity RenderSVGInlineText::positionForPoint(const LayoutPoint& point)
{
if (!firstTextBox() || !textLength())
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
float baseline = m_scaledFont.fontMetrics().floatAscent();
@@ -203,10 +203,10 @@
}
if (!closestDistanceFragment)
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
int offset = closestDistanceBox->offsetForPositionInFragment(*closestDistanceFragment, absolutePoint.x() - closestDistancePosition, true);
- return createVisiblePosition(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
+ return createPositionWithAffinity(offset + closestDistanceBox->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
void RenderSVGInlineText::updateScaledFont()
diff --git a/Source/core/rendering/svg/RenderSVGInlineText.h b/Source/core/rendering/svg/RenderSVGInlineText.h
index ec01d03..8ce8fd2 100644
--- a/Source/core/rendering/svg/RenderSVGInlineText.h
+++ b/Source/core/rendering/svg/RenderSVGInlineText.h
@@ -55,7 +55,7 @@
virtual bool requiresLayer() const { return false; }
virtual bool isSVGInlineText() const { return true; }
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0);
virtual IntRect linesBoundingBox() const;
virtual InlineTextBox* createTextBox();
diff --git a/Source/core/rendering/svg/RenderSVGModelObject.cpp b/Source/core/rendering/svg/RenderSVGModelObject.cpp
index 4f66d62..10f3d8f 100644
--- a/Source/core/rendering/svg/RenderSVGModelObject.cpp
+++ b/Source/core/rendering/svg/RenderSVGModelObject.cpp
@@ -35,11 +35,11 @@
#include "SVGNames.h"
#include "core/rendering/svg/RenderSVGRoot.h"
#include "core/rendering/svg/SVGResourcesCache.h"
-#include "core/svg/SVGStyledElement.h"
+#include "core/svg/SVGElement.h"
namespace WebCore {
-RenderSVGModelObject::RenderSVGModelObject(SVGStyledElement* node)
+RenderSVGModelObject::RenderSVGModelObject(SVGElement* node)
: RenderObject(node)
{
}
@@ -100,7 +100,7 @@
SVGRenderSupport::findTreeRootObject(this)->computeLayerHitTestRects(rects);
}
-void RenderSVGModelObject::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset) const
+void RenderSVGModelObject::addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
{
// We don't walk into SVG trees at all - just report their container.
}
@@ -140,10 +140,8 @@
while (current && current->isSVGElement()) {
SVGElement* currentElement = toSVGElement(current);
- if (currentElement->isSVGStyledElement()) {
- localTransform = currentElement->renderer()->localToParentTransform();
- transform = localTransform.multiply(transform);
- }
+ localTransform = currentElement->renderer()->localToParentTransform();
+ transform = localTransform.multiply(transform);
// For getCTM() computation, stop at the nearest viewport element
if (currentElement == stopAtElement)
break;
diff --git a/Source/core/rendering/svg/RenderSVGModelObject.h b/Source/core/rendering/svg/RenderSVGModelObject.h
index 2a616d8..0a36ff8 100644
--- a/Source/core/rendering/svg/RenderSVGModelObject.h
+++ b/Source/core/rendering/svg/RenderSVGModelObject.h
@@ -42,11 +42,11 @@
// required by SVG renders need to be declared on RenderObject, but shared
// logic can go in this class or in SVGRenderSupport.
-class SVGStyledElement;
+class SVGElement;
class RenderSVGModelObject : public RenderObject {
public:
- explicit RenderSVGModelObject(SVGStyledElement*);
+ explicit RenderSVGModelObject(SVGElement*);
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE FINAL;
@@ -66,7 +66,7 @@
virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE;
protected:
- virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset) const OVERRIDE;
+ virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE;
virtual void willBeDestroyed();
private:
diff --git a/Source/core/rendering/svg/RenderSVGResourceClipper.cpp b/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
index a1875ff..92a96dd 100644
--- a/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
@@ -226,7 +226,7 @@
// Draw all clipPath children into a global mask.
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
+ if (!childNode->isSVGElement() || !renderer)
continue;
if (renderer->needsLayout()) {
frame()->view()->setPaintBehavior(oldBehavior);
@@ -268,7 +268,7 @@
// This is a rough heuristic to appraise the clip size and doesn't consider clip on clip.
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
+ if (!childNode->isSVGElement() || !renderer)
continue;
if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
continue;
@@ -298,7 +298,7 @@
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
+ if (!childNode->isSVGElement() || !renderer)
continue;
if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
continue;
diff --git a/Source/core/rendering/svg/RenderSVGResourceContainer.cpp b/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
index f60b32b..33fb263 100644
--- a/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
@@ -37,7 +37,7 @@
return node->document()->accessSVGExtensions();
}
-RenderSVGResourceContainer::RenderSVGResourceContainer(SVGStyledElement* node)
+RenderSVGResourceContainer::RenderSVGResourceContainer(SVGElement* node)
: RenderSVGHiddenContainer(node)
, m_id(node->getIdAttribute())
, m_registered(false)
diff --git a/Source/core/rendering/svg/RenderSVGResourceContainer.h b/Source/core/rendering/svg/RenderSVGResourceContainer.h
index 3bb912d..a2e4bd1 100644
--- a/Source/core/rendering/svg/RenderSVGResourceContainer.h
+++ b/Source/core/rendering/svg/RenderSVGResourceContainer.h
@@ -30,7 +30,7 @@
class RenderSVGResourceContainer : public RenderSVGHiddenContainer,
public RenderSVGResource {
public:
- RenderSVGResourceContainer(SVGStyledElement*);
+ RenderSVGResourceContainer(SVGElement*);
virtual ~RenderSVGResourceContainer();
virtual void layout();
diff --git a/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h b/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h
index 50b5f0d..c44b1e7 100644
--- a/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h
+++ b/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h
@@ -35,7 +35,7 @@
class RenderSVGResourceFilterPrimitive FINAL : public RenderSVGHiddenContainer {
public:
- explicit RenderSVGResourceFilterPrimitive(SVGStyledElement* filterPrimitiveElement)
+ explicit RenderSVGResourceFilterPrimitive(SVGElement* filterPrimitiveElement)
: RenderSVGHiddenContainer(filterPrimitiveElement)
{
}
diff --git a/Source/core/rendering/svg/RenderSVGResourceMarker.cpp b/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
index 3a9cead..d6e5e60 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
@@ -29,7 +29,6 @@
#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGMarkerElement.h"
-#include "core/svg/SVGStyledElement.h"
namespace WebCore {
diff --git a/Source/core/rendering/svg/RenderSVGResourceMarker.h b/Source/core/rendering/svg/RenderSVGResourceMarker.h
index 7e83c53..528f1f1 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMarker.h
+++ b/Source/core/rendering/svg/RenderSVGResourceMarker.h
@@ -22,8 +22,8 @@
#include "core/platform/graphics/FloatRect.h"
#include "core/rendering/svg/RenderSVGResourceContainer.h"
+#include "core/svg/SVGElement.h"
#include "core/svg/SVGMarkerElement.h"
-#include "core/svg/SVGStyledElement.h"
#include "wtf/HashSet.h"
diff --git a/Source/core/rendering/svg/RenderSVGResourceMasker.cpp b/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
index b4790e4..ad9631d 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
@@ -91,7 +91,7 @@
FloatRect repaintRect = object->repaintRectInLocalCoordinates();
if (!maskerData->maskImage && !repaintRect.isEmpty()) {
- SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ SVGMaskElement* maskElement = toSVGMaskElement(node());
if (!maskElement)
return false;
@@ -131,7 +131,7 @@
// Draw the content into the ImageBuffer.
for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
RenderObject* renderer = node->renderer();
- if (!node->isSVGElement() || !toSVGElement(node)->isSVGStyledElement() || !renderer)
+ if (!node->isSVGElement() || !renderer)
continue;
if (renderer->needsLayout())
return false;
@@ -156,7 +156,7 @@
{
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
+ if (!childNode->isSVGElement() || !renderer)
continue;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
@@ -167,7 +167,7 @@
FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
{
- SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ SVGMaskElement* maskElement = toSVGMaskElement(node());
ASSERT(maskElement);
FloatRect objectBoundingBox = object->objectBoundingBox();
diff --git a/Source/core/rendering/svg/RenderSVGResourceMasker.h b/Source/core/rendering/svg/RenderSVGResourceMasker.h
index 66a34c6..c3f6272 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMasker.h
+++ b/Source/core/rendering/svg/RenderSVGResourceMasker.h
@@ -49,8 +49,8 @@
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(RenderObject*);
- SVGUnitTypes::SVGUnitType maskUnits() const { return static_cast<SVGMaskElement*>(node())->maskUnitsCurrentValue(); }
- SVGUnitTypes::SVGUnitType maskContentUnits() const { return static_cast<SVGMaskElement*>(node())->maskContentUnitsCurrentValue(); }
+ SVGUnitTypes::SVGUnitType maskUnits() const { return toSVGMaskElement(node())->maskUnitsCurrentValue(); }
+ SVGUnitTypes::SVGUnitType maskContentUnits() const { return toSVGMaskElement(node())->maskContentUnitsCurrentValue(); }
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
diff --git a/Source/core/rendering/svg/RenderSVGResourcePattern.cpp b/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
index ff4f87b..b8dfe39 100644
--- a/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
@@ -261,7 +261,7 @@
// Draw the content into the ImageBuffer.
for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement() || !toSVGElement(node)->isSVGStyledElement() || !node->renderer())
+ if (!node->isSVGElement() || !node->renderer())
continue;
if (node->renderer()->needsLayout())
return nullptr;
diff --git a/Source/core/rendering/svg/RenderSVGRoot.cpp b/Source/core/rendering/svg/RenderSVGRoot.cpp
index 0537fbb..7f52741 100644
--- a/Source/core/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/core/rendering/svg/RenderSVGRoot.cpp
@@ -38,14 +38,14 @@
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
+#include "core/svg/SVGElement.h"
#include "core/svg/SVGSVGElement.h"
-#include "core/svg/SVGStyledElement.h"
using namespace std;
namespace WebCore {
-RenderSVGRoot::RenderSVGRoot(SVGStyledElement* node)
+RenderSVGRoot::RenderSVGRoot(SVGElement* node)
: RenderReplaced(node)
, m_objectBoundingBoxValid(false)
, m_isLayoutSizeChanged(false)
diff --git a/Source/core/rendering/svg/RenderSVGRoot.h b/Source/core/rendering/svg/RenderSVGRoot.h
index 1872904..ff1fbe3 100644
--- a/Source/core/rendering/svg/RenderSVGRoot.h
+++ b/Source/core/rendering/svg/RenderSVGRoot.h
@@ -30,11 +30,11 @@
namespace WebCore {
class AffineTransform;
-class SVGStyledElement;
+class SVGElement;
class RenderSVGRoot FINAL : public RenderReplaced {
public:
- explicit RenderSVGRoot(SVGStyledElement*);
+ explicit RenderSVGRoot(SVGElement*);
virtual ~RenderSVGRoot();
bool isEmbeddedThroughSVGImage() const;
diff --git a/Source/core/rendering/svg/RenderSVGText.cpp b/Source/core/rendering/svg/RenderSVGText.cpp
index 4f79c74..f3e17a0 100644
--- a/Source/core/rendering/svg/RenderSVGText.cpp
+++ b/Source/core/rendering/svg/RenderSVGText.cpp
@@ -28,7 +28,6 @@
#include "core/rendering/svg/RenderSVGText.h"
-#include "core/editing/VisiblePosition.h"
#include "core/platform/FloatConversion.h"
#include "core/platform/graphics/FloatQuad.h"
#include "core/platform/graphics/FontCache.h"
@@ -70,7 +69,7 @@
bool RenderSVGText::isChildAllowed(RenderObject* child, RenderStyle*) const
{
- return child->isInline();
+ return child->isInline() && !SVGRenderSupport::isEmptySVGInlineText(child);
}
RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject* start)
@@ -434,7 +433,7 @@
RootInlineBox* RenderSVGText::createRootInlineBox()
{
- RootInlineBox* box = new (renderArena()) SVGRootInlineBox(this);
+ RootInlineBox* box = new SVGRootInlineBox(this);
box->setHasVirtualLogicalHeight();
return box;
}
@@ -465,11 +464,11 @@
return false;
}
-VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents)
+PositionWithAffinity RenderSVGText::positionForPoint(const LayoutPoint& pointInContents)
{
RootInlineBox* rootBox = firstRootBox();
if (!rootBox)
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
ASSERT_WITH_SECURITY_IMPLICATION(rootBox->isSVGRootInlineBox());
ASSERT(!rootBox->nextRootBox());
@@ -477,7 +476,7 @@
InlineBox* closestBox = static_cast<SVGRootInlineBox*>(rootBox)->closestLeafChildForPosition(pointInContents);
if (!closestBox)
- return createVisiblePosition(0, DOWNSTREAM);
+ return createPositionWithAffinity(0, DOWNSTREAM);
return closestBox->renderer()->positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
}
diff --git a/Source/core/rendering/svg/RenderSVGText.h b/Source/core/rendering/svg/RenderSVGText.h
index ac8f498..a048138 100644
--- a/Source/core/rendering/svg/RenderSVGText.h
+++ b/Source/core/rendering/svg/RenderSVGText.h
@@ -63,7 +63,7 @@
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual VisiblePosition positionForPoint(const LayoutPoint&);
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
virtual bool requiresLayer() const { return false; }
virtual void layout();
diff --git a/Source/core/rendering/svg/RenderSVGViewportContainer.cpp b/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
index 67c82e5..3b79919 100644
--- a/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
+RenderSVGViewportContainer::RenderSVGViewportContainer(SVGElement* node)
: RenderSVGContainer(node)
, m_didTransformToRootUpdate(false)
, m_isLayoutSizeChanged(false)
diff --git a/Source/core/rendering/svg/RenderSVGViewportContainer.h b/Source/core/rendering/svg/RenderSVGViewportContainer.h
index 3416ede..c01e7a5 100644
--- a/Source/core/rendering/svg/RenderSVGViewportContainer.h
+++ b/Source/core/rendering/svg/RenderSVGViewportContainer.h
@@ -31,7 +31,7 @@
// thus we inherit from RenderSVGContainer instead of RenderSVGTransformableContainer
class RenderSVGViewportContainer FINAL : public RenderSVGContainer {
public:
- explicit RenderSVGViewportContainer(SVGStyledElement*);
+ explicit RenderSVGViewportContainer(SVGElement*);
FloatRect viewport() const { return m_viewport; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
diff --git a/Source/core/rendering/svg/SVGInlineTextBox.cpp b/Source/core/rendering/svg/SVGInlineTextBox.cpp
index cb54b01..8731b0c 100644
--- a/Source/core/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/core/rendering/svg/SVGInlineTextBox.cpp
@@ -432,6 +432,10 @@
RenderText* text = textRenderer();
ASSERT(text);
+ // FIXME(crbug.com/264211): This should not be necessary but can occur if we
+ // layout during layout. Remove this when 264211 is fixed.
+ RELEASE_ASSERT(!text->needsLayout());
+
TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero.
, 0 // length, will be set below if non-zero.
, 0 // xPos, only relevant with allowTabs=true
diff --git a/Source/core/rendering/svg/SVGRenderSupport.cpp b/Source/core/rendering/svg/SVGRenderSupport.cpp
index 3c5ad62..8d4a272 100644
--- a/Source/core/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/core/rendering/svg/SVGRenderSupport.cpp
@@ -29,6 +29,7 @@
#include "core/platform/graphics/transforms/TransformState.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderLayer.h"
+#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGResourceClipper.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
#include "core/rendering/svg/RenderSVGResourceMasker.h"
@@ -37,7 +38,7 @@
#include "core/rendering/svg/RenderSVGViewportContainer.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
-#include "core/svg/SVGStyledElement.h"
+#include "core/svg/SVGElement.h"
#include "wtf/UnusedParam.h"
namespace WebCore {
@@ -225,7 +226,7 @@
if (layoutSizeChanged) {
// When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
if (SVGElement* element = child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) {
- if (element->isSVGStyledElement() && toSVGStyledElement(element)->hasRelativeLengths()) {
+ if (element->hasRelativeLengths()) {
// When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
if (child->isSVGShape())
toRenderSVGShape(child)->setNeedsShapeUpdate();
@@ -388,4 +389,12 @@
strokeData->setLineDash(dashArray, svgStyle->strokeDashOffset().value(lengthContext));
}
+bool SVGRenderSupport::isEmptySVGInlineText(const RenderObject* object)
+{
+ // RenderSVGInlineText performs whitespace filtering in order to support xml:space
+ // (http://www.w3.org/TR/SVG/struct.html#LangSpaceAttrs), and can end up with an empty string
+ // even when its original constructor argument is non-empty.
+ return object->isSVGInlineText() && toRenderSVGInlineText(object)->hasEmptyText();
+}
+
}
diff --git a/Source/core/rendering/svg/SVGRenderSupport.h b/Source/core/rendering/svg/SVGRenderSupport.h
index ee15e3b..285e447 100644
--- a/Source/core/rendering/svg/SVGRenderSupport.h
+++ b/Source/core/rendering/svg/SVGRenderSupport.h
@@ -78,6 +78,9 @@
// FIXME: These methods do not belong here.
static const RenderSVGRoot* findTreeRootObject(const RenderObject*);
+ // Helper method for determining whether an RenderSVGInlineText object has zero length text.
+ static bool isEmptySVGInlineText(const RenderObject*);
+
private:
// This class is not constructable.
SVGRenderSupport();
diff --git a/Source/core/rendering/svg/SVGResources.cpp b/Source/core/rendering/svg/SVGResources.cpp
index 6acd132..3fd84a8 100644
--- a/Source/core/rendering/svg/SVGResources.cpp
+++ b/Source/core/rendering/svg/SVGResources.cpp
@@ -176,8 +176,7 @@
static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement* element)
{
ASSERT(element);
- ASSERT_WITH_SECURITY_IMPLICATION(element->isSVGStyledElement());
- extensions->addPendingResource(id, toSVGStyledElement(element));
+ extensions->addPendingResource(id, element);
}
bool SVGResources::buildResources(const RenderObject* object, const SVGRenderStyle* style)
diff --git a/Source/core/rendering/svg/SVGTextLayoutEngine.cpp b/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
index 2fca5c2..0ade353 100644
--- a/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
@@ -268,12 +268,12 @@
fprintf(stderr, " textBox properties, start=%i, len=%i, box direction=%i\n", textBox->start(), textBox->len(), textBox->direction());
fprintf(stderr, " textRenderer properties, textLength=%i\n", textBox->textRenderer()->textLength());
- const UChar* characters = textBox->textRenderer()->characters();
+ String characters = textBox->textRenderer()->text();
unsigned fragmentCount = fragments.size();
for (unsigned i = 0; i < fragmentCount; ++i) {
SVGTextFragment& fragment = fragments.at(i);
- String fragmentString(characters + fragment.characterOffset, fragment.length);
+ String fragmentString = characters.substring(fragment.characterOffset, fragment.length);
fprintf(stderr, " -> Fragment %i, x=%lf, y=%lf, width=%lf, height=%lf, characterOffset=%i, length=%i, characters='%s'\n"
, i, fragment.x, fragment.y, fragment.width, fragment.height, fragment.characterOffset, fragment.length, fragmentString.utf8().data());
}
@@ -389,9 +389,6 @@
unsigned boxStart = textBox->start();
unsigned boxLength = textBox->len();
- if (m_visualMetricsListOffset == textMetricsSize)
- return false;
-
while (m_visualMetricsListOffset < textMetricsSize) {
// Advance to text box start location.
if (m_visualCharacterOffset < boxStart) {