diff options
| author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-07 11:22:47 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-07 11:22:47 +0100 |
| commit | cfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch) | |
| tree | 24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/WebCore/rendering/svg | |
| parent | 69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff) | |
| download | qtwebkit-cfd86b747d32ac22246a1aa908eaa720c63a88c1.tar.gz | |
Imported WebKit commit 20271caf2e2c016d5cef40184cddeefeac4f1876 (http://svn.webkit.org/repository/webkit/trunk@133733)
New snapshot that contains all previous fixes as well as build fix for latest QtMultimedia API changes.
Diffstat (limited to 'Source/WebCore/rendering/svg')
6 files changed, 52 insertions, 60 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.h b/Source/WebCore/rendering/svg/RenderSVGContainer.h index 335732b84..3c0fa9814 100644 --- a/Source/WebCore/rendering/svg/RenderSVGContainer.h +++ b/Source/WebCore/rendering/svg/RenderSVGContainer.h @@ -36,6 +36,9 @@ public: explicit RenderSVGContainer(SVGStyledElement*); virtual ~RenderSVGContainer(); + RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); } + RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); } + const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp index 74e5b36d3..7d4eedfc9 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp @@ -57,25 +57,6 @@ using namespace std; namespace WebCore { -class ApplyingFilterEffectGuard { -public: - ApplyingFilterEffectGuard(FilterData* data) - : m_filterData(data) - { - // The guard must be constructed when the filter is not applying. - ASSERT(!m_filterData->isApplying); - m_filterData->isApplying = true; - } - - ~ApplyingFilterEffectGuard() - { - ASSERT(m_filterData->isApplying); - m_filterData->isApplying = false; - } - - FilterData* m_filterData; -}; - RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceType; RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node) @@ -108,7 +89,7 @@ void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool m if (FilterData* filterData = m_filter.get(client)) { if (filterData->savedContext) - filterData->markedForRemoval = true; + filterData->state = FilterData::MarkedForRemoval; else delete m_filter.take(client); } @@ -168,14 +149,11 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, ASSERT(context); ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); - // Returning false here, to avoid drawings onto the context. We just want to - // draw the stored filter output, not the unfiltered object as well. if (m_filter.contains(object)) { FilterData* filterData = m_filter.get(object); - if (filterData->isBuilt || filterData->isApplying) - return false; - - delete m_filter.take(object); // Oops, have to rebuild, go through normal code path + if (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Applying) + filterData->state = FilterData::CycleDetected; + return false; // Already built, or we're in a cycle, or we're marked for removal. Regardless, just do nothing more now. } OwnPtr<FilterData> filterData(adoptPtr(new FilterData)); @@ -292,17 +270,21 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo if (!filterData) return; - if (filterData->markedForRemoval) { + switch (filterData->state) { + case FilterData::MarkedForRemoval: delete m_filter.take(object); return; - } - // We have a cycle if we are already applying the data. - // This can occur due to FeImage referencing a source that makes use of the FEImage itself. - if (filterData->isApplying) + case FilterData::CycleDetected: + case FilterData::Applying: + // We have a cycle if we are already applying the data. + // This can occur due to FeImage referencing a source that makes use of the FEImage itself. + // This is the first place we've hit the cycle, so set the state back to PaintingSource so the return stack + // will continue correctly. + filterData->state = FilterData::PaintingSource; return; - if (!filterData->isBuilt) { + case FilterData::PaintingSource: if (!filterData->savedContext) { removeClientFromCache(object); return; @@ -310,9 +292,10 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo context = filterData->savedContext; filterData->savedContext = 0; - } + break; - ApplyingFilterEffectGuard isApplyingGuard(filterData); + case FilterData::Built: { } // Empty + } FilterEffect* lastEffect = filterData->builder->lastEffect(); @@ -320,11 +303,12 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo // This is the real filtering of the object. It just needs to be called on the // initial filtering process. We just take the stored filter result on a // second drawing. - if (!filterData->isBuilt) + if (filterData->state != FilterData::Built) filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release()); - // Always true if filterData is just built (filterData->isBuilt is false). + // Always true if filterData is just built (filterData->state == FilterData::Built). if (!lastEffect->hasResult()) { + filterData->state = FilterData::Applying; lastEffect->apply(); lastEffect->correctFilterResultIfNeeded(); #if !USE(CG) @@ -333,7 +317,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB); #endif } - filterData->isBuilt = true; + filterData->state = FilterData::Built; ImageBuffer* resultImage = lastEffect->asImageBuffer(); if (resultImage) { @@ -365,7 +349,7 @@ void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co for (; it != end; ++it) { FilterData* filterData = it->value; - if (!filterData->isBuilt) + if (filterData->state != FilterData::Built) continue; SVGFilterBuilder* builder = filterData->builder.get(); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h index 0101bbc1e..db422c17e 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h +++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h @@ -42,11 +42,11 @@ namespace WebCore { struct FilterData { WTF_MAKE_FAST_ALLOCATED; public: + enum FilterDataState { PaintingSource, Applying, Built, CycleDetected, MarkedForRemoval }; + FilterData() : savedContext(0) - , isBuilt(false) - , isApplying(false) - , markedForRemoval(false) + , state(PaintingSource) { } @@ -57,9 +57,7 @@ public: AffineTransform shearFreeAbsoluteTransform; FloatRect boundaries; FloatSize scale; - bool isBuilt : 1; - bool isApplying : 1; - bool markedForRemoval : 1; + FilterDataState state; }; class GraphicsContext; diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp index 797b70ea7..2733ae446 100644 --- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp @@ -297,18 +297,22 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset); - childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x() - x(), adjustedPaintOffset.y() - y()) * localToParentTransform()); + childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform()); + + // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have + // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter. + { + SVGRenderingContext renderingContext; + bool continueRendering = true; + if (childPaintInfo.phase == PaintPhaseForeground) { + renderingContext.prepareToRenderSVGContent(this, childPaintInfo); + continueRendering = renderingContext.isRenderingPrepared(); + } - SVGRenderingContext renderingContext; - bool continueRendering = true; - if (childPaintInfo.phase == PaintPhaseForeground) { - renderingContext.prepareToRenderSVGContent(this, childPaintInfo); - continueRendering = renderingContext.isRenderingPrepared(); + if (continueRendering) + RenderBox::paint(childPaintInfo, LayoutPoint()); } - if (continueRendering) - RenderBox::paint(childPaintInfo, LayoutPoint()); - childPaintInfo.context->restore(); } diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.h b/Source/WebCore/rendering/svg/RenderSVGRoot.h index 3fadc910b..1e112a199 100644 --- a/Source/WebCore/rendering/svg/RenderSVGRoot.h +++ b/Source/WebCore/rendering/svg/RenderSVGRoot.h @@ -43,6 +43,10 @@ public: bool isEmbeddedThroughFrameContainingSVGDocument() const; virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const; + + RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); } + RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); } + const RenderObjectChildList* children() const { return &m_children; } RenderObjectChildList* children() { return &m_children; } diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp index 066ba31af..7341e69cd 100644 --- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp +++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp @@ -188,6 +188,12 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co return glyphData; } + // Save data fromt he font fallback list because we may modify it later. Do this before the + // potential change to glyphData.fontData below. + FontFallbackList* fontList = font.fontList(); + ASSERT(fontList); + FontFallbackList::GlyphPagesStateSaver glyphPagesSaver(*fontList); + // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage. const SimpleFontData* originalFontData = glyphData.fontData; if (glyphData.fontData && !glyphData.fontData->isSVGFont()) { @@ -225,14 +231,9 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co GlyphPage* page = pair.second; ASSERT(page); - FontFallbackList* fontList = font.fontList(); - ASSERT(fontList); - // No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.) // Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily // remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly. - GlyphPageTreeNode* originalGlyphPageZero = fontList->glyphPageZero(); - const FontFallbackList::GlyphPages& originalGlyphPages = fontList->glyphPages(); page->setGlyphDataForCharacter(character, glyphData.glyph, 0); // Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before. @@ -242,8 +243,6 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co // Restore original state of the SVG Font glyph table and the current font fallback list, // to assure the next lookup of the same glyph won't immediately return the fallback glyph. page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData); - fontList->setGlyphPageZero(originalGlyphPageZero); - fontList->setGlyphPages(originalGlyphPages); ASSERT(fallbackGlyphData.fontData); return fallbackGlyphData; } |
