18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * Copyright (C) 2010 Sencha, Inc. 3bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * Copyright (C) 2010 Igalia S.L. 4f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * 5f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * All rights reserved. 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#ifndef ContextShadow_h 30f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#define ContextShadow_h 31f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 32bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "Color.h" 33bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "FloatRect.h" 34bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "IntRect.h" 352bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/RefCounted.h> 36bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CAIRO) 38bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsentypedef struct _cairo cairo_t; 39bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsentypedef struct _cairo_surface cairo_surface_t; 40bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#elif PLATFORM(QT) 41bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <QImage> 42cad810f21b803229eb11403f9209855525a25d57Steve BlockQT_BEGIN_NAMESPACE 43bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass QPainter; 44cad810f21b803229eb11403f9209855525a25d57Steve BlockQT_END_NAMESPACE 45bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricknamespace WebCore { 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49cad810f21b803229eb11403f9209855525a25d57Steve Blockclass AffineTransform; 50cad810f21b803229eb11403f9209855525a25d57Steve Blockclass GraphicsContext; 51cad810f21b803229eb11403f9209855525a25d57Steve Block 522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CAIRO) 536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennertypedef cairo_surface_t* PlatformImage; 546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennertypedef cairo_t* PlatformContext; 556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#elif PLATFORM(QT) 566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennertypedef QImage PlatformImage; 576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennertypedef QPainter* PlatformContext; 586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#else 596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennertypedef void* PlatformImage; 606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennertypedef void* PlatformContext; 616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif 626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 63f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// This is to track and keep the shadow state. We use this rather than 64f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// using GraphicsContextState to allow possible optimizations (right now 65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// only to determine the shadow type, but in future it might covers things 66f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// like cached scratch image, persistent shader, etc). 67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 68f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// This class should be copyable since GraphicsContextQt keeps a stack of 69f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick// the shadow state for savePlatformState and restorePlatformState. 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// This class is Deprecated. Platforms should migrate to ShadowBlur. 722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickclass ContextShadow { 74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickpublic: 75f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick enum { 76f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick NoShadow, 77bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen SolidShadow, 78f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick BlurShadow 79bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } m_type; 80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 81bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Color m_color; 82a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int m_blurDistance; 83bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen FloatSize m_offset; 84f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 85f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ContextShadow(); 86bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen ContextShadow(const Color&, float radius, const FloatSize& offset); 87f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 88cad810f21b803229eb11403f9209855525a25d57Steve Block bool mustUseContextShadow(GraphicsContext*); 89f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick void clear(); 90f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 91e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // The pair beginShadowLayer and endShadowLayer creates a temporary image 92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // where the caller can draw onto, using the returned context. This context 93bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // must be used only to draw between the call to beginShadowLayer and 94bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // endShadowLayer. 95e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // 96bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Note: multiple/nested shadow layers are NOT allowed. 97e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // 98e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // The current clip region will be used to optimize the size of the 99bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // temporary image. Thus, the original context should not change any 100bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // clipping until endShadowLayer. If the shadow will be completely outside 101bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // the clipping region, beginShadowLayer will return 0. 102e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // 103bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // The returned context will have the transformation matrix and clipping 104bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // properly initialized to start doing the painting (no need to account for 105bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // the shadow offset), however it will not have the same render hints, pen, 106bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // brush, etc as the passed context. This is intentional, usually shadows 107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // have different properties than the shapes which cast them. 108e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // 109bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Once endShadowLayer is called, the temporary image will be drawn with the 110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // original context. If blur radius is specified, the shadow will be 111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // filtered first. 112bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 113cad810f21b803229eb11403f9209855525a25d57Steve Block PlatformContext beginShadowLayer(GraphicsContext*, const FloatRect& layerArea); 114cad810f21b803229eb11403f9209855525a25d57Steve Block void endShadowLayer(GraphicsContext*); 115bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen static void purgeScratchBuffer(); 116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void setShadowsIgnoreTransforms(bool enable) { m_shadowsIgnoreTransforms = enable; } 118f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; } 1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CAIRO) 120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius = IntSize(), const IntSize& topRightRadius = IntSize(), const IntSize& bottomLeftRadius = IntSize(), const IntSize& bottomRightRadius = IntSize()); 121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif 122bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if PLATFORM(QT) 123f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch QPointF offset() const { return QPointF(m_offset.width(), m_offset.height()); } 124bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif 125bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 126e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockprivate: 127f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch PlatformImage m_layerImage; // Buffer to where the temporary shadow will be drawn to. 128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch PlatformContext m_layerContext; // Context used to paint the shadow to the layer image. 129f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch FloatRect m_sourceRect; // Sub-rect of m_layerImage that contains the shadow pixels. 130f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch FloatPoint m_layerOrigin; // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to. 131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch FloatPoint m_layerContextTranslation; // Translation to apply to m_layerContext for the shadow to be correctly clipped. 132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool m_shadowsIgnoreTransforms; 133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 134cad810f21b803229eb11403f9209855525a25d57Steve Block void adjustBlurDistance(GraphicsContext*); 135bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void blurLayerImage(unsigned char*, const IntSize& imageSize, int stride); 136cad810f21b803229eb11403f9209855525a25d57Steve Block IntRect calculateLayerBoundingRect(GraphicsContext*, const FloatRect& layerArea, const IntRect& clipRect); 137f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CAIRO) 139cad810f21b803229eb11403f9209855525a25d57Steve Block void drawRectShadowWithoutTiling(GraphicsContext*, const IntRect& shadowRect, const IntSize& topLeftRadius, const IntSize& topRightRadius, const IntSize& bottomLeftRadius, const IntSize& bottomRightRadius, float alpha); 140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif 141f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}; 142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore 144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 145f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#endif // ContextShadow_h 146