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 THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_ROOT_INLINE_BOX_H_
22 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_ROOT_INLINE_BOX_H_
23 
24 #include <memory>
25 
26 #include "third_party/blink/renderer/core/layout/api/line_layout_item.h"
27 #include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
28 #include "third_party/blink/renderer/platform/text/bidi_context.h"
29 
30 namespace blink {
31 
32 class EllipsisBox;
33 class HitTestResult;
34 class LineLayoutBlockFlow;
35 
36 struct BidiStatus;
37 
38 enum ForceEllipsisOnLine { DoNotForceEllipsis, ForceEllipsis };
39 
40 class RootInlineBox : public InlineFlowBox {
41  public:
42   explicit RootInlineBox(LineLayoutItem);
43 
44   void Destroy() final;
45 
IsRootInlineBox()46   bool IsRootInlineBox() const final { return true; }
47 
48   void DetachEllipsisBox();
49 
NextRootBox()50   RootInlineBox* NextRootBox() const {
51     return static_cast<RootInlineBox*>(next_line_box_);
52   }
PrevRootBox()53   RootInlineBox* PrevRootBox() const {
54     return static_cast<RootInlineBox*>(prev_line_box_);
55   }
56 
57   void Move(const LayoutSize&) final;
58 
LineTop()59   LayoutUnit LineTop() const { return line_top_; }
LineBottom()60   LayoutUnit LineBottom() const { return line_bottom_; }
61 
LineTopWithLeading()62   LayoutUnit LineTopWithLeading() const { return line_top_with_leading_; }
LineBottomWithLeading()63   LayoutUnit LineBottomWithLeading() const { return line_bottom_with_leading_; }
64 
PaginationStrut()65   LayoutUnit PaginationStrut() const { return pagination_strut_; }
SetPaginationStrut(LayoutUnit strut)66   void SetPaginationStrut(LayoutUnit strut) { pagination_strut_ = strut; }
67 
68   LayoutUnit SelectionTop() const;
69   LayoutUnit SelectionBottom() const;
SelectionHeight()70   LayoutUnit SelectionHeight() const {
71     return (SelectionBottom() - SelectionTop()).ClampNegativeToZero();
72   }
73 
74   LayoutUnit BlockDirectionPointInLine() const;
75 
76   LayoutUnit AlignBoxesInBlockDirection(LayoutUnit height_of_block,
77                                         GlyphOverflowAndFallbackFontsMap&,
78                                         VerticalPositionCache&);
79   void SetLineTopBottomPositions(
80       LayoutUnit top,
81       LayoutUnit bottom,
82       LayoutUnit top_with_leading,
83       LayoutUnit bottom_with_leading,
84       LayoutUnit selection_bottom = LayoutUnit::Min()) {
85     line_top_ = top;
86     line_bottom_ = bottom;
87     line_top_with_leading_ = top_with_leading;
88     line_bottom_with_leading_ = bottom_with_leading;
89     selection_bottom_ =
90         selection_bottom == LayoutUnit::Min() ? bottom : selection_bottom;
91   }
92 
93   LineBoxList* LineBoxes() const final;
94 
LineBreakObj()95   LineLayoutItem LineBreakObj() const { return line_break_obj_; }
96   BidiStatus LineBreakBidiStatus() const;
97   void SetLineBreakInfo(LineLayoutItem, unsigned break_pos, const BidiStatus&);
98 
LineBreakPos()99   unsigned LineBreakPos() const { return line_break_pos_; }
SetLineBreakPos(unsigned p)100   void SetLineBreakPos(unsigned p) { line_break_pos_ = p; }
101 
102   using InlineBox::EndsWithBreak;
103   using InlineBox::SetEndsWithBreak;
104 
105   void ChildRemoved(InlineBox*);
106 
107   bool LineCanAccommodateEllipsis(bool ltr,
108                                   LayoutUnit block_edge,
109                                   LayoutUnit line_box_edge,
110                                   LayoutUnit ellipsis_width);
111   // Return the truncatedWidth, the width of the truncated text + ellipsis.
112   LayoutUnit PlaceEllipsis(const AtomicString& ellipsis_str,
113                            bool ltr,
114                            LayoutUnit block_left_edge,
115                            LayoutUnit block_right_edge,
116                            LayoutUnit ellipsis_width,
117                            LayoutUnit logical_left_offset,
118                            InlineBox** found_box,
119                            ForceEllipsisOnLine = DoNotForceEllipsis);
120   // Return the position of the EllipsisBox or -1.
121   LayoutUnit PlaceEllipsisBox(bool ltr,
122                               LayoutUnit block_left_edge,
123                               LayoutUnit block_right_edge,
124                               LayoutUnit ellipsis_width,
125                               LayoutUnit& truncated_width,
126                               InlineBox** found_box,
127                               LayoutUnit logical_left_offset) final;
128 
129   using InlineBox::HasEllipsisBox;
130   EllipsisBox* GetEllipsisBox() const;
131 
132   void ClearTruncation() final;
133 
134   LayoutUnit BaselinePosition(FontBaseline baseline_type) const final;
135   LayoutUnit LineHeight() const final;
136 
137   void Paint(const PaintInfo&,
138              const LayoutPoint&,
139              LayoutUnit line_top,
140              LayoutUnit line_bottom) const override;
141   bool NodeAtPoint(HitTestResult&,
142                    const HitTestLocation&,
143                    const PhysicalOffset& accumulated_offset,
144                    LayoutUnit line_top,
145                    LayoutUnit line_bottom) override;
146 
147   bool IsSelected() const final;
148   InlineBox* FirstSelectedBox() const;
149   InlineBox* LastSelectedBox() const;
150 
151   LineLayoutBlockFlow Block() const;
152 
153   const LayoutObject* ClosestLeafChildForPoint(const LayoutPoint&,
154                                                bool only_editable_leaves) const;
155   InlineBox* ClosestLeafChildForLogicalLeftPosition(
156       LayoutUnit,
157       bool only_editable_leaves = false) const;
158 
AppendFloat(LayoutBox * floating_box)159   void AppendFloat(LayoutBox* floating_box) {
160     DCHECK(!IsDirty());
161     if (floats_)
162       floats_->push_back(floating_box);
163     else
164       floats_ = std::make_unique<Vector<LayoutBox*>>(1, floating_box);
165   }
166 
FloatsPtr()167   Vector<LayoutBox*>* FloatsPtr() {
168     DCHECK(!IsDirty());
169     return floats_.get();
170   }
171 
172   void ExtractLineBoxFromLayoutObject() final;
173   void AttachLineBoxToLayoutObject() final;
174   void RemoveLineBoxFromLayoutObject() final;
175 
BaselineType()176   FontBaseline BaselineType() const {
177     return static_cast<FontBaseline>(baseline_type_);
178   }
179 
HasAnnotationsBefore()180   bool HasAnnotationsBefore() const { return has_annotations_before_; }
HasAnnotationsAfter()181   bool HasAnnotationsAfter() const { return has_annotations_after_; }
182 
183   LayoutRect PaddedLayoutOverflowRect(LayoutUnit end_padding) const;
184 
185   void AscentAndDescentForBox(InlineBox*,
186                               GlyphOverflowAndFallbackFontsMap&,
187                               LayoutUnit& ascent,
188                               LayoutUnit& descent,
189                               bool& affects_ascent,
190                               bool& affects_descent) const;
191   LayoutUnit VerticalPositionForBox(InlineBox*, VerticalPositionCache&);
192   bool IncludeLeadingForBox(InlineBox*) const;
193 
LogicalTopVisualOverflow()194   LayoutUnit LogicalTopVisualOverflow() const {
195     return InlineFlowBox::LogicalTopVisualOverflow(LineTop());
196   }
LogicalBottomVisualOverflow()197   LayoutUnit LogicalBottomVisualOverflow() const {
198     return InlineFlowBox::LogicalBottomVisualOverflow(LineBottom());
199   }
LogicalTopLayoutOverflow()200   LayoutUnit LogicalTopLayoutOverflow() const {
201     return InlineFlowBox::LogicalTopLayoutOverflow(LineTop());
202   }
LogicalBottomLayoutOverflow()203   LayoutUnit LogicalBottomLayoutOverflow() const {
204     return InlineFlowBox::LogicalBottomLayoutOverflow(LineBottom());
205   }
206 
207   typedef void (*CustomInlineBoxRangeReverse)(
208       Vector<InlineBox*>::iterator first,
209       Vector<InlineBox*>::iterator last);
210   void CollectLeafBoxesInLogicalOrder(
211       Vector<InlineBox*>&,
212       CustomInlineBoxRangeReverse custom_reverse_implementation =
213           nullptr) const;
214 
215   const InlineBox* GetLogicalStartNonPseudoBox() const;
216   const InlineBox* GetLogicalEndNonPseudoBox() const;
217 
218   const char* BoxName() const override;
219 
220  private:
221   LayoutUnit BeforeAnnotationsAdjustment() const;
222 
223   // This folds into the padding at the end of InlineFlowBox on 64-bit.
224   unsigned line_break_pos_;
225 
226   // Where this line ended.  The exact object and the position within that
227   // object are stored so that we can create an InlineIterator beginning just
228   // after the end of this line.
229   LineLayoutItem line_break_obj_;
230   scoped_refptr<BidiContext> line_break_context_;
231 
232   // Floats hanging off the line are pushed into this vector during layout. It
233   // is only good for as long as the line has not been marked dirty.
234   std::unique_ptr<Vector<LayoutBox*>> floats_;
235 
236   LayoutUnit line_top_;
237   LayoutUnit line_bottom_;
238   LayoutUnit line_top_with_leading_;
239   LayoutUnit line_bottom_with_leading_;
240   LayoutUnit selection_bottom_;
241   LayoutUnit pagination_strut_;
242 };
243 
244 }  // namespace blink
245 
246 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_ROOT_INLINE_BOX_H_
247