Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(721)

Unified Diff: third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp

Issue 2753633003: Implement SVGImage::applyShader() (Closed)
Patch Set: rebaseline Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698