Home | History | Annotate | Download | only in paint
      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