diff options
author | Steve Block <steveblock@google.com> | 2010-02-15 12:23:52 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-16 11:48:32 +0000 |
commit | 8a0914b749bbe7da7768e07a7db5c6d4bb09472b (patch) | |
tree | 73f9065f370435d6fde32ae129d458a8c77c8dff /WebCore/rendering | |
parent | bf14be70295513b8076f3fa47a268a7e42b2c478 (diff) | |
download | external_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')
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 { |