1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "core/paint/SVGImagePainter.h" 7 8 #include "core/paint/ObjectPainter.h" 9 #include "core/rendering/GraphicsContextAnnotator.h" 10 #include "core/rendering/ImageQualityController.h" 11 #include "core/rendering/PaintInfo.h" 12 #include "core/rendering/RenderImageResource.h" 13 #include "core/rendering/svg/RenderSVGImage.h" 14 #include "core/rendering/svg/SVGRenderSupport.h" 15 #include "core/rendering/svg/SVGRenderingContext.h" 16 #include "core/svg/SVGImageElement.h" 17 #include "platform/graphics/GraphicsContextStateSaver.h" 18 19 namespace blink { 20 21 void SVGImagePainter::paint(PaintInfo& paintInfo) 22 { 23 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderSVGImage); 24 25 if (paintInfo.phase != PaintPhaseForeground 26 || m_renderSVGImage.style()->visibility() == HIDDEN 27 || !m_renderSVGImage.imageResource()->hasImage()) 28 return; 29 30 FloatRect boundingBox = m_renderSVGImage.paintInvalidationRectInLocalCoordinates(); 31 if (!SVGRenderSupport::paintInfoIntersectsPaintInvalidationRect(boundingBox, m_renderSVGImage.localToParentTransform(), paintInfo)) 32 return; 33 34 PaintInfo childPaintInfo(paintInfo); 35 GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false); 36 37 childPaintInfo.applyTransform(m_renderSVGImage.localToParentTransform(), &stateSaver); 38 39 if (!m_renderSVGImage.objectBoundingBox().isEmpty()) { 40 // SVGRenderingContext may taint the state - make sure we're always saving. 41 stateSaver.saveIfNeeded(); 42 43 SVGRenderingContext renderingContext(&m_renderSVGImage, childPaintInfo); 44 if (renderingContext.isRenderingPrepared()) { 45 if (m_renderSVGImage.style()->svgStyle().bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_renderSVGImage.bufferedForeground())) 46 return; 47 48 paintForeground(m_renderSVGImage, childPaintInfo); 49 } 50 } 51 52 if (m_renderSVGImage.style()->outlineWidth()) 53 ObjectPainter(m_renderSVGImage).paintOutline(childPaintInfo, IntRect(boundingBox)); 54 } 55 56 void SVGImagePainter::paintForeground(RenderSVGImage& renderer, PaintInfo& paintInfo) 57 { 58 RefPtr<Image> image = renderer.imageResource()->image(); 59 FloatRect destRect = renderer.objectBoundingBox(); 60 FloatRect srcRect(0, 0, image->width(), image->height()); 61 62 SVGImageElement* imageElement = toSVGImageElement(renderer.element()); 63 imageElement->preserveAspectRatio()->currentValue()->transformRect(destRect, srcRect); 64 65 InterpolationQuality interpolationQuality = InterpolationDefault; 66 if (renderer.style()->svgStyle().bufferedRendering() != BR_STATIC) 67 interpolationQuality = ImageQualityController::imageQualityController()->chooseInterpolationQuality(paintInfo.context, &renderer, image.get(), image.get(), LayoutSize(destRect.size())); 68 69 InterpolationQuality previousInterpolationQuality = paintInfo.context->imageInterpolationQuality(); 70 paintInfo.context->setImageInterpolationQuality(interpolationQuality); 71 paintInfo.context->drawImage(image.get(), destRect, srcRect, CompositeSourceOver); 72 paintInfo.context->setImageInterpolationQuality(previousInterpolationQuality); 73 } 74 75 } // namespace blink 76