SVGPaintServer LayoutSVGResourcePattern::preparePaintServer(const LayoutObject& object) { clearInvalidationMask(); SVGPatternElement* patternElement = toSVGPatternElement(element()); if (!patternElement) return SVGPaintServer::invalid(); if (m_shouldCollectPatternAttributes) { patternElement->synchronizeAnimatedSVGAttribute(anyQName()); #if ENABLE(OILPAN) m_attributesWrapper->set(PatternAttributes()); #else m_attributes = PatternAttributes(); #endif patternElement->collectPatternAttributes(mutableAttributes()); 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 (attributes().patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty()) return SVGPaintServer::invalid(); PatternData* patternData = patternForLayoutObject(object); if (!patternData || !patternData->pattern) return SVGPaintServer::invalid(); patternData->pattern->setPatternSpaceTransform(patternData->transform); return SVGPaintServer(patternData->pattern); }
SVGPaintServer SVGPaintServer::requestForLayoutObject(const LayoutObject& layoutObject, const ComputedStyle& style, LayoutSVGResourceMode resourceMode) { ASSERT(resourceMode == ApplyToFillMode || resourceMode == ApplyToStrokeMode); SVGPaintDescription paintDescription = requestPaint(layoutObject, style, resourceMode); if (!paintDescription.isValid) return invalid(); if (!paintDescription.resource) return SVGPaintServer(paintDescription.color); SVGPaintServer paintServer = paintDescription.resource->preparePaintServer(layoutObject); if (paintServer.isValid()) return paintServer; if (paintDescription.hasFallback) return SVGPaintServer(paintDescription.color); return invalid(); }
SVGPaintServer LayoutSVGResourceGradient::preparePaintServer( const LayoutObject& object) { clearInvalidationMask(); // Be sure to synchronize all SVG properties on the gradientElement _before_ // processing any further. Otherwhise the call to collectGradientAttributes() // in createTileImage(), may cause the SVG DOM property synchronization to // kick in, which causes removeAllClientsFromCache() to be called, which in // turn deletes our GradientData object! Leaving out the line below will cause // svg/dynamic-updates/SVG*GradientElement-svgdom* to crash. SVGGradientElement* gradientElement = toSVGGradientElement(element()); if (!gradientElement) return SVGPaintServer::invalid(); if (m_shouldCollectGradientAttributes) { gradientElement->synchronizeAnimatedSVGAttribute(anyQName()); if (!collectGradientAttributes(gradientElement)) return SVGPaintServer::invalid(); m_shouldCollectGradientAttributes = 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 (gradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox && objectBoundingBox.isEmpty()) return SVGPaintServer::invalid(); std::unique_ptr<GradientData>& gradientData = m_gradientMap.add(&object, nullptr).storedValue->value; if (!gradientData) gradientData = WTF::wrapUnique(new GradientData); // Create gradient object if (!gradientData->gradient) { gradientData->gradient = buildGradient(); // We want the text bounding box applied to the gradient space transform // now, so the gradient shader can use it. if (gradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox && !objectBoundingBox.isEmpty()) { gradientData->userspaceTransform.translate(objectBoundingBox.x(), objectBoundingBox.y()); gradientData->userspaceTransform.scaleNonUniform( objectBoundingBox.width(), objectBoundingBox.height()); } AffineTransform gradientTransform = calculateGradientTransform(); gradientData->userspaceTransform *= gradientTransform; } if (!gradientData->gradient) return SVGPaintServer::invalid(); return SVGPaintServer(gradientData->gradient, gradientData->userspaceTransform); }