void RenderPath::calculateMarkerBoundsIfNeeded() const { Document* doc = document(); SVGElement* svgElement = static_cast<SVGElement*>(node()); ASSERT(svgElement && svgElement->document()); if (!svgElement->isStyled()) return; SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement); if (!styledElement->supportsMarkers()) return; const SVGRenderStyle* svgStyle = style()->svgStyle(); AtomicString startMarkerId(svgStyle->startMarker()); AtomicString midMarkerId(svgStyle->midMarker()); AtomicString endMarkerId(svgStyle->endMarker()); SVGResourceMarker* startMarker = getMarkerById(doc, startMarkerId, this); SVGResourceMarker* midMarker = getMarkerById(doc, midMarkerId, this); SVGResourceMarker* endMarker = getMarkerById(doc, endMarkerId, this); if (!startMarker && !startMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement); else if (startMarker) startMarker->addClient(styledElement); if (!midMarker && !midMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(midMarkerId, styledElement); else if (midMarker) midMarker->addClient(styledElement); if (!endMarker && !endMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(endMarkerId, styledElement); else if (endMarker) endMarker->addClient(styledElement); if (!startMarker && !midMarker && !endMarker) return; float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f); m_cachedLocalMarkerBBox = m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path); }
FloatRect RenderPath::drawMarkersIfNeeded(GraphicsContext* context, const FloatRect&, const Path& path) const { Document* doc = document(); SVGElement* svgElement = static_cast<SVGElement*>(node()); ASSERT(svgElement && svgElement->document() && svgElement->isStyled()); SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement); const SVGRenderStyle* svgStyle = style()->svgStyle(); AtomicString startMarkerId(svgStyle->startMarker()); AtomicString midMarkerId(svgStyle->midMarker()); AtomicString endMarkerId(svgStyle->endMarker()); SVGResourceMarker* startMarker = getMarkerById(doc, startMarkerId); SVGResourceMarker* midMarker = getMarkerById(doc, midMarkerId); SVGResourceMarker* endMarker = getMarkerById(doc, endMarkerId); if (!startMarker && !startMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement); else if (startMarker) startMarker->addClient(styledElement); if (!midMarker && !midMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(midMarkerId, styledElement); else if (midMarker) midMarker->addClient(styledElement); if (!endMarker && !endMarkerId.isEmpty()) svgElement->document()->accessSVGExtensions()->addPendingResource(endMarkerId, styledElement); else if (endMarker) endMarker->addClient(styledElement); if (!startMarker && !midMarker && !endMarker) return FloatRect(); double strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f); DrawMarkersData data(context, startMarker, midMarker, strokeWidth); path.apply(&data, drawStartAndMidMarkers); data.previousMarkerData.marker = endMarker; data.previousMarkerData.type = End; drawMarkerWithData(context, data.previousMarkerData); // We know the marker boundaries, only after they're drawn! // Otherwhise we'd need to do all the marker calculation twice // once here (through paint()) and once in absoluteClippedOverflowRect(). FloatRect bounds; if (startMarker) bounds.unite(startMarker->cachedBounds()); if (midMarker) bounds.unite(midMarker->cachedBounds()); if (endMarker) bounds.unite(endMarker->cachedBounds()); return bounds; }