2 * Copyright (C) 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "GradientImage.h"
29 #include "FloatRect.h"
30 #include "GraphicsContext.h"
31 #include "ImageBuffer.h"
33 #include "TextStream.h"
37 GradientImage::GradientImage(PassRefPtr<Gradient> generator, const FloatSize& size)
38 : m_gradient(generator)
40 setContainerSize(size);
43 GradientImage::~GradientImage()
47 void GradientImage::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)
49 GraphicsContextStateSaver stateSaver(destContext);
50 destContext.setCompositeOperation(compositeOp, blendMode);
51 destContext.clip(destRect);
52 destContext.translate(destRect.x(), destRect.y());
53 if (destRect.size() != srcRect.size())
54 destContext.scale(FloatSize(destRect.width() / srcRect.width(), destRect.height() / srcRect.height()));
55 destContext.translate(-srcRect.x(), -srcRect.y());
56 destContext.fillRect(FloatRect(FloatPoint(), size()), *m_gradient.get());
59 void GradientImage::drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
60 const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& destRect, BlendMode blendMode)
62 // Allow the generator to provide visually-equivalent tiling parameters for better performance.
63 FloatSize adjustedSize = size();
64 FloatRect adjustedSrcRect = srcRect;
65 m_gradient->adjustParametersForTiledDrawing(adjustedSize, adjustedSrcRect, spacing);
67 // Factor in the destination context's scale to generate at the best resolution
68 AffineTransform destContextCTM = destContext.getCTM(GraphicsContext::DefinitelyIncludeDeviceScale);
69 double xScale = fabs(destContextCTM.xScale());
70 double yScale = fabs(destContextCTM.yScale());
71 AffineTransform adjustedPatternCTM = patternTransform;
72 adjustedPatternCTM.scale(1.0 / xScale, 1.0 / yScale);
73 adjustedSrcRect.scale(xScale, yScale);
75 unsigned generatorHash = m_gradient->hash();
77 if (!m_cachedImageBuffer || m_cachedGeneratorHash != generatorHash || m_cachedAdjustedSize != adjustedSize || !destContext.isCompatibleWithBuffer(*m_cachedImageBuffer)) {
78 m_cachedImageBuffer = destContext.createCompatibleBuffer(adjustedSize, m_gradient->hasAlpha());
79 if (!m_cachedImageBuffer)
82 // Fill with the generated image.
83 m_cachedImageBuffer->context().fillRect(FloatRect(FloatPoint(), adjustedSize), *m_gradient);
85 m_cachedGeneratorHash = generatorHash;
86 m_cachedAdjustedSize = adjustedSize;
88 if (destContext.drawLuminanceMask())
89 m_cachedImageBuffer->convertToLuminanceMask();
92 destContext.setDrawLuminanceMask(false);
94 // Tile the image buffer into the context.
95 m_cachedImageBuffer->drawPattern(destContext, adjustedSrcRect, adjustedPatternCTM, phase, spacing, compositeOp, destRect, blendMode);
98 void GradientImage::dump(TextStream& ts) const
100 GeneratedImage::dump(ts);
101 // FIXME: dump the gradient.