Re-order the arguments to drawPattern() functions
[WebKit-https.git] / Source / WebCore / platform / graphics / CrossfadeGeneratedImage.cpp
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 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 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 "config.h"
27 #include "CrossfadeGeneratedImage.h"
28
29 #include "FloatRect.h"
30 #include "GraphicsContext.h"
31 #include "ImageBuffer.h"
32 #include "TextStream.h"
33
34 namespace WebCore {
35
36 CrossfadeGeneratedImage::CrossfadeGeneratedImage(Image& fromImage, Image& toImage, float percentage, const FloatSize& crossfadeSize, const FloatSize& size)
37     : m_fromImage(fromImage)
38     , m_toImage(toImage)
39     , m_percentage(percentage)
40     , m_crossfadeSize(crossfadeSize)
41 {
42     setContainerSize(size);
43 }
44
45 static void drawCrossfadeSubimage(GraphicsContext& context, Image& image, CompositeOperator operation, float opacity, const FloatSize& targetSize)
46 {
47     FloatSize imageSize = image.size();
48
49     // SVGImage resets the opacity when painting, so we have to use transparency layers to accurately paint one at a given opacity.
50     bool useTransparencyLayer = image.isSVGImage();
51
52     GraphicsContextStateSaver stateSaver(context);
53     
54     CompositeOperator drawImageOperation = operation;
55
56     if (useTransparencyLayer) {
57         context.setCompositeOperation(operation);
58         context.beginTransparencyLayer(opacity);
59         drawImageOperation = CompositeSourceOver;
60     } else
61         context.setAlpha(opacity);
62
63     if (targetSize != imageSize)
64         context.scale(FloatSize(targetSize.width() / imageSize.width(), targetSize.height() / imageSize.height()));
65
66     context.drawImage(image, IntPoint(), ImagePaintingOptions(drawImageOperation));
67
68     if (useTransparencyLayer)
69         context.endTransparencyLayer();
70 }
71
72 void CrossfadeGeneratedImage::drawCrossfade(GraphicsContext& context)
73 {
74     // Draw nothing if either of the images hasn't loaded yet.
75     if (m_fromImage.ptr() == Image::nullImage() || m_toImage.ptr() == Image::nullImage())
76         return;
77
78     GraphicsContextStateSaver stateSaver(context);
79
80     context.clip(FloatRect(FloatPoint(), m_crossfadeSize));
81     context.beginTransparencyLayer(1);
82
83     drawCrossfadeSubimage(context, m_fromImage.get(), CompositeSourceOver, 1 - m_percentage, m_crossfadeSize);
84     drawCrossfadeSubimage(context, m_toImage.get(), CompositePlusLighter, m_percentage, m_crossfadeSize);
85
86     context.endTransparencyLayer();
87 }
88
89 void CrossfadeGeneratedImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)
90 {
91     GraphicsContextStateSaver stateSaver(context);
92     context.setCompositeOperation(compositeOp, blendMode);
93     context.clip(dstRect);
94     context.translate(dstRect.x(), dstRect.y());
95     if (dstRect.size() != srcRect.size())
96         context.scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));
97     context.translate(-srcRect.x(), -srcRect.y());
98     
99     drawCrossfade(context);
100 }
101
102 void CrossfadeGeneratedImage::drawPattern(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, BlendMode blendMode)
103 {
104     std::unique_ptr<ImageBuffer> imageBuffer = ImageBuffer::create(size(), context.renderingMode());
105     if (!imageBuffer)
106         return;
107
108     // Fill with the cross-faded image.
109     GraphicsContext& graphicsContext = imageBuffer->context();
110     drawCrossfade(graphicsContext);
111
112     // Tile the image buffer into the context.
113     imageBuffer->drawPattern(context, dstRect, srcRect, patternTransform, phase, spacing, compositeOp, blendMode);
114 }
115
116 void CrossfadeGeneratedImage::dump(TextStream& ts) const
117 {
118     GeneratedImage::dump(ts);
119     ts.dumpProperty("from-image", m_fromImage.get());
120     ts.dumpProperty("to-image", m_toImage.get());
121     ts.dumpProperty("percentage", m_percentage);
122 }
123
124 }