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 |