1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "third_party/blink/renderer/platform/graphics/crossfade_generated_image.h"
27 
28 #include "third_party/blink/renderer/platform/geometry/float_rect.h"
29 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
30 #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
31 
32 namespace blink {
33 
CrossfadeGeneratedImage(scoped_refptr<Image> from_image,scoped_refptr<Image> to_image,float percentage,FloatSize crossfade_size,const FloatSize & size)34 CrossfadeGeneratedImage::CrossfadeGeneratedImage(
35     scoped_refptr<Image> from_image,
36     scoped_refptr<Image> to_image,
37     float percentage,
38     FloatSize crossfade_size,
39     const FloatSize& size)
40     : GeneratedImage(size),
41       from_image_(std::move(from_image)),
42       to_image_(std::move(to_image)),
43       percentage_(percentage),
44       crossfade_size_(crossfade_size) {}
45 
DrawCrossfade(cc::PaintCanvas * canvas,const PaintFlags & flags,RespectImageOrientationEnum respect_orientation,ImageClampingMode clamp_mode,ImageDecodingMode decode_mode)46 void CrossfadeGeneratedImage::DrawCrossfade(
47     cc::PaintCanvas* canvas,
48     const PaintFlags& flags,
49     RespectImageOrientationEnum respect_orientation,
50     ImageClampingMode clamp_mode,
51     ImageDecodingMode decode_mode) {
52   FloatRect from_image_rect(FloatPoint(), FloatSize(from_image_->Size()));
53   FloatRect to_image_rect(FloatPoint(), FloatSize(to_image_->Size()));
54   FloatRect dest_rect((FloatPoint()), crossfade_size_);
55 
56   // TODO(junov): The various effects encoded into paint should probably be
57   // applied here instead of inside the layer.  This probably faulty behavior
58   // was maintained in order to preserve pre-existing behavior while refactoring
59   // this code.  This should be investigated further. crbug.com/472634
60   PaintFlags layer_flags;
61   layer_flags.setBlendMode(flags.getBlendMode());
62   PaintCanvasAutoRestore ar(canvas, false);
63   canvas->saveLayer(nullptr, &layer_flags);
64 
65   PaintFlags image_flags(flags);
66   image_flags.setBlendMode(SkBlendMode::kSrcOver);
67   image_flags.setColor(ScaleAlpha(flags.getColor(), 1 - percentage_));
68   // TODO(junov): This code should probably be propagating the
69   // RespectImageOrientationEnum from CrossfadeGeneratedImage::draw(). Code was
70   // written this way during refactoring to avoid modifying existing behavior,
71   // but this warrants further investigation. crbug.com/472634
72   from_image_->Draw(canvas, image_flags, dest_rect, from_image_rect,
73                     kDoNotRespectImageOrientation, clamp_mode, decode_mode);
74   image_flags.setBlendMode(SkBlendMode::kPlus);
75   image_flags.setColor(ScaleAlpha(flags.getColor(), percentage_));
76   to_image_->Draw(canvas, image_flags, dest_rect, to_image_rect,
77                   respect_orientation, clamp_mode, decode_mode);
78 }
79 
Draw(cc::PaintCanvas * canvas,const PaintFlags & flags,const FloatRect & dst_rect,const FloatRect & src_rect,RespectImageOrientationEnum respect_orientation,ImageClampingMode clamp_mode,ImageDecodingMode decode_mode)80 void CrossfadeGeneratedImage::Draw(
81     cc::PaintCanvas* canvas,
82     const PaintFlags& flags,
83     const FloatRect& dst_rect,
84     const FloatRect& src_rect,
85     RespectImageOrientationEnum respect_orientation,
86     ImageClampingMode clamp_mode,
87     ImageDecodingMode decode_mode) {
88   // Draw nothing if either of the images hasn't loaded yet.
89   if (from_image_ == Image::NullImage() || to_image_ == Image::NullImage())
90     return;
91 
92   PaintCanvasAutoRestore ar(canvas, true);
93   canvas->clipRect(dst_rect);
94   canvas->concat(
95       SkMatrix::MakeRectToRect(src_rect, dst_rect, SkMatrix::kFill_ScaleToFit));
96   DrawCrossfade(canvas, flags, respect_orientation, clamp_mode, decode_mode);
97 }
98 
DrawTile(GraphicsContext & context,const FloatRect & src_rect,RespectImageOrientationEnum respect_orientation)99 void CrossfadeGeneratedImage::DrawTile(
100     GraphicsContext& context,
101     const FloatRect& src_rect,
102     RespectImageOrientationEnum respect_orientation) {
103   // Draw nothing if either of the images hasn't loaded yet.
104   if (from_image_ == Image::NullImage() || to_image_ == Image::NullImage())
105     return;
106 
107   PaintFlags flags = context.FillFlags();
108   flags.setBlendMode(SkBlendMode::kSrcOver);
109   FloatRect dest_rect((FloatPoint()), crossfade_size_);
110   flags.setFilterQuality(
111       context.ComputeFilterQuality(this, dest_rect, src_rect));
112   DrawCrossfade(context.Canvas(), flags, respect_orientation,
113                 kClampImageToSourceRect, kSyncDecode);
114 }
115 
116 }  // namespace blink
117