• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
paint(PaintInfo & paintInfo)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 
paintForeground(RenderSVGImage & renderer,PaintInfo & paintInfo)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