summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/RenderSVGResourcePattern.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-13 16:23:25 +0100
committerBen Murdoch <benm@google.com>2011-05-16 11:35:02 +0100
commit65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch)
treef478babb801e720de7bfaee23443ffe029f58731 /Source/WebCore/rendering/RenderSVGResourcePattern.cpp
parent47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff)
downloadexternal_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebCore/rendering/RenderSVGResourcePattern.cpp')
-rw-r--r--Source/WebCore/rendering/RenderSVGResourcePattern.cpp293
1 files changed, 0 insertions, 293 deletions
diff --git a/Source/WebCore/rendering/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/RenderSVGResourcePattern.cpp
deleted file mode 100644
index cd64183..0000000
--- a/Source/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) Research In Motion Limited 2010. 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.
- *
- */
-
-#include "config.h"
-
-#if ENABLE(SVG)
-#include "RenderSVGResourcePattern.h"
-
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "PatternAttributes.h"
-#include "RenderSVGRoot.h"
-#include "SVGImageBufferTools.h"
-#include "SVGRenderSupport.h"
-
-namespace WebCore {
-
-RenderSVGResourceType RenderSVGResourcePattern::s_resourceType = PatternResourceType;
-
-RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement* node)
- : RenderSVGResourceContainer(node)
- , m_shouldCollectPatternAttributes(true)
-{
-}
-
-RenderSVGResourcePattern::~RenderSVGResourcePattern()
-{
- if (m_pattern.isEmpty())
- return;
-
- deleteAllValues(m_pattern);
- m_pattern.clear();
-}
-
-void RenderSVGResourcePattern::removeAllClientsFromCache(bool markForInvalidation)
-{
- if (!m_pattern.isEmpty()) {
- deleteAllValues(m_pattern);
- m_pattern.clear();
- }
-
- m_shouldCollectPatternAttributes = true;
- markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
-}
-
-void RenderSVGResourcePattern::removeClientFromCache(RenderObject* client, bool markForInvalidation)
-{
- ASSERT(client);
-
- if (m_pattern.contains(client))
- delete m_pattern.take(client);
-
- markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
-}
-
-bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
-{
- ASSERT(object);
- ASSERT(style);
- ASSERT(context);
- ASSERT(resourceMode != ApplyToDefaultMode);
-
- // Be sure to synchronize all SVG properties on the patternElement _before_ processing any further.
- // Otherwhise the call to collectPatternAttributes() below, may cause the SVG DOM property
- // synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
- // PatternData object! Leaving out the line below will cause svg/dynamic-updates/SVGPatternElement-svgdom* to crash.
- SVGPatternElement* patternElement = static_cast<SVGPatternElement*>(node());
- if (!patternElement)
- return false;
-
- if (m_shouldCollectPatternAttributes) {
- patternElement->updateAnimatedSVGAttribute(anyQName());
-
- m_attributes = PatternAttributes();
- patternElement->collectPatternAttributes(m_attributes);
- m_shouldCollectPatternAttributes = false;
- }
-
- // Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified,
- // then the given effect (e.g. a gradient or a filter) will be ignored.
- FloatRect objectBoundingBox = object->objectBoundingBox();
- if (m_attributes.boundingBoxMode() && objectBoundingBox.isEmpty())
- return false;
-
- if (!m_pattern.contains(object))
- m_pattern.set(object, new PatternData);
-
- PatternData* patternData = m_pattern.get(object);
- if (!patternData->pattern) {
- // If we couldn't determine the pattern content element root, stop here.
- if (!m_attributes.patternContentElement())
- return false;
-
- // Compute all necessary transformations to build the tile image & the pattern.
- FloatRect tileBoundaries;
- AffineTransform tileImageTransform;
- if (!buildTileImageTransform(object, m_attributes, patternElement, tileBoundaries, tileImageTransform))
- return false;
-
- AffineTransform absoluteTransform;
- SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
-
- FloatRect absoluteTileBoundaries = absoluteTransform.mapRect(tileBoundaries);
-
- // Build tile image.
- OwnPtr<ImageBuffer> tileImage = createTileImage(object, m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform);
- if (!tileImage)
- return false;
-
- RefPtr<Image> copiedImage = tileImage->copyImage();
- if (!copiedImage)
- return false;
-
- // Build pattern.
- patternData->pattern = Pattern::create(copiedImage, true, true);
- if (!patternData->pattern)
- return false;
-
- // Compute pattern space transformation.
- patternData->transform.translate(tileBoundaries.x(), tileBoundaries.y());
- patternData->transform.scale(tileBoundaries.width() / absoluteTileBoundaries.width(), tileBoundaries.height() / absoluteTileBoundaries.height());
-
- AffineTransform patternTransform = m_attributes.patternTransform();
- if (!patternTransform.isIdentity())
- patternData->transform.multiply(patternTransform);
-
- patternData->pattern->setPatternSpaceTransform(patternData->transform);
- }
-
- // Draw pattern
- context->save();
-
- const SVGRenderStyle* svgStyle = style->svgStyle();
- ASSERT(svgStyle);
-
- if (resourceMode & ApplyToFillMode) {
- context->setAlpha(svgStyle->fillOpacity());
- context->setFillPattern(patternData->pattern);
- context->setFillRule(svgStyle->fillRule());
- } else if (resourceMode & ApplyToStrokeMode) {
- if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
- patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(object, patternData->transform));
- context->setAlpha(svgStyle->strokeOpacity());
- context->setStrokePattern(patternData->pattern);
- SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
- }
-
- if (resourceMode & ApplyToTextMode) {
- if (resourceMode & ApplyToFillMode) {
- context->setTextDrawingMode(TextModeFill);
-
-#if PLATFORM(CG)
- context->applyFillPattern();
-#endif
- } else if (resourceMode & ApplyToStrokeMode) {
- context->setTextDrawingMode(TextModeStroke);
-
-#if PLATFORM(CG)
- context->applyStrokePattern();
-#endif
- }
- }
-
- return true;
-}
-
-void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path)
-{
- ASSERT(context);
- ASSERT(resourceMode != ApplyToDefaultMode);
-
- if (path && !(resourceMode & ApplyToTextMode)) {
- if (resourceMode & ApplyToFillMode)
- context->fillPath(*path);
- else if (resourceMode & ApplyToStrokeMode)
- context->strokePath(*path);
- }
-
- context->restore();
-}
-
-static inline FloatRect calculatePatternBoundaries(const PatternAttributes& attributes,
- const FloatRect& objectBoundingBox,
- const SVGPatternElement* patternElement)
-{
- ASSERT(patternElement);
-
- if (attributes.boundingBoxMode())
- return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(),
- attributes.y().valueAsPercentage() * objectBoundingBox.height() + objectBoundingBox.y(),
- attributes.width().valueAsPercentage() * objectBoundingBox.width(),
- attributes.height().valueAsPercentage() * objectBoundingBox.height());
-
- return FloatRect(attributes.x().value(patternElement),
- attributes.y().value(patternElement),
- attributes.width().value(patternElement),
- attributes.height().value(patternElement));
-}
-
-bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
- const PatternAttributes& attributes,
- const SVGPatternElement* patternElement,
- FloatRect& patternBoundaries,
- AffineTransform& tileImageTransform) const
-{
- ASSERT(renderer);
- ASSERT(patternElement);
-
- FloatRect objectBoundingBox = renderer->objectBoundingBox();
- patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
- if (patternBoundaries.width() <= 0 || patternBoundaries.height() <= 0)
- return false;
-
- AffineTransform viewBoxCTM = patternElement->viewBoxToViewTransform(patternElement->viewBox(), patternElement->preserveAspectRatio(), patternBoundaries.width(), patternBoundaries.height());
-
- // Apply viewBox/objectBoundingBox transformations.
- if (!viewBoxCTM.isIdentity())
- tileImageTransform = viewBoxCTM;
- else if (attributes.boundingBoxModeContent()) {
- tileImageTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
- tileImageTransform.scale(objectBoundingBox.width(), objectBoundingBox.height());
- }
-
- return true;
-}
-
-PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(RenderObject* object,
- const PatternAttributes& attributes,
- const FloatRect& tileBoundaries,
- const FloatRect& absoluteTileBoundaries,
- const AffineTransform& tileImageTransform) const
-{
- ASSERT(object);
-
- // Clamp tile image size against SVG viewport size, as last resort, to avoid allocating huge image buffers.
- FloatRect contentBoxRect = SVGRenderSupport::findTreeRootObject(object)->contentBoxRect();
-
- FloatRect clampedAbsoluteTileBoundaries = absoluteTileBoundaries;
- if (clampedAbsoluteTileBoundaries.width() > contentBoxRect.width())
- clampedAbsoluteTileBoundaries.setWidth(contentBoxRect.width());
-
- if (clampedAbsoluteTileBoundaries.height() > contentBoxRect.height())
- clampedAbsoluteTileBoundaries.setHeight(contentBoxRect.height());
-
- OwnPtr<ImageBuffer> tileImage;
-
- if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB))
- return PassOwnPtr<ImageBuffer>();
-
- GraphicsContext* tileImageContext = tileImage->context();
- ASSERT(tileImageContext);
-
- // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
- tileImageContext->scale(FloatSize(absoluteTileBoundaries.width() / tileBoundaries.width(),
- absoluteTileBoundaries.height() / tileBoundaries.height()));
-
- // Apply tile image transformations.
- if (!tileImageTransform.isIdentity())
- tileImageContext->concatCTM(tileImageTransform);
-
- AffineTransform contentTransformation;
-
- // Draw the content into the ImageBuffer.
- for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
- continue;
- SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation);
- }
-
- return tileImage.release();
-}
-
-}
-
-#endif