summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-15 12:23:52 +0000
committerSteve Block <steveblock@google.com>2010-02-16 11:48:32 +0000
commit8a0914b749bbe7da7768e07a7db5c6d4bb09472b (patch)
tree73f9065f370435d6fde32ae129d458a8c77c8dff /WebCore/rendering
parentbf14be70295513b8076f3fa47a268a7e42b2c478 (diff)
downloadexternal_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.zip
external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.gz
external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.bz2
Merge webkit.org at r54731 : Initial merge by git
Change-Id: Ia79977b6cf3b0b00c06ef39419989b28e57e4f4a
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/BidiRun.cpp74
-rw-r--r--WebCore/rendering/BidiRun.h65
-rw-r--r--WebCore/rendering/InlineIterator.h266
-rw-r--r--WebCore/rendering/RenderBlock.h3
-rw-r--r--WebCore/rendering/RenderBlockLineLayout.cpp325
-rw-r--r--WebCore/rendering/RenderBox.cpp4
-rw-r--r--WebCore/rendering/RenderBox.h2
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp12
-rw-r--r--WebCore/rendering/RenderForeignObject.cpp9
-rw-r--r--WebCore/rendering/RenderForeignObject.h13
-rw-r--r--WebCore/rendering/RenderFrame.cpp55
-rw-r--r--WebCore/rendering/RenderFrame.h1
-rw-r--r--WebCore/rendering/RenderFrameSet.cpp122
-rw-r--r--WebCore/rendering/RenderFrameSet.h5
-rw-r--r--WebCore/rendering/RenderLayer.cpp10
-rw-r--r--WebCore/rendering/RenderListMarker.cpp263
-rw-r--r--WebCore/rendering/RenderObject.cpp28
-rw-r--r--WebCore/rendering/RenderObject.h12
-rw-r--r--WebCore/rendering/RenderPath.cpp4
-rw-r--r--WebCore/rendering/RenderPath.h8
-rw-r--r--WebCore/rendering/RenderRuby.cpp3
-rw-r--r--WebCore/rendering/RenderRuby.h4
-rw-r--r--WebCore/rendering/RenderRubyBase.cpp4
-rw-r--r--WebCore/rendering/RenderRubyBase.h4
-rw-r--r--WebCore/rendering/RenderRubyRun.cpp4
-rw-r--r--WebCore/rendering/RenderRubyRun.h4
-rw-r--r--WebCore/rendering/RenderRubyText.cpp4
-rw-r--r--WebCore/rendering/RenderRubyText.h4
-rw-r--r--WebCore/rendering/RenderSVGHiddenContainer.h3
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp1
-rw-r--r--WebCore/rendering/RenderSVGImage.h10
-rw-r--r--WebCore/rendering/RenderSVGModelObject.cpp1
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp60
-rw-r--r--WebCore/rendering/RenderSVGRoot.h18
-rw-r--r--WebCore/rendering/RenderSVGText.cpp7
-rw-r--r--WebCore/rendering/RenderSVGText.h8
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.cpp6
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.h6
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.cpp40
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.h13
-rw-r--r--WebCore/rendering/RenderTableCell.cpp3
-rw-r--r--WebCore/rendering/RenderThemeChromiumWin.cpp2
-rw-r--r--WebCore/rendering/SVGCharacterLayoutInfo.cpp4
-rw-r--r--WebCore/rendering/SVGCharacterLayoutInfo.h46
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp59
-rw-r--r--WebCore/rendering/SVGInlineTextBox.h3
-rw-r--r--WebCore/rendering/SVGMarkerLayoutInfo.h4
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp20
-rw-r--r--WebCore/rendering/SVGRenderSupport.h5
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp4
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.h4
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp82
-rw-r--r--WebCore/rendering/SVGRootInlineBox.h2
-rw-r--r--WebCore/rendering/TransformState.cpp6
-rw-r--r--WebCore/rendering/TransformState.h2
-rw-r--r--WebCore/rendering/style/RenderStyle.h6
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h132
57 files changed, 1291 insertions, 578 deletions
diff --git a/WebCore/rendering/BidiRun.cpp b/WebCore/rendering/BidiRun.cpp
new file mode 100644
index 0000000..ac13046
--- /dev/null
+++ b/WebCore/rendering/BidiRun.cpp
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "BidiRun.h"
+#include "InlineBox.h"
+#include "RenderArena.h"
+#include <wtf/RefCountedLeakCounter.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+#ifndef NDEBUG
+static RefCountedLeakCounter bidiRunCounter("BidiRun");
+
+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) throw()
+{
+#ifndef NDEBUG
+ bidiRunCounter.increment();
+#endif
+ return renderArena->allocate(sz);
+}
+
+void BidiRun::operator delete(void* ptr, size_t sz)
+{
+#ifndef NDEBUG
+ bidiRunCounter.decrement();
+#endif
+ ASSERT(inBidiRunDestroy);
+
+ // Stash size where destroy() can find it.
+ *(size_t*)ptr = sz;
+}
+
+}
diff --git a/WebCore/rendering/BidiRun.h b/WebCore/rendering/BidiRun.h
new file mode 100644
index 0000000..542081a
--- /dev/null
+++ b/WebCore/rendering/BidiRun.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BidiRun_h
+#define BidiRun_h
+
+#include <wtf/StdLibExtras.h>
+#include "BidiResolver.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+class BidiContext;
+class InlineBox;
+
+struct BidiRun : BidiCharacterRun {
+ BidiRun(int start, int stop, RenderObject* object, BidiContext* context, WTF::Unicode::Direction dir)
+ : BidiCharacterRun(start, stop, context, dir)
+ , m_object(object)
+ , m_box(0)
+ {
+ }
+
+ void destroy();
+
+ // Overloaded new operator.
+ void* operator new(size_t, RenderArena*) throw();
+
+ // Overridden to prevent the normal delete from being called.
+ void operator delete(void*, size_t);
+
+ BidiRun* next() { return static_cast<BidiRun*>(m_next); }
+
+private:
+ // The normal operator new is disallowed.
+ void* operator new(size_t) throw();
+
+public:
+ RenderObject* m_object;
+ InlineBox* m_box;
+};
+
+}
+
+#endif // BidiRun_h
diff --git a/WebCore/rendering/InlineIterator.h b/WebCore/rendering/InlineIterator.h
new file mode 100644
index 0000000..9310ea8
--- /dev/null
+++ b/WebCore/rendering/InlineIterator.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef InlineIterator_h
+#define InlineIterator_h
+
+#include "BidiRun.h"
+#include "RenderBlock.h"
+#include "RenderText.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+class InlineIterator {
+public:
+ InlineIterator()
+ : block(0)
+ , obj(0)
+ , pos(0)
+ , nextBreakablePosition(-1)
+ {
+ }
+
+ InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)
+ : block(b)
+ , obj(o)
+ , pos(p)
+ , nextBreakablePosition(-1)
+ {
+ }
+
+ void increment(InlineBidiResolver* resolver = 0);
+ bool atEnd() const;
+
+ UChar current() const;
+ WTF::Unicode::Direction direction() const;
+
+ RenderBlock* block;
+ RenderObject* obj;
+ unsigned pos;
+ int nextBreakablePosition;
+};
+
+inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
+{
+ return it1.pos == it2.pos && it1.obj == it2.obj;
+}
+
+inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
+{
+ return it1.pos != it2.pos || it1.obj != it2.obj;
+}
+
+static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0)
+{
+ RenderObject* next = 0;
+ bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
+ bool endOfInline = false;
+
+ while (current) {
+ next = 0;
+ if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
+ next = current->firstChild();
+ if (next && resolver && next->isRenderInline()) {
+ EUnicodeBidi ub = next->style()->unicodeBidi();
+ if (ub != UBNormal) {
+ TextDirection dir = next->style()->direction();
+ WTF::Unicode::Direction d = (ub == Embed
+ ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding)
+ : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
+ resolver->embed(d);
+ }
+ }
+ }
+
+ if (!next) {
+ if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {
+ next = current;
+ endOfInline = true;
+ break;
+ }
+
+ while (current && current != block) {
+ if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)
+ resolver->embed(WTF::Unicode::PopDirectionalFormat);
+
+ next = current->nextSibling();
+ if (next) {
+ if (resolver && next->isRenderInline()) {
+ EUnicodeBidi ub = next->style()->unicodeBidi();
+ if (ub != UBNormal) {
+ TextDirection dir = next->style()->direction();
+ WTF::Unicode::Direction d = (ub == Embed
+ ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding: WTF::Unicode::LeftToRightEmbedding)
+ : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
+ resolver->embed(d);
+ }
+ }
+ break;
+ }
+
+ current = current->parent();
+ if (!skipInlines && current && current != block && current->isRenderInline()) {
+ next = current;
+ endOfInline = true;
+ break;
+ }
+ }
+ }
+
+ if (!next)
+ break;
+
+ if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()
+ || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
+ && next->isRenderInline()))
+ break;
+ current = next;
+ }
+
+ if (endOfInlinePtr)
+ *endOfInlinePtr = endOfInline;
+
+ return next;
+}
+
+static inline RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true)
+{
+ if (!block->firstChild())
+ return 0;
+
+ RenderObject* o = block->firstChild();
+ if (o->isRenderInline()) {
+ if (resolver) {
+ EUnicodeBidi ub = o->style()->unicodeBidi();
+ if (ub != UBNormal) {
+ TextDirection dir = o->style()->direction();
+ WTF::Unicode::Direction d = (ub == Embed
+ ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding)
+ : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride));
+ resolver->embed(d);
+ }
+ }
+ if (skipInlines && o->firstChild())
+ o = bidiNext(block, o, resolver, skipInlines);
+ else {
+ // Never skip empty inlines.
+ if (resolver)
+ resolver->commitExplicitEmbedding();
+ return o;
+ }
+ }
+
+ if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
+ o = bidiNext(block, o, resolver, skipInlines);
+
+ if (resolver)
+ resolver->commitExplicitEmbedding();
+ return o;
+}
+
+inline void InlineIterator::increment(InlineBidiResolver* resolver)
+{
+ if (!obj)
+ return;
+ if (obj->isText()) {
+ pos++;
+ if (pos >= toRenderText(obj)->textLength()) {
+ obj = bidiNext(block, obj, resolver);
+ pos = 0;
+ nextBreakablePosition = -1;
+ }
+ } else {
+ obj = bidiNext(block, obj, resolver);
+ pos = 0;
+ nextBreakablePosition = -1;
+ }
+}
+
+inline bool InlineIterator::atEnd() const
+{
+ return !obj;
+}
+
+inline UChar InlineIterator::current() const
+{
+ if (!obj || !obj->isText())
+ return 0;
+
+ RenderText* text = toRenderText(obj);
+ if (pos >= text->textLength())
+ return 0;
+
+ return text->characters()[pos];
+}
+
+ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const
+{
+ if (UChar c = current())
+ return WTF::Unicode::direction(c);
+
+ if (obj && obj->isListMarker())
+ return obj->style()->direction() == LTR ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft;
+
+ return WTF::Unicode::OtherNeutral;
+}
+
+template<>
+inline void InlineBidiResolver::increment()
+{
+ current.increment(this);
+}
+
+template <>
+inline void InlineBidiResolver::appendRun()
+{
+ if (!emptyRun && !eor.atEnd()) {
+ int start = sor.pos;
+ RenderObject *obj = sor.obj;
+ while (obj && obj != eor.obj && obj != endOfLine.obj) {
+ RenderBlock::appendRunsForObject(start, obj->length(), obj, *this);
+ start = 0;
+ obj = bidiNext(sor.block, obj);
+ }
+ if (obj) {
+ unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX;
+ if (obj == endOfLine.obj && endOfLine.pos <= pos) {
+ reachedEndOfLine = true;
+ pos = endOfLine.pos;
+ }
+ // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
+ int end = obj->length() ? pos+1 : 0;
+ RenderBlock::appendRunsForObject(start, end, obj, *this);
+ }
+
+ eor.increment();
+ sor = eor;
+ }
+
+ m_direction = WTF::Unicode::OtherNeutral;
+ m_status.eor = WTF::Unicode::OtherNeutral;
+}
+
+}
+
+#endif // InlineIterator_h
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 884695a..d1d105a 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -138,6 +138,9 @@ public:
// style from this RenderBlock.
RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
+ static void appendRunsForObject(int start, int end, RenderObject*, InlineBidiResolver&);
+ static bool requiresLineBox(const InlineIterator&, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
+
protected:
void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child);
void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
diff --git a/WebCore/rendering/RenderBlockLineLayout.cpp b/WebCore/rendering/RenderBlockLineLayout.cpp
index c76d963..a7f3553 100644
--- a/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -24,6 +24,7 @@
#include "BidiResolver.h"
#include "CharacterNames.h"
+#include "InlineIterator.h"
#include "InlineTextBox.h"
#include "Logging.h"
#include "RenderArena.h"
@@ -53,36 +54,6 @@ namespace WebCore {
// We don't let our line box tree for a single line get any deeper than this.
const unsigned cMaxLineDepth = 200;
-class InlineIterator {
-public:
- InlineIterator()
- : block(0)
- , obj(0)
- , pos(0)
- , nextBreakablePosition(-1)
- {
- }
-
- InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)
- : block(b)
- , obj(o)
- , pos(p)
- , nextBreakablePosition(-1)
- {
- }
-
- void increment(InlineBidiResolver* resolver = 0);
- bool atEnd() const;
-
- UChar current() const;
- Direction direction() const;
-
- RenderBlock* block;
- RenderObject* obj;
- unsigned pos;
- int nextBreakablePosition;
-};
-
static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
{
bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline;
@@ -107,247 +78,6 @@ static int inlineWidth(RenderObject* child, bool start = true, bool end = true)
return extraWidth;
}
-struct BidiRun : BidiCharacterRun {
- BidiRun(int start, int stop, RenderObject* object, BidiContext* context, Direction dir)
- : BidiCharacterRun(start, stop, context, dir)
- , m_object(object)
- , m_box(0)
- {
- }
-
- void destroy();
-
- // Overloaded new operator.
- void* operator new(size_t, RenderArena*) throw();
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
-
- BidiRun* next() { return static_cast<BidiRun*>(m_next); }
-
-private:
- // The normal operator new is disallowed.
- void* operator new(size_t) throw();
-
-public:
- RenderObject* m_object;
- InlineBox* m_box;
-};
-
-#ifndef NDEBUG
-static RefCountedLeakCounter bidiRunCounter("BidiRun");
-
-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) throw()
-{
-#ifndef NDEBUG
- bidiRunCounter.increment();
-#endif
- return renderArena->allocate(sz);
-}
-
-void BidiRun::operator delete(void* ptr, size_t sz)
-{
-#ifndef NDEBUG
- bidiRunCounter.decrement();
-#endif
- ASSERT(inBidiRunDestroy);
-
- // Stash size where destroy() can find it.
- *(size_t*)ptr = sz;
-}
-
-// ---------------------------------------------------------------------
-
-inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
-{
- return it1.pos == it2.pos && it1.obj == it2.obj;
-}
-
-inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
-{
- return it1.pos != it2.pos || it1.obj != it2.obj;
-}
-
-static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0)
-{
- RenderObject* next = 0;
- bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
- bool endOfInline = false;
-
- while (current) {
- next = 0;
- if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
- next = current->firstChild();
- if (next && resolver && next->isRenderInline()) {
- EUnicodeBidi ub = next->style()->unicodeBidi();
- if (ub != UBNormal) {
- TextDirection dir = next->style()->direction();
- Direction d = (ub == Embed
- ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)
- : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
- resolver->embed(d);
- }
- }
- }
-
- if (!next) {
- if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {
- next = current;
- endOfInline = true;
- break;
- }
-
- while (current && current != block) {
- if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)
- resolver->embed(PopDirectionalFormat);
-
- next = current->nextSibling();
- if (next) {
- if (resolver && next->isRenderInline()) {
- EUnicodeBidi ub = next->style()->unicodeBidi();
- if (ub != UBNormal) {
- TextDirection dir = next->style()->direction();
- Direction d = (ub == Embed
- ? (dir == RTL ? RightToLeftEmbedding: LeftToRightEmbedding)
- : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
- resolver->embed(d);
- }
- }
- break;
- }
-
- current = current->parent();
- if (!skipInlines && current && current != block && current->isRenderInline()) {
- next = current;
- endOfInline = true;
- break;
- }
- }
- }
-
- if (!next)
- break;
-
- if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()
- || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.
- && next->isRenderInline()))
- break;
- current = next;
- }
-
- if (endOfInlinePtr)
- *endOfInlinePtr = endOfInline;
-
- return next;
-}
-
-static RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true)
-{
- if (!block->firstChild())
- return 0;
-
- RenderObject* o = block->firstChild();
- if (o->isRenderInline()) {
- if (resolver) {
- EUnicodeBidi ub = o->style()->unicodeBidi();
- if (ub != UBNormal) {
- TextDirection dir = o->style()->direction();
- Direction d = (ub == Embed
- ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)
- : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));
- resolver->embed(d);
- }
- }
- if (skipInlines && o->firstChild())
- o = bidiNext(block, o, resolver, skipInlines);
- else {
- // Never skip empty inlines.
- if (resolver)
- resolver->commitExplicitEmbedding();
- return o;
- }
- }
-
- if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())
- o = bidiNext(block, o, resolver, skipInlines);
-
- if (resolver)
- resolver->commitExplicitEmbedding();
- return o;
-}
-
-inline void InlineIterator::increment(InlineBidiResolver* resolver)
-{
- if (!obj)
- return;
- if (obj->isText()) {
- pos++;
- if (pos >= toRenderText(obj)->textLength()) {
- obj = bidiNext(block, obj, resolver);
- pos = 0;
- nextBreakablePosition = -1;
- }
- } else {
- obj = bidiNext(block, obj, resolver);
- pos = 0;
- nextBreakablePosition = -1;
- }
-}
-
-template<>
-inline void InlineBidiResolver::increment()
-{
- current.increment(this);
-}
-
-inline bool InlineIterator::atEnd() const
-{
- return !obj;
-}
-
-inline UChar InlineIterator::current() const
-{
- if (!obj || !obj->isText())
- return 0;
-
- RenderText* text = toRenderText(obj);
- if (pos >= text->textLength())
- return 0;
-
- return text->characters()[pos];
-}
-
-ALWAYS_INLINE Direction InlineIterator::direction() const
-{
- if (UChar c = current())
- return Unicode::direction(c);
-
- if (obj && obj->isListMarker())
- return obj->style()->direction() == LTR ? LeftToRight : RightToLeft;
-
- return OtherNeutral;
-}
-
-// -------------------------------------------------------------------------------------------------
-
static void chopMidpointsAt(LineMidpointState& lineMidpointState, RenderObject* obj, unsigned pos)
{
if (!lineMidpointState.numMidpoints)
@@ -405,7 +135,7 @@ static void addMidpoint(LineMidpointState& lineMidpointState, const InlineIterat
midpoints[lineMidpointState.numMidpoints++] = midpoint;
}
-static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
+void RenderBlock::appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
{
if (start > end || obj->isFloating() ||
(obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline()))
@@ -448,36 +178,6 @@ static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBid
}
}
-template <>
-void InlineBidiResolver::appendRun()
-{
- if (!emptyRun && !eor.atEnd()) {
- int start = sor.pos;
- RenderObject *obj = sor.obj;
- while (obj && obj != eor.obj && obj != endOfLine.obj) {
- appendRunsForObject(start, obj->length(), obj, *this);
- start = 0;
- obj = bidiNext(sor.block, obj);
- }
- if (obj) {
- unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX;
- if (obj == endOfLine.obj && endOfLine.pos <= pos) {
- reachedEndOfLine = true;
- pos = endOfLine.pos;
- }
- // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
- int end = obj->length() ? pos+1 : 0;
- appendRunsForObject(start, end, obj, *this);
- }
-
- eor.increment();
- sor = eor;
- }
-
- m_direction = OtherNeutral;
- m_status.eor = OtherNeutral;
-}
-
static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
{
if (isRootLineBox)
@@ -1551,7 +1251,7 @@ static bool inlineFlowRequiresLineBox(RenderInline* flow)
return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();
}
-static inline bool requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
+bool RenderBlock::requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
{
if (it.obj->isFloatingOrPositioned())
return false;
@@ -2265,19 +1965,12 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
lBreak.nextBreakablePosition = -1;
}
} else if (lBreak.obj) {
- if (last != o && !last->isListMarker()) {
- // better to break between object boundaries than in the middle of a word (except for list markers)
- lBreak.obj = o;
- lBreak.pos = 0;
- lBreak.nextBreakablePosition = -1;
- } else {
- // Don't ever break in the middle of a word if we can help it.
- // There's no room at all. We just have to be on this line,
- // even though we'll spill out.
- lBreak.obj = o;
- lBreak.pos = pos;
- lBreak.nextBreakablePosition = -1;
- }
+ // Don't ever break in the middle of a word if we can help it.
+ // There's no room at all. We just have to be on this line,
+ // even though we'll spill out.
+ lBreak.obj = o;
+ lBreak.pos = pos;
+ lBreak.nextBreakablePosition = -1;
}
}
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 60230d4..92c3d99 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -2951,9 +2951,9 @@ void RenderBox::clearLayoutOverflow()
#if ENABLE(SVG)
-TransformationMatrix RenderBox::localTransform() const
+AffineTransform RenderBox::localTransform() const
{
- return TransformationMatrix(1, 0, 0, 1, x(), y());
+ return AffineTransform(1, 0, 0, 1, x(), y());
}
#endif
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 11c65e8..401a46d 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -297,7 +297,7 @@ public:
virtual bool avoidsFloats() const;
#if ENABLE(SVG)
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
#endif
protected:
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index a68c930..f8bf05e 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -50,7 +50,7 @@ static const double cLowQualityTimeThreshold = 0.500; // 500 ms
class RenderBoxModelScaleData : public Noncopyable {
public:
- RenderBoxModelScaleData(RenderBoxModelObject* object, const IntSize& size, const TransformationMatrix& transform, double time, bool lowQualityScale)
+ RenderBoxModelScaleData(RenderBoxModelObject* object, const IntSize& size, const AffineTransform& transform, double time, bool lowQualityScale)
: m_size(size)
, m_transform(transform)
, m_lastPaintTime(time)
@@ -71,8 +71,8 @@ public:
double lastPaintTime() const { return m_lastPaintTime; }
void setLastPaintTime(double t) { m_lastPaintTime = t; }
bool useLowQualityScale() const { return m_lowQualityScale; }
- const TransformationMatrix& transform() const { return m_transform; }
- void setTransform(const TransformationMatrix& transform) { m_transform = transform; }
+ const AffineTransform& transform() const { return m_transform; }
+ void setTransform(const AffineTransform& transform) { m_transform = transform; }
void setUseLowQualityScale(bool b)
{
m_highQualityRepaintTimer.stop();
@@ -83,7 +83,7 @@ public:
private:
IntSize m_size;
- TransformationMatrix m_transform;
+ AffineTransform m_transform;
double m_lastPaintTime;
bool m_lowQualityScale;
Timer<RenderBoxModelObject> m_highQualityRepaintTimer;
@@ -130,7 +130,7 @@ bool RenderBoxModelScaleObserver::shouldPaintBackgroundAtLowQuality(GraphicsCont
if (gBoxModelObjects)
data = gBoxModelObjects->get(object);
- const TransformationMatrix& currentTransform = context->getCTM();
+ const AffineTransform& currentTransform = context->getCTM();
bool contextIsScaled = !currentTransform.isIdentityOrTranslation();
if (!contextIsScaled && imageSize == size) {
// There is no scale in effect. If we had a scale in effect before, we can just delete this data.
@@ -1390,7 +1390,7 @@ void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int
// edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
// by one pixel.
if (hasOpaqueBackground) {
- TransformationMatrix currentTransformation = context->getCTM();
+ AffineTransform currentTransformation = context->getCTM();
if (currentTransformation.a() != 1 || (currentTransformation.d() != 1 && currentTransformation.d() != -1)
|| currentTransformation.b() || currentTransformation.c())
rectToClipOut.inflate(-1);
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index 6597554..5bb4439 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -38,10 +38,10 @@ RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
{
}
-TransformationMatrix RenderForeignObject::translationForAttributes() const
+FloatPoint RenderForeignObject::translationForAttributes() const
{
SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
- return TransformationMatrix().translate(foreign->x().value(foreign), foreign->y().value(foreign));
+ return FloatPoint(foreign->x().value(foreign), foreign->y().value(foreign));
}
void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
@@ -88,9 +88,10 @@ void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintCon
RenderBlock::computeRectForRepaint(repaintContainer, rect, fixed);
}
-const TransformationMatrix& RenderForeignObject::localToParentTransform() const
+const AffineTransform& RenderForeignObject::localToParentTransform() const
{
- m_localToParentTransform = localTransform() * translationForAttributes();
+ FloatPoint attributeTranslation(translationForAttributes());
+ m_localToParentTransform = localTransform().translateRight(attributeTranslation.x(), attributeTranslation.y());
return m_localToParentTransform;
}
diff --git a/WebCore/rendering/RenderForeignObject.h b/WebCore/rendering/RenderForeignObject.h
index 8cb9a55..f32069c 100644
--- a/WebCore/rendering/RenderForeignObject.h
+++ b/WebCore/rendering/RenderForeignObject.h
@@ -23,7 +23,8 @@
#define RenderForeignObject_h
#if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
-#include "TransformationMatrix.h"
+#include "AffineTransform.h"
+#include "FloatPoint.h"
#include "RenderSVGBlock.h"
namespace WebCore {
@@ -38,7 +39,7 @@ public:
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual const TransformationMatrix& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
virtual bool requiresLayer() const { return false; }
@@ -55,12 +56,12 @@ public:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const;
private:
- TransformationMatrix translationForAttributes() const;
+ FloatPoint translationForAttributes() const;
- virtual TransformationMatrix localTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
- TransformationMatrix m_localTransform;
- mutable TransformationMatrix m_localToParentTransform;
+ AffineTransform m_localTransform;
+ mutable AffineTransform m_localToParentTransform;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderFrame.cpp b/WebCore/rendering/RenderFrame.cpp
index 482d10d..8f704e3 100644
--- a/WebCore/rendering/RenderFrame.cpp
+++ b/WebCore/rendering/RenderFrame.cpp
@@ -26,6 +26,7 @@
#include "FrameView.h"
#include "HTMLFrameElement.h"
+#include "RenderView.h"
#ifdef FLATTEN_FRAMESET
#include "Frame.h"
@@ -64,6 +65,7 @@ void RenderFrame::viewCleared()
view->setMarginHeight(marginh);
}
+<<<<<<< HEAD
#ifdef FLATTEN_FRAMESET
void RenderFrame::layout()
{
@@ -92,5 +94,58 @@ void RenderFrame::layout()
setNeedsLayout(false);
}
#endif
+=======
+void RenderFrame::layoutWithFlattening(bool fixedWidth, bool fixedHeight)
+{
+ // NOTE: The width and height have been set at this point by
+ // RenderFrameSet::positionFramesWithFlattening()
+
+ FrameView* childFrameView = static_cast<FrameView*>(widget());
+ RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0;
+ HTMLFrameElement* element = static_cast<HTMLFrameElement*>(node());
+
+ // Do not expand framesets which has zero width or height
+ if (!width() || !height() || !childRoot) {
+ updateWidgetPosition();
+ if (childFrameView)
+ childFrameView->layout();
+ setNeedsLayout(false);
+ return;
+ }
+
+ // need to update to calculate min/max correctly
+ updateWidgetPosition();
+ if (childRoot->prefWidthsDirty())
+ childRoot->calcPrefWidths();
+
+ // if scrollbars are off, and the width or height are fixed
+ // we obey them and do not expand. With frame flattening
+ // no subframe much ever become scrollable.
+
+ bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff;
+
+ // make sure minimum preferred width is enforced
+ if (isScrollable || !fixedWidth || childRoot->isFrameSet())
+ setWidth(max(width(), childRoot->minPrefWidth()));
+
+ // update again to pass the width to the child frame
+ updateWidgetPosition();
+ childFrameView->layout();
+
+ // expand the frame by setting frame height = content height
+ if (isScrollable || !fixedHeight || childRoot->isFrameSet())
+ setHeight(max(height(), childFrameView->contentsHeight()));
+ if (isScrollable || !fixedWidth || childRoot->isFrameSet())
+ setWidth(max(width(), childFrameView->contentsWidth()));
+
+ updateWidgetPosition();
+
+ ASSERT(!childFrameView->layoutPending());
+ ASSERT(!childRoot->needsLayout());
+ ASSERT(!childRoot->firstChild() || !childRoot->firstChild()->firstChild() || !childRoot->firstChild()->firstChild()->needsLayout());
+
+ setNeedsLayout(false);
+}
+>>>>>>> webkit.org at r54731
} // namespace WebCore
diff --git a/WebCore/rendering/RenderFrame.h b/WebCore/rendering/RenderFrame.h
index 5b3b533..a66aa14 100644
--- a/WebCore/rendering/RenderFrame.h
+++ b/WebCore/rendering/RenderFrame.h
@@ -35,6 +35,7 @@ public:
RenderFrame(HTMLFrameElement*);
FrameEdgeInfo edgeInfo() const;
+ void layoutWithFlattening(bool fixedWidth, bool fixedHeight);
private:
virtual const char* renderName() const { return "RenderFrame"; }
diff --git a/WebCore/rendering/RenderFrameSet.cpp b/WebCore/rendering/RenderFrameSet.cpp
index 09ad11f..cf78b2b 100644
--- a/WebCore/rendering/RenderFrameSet.cpp
+++ b/WebCore/rendering/RenderFrameSet.cpp
@@ -36,6 +36,7 @@
#include "MouseEvent.h"
#include "RenderFrame.h"
#include "RenderView.h"
+#include "Settings.h"
namespace WebCore {
@@ -496,7 +497,10 @@ void RenderFrameSet::layout()
}
#endif
- positionFrames();
+ if (flattenFrameSet())
+ positionFramesWithFlattening();
+ else
+ positionFrames();
RenderBox::layout();
@@ -635,6 +639,119 @@ void RenderFrameSet::positionFrames()
}
}
+void RenderFrameSet::positionFramesWithFlattening()
+{
+ RenderBox* child = firstChildBox();
+ if (!child)
+ return;
+
+ int rows = frameSet()->totalRows();
+ int cols = frameSet()->totalCols();
+
+ int borderThickness = frameSet()->border();
+ bool repaintNeeded = false;
+
+ // calculate frameset height based on actual content height to eliminate scrolling
+ bool out = false;
+ for (int r = 0; r < rows && !out; r++) {
+ int extra = 0;
+ int height = m_rows.m_sizes[r];
+
+ for (int c = 0; c < cols; c++) {
+ IntRect oldFrameRect = child->frameRect();
+
+ int width = m_cols.m_sizes[c];
+
+ bool fixedWidth = frameSet()->colLengths() && frameSet()->colLengths()[c].isFixed();
+ bool fixedHeight = frameSet()->rowLengths() && frameSet()->rowLengths()[r].isFixed();
+
+ // has to be resized and itself resize its contents
+ if (!fixedWidth)
+ child->setWidth(width ? width + extra / (cols - c) : 0);
+ else
+ child->setWidth(width);
+ child->setHeight(height);
+
+ child->setNeedsLayout(true);
+
+ if (child->isFrameSet())
+ toRenderFrameSet(child)->layout();
+ else
+ toRenderFrame(child)->layoutWithFlattening(fixedWidth, fixedHeight);
+
+ if (child->height() > m_rows.m_sizes[r])
+ m_rows.m_sizes[r] = child->height();
+ if (child->width() > m_cols.m_sizes[c])
+ m_cols.m_sizes[c] = child->width();
+
+ if (child->frameRect() != oldFrameRect)
+ repaintNeeded = true;
+
+ // difference between calculated frame width and the width it actually decides to have
+ extra += width - m_cols.m_sizes[c];
+
+ child = child->nextSiblingBox();
+ if (!child) {
+ out = true;
+ break;
+ }
+ }
+ }
+
+ int xPos = 0;
+ int yPos = 0;
+ out = false;
+ child = firstChildBox();
+ for (int r = 0; r < rows && !out; r++) {
+ xPos = 0;
+ for (int c = 0; c < cols; c++) {
+ // ensure the rows and columns are filled
+ IntRect oldRect = child->frameRect();
+
+ child->setLocation(xPos, yPos);
+ child->setHeight(m_rows.m_sizes[r]);
+ child->setWidth(m_cols.m_sizes[c]);
+
+ if (child->frameRect() != oldRect) {
+ repaintNeeded = true;
+
+ // update to final size
+ child->setNeedsLayout(true);
+ if (child->isFrameSet())
+ toRenderFrameSet(child)->layout();
+ else
+ toRenderFrame(child)->layoutWithFlattening(true, true);
+ }
+
+ xPos += m_cols.m_sizes[c] + borderThickness;
+ child = child->nextSiblingBox();
+ if (!child) {
+ out = true;
+ break;
+ }
+ }
+ yPos += m_rows.m_sizes[r] + borderThickness;
+ }
+
+ setWidth(xPos - borderThickness);
+ setHeight(yPos - borderThickness);
+
+ if (repaintNeeded)
+ repaint();
+
+ // all the remaining frames are hidden to avoid ugly spurious unflowed frames
+ for (; child; child = child->nextSiblingBox()) {
+ child->setWidth(0);
+ child->setHeight(0);
+ child->setNeedsLayout(false);
+ }
+}
+
+bool RenderFrameSet::flattenFrameSet() const
+{
+ return document()->frame() && document()->frame()->settings()->frameSetFlatteningEnabled();
+}
+
void RenderFrameSet::startResizing(GridAxis& axis, int position)
{
int split = hitTestSplit(axis, position);
@@ -663,6 +780,9 @@ void RenderFrameSet::continueResizing(GridAxis& axis, int position)
bool RenderFrameSet::userResize(MouseEvent* evt)
{
+ if (flattenFrameSet())
+ return false;
+
if (!m_isResizing) {
if (needsLayout())
return false;
diff --git a/WebCore/rendering/RenderFrameSet.h b/WebCore/rendering/RenderFrameSet.h
index ef92c39..0e8ef2f 100644
--- a/WebCore/rendering/RenderFrameSet.h
+++ b/WebCore/rendering/RenderFrameSet.h
@@ -70,9 +70,13 @@ public:
bool canResizeRow(const IntPoint&) const;
bool canResizeColumn(const IntPoint&) const;
+<<<<<<< HEAD
#ifdef FLATTEN_FRAMESET
void setGridNeedsLayout() { m_gridCalculated = false; }
#endif
+=======
+ bool flattenFrameSet() const;
+>>>>>>> webkit.org at r54731
private:
static const int noSplit = -1;
@@ -108,6 +112,7 @@ private:
void computeEdgeInfo();
void fillFromEdgeInfo(const FrameEdgeInfo& edgeInfo, int r, int c);
void positionFrames();
+ void positionFramesWithFlattening();
int splitPosition(const GridAxis&, int split) const;
int hitTestSplit(const GridAxis&, int position) const;
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 38e5f44..645edf9 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -1934,8 +1934,8 @@ RenderLayer::updateScrollInfoAfterLayout()
// Set up the range (and page step/line step).
if (m_hBar) {
int clientWidth = box->clientWidth();
- int pageStep = max(clientWidth * cFractionToStepWhenPaging, 1.f);
- m_hBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
+ int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
+ m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_hBar->setProportion(clientWidth, m_scrollWidth);
// Explicitly set the horizontal scroll value. This ensures that when a
// right-to-left scrollable area's width (or content width) changes, the
@@ -1949,8 +1949,8 @@ RenderLayer::updateScrollInfoAfterLayout()
}
if (m_vBar) {
int clientHeight = box->clientHeight();
- int pageStep = max(clientHeight * cFractionToStepWhenPaging, 1.f);
- m_vBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
+ int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
+ m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
@@ -2241,7 +2241,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Apply the transform.
p->save();
- p->concatCTM(transform);
+ p->concatCTM(transform.toAffineTransform());
// Now do a paint with the root layer shifted to be us.
paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index f67bc0f..d0353ee 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -41,6 +41,8 @@ namespace WebCore {
const int cMarkerPadding = 7;
+enum SequenceType { NumericSequence, AlphabeticSequence };
+
static String toRoman(int number, bool upper)
{
// FIXME: CSS3 describes how to make this work for much larger numbers,
@@ -78,31 +80,63 @@ static String toRoman(int number, bool upper)
return String(&letters[lettersSize - length], length);
}
-static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize)
+static inline String toAlphabeticOrNumeric(int number, const UChar* sequence, int sequenceSize, SequenceType type)
{
- ASSERT(alphabetSize >= 10);
+ ASSERT(sequenceSize >= 2);
- if (number < 1)
- return String::number(number);
+ const int lettersSize = sizeof(number) * 8 + 1; // Binary is the worst case; requires one character per bit plus a minus sign.
- const int lettersSize = 10; // big enough for a 32-bit int, with a 10-letter alphabet
UChar letters[lettersSize];
- --number;
- letters[lettersSize - 1] = alphabet[number % alphabetSize];
+ bool isNegativeNumber = false;
+ unsigned numberShadow = number;
+ if (type == AlphabeticSequence) {
+ ASSERT(number > 0);
+ --numberShadow;
+ } else if (number < 0) {
+ numberShadow = -number;
+ isNegativeNumber = true;
+ }
+ letters[lettersSize - 1] = sequence[numberShadow % sequenceSize];
int length = 1;
- while ((number /= alphabetSize) > 0)
- letters[lettersSize - ++length] = alphabet[number % alphabetSize - 1];
+
+ if (type == AlphabeticSequence) {
+ while ((numberShadow /= sequenceSize) > 0)
+ letters[lettersSize - ++length] = sequence[numberShadow % sequenceSize - 1];
+ } else {
+ while ((numberShadow /= sequenceSize) > 0)
+ letters[lettersSize - ++length] = sequence[numberShadow % sequenceSize];
+ }
+ if (isNegativeNumber)
+ letters[lettersSize - ++length] = hyphenMinus;
ASSERT(length <= lettersSize);
return String(&letters[lettersSize - length], length);
}
+static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize)
+{
+ if (number < 1)
+ return String::number(number);
+
+ return toAlphabeticOrNumeric(number, alphabet, alphabetSize, AlphabeticSequence);
+}
+
+static String toNumeric(int number, const UChar* numerals, int numeralsSize)
+{
+ return toAlphabeticOrNumeric(number, numerals, numeralsSize, NumericSequence);
+}
+
template <size_t size> static inline String toAlphabetic(int number, const UChar(&alphabet)[size])
{
return toAlphabetic(number, alphabet, size);
}
+template <size_t size> static inline String toNumeric(int number, const UChar(&alphabet)[size])
+{
+ return toNumeric(number, alphabet, size);
+}
+
static int toHebrewUnder1000(int number, UChar letters[5])
{
// FIXME: CSS3 mentions various refinements not implemented here.
@@ -383,29 +417,51 @@ static UChar listMarkerSuffix(EListStyleType type)
case TigrinyaEtAbegede:
return ethiopicPrefaceColon;
case Armenian:
+ case ArabicIndic:
+ case Bengali:
+ case BinaryListStyle:
+ case Cambodian:
case CJKIdeographic:
case CjkEarthlyBranch:
case CjkHeavenlyStem:
case DecimalLeadingZero:
case DecimalListStyle:
+ case Devanagari:
case Georgian:
+ case Gujarati:
+ case Gurmukhi:
case Hangul:
case HangulConsonant:
case Hebrew:
case Hiragana:
case HiraganaIroha:
+ case Kannada:
case Katakana:
case KatakanaIroha:
+ case Khmer:
+ case Lao:
case LowerAlpha:
case LowerGreek:
+ case LowerHexadecimal:
case LowerLatin:
case LowerNorwegian:
case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
+ case Persian:
+ case Telugu:
+ case Thai:
+ case Tibetan:
case UpperAlpha:
case UpperGreek:
+ case UpperHexadecimal:
case UpperLatin:
case UpperNorwegian:
case UpperRoman:
+ case Urdu:
return '.';
}
@@ -439,6 +495,129 @@ String listMarkerText(EListStyleType type, int value)
return "-0" + String::number(-value); // -01 to -09
return "0" + String::number(value); // 00 to 09
+ case ArabicIndic: {
+ static const UChar arabicIndicNumerals[10] = {
+ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669
+ };
+ return toNumeric(value, arabicIndicNumerals);
+ }
+ case BinaryListStyle: {
+ static const UChar binaryNumerals[2] = {
+ '0', '1'
+ };
+ return toNumeric(value, binaryNumerals);
+ }
+ case Bengali: {
+ static const UChar bengaliNumerals[10] = {
+ 0x09E6, 0x09E7, 0x09E8, 0x09E9, 0x09EA, 0x09EB, 0x09EC, 0x09ED, 0x09EE, 0x09EF
+ };
+ return toNumeric(value, bengaliNumerals);
+ }
+ case Cambodian:
+ case Khmer: {
+ static const UChar khmerNumerals[10] = {
+ 0x17E0, 0x17E1, 0x17E2, 0x17E3, 0x17E4, 0x17E5, 0x17E6, 0x17E7, 0x17E8, 0x17E9
+ };
+ return toNumeric(value, khmerNumerals);
+ }
+ case Devanagari: {
+ static const UChar devanagariNumerals[10] = {
+ 0x0966, 0x0967, 0x0968, 0x0969, 0x096A, 0x096B, 0x096C, 0x096D, 0x096E, 0x096F
+ };
+ return toNumeric(value, devanagariNumerals);
+ }
+ case Gujarati: {
+ static const UChar gujaratiNumerals[10] = {
+ 0x0AE6, 0x0AE7, 0x0AE8, 0x0AE9, 0x0AEA, 0x0AEB, 0x0AEC, 0x0AED, 0x0AEE, 0x0AEF
+ };
+ return toNumeric(value, gujaratiNumerals);
+ }
+ case Gurmukhi: {
+ static const UChar gurmukhiNumerals[10] = {
+ 0x0A66, 0x0A67, 0x0A68, 0x0A69, 0x0A6A, 0x0A6B, 0x0A6C, 0x0A6D, 0x0A6E, 0x0A6F
+ };
+ return toNumeric(value, gurmukhiNumerals);
+ }
+ case Kannada: {
+ static const UChar kannadaNumerals[10] = {
+ 0x0CE6, 0x0CE7, 0x0CE8, 0x0CE9, 0x0CEA, 0x0CEB, 0x0CEC, 0x0CED, 0x0CEE, 0x0CEF
+ };
+ return toNumeric(value, kannadaNumerals);
+ }
+ case LowerHexadecimal: {
+ static const UChar lowerHexadecimalNumerals[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ return toNumeric(value, lowerHexadecimalNumerals);
+ }
+ case Lao: {
+ static const UChar laoNumerals[10] = {
+ 0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5, 0x0ED6, 0x0ED7, 0x0ED8, 0x0ED9
+ };
+ return toNumeric(value, laoNumerals);
+ }
+ case Malayalam: {
+ static const UChar malayalamNumerals[10] = {
+ 0x0D66, 0x0D67, 0x0D68, 0x0D69, 0x0D6A, 0x0D6B, 0x0D6C, 0x0D6D, 0x0D6E, 0x0D6F
+ };
+ return toNumeric(value, malayalamNumerals);
+ }
+ case Mongolian: {
+ static const UChar mongolianNumerals[10] = {
+ 0x1810, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1817, 0x1818, 0x1819
+ };
+ return toNumeric(value, mongolianNumerals);
+ }
+ case Myanmar: {
+ static const UChar myanmarNumerals[10] = {
+ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049
+ };
+ return toNumeric(value, myanmarNumerals);
+ }
+ case Octal: {
+ static const UChar octalNumerals[8] = {
+ '0', '1', '2', '3', '4', '5', '6', '7'
+ };
+ return toNumeric(value, octalNumerals);
+ }
+ case Oriya: {
+ static const UChar oriyaNumerals[10] = {
+ 0x0B66, 0x0B67, 0x0B68, 0x0B69, 0x0B6A, 0x0B6B, 0x0B6C, 0x0B6D, 0x0B6E, 0x0B6F
+ };
+ return toNumeric(value, oriyaNumerals);
+ }
+ case Persian:
+ case Urdu: {
+ static const UChar urduNumerals[10] = {
+ 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9
+ };
+ return toNumeric(value, urduNumerals);
+ }
+ case Telugu: {
+ static const UChar teluguNumerals[10] = {
+ 0x0C66, 0x0C67, 0x0C68, 0x0C69, 0x0C6A, 0x0C6B, 0x0C6C, 0x0C6D, 0x0C6E, 0x0C6F
+ };
+ return toNumeric(value, teluguNumerals);
+ }
+ case Tibetan: {
+ static const UChar tibetanNumerals[10] = {
+ 0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24, 0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29
+ };
+ return toNumeric(value, tibetanNumerals);
+ }
+ case Thai: {
+ static const UChar thaiNumerals[10] = {
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59
+ };
+ return toNumeric(value, thaiNumerals);
+ }
+ case UpperHexadecimal: {
+ static const UChar upperHexadecimalNumerals[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+ return toNumeric(value, upperHexadecimalNumerals);
+ }
+
case LowerAlpha:
case LowerLatin: {
static const UChar lowerLatinAlphabet[26] = {
@@ -851,12 +1030,17 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
case Afar:
case Amharic:
case AmharicAbegede:
+ case ArabicIndic:
case Armenian:
+ case BinaryListStyle:
+ case Bengali:
+ case Cambodian:
case CJKIdeographic:
case CjkEarthlyBranch:
case CjkHeavenlyStem:
case DecimalLeadingZero:
case DecimalListStyle:
+ case Devanagari:
case Ethiopic:
case EthiopicAbegede:
case EthiopicAbegedeAmEt:
@@ -874,21 +1058,36 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
case EthiopicHalehameTiEt:
case EthiopicHalehameTig:
case Georgian:
+ case Gujarati:
+ case Gurmukhi:
case Hangul:
case HangulConsonant:
case Hebrew:
case Hiragana:
case HiraganaIroha:
+ case Kannada:
case Katakana:
case KatakanaIroha:
+ case Khmer:
+ case Lao:
case LowerAlpha:
case LowerGreek:
+ case LowerHexadecimal:
case LowerLatin:
case LowerNorwegian:
case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
case Oromo:
+ case Persian:
case Sidama:
case Somali:
+ case Telugu:
+ case Thai:
+ case Tibetan:
case Tigre:
case TigrinyaEr:
case TigrinyaErAbegede:
@@ -896,9 +1095,11 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
case TigrinyaEtAbegede:
case UpperAlpha:
case UpperGreek:
+ case UpperHexadecimal:
case UpperLatin:
case UpperNorwegian:
case UpperRoman:
+ case Urdu:
break;
}
if (m_text.isEmpty())
@@ -1004,12 +1205,17 @@ void RenderListMarker::calcPrefWidths()
case Afar:
case Amharic:
case AmharicAbegede:
+ case ArabicIndic:
case Armenian:
+ case BinaryListStyle:
+ case Bengali:
+ case Cambodian:
case CJKIdeographic:
case CjkEarthlyBranch:
case CjkHeavenlyStem:
case DecimalLeadingZero:
case DecimalListStyle:
+ case Devanagari:
case Ethiopic:
case EthiopicAbegede:
case EthiopicAbegedeAmEt:
@@ -1027,21 +1233,36 @@ void RenderListMarker::calcPrefWidths()
case EthiopicHalehameTiEt:
case EthiopicHalehameTig:
case Georgian:
+ case Gujarati:
+ case Gurmukhi:
case Hangul:
case HangulConsonant:
case Hebrew:
case Hiragana:
case HiraganaIroha:
+ case Kannada:
case Katakana:
case KatakanaIroha:
+ case Khmer:
+ case Lao:
case LowerAlpha:
case LowerGreek:
+ case LowerHexadecimal:
case LowerLatin:
case LowerNorwegian:
case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
case Oromo:
+ case Persian:
case Sidama:
case Somali:
+ case Telugu:
+ case Thai:
+ case Tibetan:
case Tigre:
case TigrinyaEr:
case TigrinyaErAbegede:
@@ -1049,9 +1270,11 @@ void RenderListMarker::calcPrefWidths()
case TigrinyaEtAbegede:
case UpperAlpha:
case UpperGreek:
+ case UpperHexadecimal:
case UpperLatin:
case UpperNorwegian:
case UpperRoman:
+ case Urdu:
m_text = listMarkerText(type, m_listItem->value());
if (m_text.isEmpty())
width = 0;
@@ -1185,12 +1408,17 @@ IntRect RenderListMarker::getRelativeMarkerRect()
case Afar:
case Amharic:
case AmharicAbegede:
+ case ArabicIndic:
case Armenian:
+ case BinaryListStyle:
+ case Bengali:
+ case Cambodian:
case CJKIdeographic:
case CjkEarthlyBranch:
case CjkHeavenlyStem:
case DecimalLeadingZero:
case DecimalListStyle:
+ case Devanagari:
case Ethiopic:
case EthiopicAbegede:
case EthiopicAbegedeAmEt:
@@ -1208,21 +1436,36 @@ IntRect RenderListMarker::getRelativeMarkerRect()
case EthiopicHalehameTiEt:
case EthiopicHalehameTig:
case Georgian:
+ case Gujarati:
+ case Gurmukhi:
case Hangul:
case HangulConsonant:
case Hebrew:
case Hiragana:
case HiraganaIroha:
+ case Kannada:
case Katakana:
case KatakanaIroha:
+ case Khmer:
+ case Lao:
case LowerAlpha:
case LowerGreek:
+ case LowerHexadecimal:
case LowerLatin:
case LowerNorwegian:
case LowerRoman:
+ case Malayalam:
+ case Mongolian:
+ case Myanmar:
+ case Octal:
+ case Oriya:
case Oromo:
+ case Persian:
case Sidama:
case Somali:
+ case Telugu:
+ case Thai:
+ case Tibetan:
case Tigre:
case TigrinyaEr:
case TigrinyaErAbegede:
@@ -1230,9 +1473,11 @@ IntRect RenderListMarker::getRelativeMarkerRect()
case TigrinyaEtAbegede:
case UpperAlpha:
case UpperGreek:
+ case UpperHexadecimal:
case UpperLatin:
case UpperNorwegian:
case UpperRoman:
+ case Urdu:
if (m_text.isEmpty())
return IntRect();
const Font& font = style()->font();
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 0368490..1d1e7c2 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -114,6 +114,7 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
return image;
}
+#if ENABLE(RUBY)
if (node->hasTagName(rubyTag)) {
if (style->display() == INLINE)
return new (arena) RenderRubyAsInline(node);
@@ -123,6 +124,7 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
// treat <rt> as ruby text ONLY if it still has its default treatment of block
if (node->hasTagName(rtTag) && style->display() == BLOCK)
return new (arena) RenderRubyText(node);
+#endif
switch (style->display()) {
case NONE:
@@ -1686,6 +1688,15 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
if (diff == StyleDifferenceLayout) {
RenderCounter::rendererStyleChanged(this, oldStyle, m_style.get());
+
+ // If the object already needs layout, then setNeedsLayout won't do
+ // any work. But if the containing block has changed, then we may need
+ // to mark the new containing blocks for layout. The change that can
+ // directly affect the containing block of this object is a change to
+ // the position style.
+ if (m_needsLayout && oldStyle->position() != m_style->position())
+ markContainingBlocksForLayout();
+
setNeedsLayoutAndPrefWidthsRecalc();
} else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
setNeedsPositionedMovementLayout();
@@ -2523,27 +2534,18 @@ FloatRect RenderObject::repaintRectInLocalCoordinates() const
return FloatRect();
}
-TransformationMatrix RenderObject::localTransform() const
+AffineTransform RenderObject::localTransform() const
{
- static const TransformationMatrix identity;
+ static const AffineTransform identity;
return identity;
}
-const TransformationMatrix& RenderObject::localToParentTransform() const
+const AffineTransform& RenderObject::localToParentTransform() const
{
- static const TransformationMatrix identity;
+ static const AffineTransform identity;
return identity;
}
-TransformationMatrix RenderObject::absoluteTransform() const
-{
- // FIXME: This should use localToParentTransform(), but much of the SVG code
- // depends on RenderBox::absoluteTransform() being the sum of the localTransform()s of all parent renderers.
- if (parent())
- return localTransform() * parent()->absoluteTransform();
- return localTransform();
-}
-
bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 03ba1e6..6764818 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -26,6 +26,7 @@
#ifndef RenderObject_h
#define RenderObject_h
+#include "AffineTransform.h"
#include "CachedResourceClient.h"
#include "Document.h"
#include "Element.h"
@@ -282,10 +283,12 @@ public:
virtual bool isRenderPart() const { return false; }
virtual bool isRenderView() const { return false; }
virtual bool isReplica() const { return false; }
+#if ENABLE(RUBY)
virtual bool isRuby() const { return false; }
virtual bool isRubyBase() const { return false; }
virtual bool isRubyRun() const { return false; }
virtual bool isRubyText() const { return false; }
+#endif
virtual bool isSlider() const { return false; }
virtual bool isTable() const { return false; }
virtual bool isTableCell() const { return false; }
@@ -347,16 +350,11 @@ public:
// FIXME: This accessor is deprecated and mostly around for SVGRenderTreeAsText.
// This only returns the transform="" value from the element
// most callsites want localToParentTransform() instead.
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
// Returns the full transform mapping from local coordinates to local coords for the parent SVG renderer
// This includes any viewport transforms and x/y offsets as well as the transform="" value off the element.
- virtual const TransformationMatrix& localToParentTransform() const;
-
- // Walks up the parent chain to create a transform which maps from local to document coords
- // NOTE: This method is deprecated! It doesn't respect scroll offsets or repaint containers.
- // FIXME: This is only virtual so that RenderSVGHiddenContainer can override it to match old LayoutTest results.
- virtual TransformationMatrix absoluteTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
// SVG uses FloatPoint precise hit testing, and passes the point in parent
// coordinates instead of in repaint container coordinates. Eventually the
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index f497dcf..7dbde42 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -69,12 +69,12 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
{
}
-const TransformationMatrix& RenderPath::localToParentTransform() const
+const AffineTransform& RenderPath::localToParentTransform() const
{
return m_localTransform;
}
-TransformationMatrix RenderPath::localTransform() const
+AffineTransform RenderPath::localTransform() const
{
return m_localTransform;
}
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index be4c2dc..d530f3c 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -25,10 +25,10 @@
#define RenderPath_h
#if ENABLE(SVG)
+#include "AffineTransform.h"
#include "FloatRect.h"
#include "RenderSVGModelObject.h"
#include "SVGMarkerLayoutInfo.h"
-#include "TransformationMatrix.h"
namespace WebCore {
@@ -52,7 +52,7 @@ private:
virtual FloatRect markerBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
- virtual const TransformationMatrix& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
void setPath(const Path&);
@@ -68,7 +68,7 @@ private:
void calculateMarkerBoundsIfNeeded() const;
private:
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
mutable Path m_path;
mutable FloatRect m_cachedLocalFillBBox;
@@ -76,7 +76,7 @@ private:
mutable FloatRect m_cachedLocalRepaintRect;
mutable FloatRect m_cachedLocalMarkerBBox;
mutable SVGMarkerLayoutInfo m_markerLayoutInfo;
- TransformationMatrix m_localTransform;
+ AffineTransform m_localTransform;
};
inline RenderPath* toRenderPath(RenderObject* object)
diff --git a/WebCore/rendering/RenderRuby.cpp b/WebCore/rendering/RenderRuby.cpp
index 8d113f9..f13e2b4 100644
--- a/WebCore/rendering/RenderRuby.cpp
+++ b/WebCore/rendering/RenderRuby.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(RUBY)
#include "RenderRuby.h"
#include "RenderRubyRun.h"
@@ -192,3 +194,4 @@ void RenderRubyAsBlock::removeChild(RenderObject* child)
} // namespace WebCore
+#endif
diff --git a/WebCore/rendering/RenderRuby.h b/WebCore/rendering/RenderRuby.h
index 49a84d8..a5dafe9 100644
--- a/WebCore/rendering/RenderRuby.h
+++ b/WebCore/rendering/RenderRuby.h
@@ -31,6 +31,8 @@
#ifndef RenderRuby_h
#define RenderRuby_h
+#if ENABLE(RUBY)
+
#include "RenderBlock.h"
#include "RenderInline.h"
@@ -84,4 +86,6 @@ private:
} // namespace WebCore
+#endif
+
#endif // RenderRuby_h
diff --git a/WebCore/rendering/RenderRubyBase.cpp b/WebCore/rendering/RenderRubyBase.cpp
index 41ac4e3..65f9bc0 100644
--- a/WebCore/rendering/RenderRubyBase.cpp
+++ b/WebCore/rendering/RenderRubyBase.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(RUBY)
#include "RenderRubyBase.h"
namespace WebCore {
@@ -184,3 +186,5 @@ void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fr
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/rendering/RenderRubyBase.h b/WebCore/rendering/RenderRubyBase.h
index c029bd5..29c4858 100644
--- a/WebCore/rendering/RenderRubyBase.h
+++ b/WebCore/rendering/RenderRubyBase.h
@@ -31,6 +31,8 @@
#ifndef RenderRubyBase_h
#define RenderRubyBase_h
+#if ENABLE(RUBY)
+
#include "RenderBlock.h"
namespace WebCore {
@@ -60,4 +62,6 @@ private:
} // namespace WebCore
+#endif
+
#endif // RenderRubyBase_h
diff --git a/WebCore/rendering/RenderRubyRun.cpp b/WebCore/rendering/RenderRubyRun.cpp
index a3e6281..61be455 100644
--- a/WebCore/rendering/RenderRubyRun.cpp
+++ b/WebCore/rendering/RenderRubyRun.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(RUBY)
#include "RenderRubyRun.h"
#include "RenderRubyBase.h"
@@ -222,3 +224,5 @@ RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/rendering/RenderRubyRun.h b/WebCore/rendering/RenderRubyRun.h
index 222ddb6..acf359b 100644
--- a/WebCore/rendering/RenderRubyRun.h
+++ b/WebCore/rendering/RenderRubyRun.h
@@ -31,6 +31,8 @@
#ifndef RenderRubyRun_h
#define RenderRubyRun_h
+#if ENABLE(RUBY)
+
#include "RenderBlock.h"
namespace WebCore {
@@ -78,4 +80,6 @@ private:
} // namespace WebCore
+#endif
+
#endif // RenderRubyRun_h
diff --git a/WebCore/rendering/RenderRubyText.cpp b/WebCore/rendering/RenderRubyText.cpp
index cfe3b5c..1cf2b9e 100644
--- a/WebCore/rendering/RenderRubyText.cpp
+++ b/WebCore/rendering/RenderRubyText.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(RUBY)
#include "RenderRubyText.h"
namespace WebCore {
@@ -48,3 +50,5 @@ bool RenderRubyText::isChildAllowed(RenderObject* child, RenderStyle*) const
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/rendering/RenderRubyText.h b/WebCore/rendering/RenderRubyText.h
index e475914..865d179 100644
--- a/WebCore/rendering/RenderRubyText.h
+++ b/WebCore/rendering/RenderRubyText.h
@@ -31,6 +31,8 @@
#ifndef RenderRubyText_h
#define RenderRubyText_h
+#if ENABLE(RUBY)
+
#include "RenderBlock.h"
namespace WebCore {
@@ -49,4 +51,6 @@ public:
} // namespace WebCore
+#endif
+
#endif // RenderRubyText_h
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.h b/WebCore/rendering/RenderSVGHiddenContainer.h
index 0ef0a43..fdbd2bc 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.h
+++ b/WebCore/rendering/RenderSVGHiddenContainer.h
@@ -51,9 +51,6 @@ namespace WebCore {
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&);
- // FIXME: This override only exists to match existing LayoutTest results.
- virtual TransformationMatrix absoluteTransform() const { return TransformationMatrix(); }
-
virtual FloatRect objectBoundingBox() const;
virtual FloatRect repaintRectInLocalCoordinates() const;
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index c8fb132..96eeaf9 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -177,7 +177,6 @@ IntRect RenderSVGImage::clippedOverflowRectForRepaint(RenderBoxModelObject* repa
void RenderSVGImage::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- style()->svgStyle()->inflateForShadow(repaintRect);
SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 0558aed..8ed9146 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -24,17 +24,17 @@
#define RenderSVGImage_h
#if ENABLE(SVG)
+#include "AffineTransform.h"
#include "FloatRect.h"
#include "RenderImage.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
-#include "TransformationMatrix.h"
namespace WebCore {
class SVGImageElement;
- class RenderSVGImage : public RenderImage, SVGRenderBase {
+ class RenderSVGImage : public RenderImage, protected SVGRenderBase {
public:
RenderSVGImage(SVGImageElement*);
@@ -43,7 +43,7 @@ namespace WebCore {
virtual const char* renderName() const { return "RenderSVGImage"; }
virtual bool isSVGImage() const { return true; }
- virtual const TransformationMatrix& localToParentTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual FloatRect objectBoundingBox() const;
virtual FloatRect strokeBoundingBox() const { return m_localBounds; }
@@ -68,9 +68,9 @@ namespace WebCore {
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
- virtual TransformationMatrix localTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
- TransformationMatrix m_localTransform;
+ AffineTransform m_localTransform;
FloatRect m_localBounds;
mutable FloatRect m_cachedLocalRepaintRect;
};
diff --git a/WebCore/rendering/RenderSVGModelObject.cpp b/WebCore/rendering/RenderSVGModelObject.cpp
index 7a76fbd..3fab5a6 100644
--- a/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/WebCore/rendering/RenderSVGModelObject.cpp
@@ -56,7 +56,6 @@ IntRect RenderSVGModelObject::clippedOverflowRectForRepaint(RenderBoxModelObject
void RenderSVGModelObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- style()->svgStyle()->inflateForShadow(repaintRect);
SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 4a3bbcc..74172fc 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -129,7 +129,7 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
paintBoxDecorations(paintInfo, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y());
// An empty viewport disables rendering. FIXME: Should we still render filters?
- if (viewportSize().isEmpty())
+ if (m_viewportSize.isEmpty())
return;
// Don't paint if we don't have kids, except if we have filters we should paint those.
@@ -140,9 +140,8 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
RenderObject::PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
- // SVG does not support independent x/y clipping
- if (style()->overflowX() != OVISIBLE)
- childPaintInfo.context->clip(overflowClipRect(borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y()));
+ // Apply initial viewport clip - not affected by overflow handling
+ childPaintInfo.context->clip(overflowClipRect(borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y()));
// Convert from container offsets (html renderers) to a relative transform (svg renderers).
// Transform from our paint container's coordinate system to our local coords.
@@ -167,11 +166,6 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height(), style());
}
-const FloatSize& RenderSVGRoot::viewportSize() const
-{
- return m_viewportSize;
-}
-
void RenderSVGRoot::calcViewport()
{
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
@@ -196,13 +190,12 @@ void RenderSVGRoot::calcViewport()
// RenderBox methods will expect coordinates w/o any transforms in coordinates
// relative to our borderBox origin. This method gives us exactly that.
-TransformationMatrix RenderSVGRoot::localToBorderBoxTransform() const
+AffineTransform RenderSVGRoot::localToBorderBoxTransform() const
{
- TransformationMatrix ctm;
IntSize borderAndPadding = borderOriginToContentBox();
- ctm.translate(borderAndPadding.width(), borderAndPadding.height());
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
- ctm.scale(svg->currentScale());
+ float scale = svg->currentScale();
+ AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width(), borderAndPadding.height());
ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
return svg->viewBoxToViewTransform(width(), height()) * ctm;
}
@@ -217,31 +210,23 @@ IntSize RenderSVGRoot::borderOriginToContentBox() const
return IntSize(borderLeft() + paddingLeft(), borderTop() + paddingTop());
}
-TransformationMatrix RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
+AffineTransform RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
{
- TransformationMatrix parentToContainer;
- parentToContainer.translate(parentOriginInContainer.x(), parentOriginInContainer.y());
- return localToParentTransform() * parentToContainer;
+ AffineTransform parentToContainer(localToParentTransform());
+ return parentToContainer.translateRight(parentOriginInContainer.x(), parentOriginInContainer.y());
}
-const TransformationMatrix& RenderSVGRoot::localToParentTransform() const
+const AffineTransform& RenderSVGRoot::localToParentTransform() const
{
IntSize parentToBorderBoxOffset = parentOriginToBorderBox();
- TransformationMatrix borderBoxOriginToParentOrigin;
- borderBoxOriginToParentOrigin.translate(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
+ AffineTransform borderBoxOriginToParentOrigin(localToBorderBoxTransform());
+ borderBoxOriginToParentOrigin.translateRight(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
- m_localToParentTransform = localToBorderBoxTransform() * borderBoxOriginToParentOrigin;
+ m_localToParentTransform = borderBoxOriginToParentOrigin;
return m_localToParentTransform;
}
-// FIXME: This method should be removed as soon as callers to RenderBox::absoluteTransform() can be removed.
-TransformationMatrix RenderSVGRoot::absoluteTransform() const
-{
- // This would apply localTransform() twice if localTransform() were not the identity.
- return localToParentTransform() * RenderBox::absoluteTransform();
-}
-
FloatRect RenderSVGRoot::objectBoundingBox() const
{
return computeContainerBoundingBox(this, false);
@@ -255,9 +240,9 @@ FloatRect RenderSVGRoot::repaintRectInLocalCoordinates() const
return repaintRect;
}
-TransformationMatrix RenderSVGRoot::localTransform() const
+AffineTransform RenderSVGRoot::localTransform() const
{
- return TransformationMatrix();
+ return AffineTransform();
}
void RenderSVGRoot::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
@@ -265,6 +250,10 @@ void RenderSVGRoot::computeRectForRepaint(RenderBoxModelObject* repaintContainer
// Apply our local transforms (except for x/y translation), then our shadow,
// and then call RenderBox's method to handle all the normal CSS Box model bits
repaintRect = localToBorderBoxTransform().mapRect(repaintRect);
+
+ // Apply initial viewport clip - not affected by overflow settings
+ repaintRect.intersect(enclosingIntRect(FloatRect(FloatPoint(), m_viewportSize)));
+
style()->svgStyle()->inflateForShadow(repaintRect);
RenderBox::computeRectForRepaint(repaintContainer, repaintRect, fixed);
}
@@ -288,14 +277,9 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
IntPoint pointInBorderBox = pointInParent - parentOriginToBorderBox();
// Note: For now, we're ignoring hits to border and padding for <svg>
-
- if (style()->overflowX() == OHIDDEN) {
- // SVG doesn't support independent x/y overflow
- ASSERT(style()->overflowY() == OHIDDEN);
- IntPoint pointInContentBox = pointInBorderBox - borderOriginToContentBox();
- if (!contentBoxRect().contains(pointInContentBox))
- return false;
- }
+ IntPoint pointInContentBox = pointInBorderBox - borderOriginToContentBox();
+ if (!contentBoxRect().contains(pointInContentBox))
+ return false;
IntPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index b2f8f7c..8ad5e40 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -31,9 +31,9 @@
namespace WebCore {
class SVGStyledElement;
-class TransformationMatrix;
+class AffineTransform;
-class RenderSVGRoot : public RenderBox, SVGRenderBase {
+class RenderSVGRoot : public RenderBox, protected SVGRenderBase {
public:
RenderSVGRoot(SVGStyledElement*);
@@ -54,7 +54,7 @@ private:
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual const TransformationMatrix& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
bool fillContains(const FloatPoint&) const;
bool strokeContains(const FloatPoint&) const;
@@ -63,9 +63,8 @@ private:
virtual FloatRect strokeBoundingBox() const { return computeContainerBoundingBox(this, true); }
virtual FloatRect repaintRectInLocalCoordinates() const;
- // FIXME: Both of these overrides should be removed.
- virtual TransformationMatrix localTransform() const;
- virtual TransformationMatrix absoluteTransform() const;
+ // FIXME: This override should be removed.
+ virtual AffineTransform localTransform() const;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -74,18 +73,17 @@ private:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
void calcViewport();
- const FloatSize& viewportSize() const;
bool selfWillPaint() const;
IntSize parentOriginToBorderBox() const;
IntSize borderOriginToContentBox() const;
- TransformationMatrix localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const;
- TransformationMatrix localToBorderBoxTransform() const;
+ AffineTransform localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const;
+ AffineTransform localToBorderBoxTransform() const;
RenderObjectChildList m_children;
FloatSize m_viewportSize;
- mutable TransformationMatrix m_localToParentTransform;
+ mutable AffineTransform m_localToParentTransform;
};
inline RenderSVGRoot* toRenderSVGRoot(RenderObject* object)
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index 0cf0332..e332c85 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -59,7 +59,6 @@ IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* repai
void RenderSVGText::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
- style()->svgStyle()->inflateForShadow(repaintRect);
SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
@@ -71,10 +70,6 @@ void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
void RenderSVGText::layout()
{
ASSERT(needsLayout());
-
- // FIXME: This is a hack to avoid the RenderBlock::layout() partial repainting code which is not (yet) SVG aware
- setNeedsLayout(true);
-
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
// Best guess for a relative starting point
@@ -192,7 +187,7 @@ FloatRect RenderSVGText::strokeBoundingBox() const
// SVG needs to include the strokeWidth(), not the textStrokeWidth().
if (style()->svgStyle()->hasStroke()) {
- float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0f);
+ float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 1.0f);
#if ENABLE(SVG_FONTS)
const Font& font = style()->font();
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index d001d1c..9ae96a0 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -26,7 +26,7 @@
#if ENABLE(SVG)
-#include "TransformationMatrix.h"
+#include "AffineTransform.h"
#include "RenderSVGBlock.h"
namespace WebCore {
@@ -44,7 +44,7 @@ private:
virtual bool isSVGText() const { return true; }
- virtual const TransformationMatrix& localToParentTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -66,11 +66,11 @@ private:
virtual FloatRect repaintRectInLocalCoordinates() const;
// FIXME: This can be removed when localTransform() is removed from RenderObject
- virtual TransformationMatrix localTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
virtual RootInlineBox* createRootInlineBox();
- TransformationMatrix m_localTransform;
+ AffineTransform m_localTransform;
};
}
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.cpp b/WebCore/rendering/RenderSVGTransformableContainer.cpp
index 050e1bd..4bec7a7 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.cpp
+++ b/WebCore/rendering/RenderSVGTransformableContainer.cpp
@@ -34,12 +34,12 @@ RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransf
{
}
-const TransformationMatrix& RenderSVGTransformableContainer::localToParentTransform() const
+const AffineTransform& RenderSVGTransformableContainer::localToParentTransform() const
{
return m_localTransform;
}
-TransformationMatrix RenderSVGTransformableContainer::localTransform() const
+AffineTransform RenderSVGTransformableContainer::localTransform() const
{
return m_localTransform;
}
@@ -54,7 +54,7 @@ void RenderSVGTransformableContainer::calculateLocalTransform()
if (translation.width() == 0 && translation.height() == 0)
return;
- m_localTransform.translateRight(translation.width(), translation.height());
+ m_localTransform.translate(translation.width(), translation.height());
}
}
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.h b/WebCore/rendering/RenderSVGTransformableContainer.h
index 43e4001..1de0b19 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.h
+++ b/WebCore/rendering/RenderSVGTransformableContainer.h
@@ -31,14 +31,14 @@ namespace WebCore {
public:
RenderSVGTransformableContainer(SVGStyledTransformableElement*);
- virtual const TransformationMatrix& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
private:
virtual void calculateLocalTransform();
// FIXME: This can be made non-virtual once SVGRenderTreeAsText stops using localTransform()
- virtual TransformationMatrix localTransform() const;
+ virtual AffineTransform localTransform() const;
- TransformationMatrix m_localTransform;
+ AffineTransform m_localTransform;
};
}
diff --git a/WebCore/rendering/RenderSVGViewportContainer.cpp b/WebCore/rendering/RenderSVGViewportContainer.cpp
index b46e8c2..103d9d2 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.cpp
+++ b/WebCore/rendering/RenderSVGViewportContainer.cpp
@@ -38,7 +38,7 @@ RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
{
}
-FloatRect RenderSVGViewportContainer::markerBoundaries(const TransformationMatrix& markerTransformation) const
+FloatRect RenderSVGViewportContainer::markerBoundaries(const AffineTransform& markerTransformation) const
{
FloatRect coordinates = repaintRectInLocalCoordinates();
@@ -48,12 +48,12 @@ FloatRect RenderSVGViewportContainer::markerBoundaries(const TransformationMatri
return markerTransformation.mapRect(coordinates);
}
-TransformationMatrix RenderSVGViewportContainer::markerContentTransformation(const TransformationMatrix& contentTransformation, const FloatPoint& origin, float strokeWidth) const
+AffineTransform RenderSVGViewportContainer::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
{
// The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker
FloatPoint mappedOrigin = viewportTransform().mapPoint(origin);
- TransformationMatrix transformation = contentTransformation;
+ AffineTransform transformation = contentTransformation;
if (strokeWidth != -1)
transformation.scaleNonUniform(strokeWidth, strokeWidth);
@@ -63,8 +63,8 @@ TransformationMatrix RenderSVGViewportContainer::markerContentTransformation(con
void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
{
- if (style()->overflowX() != OVISIBLE)
- paintInfo.context->clip(enclosingIntRect(m_viewport)); // FIXME: Eventually we'll want float-precision clipping
+ if (SVGRenderBase::isOverflowHidden(this))
+ paintInfo.context->clip(m_viewport);
}
void RenderSVGViewportContainer::calcViewport()
@@ -92,7 +92,7 @@ void RenderSVGViewportContainer::calcViewport()
}
}
-TransformationMatrix RenderSVGViewportContainer::viewportTransform() const
+AffineTransform RenderSVGViewportContainer::viewportTransform() const
{
if (node()->hasTagName(SVGNames::svgTag)) {
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
@@ -102,35 +102,25 @@ TransformationMatrix RenderSVGViewportContainer::viewportTransform() const
return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}
- return TransformationMatrix();
+ return AffineTransform();
}
-const TransformationMatrix& RenderSVGViewportContainer::localToParentTransform() const
+const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
{
- TransformationMatrix viewportTranslation;
- viewportTranslation.translate(m_viewport.x(), m_viewport.y());
- m_localToParentTransform = viewportTransform() * viewportTranslation;
+ AffineTransform viewportTranslation(viewportTransform());
+ m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
return m_localToParentTransform;
// If this class were ever given a localTransform(), then the above would read:
// return viewportTransform() * localTransform() * viewportTranslation;
}
-// FIXME: This method should be removed as soon as callers to RenderBox::absoluteTransform() can be removed.
-TransformationMatrix RenderSVGViewportContainer::absoluteTransform() const
-{
- // This would apply localTransform() twice if localTransform() were not the identity.
- return localToParentTransform() * RenderSVGContainer::absoluteTransform();
-}
-
bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
{
- // Respect the viewport clip (which is in parent coords). SVG does not support separate x/y overflow rules.
- if (style()->overflowX() == OHIDDEN) {
- ASSERT(style()->overflowY() == OHIDDEN);
- if (!m_viewport.contains(pointInParent))
- return false;
- }
- return true;
+ // Respect the viewport clip (which is in parent coords)
+ if (!SVGRenderBase::isOverflowHidden(this))
+ return true;
+
+ return m_viewport.contains(pointInParent);
}
}
diff --git a/WebCore/rendering/RenderSVGViewportContainer.h b/WebCore/rendering/RenderSVGViewportContainer.h
index ee08b60..c4043ec 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.h
+++ b/WebCore/rendering/RenderSVGViewportContainer.h
@@ -35,21 +35,18 @@ public:
RenderSVGViewportContainer(SVGStyledElement*);
// Calculates marker boundaries, mapped to the target element's coordinate space
- FloatRect markerBoundaries(const TransformationMatrix& markerTransformation) const;
+ FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
// Generates a transformation matrix usable to render marker content. Handles scaling the marker content
// acording to SVGs markerUnits="strokeWidth" concept, when a strokeWidth value != -1 is passed in.
- TransformationMatrix markerContentTransformation(const TransformationMatrix& contentTransformation, const FloatPoint& origin, float strokeWidth = -1) const;
+ AffineTransform markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth = -1) const;
private:
virtual bool isSVGContainer() const { return true; }
virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
- TransformationMatrix viewportTransform() const;
- virtual const TransformationMatrix& localToParentTransform() const;
-
- // FIXME: This override should be removed once callers of RenderBox::absoluteTransform() can be removed.
- virtual TransformationMatrix absoluteTransform() const;
+ AffineTransform viewportTransform() const;
+ virtual const AffineTransform& localToParentTransform() const;
virtual void calcViewport();
@@ -57,7 +54,7 @@ private:
virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent);
FloatRect m_viewport;
- mutable TransformationMatrix m_localToParentTransform;
+ mutable AffineTransform m_localToParentTransform;
};
inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* object)
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index 39a821f..d97ae6e 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -643,6 +643,9 @@ int RenderTableCell::borderHalfBottom(bool outer) const
void RenderTableCell::paint(PaintInfo& paintInfo, int tx, int ty)
{
if (paintInfo.phase == PaintPhaseCollapsedTableBorders && style()->visibility() == VISIBLE) {
+ if (!shouldPaintWithinRoot(paintInfo))
+ return;
+
tx += x();
ty += y();
int os = 2 * maximalOutlineSize(paintInfo.phase);
diff --git a/WebCore/rendering/RenderThemeChromiumWin.cpp b/WebCore/rendering/RenderThemeChromiumWin.cpp
index 4b38d53..db31825 100644
--- a/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -86,7 +86,7 @@ private:
return transformMode == KeepTransform ? NoLayer : OpaqueCompositeLayer;
}
- static TransformMode getTransformMode(const TransformationMatrix& matrix)
+ static TransformMode getTransformMode(const AffineTransform& matrix)
{
if (matrix.b() != 0 || matrix.c() != 0) // Skew.
return Untransform;
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.cpp b/WebCore/rendering/SVGCharacterLayoutInfo.cpp
index 900e0ba..7e85672 100644
--- a/WebCore/rendering/SVGCharacterLayoutInfo.cpp
+++ b/WebCore/rendering/SVGCharacterLayoutInfo.cpp
@@ -512,9 +512,9 @@ bool SVGChar::isHidden() const
return pathData && pathData->hidden;
}
-TransformationMatrix SVGChar::characterTransform() const
+AffineTransform SVGChar::characterTransform() const
{
- TransformationMatrix ctm;
+ AffineTransform ctm;
// Rotate character around angle, and possibly scale.
ctm.translate(x, y);
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.h b/WebCore/rendering/SVGCharacterLayoutInfo.h
index fb29110..f80c79c 100644
--- a/WebCore/rendering/SVGCharacterLayoutInfo.h
+++ b/WebCore/rendering/SVGCharacterLayoutInfo.h
@@ -24,15 +24,15 @@
#define SVGCharacterLayoutInfo_h
#if ENABLE(SVG)
+#include "AffineTransform.h"
+#include "SVGRenderStyle.h"
+#include "SVGTextContentElement.h"
+
#include <wtf/Assertions.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-
-#include "TransformationMatrix.h"
#include <wtf/RefCounted.h>
-#include "SVGRenderStyle.h"
-#include "SVGTextContentElement.h"
+#include <wtf/Vector.h>
namespace WebCore {
@@ -234,7 +234,7 @@ struct SVGChar {
// Helper methods
bool isHidden() const;
- TransformationMatrix characterTransform() const;
+ AffineTransform characterTransform() const;
};
struct SVGInlineBoxCharacterRange {
@@ -275,7 +275,7 @@ struct SVGTextChunk {
// textLength & lengthAdjust support
float textLength;
ELengthAdjust lengthAdjust;
- TransformationMatrix ctm;
+ AffineTransform ctm;
// status flags
bool isVerticalText : 1;
@@ -291,7 +291,7 @@ struct SVGTextChunk {
struct SVGTextChunkWalkerBase {
virtual ~SVGTextChunkWalkerBase() { }
- virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end) = 0;
// Followings methods are only used for painting text chunks
@@ -300,7 +300,9 @@ struct SVGTextChunkWalkerBase {
virtual bool setupBackground(InlineBox*) = 0;
virtual bool setupFill(InlineBox*) = 0;
+ virtual bool setupFillSelection(InlineBox*) = 0;
virtual bool setupStroke(InlineBox*) = 0;
+ virtual bool setupStrokeSelection(InlineBox*) = 0;
virtual bool setupForeground(InlineBox*) = 0;
};
@@ -309,7 +311,7 @@ struct SVGTextChunkWalker : public SVGTextChunkWalkerBase {
public:
typedef void (CallbackClass::*SVGTextChunkWalkerCallback)(SVGInlineTextBox* textBox,
int startOffset,
- const TransformationMatrix& chunkCtm,
+ const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start,
const Vector<SVGChar>::iterator& end);
@@ -328,7 +330,9 @@ public:
SVGTextChunkEndCallback end = 0,
SVGTextChunkSetupBackgroundCallback background = 0,
SVGTextChunkSetupFillCallback fill = 0,
+ SVGTextChunkSetupFillCallback fillSelection = 0,
SVGTextChunkSetupStrokeCallback stroke = 0,
+ SVGTextChunkSetupStrokeCallback strokeSelection = 0,
SVGTextChunkSetupForegroundCallback foreground = 0)
: m_object(object)
, m_walkerCallback(walker)
@@ -336,14 +340,16 @@ public:
, m_endCallback(end)
, m_setupBackgroundCallback(background)
, m_setupFillCallback(fill)
+ , m_setupFillSelectionCallback(fillSelection)
, m_setupStrokeCallback(stroke)
+ , m_setupStrokeSelectionCallback(strokeSelection)
, m_setupForegroundCallback(foreground)
{
ASSERT(object);
ASSERT(walker);
}
- virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
(*m_object.*m_walkerCallback)(textBox, startOffset, chunkCtm, start, end);
@@ -384,6 +390,15 @@ public:
return false;
}
+ virtual bool setupFillSelection(InlineBox* box)
+ {
+ if (m_setupFillSelectionCallback)
+ return (*m_object.*m_setupFillSelectionCallback)(box);
+
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
virtual bool setupStroke(InlineBox* box)
{
if (m_setupStrokeCallback)
@@ -393,6 +408,15 @@ public:
return false;
}
+ virtual bool setupStrokeSelection(InlineBox* box)
+ {
+ if (m_setupStrokeSelectionCallback)
+ return (*m_object.*m_setupStrokeSelectionCallback)(box);
+
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
virtual bool setupForeground(InlineBox* box)
{
if (m_setupForegroundCallback)
@@ -409,7 +433,9 @@ private:
SVGTextChunkEndCallback m_endCallback;
SVGTextChunkSetupBackgroundCallback m_setupBackgroundCallback;
SVGTextChunkSetupFillCallback m_setupFillCallback;
+ SVGTextChunkSetupFillCallback m_setupFillSelectionCallback;
SVGTextChunkSetupStrokeCallback m_setupStrokeCallback;
+ SVGTextChunkSetupStrokeCallback m_setupStrokeSelectionCallback;
SVGTextChunkSetupForegroundCallback m_setupForegroundCallback;
};
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index 2f56e68..65aa5a1 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -108,9 +108,7 @@ FloatRect SVGInlineTextBox::calculateGlyphBoundaries(RenderStyle* style, int off
FloatRect glyphRect(x1, y1, x2 - x1, y2 - y1);
// Take per-character transformations into account
- TransformationMatrix ctm = svgChar.characterTransform();
- if (!ctm.isIdentity())
- glyphRect = ctm.mapRect(glyphRect);
+ glyphRect = svgChar.characterTransform().mapRect(glyphRect);
return glyphRect;
}
@@ -126,7 +124,7 @@ struct SVGInlineTextBoxClosestCharacterToPositionWalker {
{
}
- void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
RenderStyle* style = textBox->textRenderer()->style();
@@ -193,7 +191,7 @@ struct SVGInlineTextBoxSelectionRectWalker {
{
}
- void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
RenderStyle* style = textBox->textRenderer()->style();
@@ -324,6 +322,32 @@ IntRect SVGInlineTextBox::selectionRect(int, int, int startPos, int endPos)
return enclosingIntRect(walkerCallback.selectionRect());
}
+bool SVGInlineTextBox::chunkSelectionStartEnd(const UChar* chunk, int chunkLength, int& selectionStart, int& selectionEnd)
+{
+ // NOTE: We ignore SVGInlineTextBox::m_start here because it is always 0.
+ // Curently SVG doesn't use HTML block-level layout, in which m_start would be set.
+
+ int chunkStart = chunk - textRenderer()->characters();
+ ASSERT(0 <= chunkStart);
+
+ selectionStartEnd(selectionStart, selectionEnd);
+ if (selectionEnd <= chunkStart)
+ return false;
+ if (chunkStart + chunkLength <= selectionStart)
+ return false;
+
+ // Map indices from view-global to chunk-local.
+ selectionStart -= chunkStart;
+ selectionEnd -= chunkStart;
+ // Then clamp with chunk range
+ if (selectionStart < 0)
+ selectionStart = 0;
+ if (chunkLength < selectionEnd)
+ selectionEnd = chunkLength;
+
+ return selectionStart < selectionEnd;
+}
+
void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int tx, int ty, const SVGChar& svgChar, const UChar* chars, int length, SVGTextPaintInfo& textPaintInfo)
{
if (renderer()->style()->visibility() != VISIBLE || paintInfo.phase == PaintPhaseOutline)
@@ -350,7 +374,7 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
RenderStyle* styleToUse = text->style(isFirstLineStyle());
const Font& font = styleToUse->font();
- TransformationMatrix ctm = svgChar.characterTransform();
+ AffineTransform ctm = svgChar.characterTransform();
if (!ctm.isIdentity())
paintInfo.context->concatCTM(ctm);
@@ -376,7 +400,10 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
}
}
- if (textPaintInfo.subphase == SVGTextPaintSubphaseGlyphFill || textPaintInfo.subphase == SVGTextPaintSubphaseGlyphStroke) {
+ bool isGlyphPhase = textPaintInfo.subphase == SVGTextPaintSubphaseGlyphFill || textPaintInfo.subphase == SVGTextPaintSubphaseGlyphStroke;
+ bool isSelectionGlyphPhase = textPaintInfo.subphase == SVGTextPaintSubphaseGlyphFillSelection || textPaintInfo.subphase == SVGTextPaintSubphaseGlyphStrokeSelection;
+
+ if (isGlyphPhase || isSelectionGlyphPhase) {
// Set a text shadow if we have one.
// FIXME: Support multiple shadow effects. Need more from the CG API before
// we can do this.
@@ -398,7 +425,21 @@ void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int t
run.setActivePaintServer(textPaintInfo.activePaintServer);
#endif
- paintInfo.context->drawText(font, run, origin);
+ int selectionStart = 0;
+ int selectionEnd = 0;
+ bool haveSelectedRange = haveSelection && chunkSelectionStartEnd(chars, length, selectionStart, selectionEnd);
+
+ if (isGlyphPhase) {
+ if (haveSelectedRange) {
+ paintInfo.context->drawText(font, run, origin, 0, selectionStart);
+ paintInfo.context->drawText(font, run, origin, selectionEnd, run.length());
+ } else
+ paintInfo.context->drawText(font, run, origin);
+ } else {
+ ASSERT(isSelectionGlyphPhase);
+ if (haveSelectedRange)
+ paintInfo.context->drawText(font, run, origin, selectionStart, selectionEnd);
+ }
if (setShadow)
paintInfo.context->clearShadow();
@@ -523,7 +564,7 @@ void SVGInlineTextBox::paintDecoration(ETextDecoration decoration, GraphicsConte
context->save();
context->beginPath();
- TransformationMatrix ctm = svgChar.characterTransform();
+ AffineTransform ctm = svgChar.characterTransform();
if (!ctm.isIdentity())
context->concatCTM(ctm);
diff --git a/WebCore/rendering/SVGInlineTextBox.h b/WebCore/rendering/SVGInlineTextBox.h
index eea6744..596fdf3 100644
--- a/WebCore/rendering/SVGInlineTextBox.h
+++ b/WebCore/rendering/SVGInlineTextBox.h
@@ -35,7 +35,9 @@ namespace WebCore {
enum SVGTextPaintSubphase {
SVGTextPaintSubphaseBackground,
SVGTextPaintSubphaseGlyphFill,
+ SVGTextPaintSubphaseGlyphFillSelection,
SVGTextPaintSubphaseGlyphStroke,
+ SVGTextPaintSubphaseGlyphStrokeSelection,
SVGTextPaintSubphaseForeground
};
@@ -83,6 +85,7 @@ namespace WebCore {
private:
friend class RenderSVGInlineText;
bool svgCharacterHitsPosition(int x, int y, int& offset) const;
+ bool chunkSelectionStartEnd(const UChar* chunk, int chunkLength, int& selectionStart, int& selectionEnd);
int m_height;
};
diff --git a/WebCore/rendering/SVGMarkerLayoutInfo.h b/WebCore/rendering/SVGMarkerLayoutInfo.h
index 1dfeee9..517c993 100644
--- a/WebCore/rendering/SVGMarkerLayoutInfo.h
+++ b/WebCore/rendering/SVGMarkerLayoutInfo.h
@@ -31,7 +31,7 @@ class Path;
class SVGResourceMarker;
struct MarkerLayout {
- MarkerLayout(SVGResourceMarker* markerObj = 0, TransformationMatrix matrixObj = TransformationMatrix())
+ MarkerLayout(SVGResourceMarker* markerObj = 0, AffineTransform matrixObj = AffineTransform())
: marker(markerObj)
, matrix(matrixObj)
{
@@ -39,7 +39,7 @@ struct MarkerLayout {
}
SVGResourceMarker* marker;
- TransformationMatrix matrix;
+ AffineTransform matrix;
};
class SVGMarkerLayoutInfo : public Noncopyable {
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 86cbf32..079a36e 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -27,6 +27,7 @@
#if ENABLE(SVG)
#include "SVGRenderSupport.h"
+#include "AffineTransform.h"
#include "ImageBuffer.h"
#include "RenderObject.h"
#include "RenderSVGContainer.h"
@@ -37,7 +38,6 @@
#include "SVGStyledElement.h"
#include "SVGURIReference.h"
#include "TransformState.h"
-#include "TransformationMatrix.h"
#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -61,6 +61,8 @@ IntRect SVGRenderBase::clippedOverflowRectForRepaint(RenderObject* object, Rende
void SVGRenderBase::computeRectForRepaint(RenderObject* object, RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
+ object->style()->svgStyle()->inflateForShadow(repaintRect);
+
// Translate to coords in our parent renderer, and then call computeRectForRepaint on our parent
repaintRect = object->localToParentTransform().mapRect(repaintRect);
object->parent()->computeRectForRepaint(repaintContainer, repaintRect, fixed);
@@ -258,6 +260,20 @@ void SVGRenderBase::layoutChildren(RenderObject* start, bool selfNeedsLayout)
}
}
+bool SVGRenderBase::isOverflowHidden(const RenderObject* object)
+{
+ // SVG doesn't support independent x/y overflow
+ ASSERT(object->style()->overflowX() == object->style()->overflowY());
+
+ // OSCROLL is never set for SVG - see CSSStyleSelector::adjustRenderStyle
+ ASSERT(object->style()->overflowX() != OSCROLL);
+
+ // RenderSVGRoot should never query for overflow state - it should always clip itself to the initial viewport size.
+ ASSERT(!object->isRoot());
+
+ return object->style()->overflowX() == OHIDDEN;
+}
+
FloatRect SVGRenderBase::filterBoundingBoxForRenderer(const RenderObject* object) const
{
#if ENABLE(FILTERS)
@@ -288,7 +304,7 @@ FloatRect SVGRenderBase::maskerBoundingBoxForRenderer(const RenderObject* object
return FloatRect();
}
-void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const TransformationMatrix& localToAncestorTransform)
+void applyTransformToPaintInfo(RenderObject::PaintInfo& paintInfo, const AffineTransform& localToAncestorTransform)
{
if (localToAncestorTransform.isIdentity())
return;
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 0804ede..cf75365 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -51,6 +51,9 @@ namespace WebCore {
// Layout all children of the passed render object
static void layoutChildren(RenderObject*, bool selfNeedsLayout);
+ // Helper function determining wheter overflow is hidden
+ static bool isOverflowHidden(const RenderObject*);
+
virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
virtual FloatRect markerBoundingBox() const { return FloatRect(); }
@@ -72,7 +75,7 @@ namespace WebCore {
// FIXME: This should move to RenderObject or PaintInfo
// Used for transforming the GraphicsContext and damage rect before passing PaintInfo to child renderers.
- void applyTransformToPaintInfo(RenderObject::PaintInfo&, const TransformationMatrix& localToChildTransform);
+ void applyTransformToPaintInfo(RenderObject::PaintInfo&, const AffineTransform& localToChildTransform);
// This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
void renderSubtreeToImage(ImageBuffer*, RenderObject*);
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index bd6a465..aff718f 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -179,7 +179,7 @@ TextStream& operator<<(TextStream& ts, const FloatSize& s)
return ts;
}
-TextStream& operator<<(TextStream& ts, const TransformationMatrix& transform)
+TextStream& operator<<(TextStream& ts, const AffineTransform& transform)
{
if (transform.isIdentity())
ts << "identity";
@@ -310,7 +310,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& object)
{
- ts << " " << object.absoluteTransform().mapRect(object.repaintRectInLocalCoordinates());
+ ts << " " << const_cast<RenderObject&>(object).absoluteClippedOverflowRect();
writeStyle(ts, object);
return ts;
}
diff --git a/WebCore/rendering/SVGRenderTreeAsText.h b/WebCore/rendering/SVGRenderTreeAsText.h
index bee4f36..13fc475 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.h
+++ b/WebCore/rendering/SVGRenderTreeAsText.h
@@ -45,7 +45,7 @@ namespace WebCore {
class RenderPath;
class RenderSVGRoot;
class RenderText;
- class TransformationMatrix;
+ class AffineTransform;
// functions used by the main RenderTreeAsText code
void write(TextStream&, const RenderPath&, int indent);
@@ -58,7 +58,7 @@ void writeSVGText(TextStream&, const RenderBlock&, int indent);
void writeRenderResources(TextStream&, Node* parent);
// helper operators defined used in various classes to dump the render tree.
-TextStream& operator<<(TextStream&, const TransformationMatrix&);
+TextStream& operator<<(TextStream&, const AffineTransform&);
TextStream& operator<<(TextStream&, const IntRect&);
TextStream& operator<<(TextStream&, const Color&);
TextStream& operator<<(TextStream&, const IntPoint&);
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp
index 92e7654..d0dd4a8 100644
--- a/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/WebCore/rendering/SVGRootInlineBox.cpp
@@ -363,6 +363,13 @@ struct SVGRootInlineBoxPaintWalker {
ASSERT(!m_chunkStarted);
}
+ bool mayHaveSelection(InlineBox* box) const
+ {
+ int selectionStart = 0, selectionEnd = 0;
+ box->renderer()->selectionStartEnd(selectionStart, selectionEnd);
+ return selectionStart < selectionEnd;
+ }
+
void teardownFillPaintServer()
{
if (!m_fillPaintServer)
@@ -457,6 +464,34 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
+ bool chunkSetupFillSelectionCallback(InlineBox* box)
+ {
+ InlineFlowBox* flowBox = box->parent();
+
+ // Setup fill paint server
+ RenderObject* object = flowBox->renderer();
+ ASSERT(object);
+ RenderStyle* style = object->getCachedPseudoStyle(SELECTION);
+ if (!style)
+ style = object->style();
+
+ ASSERT(!m_strokePaintServer);
+ teardownFillPaintServer();
+
+ if (!mayHaveSelection(box))
+ return false;
+
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphFillSelection;
+ m_fillPaintServer = SVGPaintServer::fillPaintServer(style, object);
+ if (m_fillPaintServer) {
+ m_fillPaintServer->setup(m_paintInfo.context, object, style, ApplyToFillTargetType, true);
+ m_fillPaintServerObject = object;
+ return true;
+ }
+
+ return false;
+ }
+
bool chunkSetupStrokeCallback(InlineBox* box)
{
InlineFlowBox* flowBox = box->parent();
@@ -481,6 +516,35 @@ struct SVGRootInlineBoxPaintWalker {
return false;
}
+ bool chunkSetupStrokeSelectionCallback(InlineBox* box)
+ {
+ InlineFlowBox* flowBox = box->parent();
+
+ // Setup stroke paint server
+ RenderObject* object = flowBox->renderer();
+ ASSERT(object);
+ RenderStyle* style = object->getCachedPseudoStyle(SELECTION);
+ if (!style)
+ style = object->style();
+
+ // If we're both stroked & filled, teardown fill paint server before stroking.
+ teardownFillPaintServer();
+ teardownStrokePaintServer();
+
+ if (!mayHaveSelection(box))
+ return false;
+
+ m_textPaintInfo.subphase = SVGTextPaintSubphaseGlyphStrokeSelection;
+ m_strokePaintServer = SVGPaintServer::strokePaintServer(style, object);
+ if (m_strokePaintServer) {
+ m_strokePaintServer->setup(m_paintInfo.context, object, style, ApplyToStrokeTargetType, true);
+ m_strokePaintServerObject = object;
+ return true;
+ }
+
+ return false;
+ }
+
bool chunkSetupForegroundCallback(InlineBox* /*box*/)
{
teardownFillPaintServer();
@@ -495,9 +559,11 @@ struct SVGRootInlineBoxPaintWalker {
{
switch (m_textPaintInfo.subphase) {
case SVGTextPaintSubphaseGlyphFill:
+ case SVGTextPaintSubphaseGlyphFillSelection:
ASSERT(m_fillPaintServer);
return m_fillPaintServer;
case SVGTextPaintSubphaseGlyphStroke:
+ case SVGTextPaintSubphaseGlyphStrokeSelection:
ASSERT(m_strokePaintServer);
return m_strokePaintServer;
case SVGTextPaintSubphaseBackground:
@@ -507,7 +573,7 @@ struct SVGRootInlineBoxPaintWalker {
}
}
- void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
+ void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
RenderText* text = textBox->textRenderer();
@@ -616,7 +682,9 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
&SVGRootInlineBoxPaintWalker::chunkEndCallback,
&SVGRootInlineBoxPaintWalker::chunkSetupBackgroundCallback,
&SVGRootInlineBoxPaintWalker::chunkSetupFillCallback,
+ &SVGRootInlineBoxPaintWalker::chunkSetupFillSelectionCallback,
&SVGRootInlineBoxPaintWalker::chunkSetupStrokeCallback,
+ &SVGRootInlineBoxPaintWalker::chunkSetupStrokeSelectionCallback,
&SVGRootInlineBoxPaintWalker::chunkSetupForegroundCallback);
walkTextChunks(&walker);
@@ -865,9 +933,8 @@ static void applyTextLengthCorrectionToTextChunk(SVGTextChunk& chunk)
SVGChar& firstChar = *(chunk.start);
// Assure we apply the chunk scaling in the right origin
- TransformationMatrix newChunkCtm;
- newChunkCtm.translate(firstChar.x, firstChar.y);
- newChunkCtm = chunk.ctm * newChunkCtm;
+ AffineTransform newChunkCtm(chunk.ctm);
+ newChunkCtm.translateRight(firstChar.x, firstChar.y);
newChunkCtm.translate(-firstChar.x, -firstChar.y);
chunk.ctm = newChunkCtm;
@@ -978,7 +1045,6 @@ void SVGRootInlineBox::buildLayoutInformation(InlineFlowBox* start, SVGCharacter
Vector<SVGTextChunk>::iterator it = tempChunks.begin();
Vector<SVGTextChunk>::iterator end = tempChunks.end();
- TransformationMatrix ctm;
float computedLength = 0.0f;
for (; it != end; ++it) {
@@ -1720,9 +1786,15 @@ void SVGRootInlineBox::walkTextChunks(SVGTextChunkWalkerBase* walker, const SVGI
if (walker->setupFill(range.box))
(*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
+ if (walker->setupFillSelection(range.box))
+ (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
+
if (walker->setupStroke(range.box))
(*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
+ if (walker->setupStrokeSelection(range.box))
+ (*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
+
if (walker->setupForeground(range.box))
(*walker)(rangeTextBox, range.startOffset, curChunk.ctm, itCharBegin, itCharEnd);
diff --git a/WebCore/rendering/SVGRootInlineBox.h b/WebCore/rendering/SVGRootInlineBox.h
index d2dab98..7b1dcc4 100644
--- a/WebCore/rendering/SVGRootInlineBox.h
+++ b/WebCore/rendering/SVGRootInlineBox.h
@@ -44,7 +44,7 @@ struct LastGlyphInfo {
bool isValid;
};
-class SVGRootInlineBox : public RootInlineBox, SVGRenderBase {
+class SVGRootInlineBox : public RootInlineBox, protected SVGRenderBase {
public:
SVGRootInlineBox(RenderObject* obj)
: RootInlineBox(obj)
diff --git a/WebCore/rendering/TransformState.cpp b/WebCore/rendering/TransformState.cpp
index 700831b..ecc614e 100644
--- a/WebCore/rendering/TransformState.cpp
+++ b/WebCore/rendering/TransformState.cpp
@@ -49,6 +49,12 @@ void TransformState::move(int x, int y, TransformAccumulation accumulate)
m_accumulatingTransform = accumulate == AccumulateTransform;
}
+// FIXME: We transform AffineTransform to TransformationMatrix. This is rather inefficient.
+void TransformState::applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation accumulate)
+{
+ applyTransform(transformFromContainer.toTransformationMatrix(), accumulate);
+}
+
void TransformState::applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation accumulate)
{
// If we have an accumulated transform from last time, multiply in this transform
diff --git a/WebCore/rendering/TransformState.h b/WebCore/rendering/TransformState.h
index d2c962a..0b4ca46 100644
--- a/WebCore/rendering/TransformState.h
+++ b/WebCore/rendering/TransformState.h
@@ -26,6 +26,7 @@
#ifndef TransformState_h
#define TransformState_h
+#include "AffineTransform.h"
#include "FloatPoint.h"
#include "FloatQuad.h"
#include "IntSize.h"
@@ -59,6 +60,7 @@ public:
}
void move(int x, int y, TransformAccumulation = FlattenTransform);
+ void applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation = FlattenTransform);
void applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation = FlattenTransform);
void flatten();
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index c59d953..696a2b7 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -183,7 +183,7 @@ protected:
unsigned _empty_cells : 1; // EEmptyCell
unsigned _caption_side : 2; // ECaptionSide
- unsigned _list_style_type : 6; // EListStyleType
+ unsigned _list_style_type : 7; // EListStyleType
unsigned _list_style_position : 1; // EListStylePosition
unsigned _visibility : 2; // EVisibility
unsigned _text_align : 3; // ETextAlign
@@ -194,14 +194,14 @@ protected:
bool _border_collapse : 1 ;
unsigned _white_space : 3; // EWhiteSpace
unsigned _box_direction : 1; // EBoxDirection (CSS3 box_direction property, flexible box layout module)
- // 33 bits
+ // 34 bits
// non CSS2 inherited
bool _visuallyOrdered : 1;
bool _htmlHacks : 1;
bool _force_backgrounds_to_white : 1;
unsigned _pointerEvents : 4; // EPointerEvents
- // 40 bits
+ // 41 bits
} inherited_flags;
// don't inherit
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index d2c80ca..01862f6 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -205,61 +205,83 @@ enum EResize {
// The order of this enum must match the order of the list style types in CSSValueKeywords.in.
enum EListStyleType {
- Disc,
- Circle,
- Square,
- DecimalListStyle,
- DecimalLeadingZero,
- LowerRoman,
- UpperRoman,
- LowerGreek,
- LowerAlpha,
- LowerLatin,
- UpperAlpha,
- UpperLatin,
- Afar,
- EthiopicHalehameAaEt,
- EthiopicHalehameAaEr,
- Amharic,
- EthiopicHalehameAmEt,
- AmharicAbegede,
- EthiopicAbegedeAmEt,
- CjkEarthlyBranch,
- CjkHeavenlyStem,
- Ethiopic,
- EthiopicHalehameGez,
- EthiopicAbegede,
- EthiopicAbegedeGez,
- HangulConsonant,
- Hangul,
- LowerNorwegian,
- Oromo,
- EthiopicHalehameOmEt,
- Sidama,
- EthiopicHalehameSidEt,
- Somali,
- EthiopicHalehameSoEt,
- Tigre,
- EthiopicHalehameTig,
- TigrinyaEr,
- EthiopicHalehameTiEr,
- TigrinyaErAbegede,
- EthiopicAbegedeTiEr,
- TigrinyaEt,
- EthiopicHalehameTiEt,
- TigrinyaEtAbegede,
- EthiopicAbegedeTiEt,
- UpperGreek,
- UpperNorwegian,
- Hebrew,
- Armenian,
- Georgian,
- CJKIdeographic,
- Hiragana,
- Katakana,
- HiraganaIroha,
- KatakanaIroha,
- NoneListStyle
+ Disc,
+ Circle,
+ Square,
+ DecimalListStyle,
+ DecimalLeadingZero,
+ ArabicIndic,
+ BinaryListStyle,
+ Bengali,
+ Cambodian,
+ Khmer,
+ Devanagari,
+ Gujarati,
+ Gurmukhi,
+ Kannada,
+ LowerHexadecimal,
+ Lao,
+ Malayalam,
+ Mongolian,
+ Myanmar,
+ Octal,
+ Oriya,
+ Persian,
+ Urdu,
+ Telugu,
+ Tibetan,
+ Thai,
+ UpperHexadecimal,
+ LowerRoman,
+ UpperRoman,
+ LowerGreek,
+ LowerAlpha,
+ LowerLatin,
+ UpperAlpha,
+ UpperLatin,
+ Afar,
+ EthiopicHalehameAaEt,
+ EthiopicHalehameAaEr,
+ Amharic,
+ EthiopicHalehameAmEt,
+ AmharicAbegede,
+ EthiopicAbegedeAmEt,
+ CjkEarthlyBranch,
+ CjkHeavenlyStem,
+ Ethiopic,
+ EthiopicHalehameGez,
+ EthiopicAbegede,
+ EthiopicAbegedeGez,
+ HangulConsonant,
+ Hangul,
+ LowerNorwegian,
+ Oromo,
+ EthiopicHalehameOmEt,
+ Sidama,
+ EthiopicHalehameSidEt,
+ Somali,
+ EthiopicHalehameSoEt,
+ Tigre,
+ EthiopicHalehameTig,
+ TigrinyaEr,
+ EthiopicHalehameTiEr,
+ TigrinyaErAbegede,
+ EthiopicAbegedeTiEr,
+ TigrinyaEt,
+ EthiopicHalehameTiEt,
+ TigrinyaEtAbegede,
+ EthiopicAbegedeTiEt,
+ UpperGreek,
+ UpperNorwegian,
+ Hebrew,
+ Armenian,
+ Georgian,
+ CJKIdeographic,
+ Hiragana,
+ Katakana,
+ HiraganaIroha,
+ KatakanaIroha,
+ NoneListStyle
};
enum StyleContentType {