| Index: third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
|
| diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
|
| index ab03d70d7da505f70590c77e8ef86920724a91b1..fed6ba49013df01b9af5571334b6b7b21524e3d3 100644
|
| --- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
|
| +++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
|
| @@ -230,13 +230,8 @@ FloatSize SVGImage::concreteObjectSize(
|
| return defaultObjectSize;
|
| }
|
|
|
| -void SVGImage::drawForContainer(PaintCanvas* canvas,
|
| - const PaintFlags& flags,
|
| - const FloatSize containerSize,
|
| - float zoom,
|
| - const FloatRect& dstRect,
|
| - const FloatRect& srcRect,
|
| - const KURL& url) {
|
| +template <typename Func>
|
| +void SVGImage::forContainer(const FloatSize& containerSize, Func&& func) {
|
| if (!m_page)
|
| return;
|
|
|
| @@ -252,17 +247,29 @@ void SVGImage::drawForContainer(PaintCanvas* canvas,
|
| layoutObject->setContainerSize(roundedContainerSize);
|
| }
|
|
|
| - FloatRect scaledSrc = srcRect;
|
| - scaledSrc.scale(1 / zoom);
|
| -
|
| - // Compensate for the container size rounding by adjusting the source rect.
|
| - FloatSize adjustedSrcSize = scaledSrc.size();
|
| - adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(),
|
| - roundedContainerSize.height() / containerSize.height());
|
| - scaledSrc.setSize(adjustedSrcSize);
|
| + func(FloatSize(roundedContainerSize.width() / containerSize.width(),
|
| + roundedContainerSize.height() / containerSize.height()));
|
| +}
|
|
|
| - drawInternal(canvas, flags, dstRect, scaledSrc, DoNotRespectImageOrientation,
|
| - ClampImageToSourceRect, url);
|
| +void SVGImage::drawForContainer(PaintCanvas* canvas,
|
| + const PaintFlags& flags,
|
| + const FloatSize& containerSize,
|
| + float zoom,
|
| + const FloatRect& dstRect,
|
| + const FloatRect& srcRect,
|
| + const KURL& url) {
|
| + forContainer(containerSize, [&](const FloatSize& residualScale) {
|
| + FloatRect scaledSrc = srcRect;
|
| + scaledSrc.scale(1 / zoom);
|
| +
|
| + // Compensate for the container size rounding by adjusting the source rect.
|
| + FloatSize adjustedSrcSize = scaledSrc.size();
|
| + adjustedSrcSize.scale(residualScale.width(), residualScale.height());
|
| + scaledSrc.setSize(adjustedSrcSize);
|
| +
|
| + drawInternal(canvas, flags, dstRect, scaledSrc,
|
| + DoNotRespectImageOrientation, ClampImageToSourceRect, url);
|
| + });
|
| }
|
|
|
| sk_sp<SkImage> SVGImage::imageForCurrentFrame() {
|
| @@ -355,6 +362,48 @@ static bool drawNeedsLayer(const PaintFlags& flags) {
|
| return !flags.isSrcOver();
|
| }
|
|
|
| +bool SVGImage::applyShaderInternal(PaintFlags& flags,
|
| + const SkMatrix& localMatrix,
|
| + const KURL& url) {
|
| + const FloatSize size(containerSize());
|
| + if (size.isEmpty())
|
| + return false;
|
| +
|
| + const FloatRect bounds(FloatPoint(), size);
|
| + flags.setShader(SkShader::MakePictureShader(
|
| + paintRecordForCurrentFrame(bounds, bounds, url),
|
| + SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix,
|
| + nullptr));
|
| +
|
| + // Animation is normally refreshed in draw() impls, which we don't reach when
|
| + // painting via shaders.
|
| + startAnimation();
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool SVGImage::applyShader(PaintFlags& flags, const SkMatrix& localMatrix) {
|
| + return applyShaderInternal(flags, localMatrix, KURL());
|
| +}
|
| +
|
| +bool SVGImage::applyShaderForContainer(const FloatSize& containerSize,
|
| + float zoom,
|
| + const KURL& url,
|
| + PaintFlags& flags,
|
| + const SkMatrix& localMatrix) {
|
| + bool result = false;
|
| + forContainer(containerSize, [&](const FloatSize& residualScale) {
|
| + // Compensate for the container size rounding.
|
| + auto adjustedLocalMatrix = localMatrix;
|
| + adjustedLocalMatrix.preScale(zoom * residualScale.width(),
|
| + zoom * residualScale.height());
|
| +
|
| + result = applyShaderInternal(flags, adjustedLocalMatrix, url);
|
| + });
|
| +
|
| + return result;
|
| +}
|
| +
|
| void SVGImage::draw(PaintCanvas* canvas,
|
| const PaintFlags& flags,
|
| const FloatRect& dstRect,
|
| @@ -368,13 +417,10 @@ void SVGImage::draw(PaintCanvas* canvas,
|
| clampMode, KURL());
|
| }
|
|
|
| -void SVGImage::drawInternal(PaintCanvas* canvas,
|
| - const PaintFlags& flags,
|
| - const FloatRect& dstRect,
|
| - const FloatRect& srcRect,
|
| - RespectImageOrientationEnum,
|
| - ImageClampingMode,
|
| - const KURL& url) {
|
| +sk_sp<PaintRecord> SVGImage::paintRecordForCurrentFrame(
|
| + const FloatRect& srcRect,
|
| + const FloatRect& dstRect,
|
| + const KURL& url) {
|
| DCHECK(m_page);
|
| FrameView* view = toLocalFrame(m_page->mainFrame())->view();
|
| view->resize(containerSize());
|
| @@ -424,14 +470,24 @@ void SVGImage::drawInternal(PaintCanvas* canvas,
|
| DCHECK(!view->needsLayout());
|
| }
|
|
|
| + return builder.endRecording();
|
| +}
|
| +
|
| +void SVGImage::drawInternal(PaintCanvas* canvas,
|
| + const PaintFlags& flags,
|
| + const FloatRect& dstRect,
|
| + const FloatRect& srcRect,
|
| + RespectImageOrientationEnum,
|
| + ImageClampingMode,
|
| + const KURL& url) {
|
| {
|
| PaintCanvasAutoRestore ar(canvas, false);
|
| if (drawNeedsLayer(flags)) {
|
| SkRect layerRect = dstRect;
|
| canvas->saveLayer(&layerRect, &flags);
|
| }
|
| - sk_sp<PaintRecord> recording = builder.endRecording();
|
| - canvas->drawPicture(recording.get());
|
| +
|
| + canvas->drawPicture(paintRecordForCurrentFrame(srcRect, dstRect, url));
|
| }
|
|
|
| // Start any (SMIL) animations if needed. This will restart or continue
|
|
|