OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> | 2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> |
3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. |
4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 return FloatSize(solutionWidth, defaultObjectSize.height()); | 223 return FloatSize(solutionWidth, defaultObjectSize.height()); |
224 | 224 |
225 float solutionHeight = resolveHeightForRatio( | 225 float solutionHeight = resolveHeightForRatio( |
226 defaultObjectSize.width(), intrinsicSizingInfo.aspectRatio); | 226 defaultObjectSize.width(), intrinsicSizingInfo.aspectRatio); |
227 return FloatSize(defaultObjectSize.width(), solutionHeight); | 227 return FloatSize(defaultObjectSize.width(), solutionHeight); |
228 } | 228 } |
229 | 229 |
230 return defaultObjectSize; | 230 return defaultObjectSize; |
231 } | 231 } |
232 | 232 |
233 void SVGImage::drawForContainer(PaintCanvas* canvas, | 233 template <typename Func> |
234 const PaintFlags& flags, | 234 void SVGImage::forContainer(const FloatSize& containerSize, Func&& func) { |
235 const FloatSize containerSize, | |
236 float zoom, | |
237 const FloatRect& dstRect, | |
238 const FloatRect& srcRect, | |
239 const KURL& url) { | |
240 if (!m_page) | 235 if (!m_page) |
241 return; | 236 return; |
242 | 237 |
243 // Temporarily disable the image observer to prevent changeInRect() calls due | 238 // Temporarily disable the image observer to prevent changeInRect() calls due |
244 // re-laying out the image. | 239 // re-laying out the image. |
245 ImageObserverDisabler imageObserverDisabler(this); | 240 ImageObserverDisabler imageObserverDisabler(this); |
246 | 241 |
247 IntSize roundedContainerSize = roundedIntSize(containerSize); | 242 IntSize roundedContainerSize = roundedIntSize(containerSize); |
248 | 243 |
249 if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { | 244 if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { |
250 if (LayoutSVGRoot* layoutObject = | 245 if (LayoutSVGRoot* layoutObject = |
251 toLayoutSVGRoot(rootElement->layoutObject())) | 246 toLayoutSVGRoot(rootElement->layoutObject())) |
252 layoutObject->setContainerSize(roundedContainerSize); | 247 layoutObject->setContainerSize(roundedContainerSize); |
253 } | 248 } |
254 | 249 |
250 func(FloatSize(roundedContainerSize.width() / containerSize.width(), | |
251 roundedContainerSize.height() / containerSize.height())); | |
252 } | |
253 | |
254 void SVGImage::drawForContainer(PaintCanvas* canvas, | |
255 const PaintFlags& flags, | |
256 const FloatSize& containerSize, | |
257 float zoom, | |
258 const FloatRect& dstRect, | |
259 const FloatRect& srcRect, | |
260 const KURL& url) { | |
255 FloatRect scaledSrc = srcRect; | 261 FloatRect scaledSrc = srcRect; |
256 scaledSrc.scale(1 / zoom); | 262 scaledSrc.scale(1 / zoom); |
fs
2017/03/15 21:08:58
Maybe we could move this into the lambda scope as
f(malita)
2017/03/16 12:59:03
Done.
| |
257 | 263 |
258 // Compensate for the container size rounding by adjusting the source rect. | 264 forContainer(containerSize, [&](const FloatSize& residualScale) { |
259 FloatSize adjustedSrcSize = scaledSrc.size(); | 265 // Compensate for the container size rounding by adjusting the source rect. |
260 adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(), | 266 FloatSize adjustedSrcSize = scaledSrc.size(); |
261 roundedContainerSize.height() / containerSize.height()); | 267 adjustedSrcSize.scale(residualScale.width(), residualScale.height()); |
262 scaledSrc.setSize(adjustedSrcSize); | 268 scaledSrc.setSize(adjustedSrcSize); |
263 | 269 |
264 drawInternal(canvas, flags, dstRect, scaledSrc, DoNotRespectImageOrientation, | 270 drawInternal(canvas, flags, dstRect, scaledSrc, |
265 ClampImageToSourceRect, url); | 271 DoNotRespectImageOrientation, ClampImageToSourceRect, url); |
272 }); | |
266 } | 273 } |
267 | 274 |
268 sk_sp<SkImage> SVGImage::imageForCurrentFrame() { | 275 sk_sp<SkImage> SVGImage::imageForCurrentFrame() { |
269 return imageForCurrentFrameForContainer(KURL(), size()); | 276 return imageForCurrentFrameForContainer(KURL(), size()); |
270 } | 277 } |
271 | 278 |
272 void SVGImage::drawPatternForContainer(GraphicsContext& context, | 279 void SVGImage::drawPatternForContainer(GraphicsContext& context, |
273 const FloatSize containerSize, | 280 const FloatSize containerSize, |
274 float zoom, | 281 float zoom, |
275 const FloatRect& srcRect, | 282 const FloatRect& srcRect, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 SkISize::Make(containerSize.width(), containerSize.height()), nullptr, | 355 SkISize::Make(containerSize.width(), containerSize.height()), nullptr, |
349 nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); | 356 nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); |
350 } | 357 } |
351 | 358 |
352 static bool drawNeedsLayer(const PaintFlags& flags) { | 359 static bool drawNeedsLayer(const PaintFlags& flags) { |
353 if (SkColorGetA(flags.getColor()) < 255) | 360 if (SkColorGetA(flags.getColor()) < 255) |
354 return true; | 361 return true; |
355 return !flags.isSrcOver(); | 362 return !flags.isSrcOver(); |
356 } | 363 } |
357 | 364 |
365 bool SVGImage::applyShaderInternal(PaintFlags& flags, | |
366 const SkMatrix& localMatrix, | |
367 const KURL& url) { | |
368 const FloatSize size(containerSize()); | |
369 if (size.isEmpty()) | |
370 return false; | |
371 | |
372 const FloatRect bounds(FloatPoint(), size); | |
373 flags.setShader(SkShader::MakePictureShader( | |
374 paintRecordForCurrentFrame(bounds, bounds, url), | |
375 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix, | |
376 nullptr)); | |
377 | |
378 // Animation is normally refreshed in draw() impls, which we don't reach when | |
379 // painting via shaders. | |
380 startAnimation(); | |
381 | |
382 return true; | |
383 } | |
384 | |
385 bool SVGImage::applyShader(PaintFlags& flags, const SkMatrix& localMatrix) { | |
386 return applyShaderInternal(flags, localMatrix, KURL()); | |
387 } | |
388 | |
389 bool SVGImage::applyShaderForContainer(const FloatSize& containerSize, | |
390 float zoom, | |
391 const KURL& url, | |
392 PaintFlags& flags, | |
393 const SkMatrix& localMatrix) { | |
394 bool result = false; | |
395 forContainer(containerSize, [&](const FloatSize& residualScale) { | |
396 // Compensate for the container size rounding. | |
397 auto adjustedLocalMatrix = localMatrix; | |
398 adjustedLocalMatrix.preScale(zoom * residualScale.width(), | |
399 zoom * residualScale.height()); | |
400 | |
401 result = applyShaderInternal(flags, adjustedLocalMatrix, url); | |
402 }); | |
403 | |
404 return result; | |
405 } | |
406 | |
358 void SVGImage::draw(PaintCanvas* canvas, | 407 void SVGImage::draw(PaintCanvas* canvas, |
359 const PaintFlags& flags, | 408 const PaintFlags& flags, |
360 const FloatRect& dstRect, | 409 const FloatRect& dstRect, |
361 const FloatRect& srcRect, | 410 const FloatRect& srcRect, |
362 RespectImageOrientationEnum shouldRespectImageOrientation, | 411 RespectImageOrientationEnum shouldRespectImageOrientation, |
363 ImageClampingMode clampMode) { | 412 ImageClampingMode clampMode) { |
364 if (!m_page) | 413 if (!m_page) |
365 return; | 414 return; |
366 | 415 |
367 drawInternal(canvas, flags, dstRect, srcRect, shouldRespectImageOrientation, | 416 drawInternal(canvas, flags, dstRect, srcRect, shouldRespectImageOrientation, |
368 clampMode, KURL()); | 417 clampMode, KURL()); |
369 } | 418 } |
370 | 419 |
371 void SVGImage::drawInternal(PaintCanvas* canvas, | 420 sk_sp<PaintRecord> SVGImage::paintRecordForCurrentFrame( |
372 const PaintFlags& flags, | 421 const FloatRect& srcRect, |
373 const FloatRect& dstRect, | 422 const FloatRect& dstRect, |
374 const FloatRect& srcRect, | 423 const KURL& url) { |
375 RespectImageOrientationEnum, | |
376 ImageClampingMode, | |
377 const KURL& url) { | |
378 DCHECK(m_page); | 424 DCHECK(m_page); |
379 FrameView* view = toLocalFrame(m_page->mainFrame())->view(); | 425 FrameView* view = toLocalFrame(m_page->mainFrame())->view(); |
380 view->resize(containerSize()); | 426 view->resize(containerSize()); |
381 | 427 |
382 // Always call processUrlFragment, even if the url is empty, because | 428 // Always call processUrlFragment, even if the url is empty, because |
383 // there may have been a previous url/fragment that needs to be reset. | 429 // there may have been a previous url/fragment that needs to be reset. |
384 view->processUrlFragment(url); | 430 view->processUrlFragment(url); |
385 | 431 |
386 // If the image was reset, we need to rewind the timeline back to 0. This | 432 // If the image was reset, we need to rewind the timeline back to 0. This |
387 // needs to be done before painting, or else we wouldn't get the correct | 433 // needs to be done before painting, or else we wouldn't get the correct |
(...skipping 29 matching lines...) Expand all Loading... | |
417 AffineTransform transform = | 463 AffineTransform transform = |
418 AffineTransform::translation(destOffset.x(), destOffset.y()); | 464 AffineTransform::translation(destOffset.x(), destOffset.y()); |
419 transform.scale(scale.width(), scale.height()); | 465 transform.scale(scale.width(), scale.height()); |
420 TransformRecorder transformRecorder(builder.context(), builder, transform); | 466 TransformRecorder transformRecorder(builder.context(), builder, transform); |
421 | 467 |
422 view->updateAllLifecyclePhasesExceptPaint(); | 468 view->updateAllLifecyclePhasesExceptPaint(); |
423 view->paint(builder.context(), CullRect(enclosingIntRect(srcRect))); | 469 view->paint(builder.context(), CullRect(enclosingIntRect(srcRect))); |
424 DCHECK(!view->needsLayout()); | 470 DCHECK(!view->needsLayout()); |
425 } | 471 } |
426 | 472 |
473 return builder.endRecording(); | |
474 } | |
475 | |
476 void SVGImage::drawInternal(PaintCanvas* canvas, | |
477 const PaintFlags& flags, | |
478 const FloatRect& dstRect, | |
479 const FloatRect& srcRect, | |
480 RespectImageOrientationEnum, | |
481 ImageClampingMode, | |
482 const KURL& url) { | |
427 { | 483 { |
428 PaintCanvasAutoRestore ar(canvas, false); | 484 PaintCanvasAutoRestore ar(canvas, false); |
429 if (drawNeedsLayer(flags)) { | 485 if (drawNeedsLayer(flags)) { |
430 SkRect layerRect = dstRect; | 486 SkRect layerRect = dstRect; |
431 canvas->saveLayer(&layerRect, &flags); | 487 canvas->saveLayer(&layerRect, &flags); |
432 } | 488 } |
433 sk_sp<PaintRecord> recording = builder.endRecording(); | 489 |
434 canvas->drawPicture(recording.get()); | 490 canvas->drawPicture(paintRecordForCurrentFrame(srcRect, dstRect, url)); |
435 } | 491 } |
436 | 492 |
437 // Start any (SMIL) animations if needed. This will restart or continue | 493 // Start any (SMIL) animations if needed. This will restart or continue |
438 // animations if preceded by calls to resetAnimation or stopAnimation | 494 // animations if preceded by calls to resetAnimation or stopAnimation |
439 // respectively. | 495 // respectively. |
440 startAnimation(); | 496 startAnimation(); |
441 } | 497 } |
442 | 498 |
443 LayoutReplaced* SVGImage::embeddedReplacedContent() const { | 499 LayoutReplaced* SVGImage::embeddedReplacedContent() const { |
444 SVGSVGElement* rootElement = svgRootElement(m_page.get()); | 500 SVGSVGElement* rootElement = svgRootElement(m_page.get()); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
658 } | 714 } |
659 | 715 |
660 return m_page ? SizeAvailable : SizeUnavailable; | 716 return m_page ? SizeAvailable : SizeUnavailable; |
661 } | 717 } |
662 | 718 |
663 String SVGImage::filenameExtension() const { | 719 String SVGImage::filenameExtension() const { |
664 return "svg"; | 720 return "svg"; |
665 } | 721 } |
666 | 722 |
667 } // namespace blink | 723 } // namespace blink |
OLD | NEW |