Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2010 Sencha, Inc.
      3  * Copyright (C) 2010 Igalia S.L.
      4  *
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #ifndef ContextShadow_h
     30 #define ContextShadow_h
     31 
     32 #include "Color.h"
     33 #include "FloatRect.h"
     34 #include "IntRect.h"
     35 #include <wtf/RefCounted.h>
     36 
     37 #if USE(CAIRO)
     38 typedef struct _cairo cairo_t;
     39 typedef struct _cairo_surface cairo_surface_t;
     40 #elif PLATFORM(QT)
     41 #include <QImage>
     42 QT_BEGIN_NAMESPACE
     43 class QPainter;
     44 QT_END_NAMESPACE
     45 #endif
     46 
     47 namespace WebCore {
     48 
     49 class AffineTransform;
     50 class GraphicsContext;
     51 
     52 #if USE(CAIRO)
     53 typedef cairo_surface_t* PlatformImage;
     54 typedef cairo_t* PlatformContext;
     55 #elif PLATFORM(QT)
     56 typedef QImage PlatformImage;
     57 typedef QPainter* PlatformContext;
     58 #else
     59 typedef void* PlatformImage;
     60 typedef void* PlatformContext;
     61 #endif
     62 
     63 // This is to track and keep the shadow state. We use this rather than
     64 // using GraphicsContextState to allow possible optimizations (right now
     65 // only to determine the shadow type, but in future it might covers things
     66 // like cached scratch image, persistent shader, etc).
     67 
     68 // This class should be copyable since GraphicsContextQt keeps a stack of
     69 // the shadow state for savePlatformState and restorePlatformState.
     70 
     71 // This class is Deprecated. Platforms should migrate to ShadowBlur.
     72 
     73 class ContextShadow {
     74 public:
     75     enum {
     76         NoShadow,
     77         SolidShadow,
     78         BlurShadow
     79     } m_type;
     80 
     81     Color m_color;
     82     int m_blurDistance;
     83     FloatSize m_offset;
     84 
     85     ContextShadow();
     86     ContextShadow(const Color&, float radius, const FloatSize& offset);
     87 
     88     bool mustUseContextShadow(GraphicsContext*);
     89     void clear();
     90 
     91     // The pair beginShadowLayer and endShadowLayer creates a temporary image
     92     // where the caller can draw onto, using the returned context. This context
     93     // must be used only to draw between the call to beginShadowLayer and
     94     // endShadowLayer.
     95     //
     96     // Note: multiple/nested shadow layers are NOT allowed.
     97     //
     98     // The current clip region will be used to optimize the size of the
     99     // temporary image. Thus, the original context should not change any
    100     // clipping until endShadowLayer. If the shadow will be completely outside
    101     // the clipping region, beginShadowLayer will return 0.
    102     //
    103     // The returned context will have the transformation matrix and clipping
    104     // properly initialized to start doing the painting (no need to account for
    105     // the shadow offset), however it will not have the same render hints, pen,
    106     // brush, etc as the passed context. This is intentional, usually shadows
    107     // have different properties than the shapes which cast them.
    108     //
    109     // Once endShadowLayer is called, the temporary image will be drawn with the
    110     // original context. If blur radius is specified, the shadow will be
    111     // filtered first.
    112 
    113     PlatformContext beginShadowLayer(GraphicsContext*, const FloatRect& layerArea);
    114     void endShadowLayer(GraphicsContext*);
    115     static void purgeScratchBuffer();
    116 
    117     void setShadowsIgnoreTransforms(bool enable) { m_shadowsIgnoreTransforms = enable; }
    118     bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
    119 #if USE(CAIRO)
    120     void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius = IntSize(), const IntSize& topRightRadius = IntSize(), const IntSize& bottomLeftRadius = IntSize(), const IntSize& bottomRightRadius = IntSize());
    121 #endif
    122 #if PLATFORM(QT)
    123     QPointF offset() const { return QPointF(m_offset.width(), m_offset.height()); }
    124 #endif
    125 
    126 private:
    127     PlatformImage m_layerImage; // Buffer to where the temporary shadow will be drawn to.
    128     PlatformContext m_layerContext; // Context used to paint the shadow to the layer image.
    129     FloatRect m_sourceRect; // Sub-rect of m_layerImage that contains the shadow pixels.
    130     FloatPoint m_layerOrigin; // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to.
    131     FloatPoint m_layerContextTranslation; // Translation to apply to m_layerContext for the shadow to be correctly clipped.
    132     bool m_shadowsIgnoreTransforms;
    133 
    134     void adjustBlurDistance(GraphicsContext*);
    135     void blurLayerImage(unsigned char*, const IntSize& imageSize, int stride);
    136     IntRect calculateLayerBoundingRect(GraphicsContext*, const FloatRect& layerArea, const IntRect& clipRect);
    137 
    138 #if USE(CAIRO)
    139     void drawRectShadowWithoutTiling(GraphicsContext*, const IntRect& shadowRect, const IntSize& topLeftRadius, const IntSize& topRightRadius, const IntSize& bottomLeftRadius, const IntSize& bottomRightRadius, float alpha);
    140 #endif
    141 };
    142 
    143 } // namespace WebCore
    144 
    145 #endif // ContextShadow_h
    146