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/rendering/InlineFlowBox.h"
     25 #include "platform/text/BidiContext.h"
     26 
     27 namespace WebCore {
     28 
     29 class EllipsisBox;
     30 class HitTestResult;
     31 class RenderBlockFlow;
     32 
     33 struct BidiStatus;
     34 struct GapRects;
     35 
     36 class RootInlineBox : public InlineFlowBox {
     37 public:
     38     explicit RootInlineBox(RenderBlockFlow&);
     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     LayoutUnit selectionTop() const;
     67     LayoutUnit selectionBottom() const;
     68     LayoutUnit selectionHeight() const { return max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
     69 
     70     LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
     71     LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }
     72 
     73     int blockDirectionPointInLine() const;
     74 
     75     LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
     76     void setLineTopBottomPositions(LayoutUnit top, LayoutUnit bottom, LayoutUnit topWithLeading, LayoutUnit bottomWithLeading)
     77     {
     78         m_lineTop = top;
     79         m_lineBottom = bottom;
     80         m_lineTopWithLeading = topWithLeading;
     81         m_lineBottomWithLeading = bottomWithLeading;
     82     }
     83 
     84     virtual RenderLineBoxList* rendererLineBoxes() const OVERRIDE FINAL;
     85 
     86     RenderObject* lineBreakObj() const { return m_lineBreakObj; }
     87     BidiStatus lineBreakBidiStatus() const;
     88     void setLineBreakInfo(RenderObject*, unsigned breakPos, const BidiStatus&);
     89 
     90     unsigned lineBreakPos() const { return m_lineBreakPos; }
     91     void setLineBreakPos(unsigned p) { m_lineBreakPos = p; }
     92 
     93     using InlineBox::endsWithBreak;
     94     using InlineBox::setEndsWithBreak;
     95 
     96     void childRemoved(InlineBox* box);
     97 
     98     bool lineCanAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
     99     // Return the truncatedWidth, the width of the truncated text + ellipsis.
    100     float placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, InlineBox* markupBox = 0);
    101     // Return the position of the EllipsisBox or -1.
    102     virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) OVERRIDE FINAL;
    103 
    104     using InlineBox::hasEllipsisBox;
    105     EllipsisBox* ellipsisBox() const;
    106 
    107     void paintEllipsisBox(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) const;
    108 
    109     virtual void clearTruncation() OVERRIDE FINAL;
    110 
    111     bool isHyphenated() const;
    112 
    113     virtual int baselinePosition(FontBaseline baselineType) const OVERRIDE FINAL;
    114     virtual LayoutUnit lineHeight() const OVERRIDE FINAL;
    115 
    116     virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
    117     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE FINAL;
    118 
    119     using InlineBox::hasSelectedChildren;
    120     using InlineBox::setHasSelectedChildren;
    121 
    122     virtual RenderObject::SelectionState selectionState() OVERRIDE FINAL;
    123     InlineBox* firstSelectedBox();
    124     InlineBox* lastSelectedBox();
    125 
    126     GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo*);
    127 
    128     RenderBlockFlow& block() const;
    129 
    130     InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
    131     InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
    132 
    133     void appendFloat(RenderBox* floatingBox)
    134     {
    135         ASSERT(!isDirty());
    136         if (m_floats)
    137             m_floats->append(floatingBox);
    138         else
    139             m_floats= adoptPtr(new Vector<RenderBox*>(1, floatingBox));
    140     }
    141 
    142     Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_floats.get(); }
    143 
    144     virtual void extractLineBoxFromRenderObject() OVERRIDE FINAL;
    145     virtual void attachLineBoxToRenderObject() OVERRIDE FINAL;
    146     virtual void removeLineBoxFromRenderObject() OVERRIDE FINAL;
    147 
    148     FontBaseline baselineType() const { return static_cast<FontBaseline>(m_baselineType); }
    149 
    150     bool hasAnnotationsBefore() const { return m_hasAnnotationsBefore; }
    151     bool hasAnnotationsAfter() const { return m_hasAnnotationsAfter; }
    152 
    153     LayoutRect paddedLayoutOverflowRect(LayoutUnit endPadding) const;
    154 
    155     void ascentAndDescentForBox(InlineBox*, GlyphOverflowAndFallbackFontsMap&, int& ascent, int& descent, bool& affectsAscent, bool& affectsDescent) const;
    156     LayoutUnit verticalPositionForBox(InlineBox*, VerticalPositionCache&);
    157     bool includeLeadingForBox(InlineBox*) const;
    158     bool includeFontForBox(InlineBox*) const;
    159     bool includeGlyphsForBox(InlineBox*) const;
    160     bool includeMarginForBox(InlineBox*) const;
    161     bool fitsToGlyphs() const;
    162     bool includesRootLineBoxFontOrLeading() const;
    163 
    164     LayoutUnit logicalTopVisualOverflow() const
    165     {
    166         return InlineFlowBox::logicalTopVisualOverflow(lineTop());
    167     }
    168     LayoutUnit logicalBottomVisualOverflow() const
    169     {
    170         return InlineFlowBox::logicalBottomVisualOverflow(lineBottom());
    171     }
    172     LayoutUnit logicalTopLayoutOverflow() const
    173     {
    174         return InlineFlowBox::logicalTopLayoutOverflow(lineTop());
    175     }
    176     LayoutUnit logicalBottomLayoutOverflow() const
    177     {
    178         return InlineFlowBox::logicalBottomLayoutOverflow(lineBottom());
    179     }
    180 
    181     // Used to calculate the underline offset for TextUnderlinePositionUnder.
    182     float maxLogicalTop() const;
    183 
    184     Node* getLogicalStartBoxWithNode(InlineBox*&) const;
    185     Node* getLogicalEndBoxWithNode(InlineBox*&) const;
    186 
    187 #ifndef NDEBUG
    188     virtual const char* boxName() const OVERRIDE;
    189 #endif
    190 private:
    191     LayoutUnit beforeAnnotationsAdjustment() const;
    192 
    193     struct LineFragmentationData;
    194     LineFragmentationData* ensureLineFragmentationData()
    195     {
    196         if (!m_fragmentationData)
    197             m_fragmentationData = adoptPtr(new LineFragmentationData());
    198 
    199         return m_fragmentationData.get();
    200     }
    201 
    202     // This folds into the padding at the end of InlineFlowBox on 64-bit.
    203     unsigned m_lineBreakPos;
    204 
    205     // Where this line ended.  The exact object and the position within that object are stored so that
    206     // we can create an InlineIterator beginning just after the end of this line.
    207     RenderObject* m_lineBreakObj;
    208     RefPtr<BidiContext> m_lineBreakContext;
    209 
    210     LayoutUnit m_lineTop;
    211     LayoutUnit m_lineBottom;
    212 
    213     LayoutUnit m_lineTopWithLeading;
    214     LayoutUnit m_lineBottomWithLeading;
    215 
    216     struct LineFragmentationData {
    217         WTF_MAKE_NONCOPYABLE(LineFragmentationData); WTF_MAKE_FAST_ALLOCATED;
    218     public:
    219         LineFragmentationData()
    220             : m_paginationStrut(0)
    221             , m_paginatedLineWidth(0)
    222             , m_isFirstAfterPageBreak(false)
    223         {
    224 
    225         }
    226 
    227         LayoutUnit m_paginationStrut;
    228         LayoutUnit m_paginatedLineWidth;
    229         bool m_isFirstAfterPageBreak;
    230     };
    231 
    232     OwnPtr<LineFragmentationData> m_fragmentationData;
    233 
    234     // Floats hanging off the line are pushed into this vector during layout. It is only
    235     // good for as long as the line has not been marked dirty.
    236     OwnPtr<Vector<RenderBox*> > m_floats;
    237 };
    238 
    239 } // namespace WebCore
    240 
    241 #endif // RootInlineBox_h
    242