Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2011 Adobe Systems Incorporated. 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  *
      8  * 1. Redistributions of source code must retain the above
      9  *    copyright notice, this list of conditions and the following
     10  *    disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above
     12  *    copyright notice, this list of conditions and the following
     13  *    disclaimer in the documentation and/or other materials
     14  *    provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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 THE COPYRIGHT HOLDER BE
     20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     21  * 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
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     25  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     26  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #ifndef RenderRegion_h
     31 #define RenderRegion_h
     32 
     33 #include "core/rendering/RenderBlock.h"
     34 #include "core/rendering/style/StyleInheritedData.h"
     35 
     36 namespace WebCore {
     37 
     38 struct LayerFragment;
     39 typedef Vector<LayerFragment, 1> LayerFragments;
     40 class RenderBox;
     41 class RenderBoxRegionInfo;
     42 class RenderFlowThread;
     43 class RenderNamedFlowThread;
     44 
     45 class RenderRegion : public RenderBlock {
     46 public:
     47     explicit RenderRegion(Element*, RenderFlowThread*);
     48 
     49     virtual bool isRenderRegion() const { return true; }
     50 
     51     bool hitTestFlowThreadContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
     52 
     53     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
     54 
     55     void setFlowThreadPortionRect(const LayoutRect& rect) { m_flowThreadPortionRect = rect; }
     56     LayoutRect flowThreadPortionRect() const { return m_flowThreadPortionRect; }
     57     LayoutRect flowThreadPortionOverflowRect() const;
     58 
     59     void attachRegion();
     60     void detachRegion();
     61 
     62     RenderNamedFlowThread* parentNamedFlowThread() const { return m_parentNamedFlowThread; }
     63     RenderFlowThread* flowThread() const { return m_flowThread; }
     64 
     65     // Valid regions do not create circular dependencies with other flows.
     66     bool isValid() const { return m_isValid; }
     67     void setIsValid(bool valid) { m_isValid = valid; }
     68 
     69     bool hasCustomRegionStyle() const { return m_hasCustomRegionStyle; }
     70     void setHasCustomRegionStyle(bool hasCustomRegionStyle) { m_hasCustomRegionStyle = hasCustomRegionStyle; }
     71 
     72     RenderBoxRegionInfo* renderBoxRegionInfo(const RenderBox*) const;
     73     RenderBoxRegionInfo* setRenderBoxRegionInfo(const RenderBox*, LayoutUnit logicalLeftInset, LayoutUnit logicalRightInset,
     74         bool containingBlockChainIsInset);
     75     PassOwnPtr<RenderBoxRegionInfo> takeRenderBoxRegionInfo(const RenderBox*);
     76     void removeRenderBoxRegionInfo(const RenderBox*);
     77 
     78     void deleteAllRenderBoxRegionInfo();
     79 
     80     bool isFirstRegion() const;
     81     bool isLastRegion() const;
     82 
     83     void clearObjectStyleInRegion(const RenderObject*);
     84 
     85     RegionOversetState regionOversetState() const;
     86     void setRegionOversetState(RegionOversetState);
     87 
     88     Element* element() const;
     89 
     90     // These methods represent the width and height of a "page" and for a RenderRegion they are just the
     91     // content width and content height of a region. For RenderRegionSets, however, they will be the width and
     92     // height of a single column or page in the set.
     93     virtual LayoutUnit pageLogicalWidth() const;
     94     virtual LayoutUnit pageLogicalHeight() const;
     95     LayoutUnit maxPageLogicalHeight() const;
     96 
     97     LayoutUnit logicalTopOfFlowThreadContentRect(const LayoutRect&) const;
     98     LayoutUnit logicalBottomOfFlowThreadContentRect(const LayoutRect&) const;
     99     LayoutUnit logicalTopForFlowThreadContent() const { return logicalTopOfFlowThreadContentRect(flowThreadPortionRect()); };
    100     LayoutUnit logicalBottomForFlowThreadContent() const { return logicalBottomOfFlowThreadContentRect(flowThreadPortionRect()); };
    101 
    102     void getRanges(Vector<RefPtr<Range> >&) const;
    103 
    104     // This method represents the logical height of the entire flow thread portion used by the region or set.
    105     // For RenderRegions it matches logicalPaginationHeight(), but for sets it is the height of all the pages
    106     // or columns added together.
    107     virtual LayoutUnit logicalHeightOfAllFlowThreadContent() const;
    108 
    109     bool hasAutoLogicalHeight() const { return m_hasAutoLogicalHeight; }
    110 
    111     const LayoutUnit& computedAutoHeight() const
    112     {
    113         ASSERT(hasComputedAutoHeight());
    114         return m_computedAutoHeight;
    115     }
    116 
    117     void setComputedAutoHeight(LayoutUnit computedAutoHeight)
    118     {
    119         ASSERT(computedAutoHeight >= 0);
    120         m_computedAutoHeight = computedAutoHeight;
    121     }
    122 
    123     void clearComputedAutoHeight()
    124     {
    125         m_computedAutoHeight = -1;
    126     }
    127 
    128     bool hasComputedAutoHeight() const { return (m_computedAutoHeight >= 0); }
    129 
    130     virtual void updateLogicalHeight() OVERRIDE;
    131 
    132     // The top of the nearest page inside the region. For RenderRegions, this is just the logical top of the
    133     // flow thread portion we contain. For sets, we have to figure out the top of the nearest column or
    134     // page.
    135     virtual LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
    136 
    137     virtual void expandToEncompassFlowThreadContentsIfNeeded() { };
    138 
    139     // Whether or not this region is a set.
    140     virtual bool isRenderRegionSet() const { return false; }
    141 
    142     virtual void repaintFlowThreadContent(const LayoutRect& repaintRect) const;
    143 
    144     virtual void collectLayerFragments(LayerFragments&, const LayoutRect&, const LayoutRect&) { }
    145 
    146 protected:
    147     void setRegionObjectsRegionStyle();
    148     void restoreRegionObjectsOriginalStyle();
    149 
    150     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
    151 
    152     LayoutRect overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion) const;
    153     void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, const LayoutRect& flowThreadPortionRect,
    154         const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const;
    155 
    156     virtual bool shouldHaveAutoLogicalHeight() const;
    157 
    158 private:
    159     virtual const char* renderName() const { return "RenderRegion"; }
    160 
    161     virtual bool canHaveChildren() const OVERRIDE { return false; }
    162 
    163     virtual void insertedIntoTree() OVERRIDE;
    164     virtual void willBeRemovedFromTree() OVERRIDE;
    165 
    166     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
    167     virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
    168 
    169     virtual void installFlowThread();
    170 
    171     PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
    172     void computeChildrenStyleInRegion(const RenderObject*);
    173     void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached);
    174 
    175     void checkRegionStyle();
    176     void updateRegionHasAutoLogicalHeightFlag();
    177 
    178     void incrementAutoLogicalHeightCount();
    179     void decrementAutoLogicalHeightCount();
    180 
    181 protected:
    182     RenderFlowThread* m_flowThread;
    183 
    184 private:
    185     // If this RenderRegion is displayed as part of another named flow,
    186     // we need to create a dependency tree, so that layout of the
    187     // regions is always done before the regions themselves.
    188     RenderNamedFlowThread* m_parentNamedFlowThread;
    189     LayoutRect m_flowThreadPortionRect;
    190 
    191     // This map holds unique information about a block that is split across regions.
    192     // A RenderBoxRegionInfo* tells us about any layout information for a RenderBox that
    193     // is unique to the region. For now it just holds logical width information for RenderBlocks, but eventually
    194     // it will also hold a custom style for any box (for region styling).
    195     typedef HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > RenderBoxRegionInfoMap;
    196     RenderBoxRegionInfoMap m_renderBoxRegionInfo;
    197 
    198     struct ObjectRegionStyleInfo {
    199         // Used to store the original style of the object in region
    200         // so that the original style is properly restored after paint.
    201         // Also used to store computed style of the object in region between
    202         // region paintings, so that the style in region is computed only
    203         // when necessary.
    204         RefPtr<RenderStyle> style;
    205         // True if the computed style in region is cached.
    206         bool cached;
    207     };
    208     typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap;
    209     RenderObjectRegionStyleMap m_renderObjectRegionStyle;
    210 
    211     LayoutUnit m_computedAutoHeight;
    212 
    213     bool m_isValid : 1;
    214     bool m_hasCustomRegionStyle : 1;
    215     bool m_hasAutoLogicalHeight : 1;
    216 };
    217 
    218 inline RenderRegion* toRenderRegion(RenderObject* object)
    219 {
    220     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderRegion());
    221     return static_cast<RenderRegion*>(object);
    222 }
    223 
    224 inline const RenderRegion* toRenderRegion(const RenderObject* object)
    225 {
    226     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderRegion());
    227     return static_cast<const RenderRegion*>(object);
    228 }
    229 
    230 // This will catch anyone doing an unnecessary cast.
    231 void toRenderRegion(const RenderRegion*);
    232 
    233 } // namespace WebCore
    234 
    235 #endif // RenderRegion_h
    236