Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2003, 2009, 2012 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 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 #ifndef ClipRect_h
     27 #define ClipRect_h
     28 
     29 #include "platform/geometry/LayoutRect.h"
     30 
     31 #include "wtf/Vector.h"
     32 
     33 #ifndef NDEBUG
     34 #include "core/rendering/RenderBox.h" // For OverlayScrollbarSizeRelevancy.
     35 #endif
     36 
     37 namespace WebCore {
     38 
     39 class RenderLayer;
     40 class HitTestLocation;
     41 
     42 class ClipRect {
     43 public:
     44     ClipRect()
     45         : m_hasRadius(false)
     46     { }
     47 
     48     ClipRect(const LayoutRect& rect)
     49         : m_rect(rect)
     50         , m_hasRadius(false)
     51     { }
     52 
     53     const LayoutRect& rect() const { return m_rect; }
     54     void setRect(const LayoutRect& rect) { m_rect = rect; }
     55 
     56     bool hasRadius() const { return m_hasRadius; }
     57     void setHasRadius(bool hasRadius) { m_hasRadius = hasRadius; }
     58 
     59     bool operator==(const ClipRect& other) const { return rect() == other.rect() && hasRadius() == other.hasRadius(); }
     60     bool operator!=(const ClipRect& other) const { return rect() != other.rect() || hasRadius() != other.hasRadius(); }
     61     bool operator!=(const LayoutRect& otherRect) const { return rect() != otherRect; }
     62 
     63     void intersect(const LayoutRect& other) { m_rect.intersect(other); }
     64     void intersect(const ClipRect& other)
     65     {
     66         m_rect.intersect(other.rect());
     67         if (other.hasRadius())
     68             m_hasRadius = true;
     69     }
     70     void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); }
     71     void move(const LayoutSize& size) { m_rect.move(size); }
     72     void moveBy(const LayoutPoint& point) { m_rect.moveBy(point); }
     73 
     74     bool isEmpty() const { return m_rect.isEmpty(); }
     75     bool intersects(const LayoutRect& rect) const { return m_rect.intersects(rect); }
     76     bool intersects(const HitTestLocation&) const;
     77 
     78 private:
     79     LayoutRect m_rect;
     80     bool m_hasRadius;
     81 };
     82 
     83 inline ClipRect intersection(const ClipRect& a, const ClipRect& b)
     84 {
     85     ClipRect c = a;
     86     c.intersect(b);
     87     return c;
     88 }
     89 
     90 class ClipRects {
     91     WTF_MAKE_FAST_ALLOCATED;
     92 public:
     93     static PassRefPtr<ClipRects> create()
     94     {
     95         return adoptRef(new ClipRects);
     96     }
     97 
     98     static PassRefPtr<ClipRects> create(const ClipRects& other)
     99     {
    100         return adoptRef(new ClipRects(other));
    101     }
    102 
    103     ClipRects()
    104         : m_refCnt(1)
    105         , m_fixed(0)
    106     {
    107     }
    108 
    109     void reset(const LayoutRect& r)
    110     {
    111         m_overflowClipRect = r;
    112         m_fixedClipRect = r;
    113         m_posClipRect = r;
    114         m_fixed = 0;
    115     }
    116 
    117     const ClipRect& overflowClipRect() const { return m_overflowClipRect; }
    118     void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; }
    119 
    120     const ClipRect& fixedClipRect() const { return m_fixedClipRect; }
    121     void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; }
    122 
    123     const ClipRect& posClipRect() const { return m_posClipRect; }
    124     void setPosClipRect(const ClipRect& r) { m_posClipRect = r; }
    125 
    126     bool fixed() const { return static_cast<bool>(m_fixed); }
    127     void setFixed(bool fixed) { m_fixed = fixed ? 1 : 0; }
    128 
    129     void ref() { m_refCnt++; }
    130     void deref()
    131     {
    132         if (!--m_refCnt)
    133             delete this;
    134     }
    135 
    136     bool operator==(const ClipRects& other) const
    137     {
    138         return m_overflowClipRect == other.overflowClipRect()
    139             && m_fixedClipRect == other.fixedClipRect()
    140             && m_posClipRect == other.posClipRect()
    141             && fixed() == other.fixed();
    142     }
    143 
    144     ClipRects& operator=(const ClipRects& other)
    145     {
    146         m_overflowClipRect = other.overflowClipRect();
    147         m_fixedClipRect = other.fixedClipRect();
    148         m_posClipRect = other.posClipRect();
    149         m_fixed = other.fixed();
    150         return *this;
    151     }
    152 
    153 private:
    154     ClipRects(const LayoutRect& r)
    155         : m_overflowClipRect(r)
    156         , m_fixedClipRect(r)
    157         , m_posClipRect(r)
    158         , m_refCnt(1)
    159         , m_fixed(0)
    160     {
    161     }
    162 
    163     ClipRects(const ClipRects& other)
    164         : m_overflowClipRect(other.overflowClipRect())
    165         , m_fixedClipRect(other.fixedClipRect())
    166         , m_posClipRect(other.posClipRect())
    167         , m_refCnt(1)
    168         , m_fixed(other.fixed())
    169     {
    170     }
    171 
    172     ClipRect m_overflowClipRect;
    173     ClipRect m_fixedClipRect;
    174     ClipRect m_posClipRect;
    175     unsigned m_refCnt : 31;
    176     unsigned m_fixed : 1;
    177 };
    178 
    179 enum ClipRectsType {
    180     PaintingClipRects, // Relative to painting ancestor. Used for painting.
    181     RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
    182     AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
    183     NumCachedClipRectsTypes,
    184     AllClipRectTypes,
    185     TemporaryClipRects
    186 };
    187 
    188 enum ShouldRespectOverflowClip {
    189     IgnoreOverflowClip,
    190     RespectOverflowClip
    191 };
    192 
    193 struct ClipRectsCache {
    194     WTF_MAKE_FAST_ALLOCATED;
    195 public:
    196     ClipRectsCache()
    197     {
    198 #ifndef NDEBUG
    199         for (int i = 0; i < NumCachedClipRectsTypes; ++i) {
    200             m_clipRectsRoot[i] = 0;
    201             m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize;
    202         }
    203 #endif
    204     }
    205 
    206     PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; }
    207     void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects; }
    208 
    209 #ifndef NDEBUG
    210     const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
    211     OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes];
    212 #endif
    213 
    214 private:
    215     int getIndex(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow)
    216     {
    217         int index = static_cast<int>(clipRectsType);
    218         if (respectOverflow == RespectOverflowClip)
    219             index += static_cast<int>(NumCachedClipRectsTypes);
    220         return index;
    221     }
    222 
    223     RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2];
    224 };
    225 
    226 struct LayerFragment {
    227 public:
    228     LayerFragment()
    229         : shouldPaintContent(false)
    230     { }
    231 
    232     void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline)
    233     {
    234         layerBounds = bounds;
    235         backgroundRect = background;
    236         foregroundRect = foreground;
    237         outlineRect = outline;
    238     }
    239 
    240     void moveBy(const LayoutPoint& offset)
    241     {
    242         layerBounds.moveBy(offset);
    243         backgroundRect.moveBy(offset);
    244         foregroundRect.moveBy(offset);
    245         outlineRect.moveBy(offset);
    246         paginationClip.moveBy(offset);
    247     }
    248 
    249     void intersect(const LayoutRect& rect)
    250     {
    251         backgroundRect.intersect(rect);
    252         foregroundRect.intersect(rect);
    253         outlineRect.intersect(rect);
    254     }
    255 
    256     bool shouldPaintContent;
    257     LayoutRect layerBounds;
    258     ClipRect backgroundRect;
    259     ClipRect foregroundRect;
    260     ClipRect outlineRect;
    261 
    262     // Unique to paginated fragments. The physical translation to apply to shift the layer when painting/hit-testing.
    263     LayoutPoint paginationOffset;
    264 
    265     // Also unique to paginated fragments. An additional clip that applies to the layer. It is in layer-local
    266     // (physical) coordinates.
    267     LayoutRect paginationClip;
    268 };
    269 
    270 typedef Vector<LayerFragment, 1> LayerFragments;
    271 
    272 } // namespace WebCore
    273 
    274 #endif // ClipRect_h
    275