Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / paint / SVGImagePainter.cpp
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/DisplayList.h"
18 #include "platform/graphics/GraphicsContext.h"
19 #include "platform/graphics/GraphicsContextStateSaver.h"
20
21 namespace blink {
22
23 void SVGImagePainter::paint(PaintInfo& paintInfo)
24 {
25     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderSVGImage);
26
27     if (paintInfo.phase != PaintPhaseForeground
28         || m_renderSVGImage.style()->visibility() == HIDDEN
29         || !m_renderSVGImage.imageResource()->hasImage())
30         return;
31
32     FloatRect invalBox = m_renderSVGImage.paintInvalidationRectInLocalCoordinates();
33     if (!SVGRenderSupport::paintInfoIntersectsPaintInvalidationRect(invalBox, m_renderSVGImage.localToParentTransform(), paintInfo))
34         return;
35
36     PaintInfo childPaintInfo(paintInfo);
37     GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false);
38
39     childPaintInfo.applyTransform(m_renderSVGImage.localToParentTransform(), &stateSaver);
40
41     FloatRect boundingBox = m_renderSVGImage.objectBoundingBox();
42     if (!boundingBox.isEmpty()) {
43         // SVGRenderingContext may taint the state - make sure we're always saving.
44         stateSaver.saveIfNeeded();
45
46         SVGRenderingContext renderingContext(&m_renderSVGImage, childPaintInfo);
47         if (renderingContext.isRenderingPrepared()) {
48             if (m_renderSVGImage.style()->svgStyle().bufferedRendering() != BR_STATIC) {
49                 paintForeground(childPaintInfo);
50             } else {
51                 RefPtr<DisplayList>& bufferedForeground = m_renderSVGImage.bufferedForeground();
52                 if (!bufferedForeground) {
53                     childPaintInfo.context->beginRecording(boundingBox);
54                     paintForeground(childPaintInfo);
55                     bufferedForeground = childPaintInfo.context->endRecording();
56                 }
57
58                 childPaintInfo.context->drawDisplayList(bufferedForeground.get());
59             }
60         }
61     }
62
63     if (m_renderSVGImage.style()->outlineWidth())
64         ObjectPainter(m_renderSVGImage).paintOutline(childPaintInfo, IntRect(invalBox));
65 }
66
67 void SVGImagePainter::paintForeground(PaintInfo& paintInfo)
68 {
69     RefPtr<Image> image = m_renderSVGImage.imageResource()->image();
70     FloatRect destRect = m_renderSVGImage.objectBoundingBox();
71     FloatRect srcRect(0, 0, image->width(), image->height());
72
73     SVGImageElement* imageElement = toSVGImageElement(m_renderSVGImage.element());
74     imageElement->preserveAspectRatio()->currentValue()->transformRect(destRect, srcRect);
75
76     InterpolationQuality interpolationQuality = InterpolationDefault;
77     if (m_renderSVGImage.style()->svgStyle().bufferedRendering() != BR_STATIC)
78         interpolationQuality = ImageQualityController::imageQualityController()->chooseInterpolationQuality(paintInfo.context, &m_renderSVGImage, image.get(), image.get(), LayoutSize(destRect.size()));
79
80     InterpolationQuality previousInterpolationQuality = paintInfo.context->imageInterpolationQuality();
81     paintInfo.context->setImageInterpolationQuality(interpolationQuality);
82     paintInfo.context->drawImage(image.get(), destRect, srcRect, CompositeSourceOver);
83     paintInfo.context->setImageInterpolationQuality(previousInterpolationQuality);
84 }
85
86 } // namespace blink