void SVGShapePainter::paintMarker(const PaintInfo& paintInfo, RenderSVGResourceMarker& marker, const MarkerPosition& position, float strokeWidth) { // An empty viewBox disables rendering. SVGMarkerElement* markerElement = toSVGMarkerElement(marker.element()); ASSERT(markerElement); if (markerElement->hasAttribute(SVGNames::viewBoxAttr) && markerElement->viewBox()->currentValue()->isValid() && markerElement->viewBox()->currentValue()->value().isEmpty()) return; OwnPtr<DisplayItemList> displayItemList; if (RuntimeEnabledFeatures::slimmingPaintEnabled()) displayItemList = DisplayItemList::create(); GraphicsContext recordingContext(nullptr, displayItemList.get()); recordingContext.beginRecording(m_renderSVGShape.paintInvalidationRectInLocalCoordinates()); PaintInfo markerPaintInfo(paintInfo); markerPaintInfo.context = &recordingContext; { TransformRecorder transformRecorder(*markerPaintInfo.context, marker.displayItemClient(), marker.markerTransformation(position.origin, position.angle, strokeWidth)); OwnPtr<FloatClipRecorder> clipRecorder; if (SVGRenderSupport::isOverflowHidden(&marker)) clipRecorder = adoptPtr(new FloatClipRecorder(recordingContext, marker.displayItemClient(), markerPaintInfo.phase, marker.viewport())); SVGContainerPainter(marker).paint(markerPaintInfo); } if (displayItemList) displayItemList->replay(&recordingContext); RefPtr<const SkPicture> recording = recordingContext.endRecording(); paintInfo.context->drawPicture(recording.get()); }
void SVGShapePainter::paintMarkers(const PaintInfo& paintInfo, const FloatRect& boundingBox) { const Vector<MarkerPosition>* markerPositions = m_layoutSVGShape.markerPositions(); if (!markerPositions || markerPositions->isEmpty()) return; SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(&m_layoutSVGShape); if (!resources) return; LayoutSVGResourceMarker* markerStart = resources->markerStart(); LayoutSVGResourceMarker* markerMid = resources->markerMid(); LayoutSVGResourceMarker* markerEnd = resources->markerEnd(); if (!markerStart && !markerMid && !markerEnd) return; float strokeWidth = m_layoutSVGShape.strokeWidth(); unsigned size = markerPositions->size(); for (unsigned i = 0; i < size; ++i) { if (LayoutSVGResourceMarker* marker = SVGMarkerData::markerForType((*markerPositions)[i].type, markerStart, markerMid, markerEnd)) { SkPictureBuilder pictureBuilder(boundingBox, nullptr, &paintInfo.context); PaintInfo markerPaintInfo(pictureBuilder.context(), paintInfo); // It's expensive to track the transformed paint cull rect for each // marker so just disable culling. The shape paint call will already // be culled if it is outside the paint info cull rect. markerPaintInfo.m_cullRect.m_rect = LayoutRect::infiniteIntRect(); paintMarker(markerPaintInfo, *marker, (*markerPositions)[i], strokeWidth); pictureBuilder.endRecording()->playback(paintInfo.context.canvas()); } } }
void SVGShapePainter::paintMarker(const PaintInfo& paintInfo, LayoutSVGResourceMarker& marker, const MarkerPosition& position, float strokeWidth) { // An empty viewBox disables rendering. SVGMarkerElement* markerElement = toSVGMarkerElement(marker.element()); ASSERT(markerElement); if (markerElement->hasAttribute(SVGNames::viewBoxAttr) && markerElement->viewBox()->currentValue()->isValid() && markerElement->viewBox()->currentValue()->value().isEmpty()) return; { DisplayItemListContextRecorder contextRecorder(*paintInfo.context); PaintInfo markerPaintInfo(paintInfo); markerPaintInfo.context = &contextRecorder.context(); TransformRecorder transformRecorder(*markerPaintInfo.context, marker, marker.markerTransformation(position.origin, position.angle, strokeWidth)); OwnPtr<FloatClipRecorder> clipRecorder; if (SVGLayoutSupport::isOverflowHidden(&marker)) clipRecorder = adoptPtr(new FloatClipRecorder(*markerPaintInfo.context, marker, markerPaintInfo.phase, marker.viewport())); SVGContainerPainter(marker).paint(markerPaintInfo); } }