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/RenderBlockFlow.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 RenderBlockFlow {
     46 public:
     47     explicit RenderRegion(Element*, RenderFlowThread*);
     48 
     49     virtual bool isRenderRegion() const OVERRIDE { 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) OVERRIDE;
     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     // These methods represent the width and height of a "page" and for a RenderRegion they are just the
     89     // content width and content height of a region. For RenderRegionSets, however, they will be the width and
     90     // height of a single column or page in the set.
     91     virtual LayoutUnit pageLogicalWidth() const;
     92     virtual LayoutUnit pageLogicalHeight() const;
     93     virtual LayoutUnit maxPageLogicalHeight() const;
     94 
     95     LayoutUnit logicalTopOfFlowThreadContentRect(const LayoutRect&) const;
     96     LayoutUnit logicalBottomOfFlowThreadContentRect(const LayoutRect&) const;
     97     LayoutUnit logicalTopForFlowThreadContent() const { return logicalTopOfFlowThreadContentRect(flowThreadPortionRect()); };
     98     LayoutUnit logicalBottomForFlowThreadContent() const { return logicalBottomOfFlowThreadContentRect(flowThreadPortionRect()); };
     99 
    100     void getRanges(Vector<RefPtr<Range> >&) const;
    101 
    102     // This method represents the logical height of the entire flow thread portion used by the region or set.
    103     // For RenderRegions it matches logicalPaginationHeight(), but for sets it is the height of all the pages
    104     // or columns added together.
    105     virtual LayoutUnit logicalHeightOfAllFlowThreadContent() const;
    106 
    107     bool hasAutoLogicalHeight() const { return m_hasAutoLogicalHeight; }
    108 
    109     const LayoutUnit& computedAutoHeight() const
    110     {
    111         ASSERT(hasComputedAutoHeight());
    112         return m_computedAutoHeight;
    113     }
    114 
    115     void setComputedAutoHeight(LayoutUnit computedAutoHeight)
    116     {
    117         ASSERT(computedAutoHeight >= 0);
    118         m_computedAutoHeight = computedAutoHeight;
    119     }
    120 
    121     void clearComputedAutoHeight()
    122     {
    123         m_computedAutoHeight = -1;
    124     }
    125 
    126     bool hasComputedAutoHeight() const { return (m_computedAutoHeight >= 0); }
    127 
    128     // The top of the nearest page inside the region. For RenderRegions, this is just the logical top of the
    129     // flow thread portion we contain. For sets, we have to figure out the top of the nearest column or
    130     // page.
    131     virtual LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
    132 
    133     virtual void expandToEncompassFlowThreadContentsIfNeeded() { };
    134 
    135     // Whether or not this region is a set.
    136     virtual bool isRenderRegionSet() const { return false; }
    137 
    138     virtual void repaintFlowThreadContent(const LayoutRect& repaintRect) const;
    139 
    140     virtual void collectLayerFragments(LayerFragments&, const LayoutRect&, const LayoutRect&) { }
    141 
    142     virtual bool canHaveChildren() const OVERRIDE { return false; }
    143     virtual bool canHaveGeneratedChildren() const OVERRIDE { return true; }
    144 
    145     bool isElementBasedRegion() const;
    146 
    147     Node* nodeForRegion() const;
    148     Node* generatingNodeForRegion() const;
    149 
    150     virtual const char* renderName() const OVERRIDE { return "RenderRegion"; }
    151 
    152 protected:
    153     void setRegionObjectsRegionStyle();
    154     void restoreRegionObjectsOriginalStyle();
    155 
    156     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
    157 
    158     LayoutRect overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion) const;
    159     void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, const LayoutRect& flowThreadPortionRect,
    160         const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const;
    161 
    162     virtual bool shouldHaveAutoLogicalHeight() const;
    163 
    164 private:
    165     virtual void insertedIntoTree() OVERRIDE;
    166     virtual void willBeRemovedFromTree() OVERRIDE;
    167 
    168     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
    169     virtual bool supportsPartialLayout() const OVERRIDE { return false; }
    170     virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
    171 
    172     virtual void updateLogicalHeight() OVERRIDE;
    173 
    174     virtual void installFlowThread();
    175 
    176     PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
    177     void computeChildrenStyleInRegion(const RenderObject*);
    178     void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached);
    179 
    180     void checkRegionStyle();
    181     void updateRegionHasAutoLogicalHeightFlag();
    182 
    183     void incrementAutoLogicalHeightCount();
    184     void decrementAutoLogicalHeightCount();
    185 
    186     Element* element() const;
    187 
    188 protected:
    189     RenderFlowThread* m_flowThread;
    190 
    191 private:
    192     // If this RenderRegion is displayed as part of another named flow,
    193     // we need to create a dependency tree, so that layout of the
    194     // regions is always done before the regions themselves.
    195     RenderNamedFlowThread* m_parentNamedFlowThread;
    196     LayoutRect m_flowThreadPortionRect;
    197 
    198     // This map holds unique information about a block that is split across regions.
    199     // A RenderBoxRegionInfo* tells us about any layout information for a RenderBox that
    200     // is unique to the region. For now it just holds logical width information for RenderBlocks, but eventually
    201     // it will also hold a custom style for any box (for region styling).
    202     typedef HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > RenderBoxRegionInfoMap;
    203     RenderBoxRegionInfoMap m_renderBoxRegionInfo;
    204 
    205     struct ObjectRegionStyleInfo {
    206         // Used to store the original style of the object in region
    207         // so that the original style is properly restored after paint.
    208         // Also used to store computed style of the object in region between
    209         // region paintings, so that the style in region is computed only
    210         // when necessary.
    211         RefPtr<RenderStyle> style;
    212         // True if the computed style in region is cached.
    213         bool cached;
    214     };
    215     typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap;
    216     RenderObjectRegionStyleMap m_renderObjectRegionStyle;
    217 
    218     LayoutUnit m_computedAutoHeight;
    219 
    220     bool m_isValid : 1;
    221     bool m_hasCustomRegionStyle : 1;
    222     bool m_hasAutoLogicalHeight : 1;
    223 };
    224 
    225 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderRegion, isRenderRegion());
    226 
    227 } // namespace WebCore
    228 
    229 #endif // RenderRegion_h
    230