| 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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 DrawForContainer(builder.Context().Canvas(), flags, container_size, zoom, | 336 DrawForContainer(builder.Context().Canvas(), flags, container_size, zoom, |
| 337 tile, src_rect, url); | 337 tile, src_rect, url); |
| 338 } | 338 } |
| 339 sk_sp<PaintRecord> record = builder.EndRecording(); | 339 sk_sp<PaintRecord> record = builder.EndRecording(); |
| 340 | 340 |
| 341 SkMatrix pattern_transform; | 341 SkMatrix pattern_transform; |
| 342 pattern_transform.setTranslate(phase.X() + spaced_tile.X(), | 342 pattern_transform.setTranslate(phase.X() + spaced_tile.X(), |
| 343 phase.Y() + spaced_tile.Y()); | 343 phase.Y() + spaced_tile.Y()); |
| 344 | 344 |
| 345 PaintFlags flags; | 345 PaintFlags flags; |
| 346 flags.setShader( | 346 flags.setShader(MakePaintShaderRecord(record, SkShader::kRepeat_TileMode, |
| 347 MakePaintShaderRecord(record, spaced_tile, SkShader::kRepeat_TileMode, | 347 SkShader::kRepeat_TileMode, |
| 348 SkShader::kRepeat_TileMode, &pattern_transform)); | 348 &pattern_transform, nullptr)); |
| 349 // If the shader could not be instantiated (e.g. non-invertible matrix), | 349 // If the shader could not be instantiated (e.g. non-invertible matrix), |
| 350 // draw transparent. | 350 // draw transparent. |
| 351 // Note: we can't simply bail, because of arbitrary blend mode. | 351 // Note: we can't simply bail, because of arbitrary blend mode. |
| 352 if (!flags.getShader()) | 352 if (!flags.getShader()) |
| 353 flags.setColor(SK_ColorTRANSPARENT); | 353 flags.setColor(SK_ColorTRANSPARENT); |
| 354 | 354 |
| 355 flags.setBlendMode(composite_op); | 355 flags.setBlendMode(composite_op); |
| 356 flags.setColorFilter(sk_ref_sp(context.GetColorFilter())); | 356 flags.setColorFilter(sk_ref_sp(context.GetColorFilter())); |
| 357 context.DrawRect(dst_rect, flags); | 357 context.DrawRect(dst_rect, flags); |
| 358 } | 358 } |
| 359 | 359 |
| 360 sk_sp<SkImage> SVGImage::ImageForCurrentFrameForContainer( | 360 sk_sp<SkImage> SVGImage::ImageForCurrentFrameForContainer( |
| 361 const KURL& url, | 361 const KURL& url, |
| 362 const IntSize& container_size) { | 362 const IntSize& container_size) { |
| 363 if (!page_) | 363 if (!page_) |
| 364 return nullptr; | 364 return nullptr; |
| 365 | 365 |
| 366 const FloatRect container_rect((FloatPoint()), FloatSize(container_size)); | 366 const FloatRect container_rect((FloatPoint()), FloatSize(container_size)); |
| 367 | 367 |
| 368 PaintRecorder recorder; | 368 PaintRecorder recorder; |
| 369 PaintCanvas* canvas = recorder.beginRecording(container_rect); | 369 PaintCanvas* canvas = recorder.beginRecording(container_rect); |
| 370 DrawForContainer(canvas, PaintFlags(), container_rect.Size(), 1, | 370 DrawForContainer(canvas, PaintFlags(), container_rect.Size(), 1, |
| 371 container_rect, container_rect, url); | 371 container_rect, container_rect, url); |
| 372 | 372 |
| 373 return SkImage::MakeFromPicture( | 373 return SkImage::MakeFromPicture( |
| 374 ToSkPicture(recorder.finishRecordingAsPicture(), container_rect), | 374 ToSkPicture(recorder.finishRecordingAsPicture()), |
| 375 SkISize::Make(container_size.Width(), container_size.Height()), nullptr, | 375 SkISize::Make(container_size.Width(), container_size.Height()), nullptr, |
| 376 nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); | 376 nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); |
| 377 } | 377 } |
| 378 | 378 |
| 379 static bool DrawNeedsLayer(const PaintFlags& flags) { | 379 static bool DrawNeedsLayer(const PaintFlags& flags) { |
| 380 if (SkColorGetA(flags.getColor()) < 255) | 380 if (SkColorGetA(flags.getColor()) < 255) |
| 381 return true; | 381 return true; |
| 382 return !flags.isSrcOver(); | 382 return !flags.isSrcOver(); |
| 383 } | 383 } |
| 384 | 384 |
| 385 bool SVGImage::ApplyShaderInternal(PaintFlags& flags, | 385 bool SVGImage::ApplyShaderInternal(PaintFlags& flags, |
| 386 const SkMatrix& local_matrix, | 386 const SkMatrix& local_matrix, |
| 387 const KURL& url) { | 387 const KURL& url) { |
| 388 const IntSize size(ContainerSize()); | 388 const FloatSize size(ContainerSize()); |
| 389 if (size.IsEmpty()) | 389 if (size.IsEmpty()) |
| 390 return false; | 390 return false; |
| 391 | 391 |
| 392 IntRect bounds(IntPoint(), size); | 392 FloatRect float_bounds(FloatPoint(), size); |
| 393 const SkRect bounds(float_bounds); |
| 393 | 394 |
| 394 flags.setShader(MakePaintShaderRecord( | 395 flags.setShader(MakePaintShaderRecord( |
| 395 PaintRecordForCurrentFrame(bounds, url), bounds, | 396 PaintRecordForCurrentFrame(float_bounds, url), SkShader::kRepeat_TileMode, |
| 396 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &local_matrix)); | 397 SkShader::kRepeat_TileMode, &local_matrix, &bounds)); |
| 397 | 398 |
| 398 // Animation is normally refreshed in draw() impls, which we don't reach when | 399 // Animation is normally refreshed in draw() impls, which we don't reach when |
| 399 // painting via shaders. | 400 // painting via shaders. |
| 400 StartAnimation(); | 401 StartAnimation(); |
| 401 | 402 |
| 402 return true; | 403 return true; |
| 403 } | 404 } |
| 404 | 405 |
| 405 bool SVGImage::ApplyShader(PaintFlags& flags, const SkMatrix& local_matrix) { | 406 bool SVGImage::ApplyShader(PaintFlags& flags, const SkMatrix& local_matrix) { |
| 406 return ApplyShaderInternal(flags, local_matrix, KURL()); | 407 return ApplyShaderInternal(flags, local_matrix, KURL()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 431 const FloatRect& src_rect, | 432 const FloatRect& src_rect, |
| 432 RespectImageOrientationEnum should_respect_image_orientation, | 433 RespectImageOrientationEnum should_respect_image_orientation, |
| 433 ImageClampingMode clamp_mode) { | 434 ImageClampingMode clamp_mode) { |
| 434 if (!page_) | 435 if (!page_) |
| 435 return; | 436 return; |
| 436 | 437 |
| 437 DrawInternal(canvas, flags, dst_rect, src_rect, | 438 DrawInternal(canvas, flags, dst_rect, src_rect, |
| 438 should_respect_image_orientation, clamp_mode, KURL()); | 439 should_respect_image_orientation, clamp_mode, KURL()); |
| 439 } | 440 } |
| 440 | 441 |
| 441 sk_sp<PaintRecord> SVGImage::PaintRecordForCurrentFrame(const IntRect& bounds, | 442 sk_sp<PaintRecord> SVGImage::PaintRecordForCurrentFrame(const FloatRect& bounds, |
| 442 const KURL& url, | 443 const KURL& url, |
| 443 PaintCanvas* canvas) { | 444 PaintCanvas* canvas) { |
| 444 DCHECK(page_); | 445 DCHECK(page_); |
| 445 FrameView* view = ToLocalFrame(page_->MainFrame())->View(); | 446 FrameView* view = ToLocalFrame(page_->MainFrame())->View(); |
| 446 view->Resize(ContainerSize()); | 447 view->Resize(ContainerSize()); |
| 447 | 448 |
| 448 // Always call processUrlFragment, even if the url is empty, because | 449 // Always call processUrlFragment, even if the url is empty, because |
| 449 // there may have been a previous url/fragment that needs to be reset. | 450 // there may have been a previous url/fragment that needs to be reset. |
| 450 view->ProcessUrlFragment(url); | 451 view->ProcessUrlFragment(url); |
| 451 | 452 |
| 452 // If the image was reset, we need to rewind the timeline back to 0. This | 453 // If the image was reset, we need to rewind the timeline back to 0. This |
| 453 // needs to be done before painting, or else we wouldn't get the correct | 454 // needs to be done before painting, or else we wouldn't get the correct |
| 454 // reset semantics (we'd paint the "last" frame rather than the one at | 455 // reset semantics (we'd paint the "last" frame rather than the one at |
| 455 // time=0.) The reason we do this here and not in resetAnimation() is to | 456 // time=0.) The reason we do this here and not in resetAnimation() is to |
| 456 // avoid setting timers from the latter. | 457 // avoid setting timers from the latter. |
| 457 FlushPendingTimelineRewind(); | 458 FlushPendingTimelineRewind(); |
| 458 | 459 |
| 459 PaintRecordBuilder builder(bounds, nullptr, nullptr, paint_controller_.get()); | 460 IntRect int_bounds(EnclosingIntRect(bounds)); |
| 461 PaintRecordBuilder builder(int_bounds, nullptr, nullptr, |
| 462 paint_controller_.get()); |
| 460 | 463 |
| 461 view->UpdateAllLifecyclePhasesExceptPaint(); | 464 view->UpdateAllLifecyclePhasesExceptPaint(); |
| 462 view->Paint(builder.Context(), CullRect(bounds)); | 465 view->Paint(builder.Context(), CullRect(int_bounds)); |
| 463 DCHECK(!view->NeedsLayout()); | 466 DCHECK(!view->NeedsLayout()); |
| 464 | 467 |
| 465 if (canvas) { | 468 if (canvas) { |
| 466 builder.EndRecording(*canvas); | 469 builder.EndRecording(*canvas); |
| 467 return nullptr; | 470 return nullptr; |
| 468 } | 471 } |
| 469 return builder.EndRecording(); | 472 return builder.EndRecording(); |
| 470 } | 473 } |
| 471 | 474 |
| 472 void SVGImage::DrawInternal(PaintCanvas* canvas, | 475 void SVGImage::DrawInternal(PaintCanvas* canvas, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 490 FloatSize top_left_offset(src_rect.Location().X() * scale.Width(), | 493 FloatSize top_left_offset(src_rect.Location().X() * scale.Width(), |
| 491 src_rect.Location().Y() * scale.Height()); | 494 src_rect.Location().Y() * scale.Height()); |
| 492 FloatPoint dest_offset = dst_rect.Location() - top_left_offset; | 495 FloatPoint dest_offset = dst_rect.Location() - top_left_offset; |
| 493 AffineTransform transform = | 496 AffineTransform transform = |
| 494 AffineTransform::Translation(dest_offset.X(), dest_offset.Y()); | 497 AffineTransform::Translation(dest_offset.X(), dest_offset.Y()); |
| 495 transform.Scale(scale.Width(), scale.Height()); | 498 transform.Scale(scale.Width(), scale.Height()); |
| 496 | 499 |
| 497 canvas->save(); | 500 canvas->save(); |
| 498 canvas->clipRect(EnclosingIntRect(dst_rect)); | 501 canvas->clipRect(EnclosingIntRect(dst_rect)); |
| 499 canvas->concat(AffineTransformToSkMatrix(transform)); | 502 canvas->concat(AffineTransformToSkMatrix(transform)); |
| 500 PaintRecordForCurrentFrame(EnclosingIntRect(src_rect), url, canvas); | 503 PaintRecordForCurrentFrame(src_rect, url, canvas); |
| 501 canvas->restore(); | 504 canvas->restore(); |
| 502 } | 505 } |
| 503 | 506 |
| 504 // Start any (SMIL) animations if needed. This will restart or continue | 507 // Start any (SMIL) animations if needed. This will restart or continue |
| 505 // animations if preceded by calls to resetAnimation or stopAnimation | 508 // animations if preceded by calls to resetAnimation or stopAnimation |
| 506 // respectively. | 509 // respectively. |
| 507 StartAnimation(); | 510 StartAnimation(); |
| 508 } | 511 } |
| 509 | 512 |
| 510 LayoutReplaced* SVGImage::EmbeddedReplacedContent() const { | 513 LayoutReplaced* SVGImage::EmbeddedReplacedContent() const { |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 | 759 |
| 757 NOTREACHED(); | 760 NOTREACHED(); |
| 758 return kSizeAvailable; | 761 return kSizeAvailable; |
| 759 } | 762 } |
| 760 | 763 |
| 761 String SVGImage::FilenameExtension() const { | 764 String SVGImage::FilenameExtension() const { |
| 762 return "svg"; | 765 return "svg"; |
| 763 } | 766 } |
| 764 | 767 |
| 765 } // namespace blink | 768 } // namespace blink |
| OLD | NEW |