Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 #ifndef RootInlineBox_h
     22 #define RootInlineBox_h
     23 
     24 #include "core/platform/text/BidiContext.h"
     25 #include "core/rendering/InlineFlowBox.h"
     26 
     27 namespace WebCore {
     28 
     29 class EllipsisBox;
     30 class HitTestResult;
     31 class RenderRegion;
     32 
     33 struct BidiStatus;
     34 struct GapRects;
     35 
     36 class RootInlineBox : public InlineFlowBox {
     37 public:
     38     explicit RootInlineBox(RenderBlock*);
     39 
     40     virtual void destroy() OVERRIDE FINAL;
     41 
     42     virtual bool isRootInlineBox() const OVERRIDE FINAL { return true; }
     43 
     44     void detachEllipsisBox();
     45 
     46     RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLineBox); }
     47     RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLineBox); }
     48 
     49     virtual void adjustPosition(float dx, float dy) OVERRIDE FINAL;
     50 
     51     LayoutUnit lineTop() const { return m_lineTop; }
     52     LayoutUnit lineBottom() const { return m_lineBottom; }
     53 
     54     LayoutUnit lineTopWithLeading() const { return m_lineTopWithLeading; }
     55     LayoutUnit lineBottomWithLeading() const { return m_lineBottomWithLeading; }
     56 
     57     LayoutUnit paginationStrut() const { return m_fragmentationData ? m_fragmentationData->m_paginationStrut : LayoutUnit(0); }
     58     void setPaginationStrut(LayoutUnit strut) { ensureLineFragmentationData()->m_paginationStrut = strut; }
     59 
     60     bool isFirstAfterPageBreak() const { return m_fragmentationData ? m_fragmentationData->m_isFirstAfterPageBreak : false; }
     61     void setIsFirstAfterPageBreak(bool isFirstAfterPageBreak) { ensureLineFragmentationData()->m_isFirstAfterPageBreak = isFirstAfterPageBreak; }
     62 
     63     LayoutUnit paginatedLineWidth() const { return m_fragmentationData ? m_fragmentationData->m_paginatedLineWidth : LayoutUnit(0); }
     64     void setPaginatedLineWidth(LayoutUnit width) { ensureLineFragmentationData()->m_paginatedLineWidth = width; }
     65 
     66     RenderRegion* containingRegion() const;
     67     void setContainingRegion(RenderRegion*);
     68 
     69     LayoutUnit selectionTop() const;
     70     LayoutUnit selectionBottom() const;
     71     LayoutUnit selectionHeight() const { return max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
     72 
     73     LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
     74     LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }
     75 
     76     int blockDirectionPointInLine() const;
     77 
     78     LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
     79     void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom, LayoutUnit topWithLeading, LayoutUnit bottomWithLeading)
     80     {
     81         m_lineTop = top;
     82         m_lineBottom = bottom;
     83         m_lineTopWithLeading = topWithLeading;
     84         m_lineBottomWithLeading = bottomWithLeading;
     85     }
     86 
     87     virtual RenderLineBoxList* rendererLineBoxes() const OVERRIDE FINAL;
     88 
     89     RenderObject* lineBreakObj() const { return m_lineBreakObj; }
     90     BidiStatus lineBreakBidiStatus() const;
     91     void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);
     92 
     93     unsigned lineBreakPos() const { return m_lineBreakPos; }
     94     void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
     95 
     96     using InlineBox::endsWithBreak;
     97     using InlineBox::setEndsWithBreak;
     98 
     99     void childRemoved(InlineBox* box);
    100 
    101     bool lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
    102     // Return the truncatedWidth, the width of the truncated text + ellipsis.
    103     float placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, InlineBox* markupBox = 0);
    104     // Return the position of the EllipsisBox or -1.
    105     virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) OVERRIDE FINAL;
    106 
    107     using InlineBox::hasEllipsisBox;
    108     EllipsisBox* ellipsisBox() const;
    109 
    110     void paintEllipsisBox(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) const;
    111 
    112     virtual void clearTruncation() OVERRIDE FINAL;
    113 
    114     bool isHyphenated() const;
    115 
    116     virtual int baselinePosition(FontBaseline baselineType) const OVERRIDE FINAL;
    117     virtual LayoutUnit lineHeight() const OVERRIDE FINAL;
    118 
    119     virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
    120     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE FINAL;
    121 
    122     using InlineBox::hasSelectedChildren;
    123     using InlineBox::setHasSelectedChildren;
    124 
    125     virtual RenderObject::SelectionState selectionState() OVERRIDE FINAL;
    126     InlineBox* firstSelectedBox();
    127     InlineBox* lastSelectedBox();
    128 
    129     GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo*);
    130 
    131     RenderBlock* block() const;
    132 
    133     InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
    134     InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
    135 
    136     void appendFloat(RenderBox* floatingBox)
    137     {
    138         ASSERT(!isDirty());
    139         if (m_floats)
    140             m_floats->append(floatingBox);
    141         else
    142             m_floats= adoptPtr(new Vector<RenderBox*>(1, floatingBox));
    143     }
    144 
    145     Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }
    146 
    147     virtual void extractLineBoxFromRenderObject() OVERRIDE FINAL;
    148     virtual void attachLineBoxToRenderObject() OVERRIDE FINAL;
    149     virtual void removeLineBoxFromRenderObject() OVERRIDE FINAL;
    150 
    151     FontBaseline baselineType() const { return static_cast<FontBaseline>(m_baselineType); }
    152 
    153     bool hasAnnotationsBefore() const { return m_hasAnnotationsBefore; }
    154     bool hasAnnotationsAfter() const { return m_hasAnnotationsAfter; }
    155 
    156     LayoutRect paddedLayoutOverflowRect(LayoutUnit endPadding) const;
    157 
    158     void ascentAndDescentForBox(InlineBox*, GlyphOverflowAndFallbackFontsMap&, int& ascent, int& descent, bool& affectsAscent, bool& affectsDescent) const;
    159     LayoutUnit verticalPositionForBox(InlineBox*, VerticalPositionCache&);
    160     bool includeLeadingForBox(InlineBox*) const;
    161     bool includeFontForBox(InlineBox*) const;
    162     bool includeGlyphsForBox(InlineBox*) const;
    163     bool includeMarginForBox(InlineBox*) const;
    164     bool fitsToGlyphs() const;
    165     bool includesRootLineBoxFontOrLeading() const;
    166 
    167     LayoutUnit logicalTopVisualOverflow() const
    168     {
    169         return InlineFlowBox::logicalTopVisualOverflow(lineTop());
    170     }
    171     LayoutUnit logicalBottomVisualOverflow() const
    172     {
    173         return InlineFlowBox::logicalBottomVisualOverflow(lineBottom());
    174     }
    175     LayoutUnit logicalTopLayoutOverflow() const
    176     {
    177         return InlineFlowBox::logicalTopLayoutOverflow(lineTop());
    178     }
    179     LayoutUnit logicalBottomLayoutOverflow() const
    180     {
    181         return InlineFlowBox::logicalBottomLayoutOverflow(lineBottom());
    182     }
    183 
    184 #if ENABLE(CSS3_TEXT)
    185     // Used to calculate the underline offset for TextUnderlinePositionUnder.
    186     float maxLogicalTop() const;
    187 #endif // CSS3_TEXT
    188 
    189     Node* getLogicalStartBoxWithNode(InlineBox*&) const;
    190     Node* getLogicalEndBoxWithNode(InlineBox*&) const;
    191 
    192 #ifndef NDEBUG
    193     virtual const char* boxName() const;
    194 #endif
    195 private:
    196     LayoutUnit lineSnapAdjustment(LayoutUnit delta = 0) const;
    197 
    198     LayoutUnit beforeAnnotationsAdjustment() const;
    199 
    200     struct LineFragmentationData;
    201     LineFragmentationData* ensureLineFragmentationData()
    202     {
    203         if (!m_fragmentationData)
    204             m_fragmentationData = adoptPtr(new LineFragmentationData());
    205 
    206         return m_fragmentationData.get();
    207     }
    208 
    209     // This folds into the padding at the end of InlineFlowBox on 64-bit.
    210     unsigned m_lineBreakPos;
    211 
    212     // Where this line ended.  The exact object and the position within that object are stored so that
    213     // we can create an InlineIterator beginning just after the end of this line.
    214     RenderObject* m_lineBreakObj;
    215     RefPtr<BidiContext> m_lineBreakContext;
    216 
    217     LayoutUnit m_lineTop;
    218     LayoutUnit m_lineBottom;
    219 
    220     LayoutUnit m_lineTopWithLeading;
    221     LayoutUnit m_lineBottomWithLeading;
    222 
    223     struct LineFragmentationData {
    224         WTF_MAKE_NONCOPYABLE(LineFragmentationData); WTF_MAKE_FAST_ALLOCATED;
    225     public:
    226         LineFragmentationData()
    227             : m_containingRegion(0)
    228             , m_paginationStrut(0)
    229             , m_paginatedLineWidth(0)
    230             , m_isFirstAfterPageBreak(false)
    231         {
    232 
    233         }
    234 
    235         // It should not be assumed the |containingRegion| is always valid.
    236         // It can also be 0 if the flow has no region chain.
    237         RenderRegion* m_containingRegion;
    238         LayoutUnit m_paginationStrut;
    239         LayoutUnit m_paginatedLineWidth;
    240         bool m_isFirstAfterPageBreak;
    241     };
    242 
    243     OwnPtr<LineFragmentationData> m_fragmentationData;
    244 
    245     // Floats hanging off the line are pushed into this vector during layout. It is only
    246     // good for as long as the line has not been marked dirty.
    247     OwnPtr<Vector<RenderBox*> > m_floats;
    248 };
    249 
    250 } // namespace WebCore
    251 
    252 #endif // RootInlineBox_h
    253