diff options
author | Steve Block <steveblock@google.com> | 2011-06-10 16:52:27 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-06-14 01:14:02 +0100 |
commit | 54cdeeebc7adcbcd900e8b6a141a8cae27d9a631 (patch) | |
tree | 845b0d338b204a48560eca3b51b34cf92ed96840 /Source/WebCore/rendering | |
parent | d2c5226a647dc21d0c15267e09a3d19cf3e0d593 (diff) | |
download | external_webkit-54cdeeebc7adcbcd900e8b6a141a8cae27d9a631.zip external_webkit-54cdeeebc7adcbcd900e8b6a141a8cae27d9a631.tar.gz external_webkit-54cdeeebc7adcbcd900e8b6a141a8cae27d9a631.tar.bz2 |
Merge WebKit at branches/chromium/742 r88085: Initial merge by git.
Change-Id: I0501b484b9528e31b0026e5ad64416dd6541cdde
Diffstat (limited to 'Source/WebCore/rendering')
25 files changed, 241 insertions, 149 deletions
diff --git a/Source/WebCore/rendering/AutoTableLayout.cpp b/Source/WebCore/rendering/AutoTableLayout.cpp index 4eef95f..f5311c2 100644 --- a/Source/WebCore/rendering/AutoTableLayout.cpp +++ b/Source/WebCore/rendering/AutoTableLayout.cpp @@ -265,11 +265,10 @@ void AutoTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidth if (tableLogicalWidth.isFixed() && tableLogicalWidth.value() > 0) { minWidth = max(minWidth, tableLogicalWidth.value()); maxWidth = minWidth; - } - - // if there was no remaining percent, maxWidth is invalid. - if (!remainingPercent && maxNonPercent) + } else if (!remainingPercent && maxNonPercent) { + // if there was no remaining percent, maxWidth is invalid. maxWidth = intMaxForLength; + } } /* diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp index 045edff..392b0bf 100644 --- a/Source/WebCore/rendering/InlineFlowBox.cpp +++ b/Source/WebCore/rendering/InlineFlowBox.cpp @@ -539,7 +539,7 @@ void InlineFlowBox::computeLogicalBoxHeights(RootInlineBox* rootBox, int& maxPos int boxHeight = ascent + descent; if (curr->verticalAlign() == TOP) { - if (maxPositionTop < ascent) + if (maxPositionTop < boxHeight) maxPositionTop = boxHeight; } else if (curr->verticalAlign() == BOTTOM) { if (maxPositionBottom < boxHeight) diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index de3af60..22d3b3c 100644 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -81,6 +81,8 @@ typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; static int gDelayUpdateScrollInfo = 0; static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; +bool RenderBlock::s_canPropagateFloatIntoSibling = false; + // Our MarginInfo state used when laying out block children. RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding) : m_atBeforeSideOfBlock(true) @@ -200,6 +202,8 @@ void RenderBlock::destroy() void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) { + s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false; + setReplaced(newStyle->isDisplayInlineType()); if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) { @@ -263,6 +267,15 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty updateBeforeAfterContent(BEFORE); updateBeforeAfterContent(AFTER); } + + // After our style changed, if we lose our ability to propagate floats into next sibling + // blocks, then we need to mark our descendants with floats for layout and clear all floats + // from next sibling blocks that exist in our floating objects list. See bug 56299. + bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats(); + if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) { + markAllDescendantsWithFloatsForLayout(); + markSiblingsWithFloatsForLayout(); + } } void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId) @@ -2221,30 +2234,26 @@ void RenderBlock::markForPaginationRelayoutIfNeeded() void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants) { // Repaint any overhanging floats (if we know we're the one to paint them). - if (hasOverhangingFloats()) { - // We think that we must be in a bad state if m_floatingObjects is nil at this point, so - // we assert on Debug builds and nil-check Release builds. - ASSERT(m_floatingObjects); - if (!m_floatingObjects) - return; + // Otherwise, bail out. + if (!hasOverhangingFloats()) + return; - // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating - // in this block. Better yet would be to push extra state for the containers of other floats. - view()->disableLayoutState(); - FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); - FloatingObjectSetIterator end = floatingObjectSet.end(); - for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { - FloatingObject* r = *it; - // Only repaint the object if it is overhanging, is not in its own layer, and - // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter - // condition is replaced with being a descendant of us. - if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) { - r->m_renderer->repaint(); - r->m_renderer->repaintOverhangingFloats(); - } + // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating + // in this block. Better yet would be to push extra state for the containers of other floats. + view()->disableLayoutState(); + FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); + FloatingObjectSetIterator end = floatingObjectSet.end(); + for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { + FloatingObject* r = *it; + // Only repaint the object if it is overhanging, is not in its own layer, and + // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter + // condition is replaced with being a descendant of us. + if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) { + r->m_renderer->repaint(); + r->m_renderer->repaintOverhangingFloats(); } - view()->enableLayoutState(); } + view()->enableLayoutState(); } void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty) @@ -3181,10 +3190,18 @@ void RenderBlock::removeFloatingObject(RenderBox* o) // accomplished by pretending they have a height of 1. logicalBottom = max(logicalBottom, logicalTop + 1); } + if (r->m_originatingLine) { + ASSERT(r->m_originatingLine->renderer() == this); + r->m_originatingLine->markDirty(); +#if !ASSERT_DISABLED + r->m_originatingLine = 0; +#endif + } markLinesDirtyInBlockRange(0, logicalBottom); } m_floatingObjects->decreaseObjectsCount(r->type()); floatingObjectSet.remove(it); + ASSERT(!r->m_originatingLine); delete r; } } @@ -3200,6 +3217,7 @@ void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logi while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) { m_floatingObjects->decreaseObjectsCount(curr->type()); floatingObjectSet.removeLast(); + ASSERT(!curr->m_originatingLine); delete curr; curr = floatingObjectSet.last(); } @@ -3637,6 +3655,10 @@ void RenderBlock::clearFloats() } floatMap.remove(f->m_renderer); + if (oldFloatingObject->m_originatingLine) { + ASSERT(oldFloatingObject->m_originatingLine->renderer() == this); + oldFloatingObject->m_originatingLine->markDirty(); + } delete oldFloatingObject; } else { changeLogicalTop = 0; @@ -3800,6 +3822,30 @@ void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove } } +void RenderBlock::markSiblingsWithFloatsForLayout() +{ + FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); + FloatingObjectSetIterator end = floatingObjectSet.end(); + for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { + if (logicalBottomForFloat(*it) > logicalHeight()) { + RenderBox* floatingBox = (*it)->renderer(); + + RenderObject* next = nextSibling(); + while (next) { + if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) { + RenderBlock* nextBlock = toRenderBlock(next); + if (nextBlock->containsFloat(floatingBox)) + nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox); + else + break; + } + + next = next->nextSibling(); + } + } + } +} + int RenderBlock::getClearDelta(RenderBox* child, int yPos) { // There is no need to compute clearance if we have no floats. diff --git a/Source/WebCore/rendering/RenderBlock.h b/Source/WebCore/rendering/RenderBlock.h index 75d93e9..d45ab66 100644 --- a/Source/WebCore/rendering/RenderBlock.h +++ b/Source/WebCore/rendering/RenderBlock.h @@ -95,6 +95,7 @@ public: bool generatesLineBoxesForInlineChild(RenderObject*, bool isLineEmpty = true, bool previousLineBrokeCleanly = true); void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true); + void markSiblingsWithFloatsForLayout(); void markPositionedObjectsForLayout(); virtual void markForPaginationRelayoutIfNeeded(); @@ -384,6 +385,7 @@ private: FloatingObject(Type type) : m_renderer(0) + , m_originatingLine(0) , m_paginationStrut(0) , m_type(type) , m_shouldPaint(true) @@ -394,6 +396,7 @@ private: FloatingObject(Type type, const IntRect& frameRect) : m_renderer(0) + , m_originatingLine(0) , m_frameRect(frameRect) , m_paginationStrut(0) , m_type(type) @@ -425,6 +428,7 @@ private: void setFrameRect(const IntRect& frameRect) { m_frameRect = frameRect; } RenderBox* m_renderer; + RootInlineBox* m_originatingLine; IntRect m_frameRect; int m_paginationStrut; unsigned m_type : 2; // Type (left or right aligned) @@ -537,7 +541,7 @@ private: virtual bool avoidsFloats() const; - bool hasOverhangingFloats() { return parent() && !hasColumns() && lowestFloatLogicalBottom() > logicalHeight(); } + bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); } void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset); int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats); @@ -787,6 +791,10 @@ private: // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline). friend class RenderRubyBase; friend class LineWidth; // Needs to know FloatingObject + +private: + // Used to store state between styleWillChange and styleDidChange + static bool s_canPropagateFloatIntoSibling; }; inline RenderBlock* toRenderBlock(RenderObject* object) diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp index 06cbf90..a5716ed 100644 --- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp @@ -724,12 +724,8 @@ inline BidiRun* RenderBlock::handleTrailingSpaces(BidiRunList<BidiRun>& bidiRuns void RenderBlock::appendFloatingObjectToLastLine(FloatingObject* floatingObject) { - // Ensure that the float touches the line. - if (RootInlineBox* previousLine = lastRootBox()->prevRootBox()) { - if (logicalBottomForFloat(floatingObject) < previousLine->blockLogicalHeight()) - setLogicalHeightForFloat(floatingObject, previousLine->blockLogicalHeight() - logicalTopForFloat(floatingObject)); - } - + ASSERT(!floatingObject->m_originatingLine); + floatingObject->m_originatingLine = lastRootBox(); lastRootBox()->appendFloat(floatingObject->renderer()); } @@ -1161,7 +1157,9 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) { Vector<RenderBox*>::iterator end = cleanLineFloats->end(); for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) { - insertFloatingObject(*f); + FloatingObject* floatingObject = insertFloatingObject(*f); + ASSERT(!floatingObject->m_originatingLine); + floatingObject->m_originatingLine = line; setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f) + delta); positionNewFloats(); } @@ -1364,7 +1362,9 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLa if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) { Vector<RenderBox*>::iterator end = cleanLineFloats->end(); for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) { - insertFloatingObject(*f); + FloatingObject* floatingObject = insertFloatingObject(*f); + ASSERT(!floatingObject->m_originatingLine); + floatingObject->m_originatingLine = line; setLogicalHeight(logicalTopForChild(*f) - marginBeforeForChild(*f)); positionNewFloats(); ASSERT(floats[numCleanFloats].object == *f); diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index 11c0306..80d5699 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -234,7 +234,7 @@ void RenderBox::removeFloatingOrPositionedChildFromBlockLists() for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) { if (curr->isRenderBlock()) { RenderBlock* currBlock = toRenderBlock(curr); - if (currBlock->containsFloat(this)) + if (!parentBlock || currBlock->containsFloat(this)) parentBlock = currBlock; } } diff --git a/Source/WebCore/rendering/RenderCounter.cpp b/Source/WebCore/rendering/RenderCounter.cpp index 9b8c493..2a2506c 100644 --- a/Source/WebCore/rendering/RenderCounter.cpp +++ b/Source/WebCore/rendering/RenderCounter.cpp @@ -575,6 +575,19 @@ void RenderCounter::destroyCounterNode(RenderObject* owner, const AtomicString& // map associated with a renderer, so there is no risk in leaking the map. } +void RenderCounter::rendererRemovedFromTree(RenderObject* removedRenderer) +{ + RenderObject* currentRenderer = removedRenderer->lastLeafChild(); + if (!currentRenderer) + currentRenderer = removedRenderer; + while (true) { + destroyCounterNodes(currentRenderer); + if (currentRenderer == removedRenderer) + break; + currentRenderer = currentRenderer->previousInPreOrder(); + } +} + static void updateCounters(RenderObject* renderer) { ASSERT(renderer->style()); diff --git a/Source/WebCore/rendering/RenderCounter.h b/Source/WebCore/rendering/RenderCounter.h index 9557ae3..b4449dd 100644 --- a/Source/WebCore/rendering/RenderCounter.h +++ b/Source/WebCore/rendering/RenderCounter.h @@ -37,6 +37,7 @@ public: static void destroyCounterNodes(RenderObject*); static void destroyCounterNode(RenderObject*, const AtomicString& identifier); static void rendererSubtreeAttached(RenderObject*); + static void rendererRemovedFromTree(RenderObject*); static void rendererStyleChanged(RenderObject*, const RenderStyle* oldStyle, const RenderStyle* newStyle); private: diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index 4676c91..6aff65c 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -217,6 +217,9 @@ RenderLayer::~RenderLayer() destroyScrollbar(HorizontalScrollbar); destroyScrollbar(VerticalScrollbar); + if (m_reflection) + removeReflection(); + // Child layers will be deleted by their corresponding render objects, so // we don't need to delete them ourselves. @@ -232,9 +235,6 @@ RenderLayer::~RenderLayer() // Make sure we have no lingering clip rects. ASSERT(!m_clipRects); - if (m_reflection) - removeReflection(); - if (m_scrollCorner) m_scrollCorner->destroy(); if (m_resizer) diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h index cf4d61b..14a40e9 100644 --- a/Source/WebCore/rendering/RenderObject.h +++ b/Source/WebCore/rendering/RenderObject.h @@ -1007,7 +1007,9 @@ inline void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, R if (!container && !o->isRenderView()) return; if (!last->isText() && (last->style()->position() == FixedPosition || last->style()->position() == AbsolutePosition)) { - if (o->m_posChildNeedsLayout) + while (o && !o->isRenderBlock()) // Skip relatively positioned inlines and get to the enclosing RenderBlock. + o = o->container(); + if (!o || o->m_posChildNeedsLayout) return; o->m_posChildNeedsLayout = true; simplifiedNormalFlowLayout = true; diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp index e26f221..ff9ff15 100644 --- a/Source/WebCore/rendering/RenderObjectChildList.cpp +++ b/Source/WebCore/rendering/RenderObjectChildList.cpp @@ -129,8 +129,7 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render oldChild->setNextSibling(0); oldChild->setParent(0); - if (oldChild->m_hasCounterNodeMap) - RenderCounter::destroyCounterNodes(oldChild); + RenderCounter::rendererRemovedFromTree(oldChild); RenderQuote::rendererRemovedFromTree(oldChild); if (AXObjectCache::accessibilityEnabled()) diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp index 187ffd7..e9db5ad 100644 --- a/Source/WebCore/rendering/RenderTable.cpp +++ b/Source/WebCore/rendering/RenderTable.cpp @@ -122,11 +122,15 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) RenderObject* o = beforeChild->previousSibling(); while (o && o != m_caption) o = o->previousSibling(); - if (!o) + if (!o) { m_caption = 0; + setNeedsSectionRecalc(); + } } if (!m_caption) m_caption = toRenderBlock(child); + else + setNeedsSectionRecalc(); wrapInAnonymousSection = false; } else if (child->isTableCol()) { m_hasColElements = true; @@ -204,6 +208,9 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) void RenderTable::removeChild(RenderObject* oldChild) { RenderBox::removeChild(oldChild); + + if (m_caption && oldChild == m_caption && node()) + node()->setNeedsStyleRecalc(); setNeedsSectionRecalc(); } @@ -747,6 +754,21 @@ RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge) return 0; } +void RenderTable::recalcCaption(RenderBlock* caption) const +{ + if (!m_caption) { + m_caption = caption; + m_caption->setNeedsLayout(true); + } else { + // Make sure to null out the child's renderer. + if (Node* node = caption->node()) + node->setRenderer(0); + + // Destroy the child now. + caption->destroy(); + } +} + void RenderTable::recalcSections() const { m_caption = 0; @@ -756,13 +778,13 @@ void RenderTable::recalcSections() const m_hasColElements = false; // We need to get valid pointers to caption, head, foot and first body again - for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { + RenderObject* nextSibling; + for (RenderObject* child = firstChild(); child; child = nextSibling) { + nextSibling = child->nextSibling(); switch (child->style()->display()) { case TABLE_CAPTION: - if (!m_caption && child->isRenderBlock()) { - m_caption = toRenderBlock(child); - m_caption->setNeedsLayout(true); - } + if (child->isRenderBlock()) + recalcCaption(toRenderBlock(child)); break; case TABLE_COLUMN: case TABLE_COLUMN_GROUP: diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h index d781e95..c2ae053 100644 --- a/Source/WebCore/rendering/RenderTable.h +++ b/Source/WebCore/rendering/RenderTable.h @@ -242,6 +242,7 @@ private: void subtractCaptionRect(IntRect&) const; + void recalcCaption(RenderBlock*) const; void recalcSections() const; void adjustLogicalHeightForCaption(); diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.cpp b/Source/WebCore/rendering/style/SVGRenderStyle.cpp index 1ee1f36..28f80f2 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyle.cpp +++ b/Source/WebCore/rendering/style/SVGRenderStyle.cpp @@ -169,9 +169,7 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated. if (stroke != other->stroke) { if (stroke->width != other->stroke->width - || stroke->paintType != other->stroke->paintType - || stroke->paintColor != other->stroke->paintColor - || stroke->paintUri != other->stroke->paintUri + || stroke->paint != other->stroke->paint || stroke->miterLimit != other->stroke->miterLimit || stroke->dashArray != other->stroke->dashArray || stroke->dashOffset != other->stroke->dashOffset) @@ -193,7 +191,7 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const } // If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains. - if (fill->paintType != other->fill->paintType || fill->paintColor != other->fill->paintColor || fill->paintUri != other->fill->paintUri) + if (fill != other->fill) return StyleDifferenceRepaint; // If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop. diff --git a/Source/WebCore/rendering/style/SVGRenderStyle.h b/Source/WebCore/rendering/style/SVGRenderStyle.h index 88a48df..7f032e7 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyle.h +++ b/Source/WebCore/rendering/style/SVGRenderStyle.h @@ -70,19 +70,15 @@ public: static SVGWritingMode initialWritingMode() { return WM_LRTB; } static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; } static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; } - static float initialFillOpacity() { return 1; } - static SVGPaint::SVGPaintType initialFillPaintType() { return SVGPaint::SVG_PAINTTYPE_RGBCOLOR; } - static Color initialFillPaintColor() { return Color::black; } - static String initialFillPaintUri() { return String(); } - static float initialStrokeOpacity() { return 1; } - static SVGPaint::SVGPaintType initialStrokePaintType() { return SVGPaint::SVG_PAINTTYPE_NONE; } - static Color initialStrokePaintColor() { return Color(); } - static String initialStrokePaintUri() { return String(); } + static float initialFillOpacity() { return 1.0f; } + static SVGPaint* initialFillPaint() { return SVGPaint::defaultFill(); } + static float initialStrokeOpacity() { return 1.0f; } + static SVGPaint* initialStrokePaint() { return SVGPaint::defaultStroke(); } static Vector<SVGLength> initialStrokeDashArray() { return Vector<SVGLength>(); } - static float initialStrokeMiterLimit() { return 4; } - static float initialStopOpacity() { return 1; } + static float initialStrokeMiterLimit() { return 4.0f; } + static float initialStopOpacity() { return 1.0f; } static Color initialStopColor() { return Color(0, 0, 0); } - static float initialFloodOpacity() { return 1; } + static float initialFloodOpacity() { return 1.0f; } static Color initialFloodColor() { return Color(0, 0, 0); } static Color initialLightingColor() { return Color(255, 255, 255); } static ShadowData* initialShadow() { return 0; } @@ -154,14 +150,10 @@ public: fill.access()->opacity = obj; } - void setFillPaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri) + void setFillPaint(PassRefPtr<SVGPaint> obj) { - if (!(fill->paintType == type)) - fill.access()->paintType = type; - if (!(fill->paintColor == color)) - fill.access()->paintColor = color; - if (!(fill->paintUri == uri)) - fill.access()->paintUri = uri; + if (!(fill->paint == obj)) + fill.access()->paint = obj; } void setStrokeOpacity(float obj) @@ -170,14 +162,10 @@ public: stroke.access()->opacity = obj; } - void setStrokePaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri) + void setStrokePaint(PassRefPtr<SVGPaint> obj) { - if (!(stroke->paintType == type)) - stroke.access()->paintType = type; - if (!(stroke->paintColor == color)) - stroke.access()->paintColor = color; - if (!(stroke->paintUri == uri)) - stroke.access()->paintUri = uri; + if (!(stroke->paint == obj)) + stroke.access()->paint = obj; } void setStrokeDashArray(const Vector<SVGLength>& obj) @@ -305,13 +293,9 @@ public: EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; } EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; } float fillOpacity() const { return fill->opacity; } - const SVGPaint::SVGPaintType& fillPaintType() const { return fill->paintType; } - const Color& fillPaintColor() const { return fill->paintColor; } - const String& fillPaintUri() const { return fill->paintUri; } + SVGPaint* fillPaint() const { return fill->paint.get(); } float strokeOpacity() const { return stroke->opacity; } - const SVGPaint::SVGPaintType& strokePaintType() const { return stroke->paintType; } - const Color& strokePaintColor() const { return stroke->paintColor; } - const String& strokePaintUri() const { return stroke->paintUri; } + SVGPaint* strokePaint() const { return stroke->paint.get(); } Vector<SVGLength> strokeDashArray() const { return stroke->dashArray; } float strokeMiterLimit() const { return stroke->miterLimit; } SVGLength strokeWidth() const { return stroke->width; } @@ -336,8 +320,8 @@ public: bool hasMasker() const { return !maskerResource().isEmpty(); } bool hasFilter() const { return !filterResource().isEmpty(); } bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); } - bool hasStroke() const { return strokePaintType() != SVGPaint::SVG_PAINTTYPE_NONE; } - bool hasFill() const { return fillPaintType() != SVGPaint::SVG_PAINTTYPE_NONE; } + bool hasStroke() const { return strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; } + bool hasFill() const { return fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; } bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; } protected: diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp index fb23e14..c30ae6d 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp +++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.cpp @@ -37,27 +37,35 @@ namespace WebCore { StyleFillData::StyleFillData() : opacity(SVGRenderStyle::initialFillOpacity()) - , paintType(SVGRenderStyle::initialFillPaintType()) - , paintColor(SVGRenderStyle::initialFillPaintColor()) - , paintUri(SVGRenderStyle::initialFillPaintUri()) + , paint(SVGRenderStyle::initialFillPaint()) { } StyleFillData::StyleFillData(const StyleFillData& other) : RefCounted<StyleFillData>() , opacity(other.opacity) - , paintType(other.paintType) - , paintColor(other.paintColor) - , paintUri(other.paintUri) + , paint(other.paint) { } bool StyleFillData::operator==(const StyleFillData& other) const { - return opacity == other.opacity - && paintType == other.paintType - && paintColor == other.paintColor - && paintUri == other.paintUri; + if (opacity != other.opacity) + return false; + + if (!paint || !other.paint) + return paint == other.paint; + + if (paint->paintType() != other.paint->paintType()) + return false; + + if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_URI) + return paint->uri() == other.paint->uri(); + + if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR) + return paint->color() == other.paint->color(); + + return paint == other.paint; } StyleStrokeData::StyleStrokeData() @@ -66,9 +74,7 @@ StyleStrokeData::StyleStrokeData() , width(SVGRenderStyle::initialStrokeWidth()) , dashOffset(SVGRenderStyle::initialStrokeDashOffset()) , dashArray(SVGRenderStyle::initialStrokeDashArray()) - , paintType(SVGRenderStyle::initialStrokePaintType()) - , paintColor(SVGRenderStyle::initialStrokePaintColor()) - , paintUri(SVGRenderStyle::initialStrokePaintUri()) + , paint(SVGRenderStyle::initialStrokePaint()) { } @@ -79,22 +85,18 @@ StyleStrokeData::StyleStrokeData(const StyleStrokeData& other) , width(other.width) , dashOffset(other.dashOffset) , dashArray(other.dashArray) - , paintType(other.paintType) - , paintColor(other.paintColor) - , paintUri(other.paintUri) + , paint(other.paint) { } bool StyleStrokeData::operator==(const StyleStrokeData& other) const { - return width == other.width + return paint == other.paint + && width == other.width && opacity == other.opacity && miterLimit == other.miterLimit && dashOffset == other.dashOffset - && dashArray == other.dashArray - && paintType == other.paintType - && paintColor == other.paintColor - && paintUri == other.paintUri; + && dashArray == other.dashArray; } StyleStopData::StyleStopData() diff --git a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h index 00358a0..de058a2 100644 --- a/Source/WebCore/rendering/style/SVGRenderStyleDefs.h +++ b/Source/WebCore/rendering/style/SVGRenderStyleDefs.h @@ -29,8 +29,9 @@ #define SVGRenderStyleDefs_h #if ENABLE(SVG) +#include "Color.h" +#include "PlatformString.h" #include "SVGLength.h" -#include "SVGPaint.h" #include "ShadowData.h" #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> @@ -97,7 +98,7 @@ namespace WebCore { public: static PassRefPtr<StyleFillData> create() { return adoptRef(new StyleFillData); } PassRefPtr<StyleFillData> copy() const { return adoptRef(new StyleFillData(*this)); } - + bool operator==(const StyleFillData&) const; bool operator!=(const StyleFillData& other) const { @@ -105,9 +106,7 @@ namespace WebCore { } float opacity; - SVGPaint::SVGPaintType paintType; - Color paintColor; - String paintUri; + RefPtr<SVGPaint> paint; private: StyleFillData(); @@ -132,9 +131,7 @@ namespace WebCore { SVGLength dashOffset; Vector<SVGLength> dashArray; - SVGPaint::SVGPaintType paintType; - Color paintColor; - String paintUri; + RefPtr<SVGPaint> paint; private: StyleStrokeData(); @@ -265,4 +262,5 @@ namespace WebCore { } // namespace WebCore #endif // ENABLE(SVG) + #endif // SVGRenderStyleDefs_h diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp index c8539c6..5760bed 100644 --- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp @@ -70,6 +70,14 @@ RenderSVGInlineText::RenderSVGInlineText(Node* n, PassRefPtr<StringImpl> string) { } +void RenderSVGInlineText::destroy() +{ + if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this)) + textRenderer->setNeedsPositioningValuesUpdate(); + + RenderText::destroy(); +} + void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderText::styleDidChange(diff, oldStyle); diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.h b/Source/WebCore/rendering/svg/RenderSVGInlineText.h index 9eed8cd..5d1cd54 100644 --- a/Source/WebCore/rendering/svg/RenderSVGInlineText.h +++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.h @@ -48,6 +48,7 @@ public: private: virtual const char* renderName() const { return "RenderSVGInlineText"; } + virtual void destroy(); virtual void styleDidChange(StyleDifference, const RenderStyle*); // FIXME: We need objectBoundingBox for DRT results and filters at the moment. diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.cpp b/Source/WebCore/rendering/svg/RenderSVGResource.cpp index 12ed53a..c0b16c5 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResource.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResource.cpp @@ -51,36 +51,33 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m return 0; } - bool applyToFill = mode == ApplyToFillMode; - SVGPaint::SVGPaintType paintType = applyToFill ? svgStyle->fillPaintType() : svgStyle->strokePaintType(); + SVGPaint* paint = mode == ApplyToFillMode ? svgStyle->fillPaint() : svgStyle->strokePaint(); + ASSERT(paint); + + SVGPaint::SVGPaintType paintType = paint->paintType(); if (paintType == SVGPaint::SVG_PAINTTYPE_NONE) return 0; Color color; - switch (paintType) { - case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR: - case SVGPaint::SVG_PAINTTYPE_RGBCOLOR: - case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: - case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR: - case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR: - case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: - color = applyToFill ? svgStyle->fillPaintColor() : svgStyle->strokePaintColor(); - default: - break; - } + if (paintType == SVGPaint::SVG_PAINTTYPE_RGBCOLOR + || paintType == SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR + || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR + || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR) + color = paint->color(); + else if (paintType == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR || paintType == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR) + color = style->visitedDependentColor(CSSPropertyColor); if (style->insideLink() == InsideVisitedLink) { RenderStyle* visitedStyle = style->getCachedPseudoStyle(VISITED_LINK); ASSERT(visitedStyle); - const SVGRenderStyle* svgVisitedStyle = visitedStyle->svgStyle(); - SVGPaint::SVGPaintType visitedPaintType = applyToFill ? svgVisitedStyle->fillPaintType() : svgVisitedStyle->strokePaintType(); - - // For SVG_PAINTTYPE_CURRENTCOLOR, 'color' already contains the 'visitedColor'. - if (visitedPaintType < SVGPaint::SVG_PAINTTYPE_URI_NONE && visitedPaintType != SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR) { - const Color& visitedColor = applyToFill ? svgVisitedStyle->fillPaintColor() : svgVisitedStyle->strokePaintColor(); - if (visitedColor.isValid()) - color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha()); + if (SVGPaint* visitedPaint = mode == ApplyToFillMode ? visitedStyle->svgStyle()->fillPaint() : visitedStyle->svgStyle()->strokePaint()) { + // For SVG_PAINTTYPE_CURRENTCOLOR, 'color' already contains the 'visitedColor'. + if (visitedPaint->paintType() < SVGPaint::SVG_PAINTTYPE_URI_NONE && visitedPaint->paintType() != SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR) { + const Color& visitedColor = visitedPaint->color(); + if (visitedColor.isValid()) + color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha()); + } } } diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp index 245a859..c57f8b0 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp @@ -254,8 +254,8 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData RefPtr<RenderStyle> oldRenderStyle = renderer->style(); RefPtr<RenderStyle> newRenderStyle = RenderStyle::clone(oldRenderStyle.get()); SVGRenderStyle* svgStyle = newRenderStyle.get()->accessSVGStyle(); - svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri()); - svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri()); + svgStyle->setFillPaint(SVGPaint::defaultFill()); + svgStyle->setStrokePaint(SVGPaint::defaultStroke()); svgStyle->setFillRule(newClipRule); newRenderStyle.get()->setOpacity(1.0f); svgStyle->setFillOpacity(1.0f); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp index 09195f5..d6776cf 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp @@ -27,6 +27,7 @@ #include "RenderSVGResourceFilter.h" #include "AffineTransform.h" +#include "FilterEffect.h" #include "FloatPoint.h" #include "FloatRect.h" #include "GraphicsContext.h" @@ -48,8 +49,6 @@ #include <wtf/UnusedParam.h> #include <wtf/Vector.h> -static const float kMaxFilterSize = 5000.0f; - using namespace std; namespace WebCore { @@ -84,8 +83,12 @@ void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool m { ASSERT(client); - if (m_filter.contains(client)) - delete m_filter.take(client); + if (FilterData* filterData = m_filter.get(client)) { + if (filterData->savedContext) + filterData->markedForRemoval = true; + else + delete m_filter.take(client); + } markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation); } @@ -266,10 +269,15 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo UNUSED_PARAM(resourceMode); #endif - if (!m_filter.contains(object)) + FilterData* filterData = m_filter.get(object); + if (!filterData) return; - FilterData* filterData = m_filter.get(object); + if (filterData->markedForRemoval) { + delete m_filter.take(object); + return; + } + if (!filterData->builded) { if (!filterData->savedContext) { removeClientFromCache(object); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h index c809f23..45aff5c 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h +++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h @@ -43,6 +43,7 @@ struct FilterData { FilterData() : savedContext(0) , builded(false) + , markedForRemoval(false) { } @@ -53,7 +54,8 @@ struct FilterData { AffineTransform shearFreeAbsoluteTransform; FloatRect boundaries; FloatSize scale; - bool builded; + bool builded : 1; + bool markedForRemoval : 1; }; class GraphicsContext; diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp index f077bfd..b74122e 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp @@ -128,7 +128,7 @@ FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(Fi absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height()); absoluteSubregion.intersect(absoluteScaledFilterRegion); - effect->setMaxEffectRect(enclosingIntRect(absoluteSubregion)); + effect->setMaxEffectRect(absoluteSubregion); return subregion; } diff --git a/Source/WebCore/rendering/svg/SVGResources.cpp b/Source/WebCore/rendering/svg/SVGResources.cpp index d3cd184..9a2c999 100644 --- a/Source/WebCore/rendering/svg/SVGResources.cpp +++ b/Source/WebCore/rendering/svg/SVGResources.cpp @@ -152,12 +152,15 @@ static inline String targetReferenceFromResource(SVGElement* element) return SVGURIReference::getTarget(target); } -static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, const SVGPaint::SVGPaintType& paintType, const String& paintUri, AtomicString& id, bool& hasPendingResource) +static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource) { + ASSERT(paint); + + SVGPaint::SVGPaintType paintType = paint->paintType(); if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) return 0; - id = SVGURIReference::getTarget(paintUri); + id = SVGURIReference::getTarget(paint->uri()); RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id); if (!container) { hasPendingResource = true; @@ -256,7 +259,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen if (style->hasFill()) { bool hasPendingResource = false; AtomicString id; - if (setFill(paintingResourceFromSVGPaint(document, style->fillPaintType(), style->fillPaintUri(), id, hasPendingResource))) + if (setFill(paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource))) foundResources = true; else if (hasPendingResource) registerPendingResource(extensions, id, element); @@ -265,7 +268,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen if (style->hasStroke()) { bool hasPendingResource = false; AtomicString id; - if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaintType(), style->strokePaintUri(), id, hasPendingResource))) + if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource))) foundResources = true; else if (hasPendingResource) registerPendingResource(extensions, id, element); |