Chromium Code Reviews| 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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 const KURL& url) { | 288 const KURL& url) { |
| 289 // Tile adjusted for scaling/stretch. | 289 // Tile adjusted for scaling/stretch. |
| 290 FloatRect tile(srcRect); | 290 FloatRect tile(srcRect); |
| 291 tile.scale(tileScale.width(), tileScale.height()); | 291 tile.scale(tileScale.width(), tileScale.height()); |
| 292 | 292 |
| 293 // Expand the tile to account for repeat spacing. | 293 // Expand the tile to account for repeat spacing. |
| 294 FloatRect spacedTile(tile); | 294 FloatRect spacedTile(tile); |
| 295 spacedTile.expand(FloatSize(repeatSpacing)); | 295 spacedTile.expand(FloatSize(repeatSpacing)); |
| 296 | 296 |
| 297 PaintRecordBuilder builder(spacedTile, nullptr, &context); | 297 PaintRecordBuilder builder(spacedTile, nullptr, &context); |
| 298 // SVG images paint into their own property tree set that is distinct | |
| 299 // from the embedding frame tree. | |
| 300 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | |
| 301 PaintChunk::Id id(builder, DisplayItem::kSVGImage); | |
| 302 PropertyTreeState state(TransformPaintPropertyNode::root(), | |
| 303 ClipPaintPropertyNode::root(), | |
| 304 EffectPaintPropertyNode::root()); | |
| 305 m_paintController->updateCurrentPaintChunkProperties(&id, state); | |
| 306 } | |
| 307 | 298 |
| 308 { | 299 { |
| 309 DrawingRecorder recorder(builder.context(), builder, | 300 DrawingRecorder recorder(builder.context(), builder, |
| 310 DisplayItem::Type::kSVGImage, spacedTile); | 301 DisplayItem::Type::kSVGImage, spacedTile); |
| 311 // When generating an expanded tile, make sure we don't draw into the | 302 // When generating an expanded tile, make sure we don't draw into the |
| 312 // spacing area. | 303 // spacing area. |
| 313 if (tile != spacedTile) | 304 if (tile != spacedTile) |
| 314 builder.context().clip(tile); | 305 builder.context().clip(tile); |
| 315 PaintFlags flags; | 306 PaintFlags flags; |
| 316 drawForContainer(builder.context().canvas(), flags, containerSize, zoom, | 307 drawForContainer(builder.context().canvas(), flags, containerSize, zoom, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 return !flags.isSrcOver(); | 353 return !flags.isSrcOver(); |
| 363 } | 354 } |
| 364 | 355 |
| 365 bool SVGImage::applyShaderInternal(PaintFlags& flags, | 356 bool SVGImage::applyShaderInternal(PaintFlags& flags, |
| 366 const SkMatrix& localMatrix, | 357 const SkMatrix& localMatrix, |
| 367 const KURL& url) { | 358 const KURL& url) { |
| 368 const FloatSize size(containerSize()); | 359 const FloatSize size(containerSize()); |
| 369 if (size.isEmpty()) | 360 if (size.isEmpty()) |
| 370 return false; | 361 return false; |
| 371 | 362 |
| 372 const FloatRect bounds(FloatPoint(), size); | 363 FloatRect floatBounds(FloatPoint(), size); |
| 364 const SkRect bounds(floatBounds); | |
| 365 | |
| 373 flags.setShader(SkShader::MakePictureShader( | 366 flags.setShader(SkShader::MakePictureShader( |
| 374 paintRecordForCurrentFrame(bounds, bounds, url), | 367 paintRecordForCurrentFrame(floatBounds, url), SkShader::kRepeat_TileMode, |
|
chrishtr
2017/03/28 03:57:51
In this call site, the previous code applied no tr
| |
| 375 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix, | 368 SkShader::kRepeat_TileMode, &localMatrix, &bounds)); |
| 376 nullptr)); | |
| 377 | 369 |
| 378 // Animation is normally refreshed in draw() impls, which we don't reach when | 370 // Animation is normally refreshed in draw() impls, which we don't reach when |
| 379 // painting via shaders. | 371 // painting via shaders. |
| 380 startAnimation(); | 372 startAnimation(); |
| 381 | 373 |
| 382 return true; | 374 return true; |
| 383 } | 375 } |
| 384 | 376 |
| 385 bool SVGImage::applyShader(PaintFlags& flags, const SkMatrix& localMatrix) { | 377 bool SVGImage::applyShader(PaintFlags& flags, const SkMatrix& localMatrix) { |
| 386 return applyShaderInternal(flags, localMatrix, KURL()); | 378 return applyShaderInternal(flags, localMatrix, KURL()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 410 const FloatRect& srcRect, | 402 const FloatRect& srcRect, |
| 411 RespectImageOrientationEnum shouldRespectImageOrientation, | 403 RespectImageOrientationEnum shouldRespectImageOrientation, |
| 412 ImageClampingMode clampMode) { | 404 ImageClampingMode clampMode) { |
| 413 if (!m_page) | 405 if (!m_page) |
| 414 return; | 406 return; |
| 415 | 407 |
| 416 drawInternal(canvas, flags, dstRect, srcRect, shouldRespectImageOrientation, | 408 drawInternal(canvas, flags, dstRect, srcRect, shouldRespectImageOrientation, |
| 417 clampMode, KURL()); | 409 clampMode, KURL()); |
| 418 } | 410 } |
| 419 | 411 |
| 420 sk_sp<PaintRecord> SVGImage::paintRecordForCurrentFrame( | 412 sk_sp<PaintRecord> SVGImage::paintRecordForCurrentFrame(const FloatRect& bounds, |
| 421 const FloatRect& srcRect, | 413 const KURL& url) { |
| 422 const FloatRect& dstRect, | |
| 423 const KURL& url) { | |
| 424 DCHECK(m_page); | 414 DCHECK(m_page); |
| 425 FrameView* view = toLocalFrame(m_page->mainFrame())->view(); | 415 FrameView* view = toLocalFrame(m_page->mainFrame())->view(); |
| 426 view->resize(containerSize()); | 416 view->resize(containerSize()); |
| 427 | 417 |
| 428 // Always call processUrlFragment, even if the url is empty, because | 418 // Always call processUrlFragment, even if the url is empty, because |
| 429 // there may have been a previous url/fragment that needs to be reset. | 419 // there may have been a previous url/fragment that needs to be reset. |
| 430 view->processUrlFragment(url); | 420 view->processUrlFragment(url); |
| 431 | 421 |
| 432 // If the image was reset, we need to rewind the timeline back to 0. This | 422 // If the image was reset, we need to rewind the timeline back to 0. This |
| 433 // needs to be done before painting, or else we wouldn't get the correct | 423 // needs to be done before painting, or else we wouldn't get the correct |
| 434 // reset semantics (we'd paint the "last" frame rather than the one at | 424 // reset semantics (we'd paint the "last" frame rather than the one at |
| 435 // time=0.) The reason we do this here and not in resetAnimation() is to | 425 // time=0.) The reason we do this here and not in resetAnimation() is to |
| 436 // avoid setting timers from the latter. | 426 // avoid setting timers from the latter. |
| 437 flushPendingTimelineRewind(); | 427 flushPendingTimelineRewind(); |
| 438 PaintRecordBuilder builder(dstRect, nullptr, nullptr, | 428 |
| 429 IntRect intBounds(enclosingIntRect(bounds)); | |
| 430 PaintRecordBuilder builder(intBounds, nullptr, nullptr, | |
| 439 m_paintController.get()); | 431 m_paintController.get()); |
| 440 // SVG images paint into their own property tree set that is distinct | |
| 441 // from the embedding frame tree. | |
| 442 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | |
| 443 PaintChunk::Id id(builder, DisplayItem::kSVGImage); | |
| 444 PropertyTreeState state(TransformPaintPropertyNode::root(), | |
| 445 ClipPaintPropertyNode::root(), | |
| 446 EffectPaintPropertyNode::root()); | |
| 447 m_paintController->updateCurrentPaintChunkProperties(&id, state); | |
| 448 } | |
| 449 | 432 |
| 450 { | 433 view->updateAllLifecyclePhasesExceptPaint(); |
| 451 ClipRecorder clipRecorder(builder.context(), builder, | 434 view->paint(builder.context(), CullRect(intBounds)); |
| 452 DisplayItem::kClipNodeImage, | 435 DCHECK(!view->needsLayout()); |
| 453 enclosingIntRect(dstRect)); | |
| 454 | |
| 455 // We can only draw the entire frame, clipped to the rect we want. So | |
| 456 // compute where the top left of the image would be if we were drawing | |
| 457 // without clipping, and translate accordingly. | |
| 458 FloatSize scale(dstRect.width() / srcRect.width(), | |
| 459 dstRect.height() / srcRect.height()); | |
| 460 FloatSize topLeftOffset(srcRect.location().x() * scale.width(), | |
| 461 srcRect.location().y() * scale.height()); | |
| 462 FloatPoint destOffset = dstRect.location() - topLeftOffset; | |
| 463 AffineTransform transform = | |
| 464 AffineTransform::translation(destOffset.x(), destOffset.y()); | |
| 465 transform.scale(scale.width(), scale.height()); | |
| 466 TransformRecorder transformRecorder(builder.context(), builder, transform); | |
| 467 | |
| 468 view->updateAllLifecyclePhasesExceptPaint(); | |
| 469 view->paint(builder.context(), CullRect(enclosingIntRect(srcRect))); | |
| 470 DCHECK(!view->needsLayout()); | |
| 471 } | |
| 472 | 436 |
| 473 return builder.endRecording(); | 437 return builder.endRecording(); |
| 474 } | 438 } |
| 475 | 439 |
| 476 void SVGImage::drawInternal(PaintCanvas* canvas, | 440 void SVGImage::drawInternal(PaintCanvas* canvas, |
| 477 const PaintFlags& flags, | 441 const PaintFlags& flags, |
| 478 const FloatRect& dstRect, | 442 const FloatRect& dstRect, |
| 479 const FloatRect& srcRect, | 443 const FloatRect& srcRect, |
| 480 RespectImageOrientationEnum, | 444 RespectImageOrientationEnum, |
| 481 ImageClampingMode, | 445 ImageClampingMode, |
| 482 const KURL& url) { | 446 const KURL& url) { |
| 483 { | 447 { |
| 484 PaintCanvasAutoRestore ar(canvas, false); | 448 PaintCanvasAutoRestore ar(canvas, false); |
| 485 if (drawNeedsLayer(flags)) { | 449 if (drawNeedsLayer(flags)) { |
| 486 SkRect layerRect = dstRect; | 450 SkRect layerRect = dstRect; |
| 487 canvas->saveLayer(&layerRect, &flags); | 451 canvas->saveLayer(&layerRect, &flags); |
| 488 } | 452 } |
| 489 canvas->drawPicture(paintRecordForCurrentFrame(srcRect, dstRect, url)); | 453 // We can only draw the entire frame, clipped to the rect we want. So |
| 454 // compute where the top left of the image would be if we were drawing | |
| 455 // without clipping, and translate accordingly. | |
| 456 FloatSize scale(dstRect.width() / srcRect.width(), | |
| 457 dstRect.height() / srcRect.height()); | |
| 458 FloatSize topLeftOffset(srcRect.location().x() * scale.width(), | |
| 459 srcRect.location().y() * scale.height()); | |
| 460 FloatPoint destOffset = dstRect.location() - topLeftOffset; | |
| 461 AffineTransform transform = | |
| 462 AffineTransform::translation(destOffset.x(), destOffset.y()); | |
| 463 transform.scale(scale.width(), scale.height()); | |
| 464 | |
| 465 canvas->save(); | |
| 466 canvas->clipRect(enclosingIntRect(dstRect)); | |
| 467 canvas->concat(affineTransformToSkMatrix(transform)); | |
| 468 canvas->PlaybackPaintRecord(paintRecordForCurrentFrame(srcRect, url)); | |
| 469 canvas->restore(); | |
| 490 } | 470 } |
| 491 | 471 |
| 492 // Start any (SMIL) animations if needed. This will restart or continue | 472 // Start any (SMIL) animations if needed. This will restart or continue |
| 493 // animations if preceded by calls to resetAnimation or stopAnimation | 473 // animations if preceded by calls to resetAnimation or stopAnimation |
| 494 // respectively. | 474 // respectively. |
| 495 startAnimation(); | 475 startAnimation(); |
| 496 } | 476 } |
| 497 | 477 |
| 498 LayoutReplaced* SVGImage::embeddedReplacedContent() const { | 478 LayoutReplaced* SVGImage::embeddedReplacedContent() const { |
| 499 SVGSVGElement* rootElement = svgRootElement(m_page.get()); | 479 SVGSVGElement* rootElement = svgRootElement(m_page.get()); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 704 } | 684 } |
| 705 | 685 |
| 706 return m_page ? SizeAvailable : SizeUnavailable; | 686 return m_page ? SizeAvailable : SizeUnavailable; |
| 707 } | 687 } |
| 708 | 688 |
| 709 String SVGImage::filenameExtension() const { | 689 String SVGImage::filenameExtension() const { |
| 710 return "svg"; | 690 return "svg"; |
| 711 } | 691 } |
| 712 | 692 |
| 713 } // namespace blink | 693 } // namespace blink |
| OLD | NEW |