| OLD | NEW | 
|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "config.h" | 5 #include "config.h" | 
| 6 #include "core/paint/SVGImagePainter.h" | 6 #include "core/paint/SVGImagePainter.h" | 
| 7 | 7 | 
| 8 #include "core/paint/ObjectPainter.h" | 8 #include "core/paint/ObjectPainter.h" | 
| 9 #include "core/rendering/GraphicsContextAnnotator.h" | 9 #include "core/rendering/GraphicsContextAnnotator.h" | 
| 10 #include "core/rendering/ImageQualityController.h" | 10 #include "core/rendering/ImageQualityController.h" | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 35     GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false); | 35     GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false); | 
| 36 | 36 | 
| 37     childPaintInfo.applyTransform(m_renderSVGImage.localToParentTransform(), &st
     ateSaver); | 37     childPaintInfo.applyTransform(m_renderSVGImage.localToParentTransform(), &st
     ateSaver); | 
| 38 | 38 | 
| 39     if (!m_renderSVGImage.objectBoundingBox().isEmpty()) { | 39     if (!m_renderSVGImage.objectBoundingBox().isEmpty()) { | 
| 40         // SVGRenderingContext may taint the state - make sure we're always savi
     ng. | 40         // SVGRenderingContext may taint the state - make sure we're always savi
     ng. | 
| 41         stateSaver.saveIfNeeded(); | 41         stateSaver.saveIfNeeded(); | 
| 42 | 42 | 
| 43         SVGRenderingContext renderingContext(&m_renderSVGImage, childPaintInfo); | 43         SVGRenderingContext renderingContext(&m_renderSVGImage, childPaintInfo); | 
| 44         if (renderingContext.isRenderingPrepared()) { | 44         if (renderingContext.isRenderingPrepared()) { | 
| 45             if (m_renderSVGImage.style()->svgStyle().bufferedRendering() == BR_S
     TATIC && renderingContext.bufferForeground(m_renderSVGImage.bufferedForeground()
     )) | 45             if (m_renderSVGImage.style()->svgStyle().bufferedRendering() == BR_S
     TATIC && bufferForeground(childPaintInfo)) | 
| 46                 return; | 46                 return; | 
| 47 | 47 | 
| 48             paintForeground(m_renderSVGImage, childPaintInfo); | 48             paintForeground(childPaintInfo); | 
| 49         } | 49         } | 
| 50     } | 50     } | 
| 51 | 51 | 
| 52     if (m_renderSVGImage.style()->outlineWidth()) | 52     if (m_renderSVGImage.style()->outlineWidth()) | 
| 53         ObjectPainter(m_renderSVGImage).paintOutline(childPaintInfo, IntRect(bou
     ndingBox)); | 53         ObjectPainter(m_renderSVGImage).paintOutline(childPaintInfo, IntRect(bou
     ndingBox)); | 
| 54 } | 54 } | 
| 55 | 55 | 
| 56 void SVGImagePainter::paintForeground(RenderSVGImage& renderer, PaintInfo& paint
     Info) | 56 static IntSize estimateBufferSize(const AffineTransform& transform, const IntSiz
     e& boundingBox) | 
| 57 { | 57 { | 
| 58     RefPtr<Image> image = renderer.imageResource()->image(); | 58     // This is supposed to be the exact same calculation as GraphicsContext::cre
     ateRasterBuffer performs. | 
| 59     FloatRect destRect = renderer.objectBoundingBox(); | 59     int estimatedWidth = static_cast<int>(ceil(boundingBox.width() * transform.x
     Scale())); | 
|  | 60     int estimatedHeight = static_cast<int>(ceil(boundingBox.height() * transform
     .yScale())); | 
|  | 61     return IntSize(estimatedWidth, estimatedHeight); | 
|  | 62 } | 
|  | 63 | 
|  | 64 bool SVGImagePainter::bufferForeground(PaintInfo& paintInfo) | 
|  | 65 { | 
|  | 66     FloatRect boundingBox = m_renderSVGImage.objectBoundingBox(); | 
|  | 67     OwnPtr<ImageBuffer>& imageBuffer = m_renderSVGImage.bufferedForeground(); | 
|  | 68     IntSize expandedBoundingBox = expandedIntSize(boundingBox.size()); | 
|  | 69 | 
|  | 70     // Invalidate an existing buffer if the scale is not correct. | 
|  | 71     if (imageBuffer) { | 
|  | 72         IntSize estimatedBufferSize = estimateBufferSize(paintInfo.context->getC
     TM(), expandedBoundingBox); | 
|  | 73         if (estimatedBufferSize != imageBuffer->size()) | 
|  | 74             imageBuffer.clear(); | 
|  | 75     } | 
|  | 76 | 
|  | 77     // Create a new buffer and paint the foreground into it. | 
|  | 78     if (!imageBuffer) { | 
|  | 79         imageBuffer = paintInfo.context->createRasterBuffer(expandedBoundingBox)
     ; | 
|  | 80         if (!imageBuffer) | 
|  | 81             return false; | 
|  | 82 | 
|  | 83         GraphicsContext* bufferedRenderingContext = imageBuffer->context(); | 
|  | 84         bufferedRenderingContext->translate(-boundingBox.x(), -boundingBox.y()); | 
|  | 85         PaintInfo bufferedInfo(paintInfo); | 
|  | 86         bufferedInfo.context = bufferedRenderingContext; | 
|  | 87         paintForeground(bufferedInfo); | 
|  | 88     } | 
|  | 89 | 
|  | 90     paintInfo.context->drawImageBuffer(imageBuffer.get(), boundingBox); | 
|  | 91     return true; | 
|  | 92 } | 
|  | 93 | 
|  | 94 void SVGImagePainter::paintForeground(PaintInfo& paintInfo) | 
|  | 95 { | 
|  | 96     RefPtr<Image> image = m_renderSVGImage.imageResource()->image(); | 
|  | 97     FloatRect destRect = m_renderSVGImage.objectBoundingBox(); | 
| 60     FloatRect srcRect(0, 0, image->width(), image->height()); | 98     FloatRect srcRect(0, 0, image->width(), image->height()); | 
| 61 | 99 | 
| 62     SVGImageElement* imageElement = toSVGImageElement(renderer.element()); | 100     SVGImageElement* imageElement = toSVGImageElement(m_renderSVGImage.element()
     ); | 
| 63     imageElement->preserveAspectRatio()->currentValue()->transformRect(destRect,
      srcRect); | 101     imageElement->preserveAspectRatio()->currentValue()->transformRect(destRect,
      srcRect); | 
| 64 | 102 | 
| 65     InterpolationQuality interpolationQuality = InterpolationDefault; | 103     InterpolationQuality interpolationQuality = InterpolationDefault; | 
| 66     if (renderer.style()->svgStyle().bufferedRendering() != BR_STATIC) | 104     if (m_renderSVGImage.style()->svgStyle().bufferedRendering() != BR_STATIC) | 
| 67         interpolationQuality = ImageQualityController::imageQualityController()-
     >chooseInterpolationQuality(paintInfo.context, &renderer, image.get(), image.get
     (), LayoutSize(destRect.size())); | 105         interpolationQuality = ImageQualityController::imageQualityController()-
     >chooseInterpolationQuality(paintInfo.context, &m_renderSVGImage, image.get(), i
     mage.get(), LayoutSize(destRect.size())); | 
| 68 | 106 | 
| 69     InterpolationQuality previousInterpolationQuality = paintInfo.context->image
     InterpolationQuality(); | 107     InterpolationQuality previousInterpolationQuality = paintInfo.context->image
     InterpolationQuality(); | 
| 70     paintInfo.context->setImageInterpolationQuality(interpolationQuality); | 108     paintInfo.context->setImageInterpolationQuality(interpolationQuality); | 
| 71     paintInfo.context->drawImage(image.get(), destRect, srcRect, CompositeSource
     Over); | 109     paintInfo.context->drawImage(image.get(), destRect, srcRect, CompositeSource
     Over); | 
| 72     paintInfo.context->setImageInterpolationQuality(previousInterpolationQuality
     ); | 110     paintInfo.context->setImageInterpolationQuality(previousInterpolationQuality
     ); | 
| 73 } | 111 } | 
| 74 | 112 | 
| 75 } // namespace blink | 113 } // namespace blink | 
| OLD | NEW | 
|---|