OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/layout/ng/inline/ng_inline_layout_algorithm.h" | 5 #include "core/layout/ng/inline/ng_inline_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/inline/ng_bidi_paragraph.h" | 7 #include "core/layout/ng/inline/ng_bidi_paragraph.h" |
8 #include "core/layout/ng/inline/ng_inline_break_token.h" | 8 #include "core/layout/ng/inline/ng_inline_break_token.h" |
9 #include "core/layout/ng/inline/ng_inline_node.h" | 9 #include "core/layout/ng/inline/ng_inline_node.h" |
10 #include "core/layout/ng/inline/ng_line_box_fragment.h" | 10 #include "core/layout/ng/inline/ng_line_box_fragment.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 } else if (item.Type() == NGInlineItem::kCloseTag) { | 185 } else if (item.Type() == NGInlineItem::kCloseTag) { |
186 position += item_result.inline_size; | 186 position += item_result.inline_size; |
187 if (box->needs_box_fragment || item_result.needs_box_when_empty) { | 187 if (box->needs_box_fragment || item_result.needs_box_when_empty) { |
188 if (item_result.needs_box_when_empty) | 188 if (item_result.needs_box_when_empty) |
189 box->SetNeedsBoxFragment(true); | 189 box->SetNeedsBoxFragment(true); |
190 box->SetLineRightForBoxFragment(item, item_result, position); | 190 box->SetLineRightForBoxFragment(item, item_result, position); |
191 } | 191 } |
192 box = box_states_.OnCloseTag(item, &line_box, box, baseline_type_); | 192 box = box_states_.OnCloseTag(item, &line_box, box, baseline_type_); |
193 continue; | 193 continue; |
194 } else if (item.Type() == NGInlineItem::kAtomicInline) { | 194 } else if (item.Type() == NGInlineItem::kAtomicInline) { |
195 box = PlaceAtomicInline(item, &item_result, line_info->IsFirstLine(), | 195 box = PlaceAtomicInline(item, &item_result, *line_info, position, |
196 position, &line_box, &text_builder); | 196 &line_box, &text_builder); |
197 } else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { | 197 } else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { |
198 // TODO(layout-dev): Report the correct static position for the out of | 198 // TODO(layout-dev): Report the correct static position for the out of |
199 // flow descendant. We can't do this here yet as it doesn't know the | 199 // flow descendant. We can't do this here yet as it doesn't know the |
200 // size of the line box. | 200 // size of the line box. |
201 container_builder_.AddOutOfFlowDescendant( | 201 container_builder_.AddOutOfFlowDescendant( |
202 // Absolute positioning blockifies the box's display type. | 202 // Absolute positioning blockifies the box's display type. |
203 // https://drafts.csswg.org/css-display/#transformations | 203 // https://drafts.csswg.org/css-display/#transformations |
204 NGBlockNode(ToLayoutBox(item.GetLayoutObject())), | 204 NGBlockNode(ToLayoutBox(item.GetLayoutObject())), |
205 NGStaticPosition::Create(ConstraintSpace().WritingMode(), | 205 NGStaticPosition::Create(ConstraintSpace().WritingMode(), |
206 ConstraintSpace().Direction(), | 206 ConstraintSpace().Direction(), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 line_box.SetBreakToken(std::move(break_token)); | 240 line_box.SetBreakToken(std::move(break_token)); |
241 | 241 |
242 // TODO(kojii): Implement flipped line (vertical-lr). In this case, line_top | 242 // TODO(kojii): Implement flipped line (vertical-lr). In this case, line_top |
243 // and block_start do not match. | 243 // and block_start do not match. |
244 | 244 |
245 // Up until this point, children are placed so that the dominant baseline is | 245 // Up until this point, children are placed so that the dominant baseline is |
246 // at 0. Move them to the final baseline position, and set the logical top of | 246 // at 0. Move them to the final baseline position, and set the logical top of |
247 // the line box to the line top. | 247 // the line box to the line top. |
248 line_box.MoveChildrenInBlockDirection(baseline); | 248 line_box.MoveChildrenInBlockDirection(baseline); |
249 | 249 |
| 250 // Compute the offset of the line box. |
250 LayoutUnit inline_size = position; | 251 LayoutUnit inline_size = position; |
251 NGLogicalOffset offset(line_info->LineLeft(), | 252 NGLogicalOffset offset(line_info->LineLeft(), |
252 baseline - box_states_.LineBoxState().metrics.ascent); | 253 baseline - box_states_.LineBoxState().metrics.ascent); |
| 254 LayoutUnit available_width = line_info->AvailableWidth(); |
| 255 if (LayoutUnit text_indent = line_info->TextIndent()) { |
| 256 // Move the line box by indent. Negative indents are ink overflow, let the |
| 257 // line box overflow from the container box. |
| 258 if (IsLtr(Node().BaseDirection())) |
| 259 offset.inline_offset += text_indent; |
| 260 available_width -= text_indent; |
| 261 } |
253 ApplyTextAlign(line_style.GetTextAlign(line_info->IsLastLine()), | 262 ApplyTextAlign(line_style.GetTextAlign(line_info->IsLastLine()), |
254 &offset.inline_offset, inline_size, | 263 &offset.inline_offset, inline_size, available_width); |
255 line_info->AvailableWidth()); | |
256 | 264 |
257 line_box.SetInlineSize(inline_size); | 265 line_box.SetInlineSize(inline_size); |
258 container_builder_.AddChild(line_box.ToLineBoxFragment(), offset); | 266 container_builder_.AddChild(line_box.ToLineBoxFragment(), offset); |
259 | 267 |
260 max_inline_size_ = std::max(max_inline_size_, inline_size); | 268 max_inline_size_ = std::max(max_inline_size_, inline_size); |
261 content_size_ = ComputeContentSize(*line_info, line_bottom); | 269 content_size_ = ComputeContentSize(*line_info, line_bottom); |
262 | 270 |
263 return true; | 271 return true; |
264 } | 272 } |
265 | 273 |
266 // TODO(kojii): Currently, this function does not change item_result, but | 274 // TODO(kojii): Currently, this function does not change item_result, but |
267 // when NG paint is enabled, this will std::move() the LayoutResult. | 275 // when NG paint is enabled, this will std::move() the LayoutResult. |
268 NGInlineBoxState* NGInlineLayoutAlgorithm::PlaceAtomicInline( | 276 NGInlineBoxState* NGInlineLayoutAlgorithm::PlaceAtomicInline( |
269 const NGInlineItem& item, | 277 const NGInlineItem& item, |
270 NGInlineItemResult* item_result, | 278 NGInlineItemResult* item_result, |
271 bool is_first_line, | 279 const NGLineInfo& line_info, |
272 LayoutUnit position, | 280 LayoutUnit position, |
273 NGLineBoxFragmentBuilder* line_box, | 281 NGLineBoxFragmentBuilder* line_box, |
274 NGTextFragmentBuilder* text_builder) { | 282 NGTextFragmentBuilder* text_builder) { |
275 DCHECK(item_result->layout_result); | 283 DCHECK(item_result->layout_result); |
276 | 284 |
277 NGInlineBoxState* box = | 285 NGInlineBoxState* box = |
278 box_states_.OnOpenTag(item, *item_result, line_box, position); | 286 box_states_.OnOpenTag(item, *item_result, line_box, position); |
279 | 287 |
280 // For replaced elements, inline-block elements, and inline-table elements, | 288 // For replaced elements, inline-block elements, and inline-table elements, |
281 // the height is the height of their margin box. | 289 // the height is the height of their margin box. |
282 // https://drafts.csswg.org/css2/visudet.html#line-height | 290 // https://drafts.csswg.org/css2/visudet.html#line-height |
283 NGBoxFragment fragment( | 291 NGBoxFragment fragment( |
284 ConstraintSpace().WritingMode(), | 292 ConstraintSpace().WritingMode(), |
285 ToNGPhysicalBoxFragment( | 293 ToNGPhysicalBoxFragment( |
286 item_result->layout_result->PhysicalFragment().Get())); | 294 item_result->layout_result->PhysicalFragment().Get())); |
287 LayoutUnit block_size = | 295 LayoutUnit block_size = |
288 fragment.BlockSize() + item_result->margins.BlockSum(); | 296 fragment.BlockSize() + item_result->margins.BlockSum(); |
289 | 297 |
290 // TODO(kojii): Add baseline position to NGPhysicalFragment. | 298 // TODO(kojii): Add baseline position to NGPhysicalFragment. |
291 LayoutBox* layout_box = ToLayoutBox(item.GetLayoutObject()); | 299 LayoutBox* layout_box = ToLayoutBox(item.GetLayoutObject()); |
292 LineDirectionMode line_direction_mode = | 300 LineDirectionMode line_direction_mode = |
293 IsHorizontalWritingMode() ? LineDirectionMode::kHorizontalLine | 301 IsHorizontalWritingMode() ? LineDirectionMode::kHorizontalLine |
294 : LineDirectionMode::kVerticalLine; | 302 : LineDirectionMode::kVerticalLine; |
295 LayoutUnit baseline_offset(layout_box->BaselinePosition( | 303 LayoutUnit baseline_offset(layout_box->BaselinePosition( |
296 baseline_type_, is_first_line, line_direction_mode)); | 304 baseline_type_, line_info.UseFirstLineStyle(), line_direction_mode)); |
297 | 305 |
298 NGLineHeightMetrics metrics(baseline_offset, block_size - baseline_offset); | 306 NGLineHeightMetrics metrics(baseline_offset, block_size - baseline_offset); |
299 box->metrics.Unite(metrics); | 307 box->metrics.Unite(metrics); |
300 | 308 |
301 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult. | 309 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult. |
302 // Floats are ok because atomic inlines are BFC? | 310 // Floats are ok because atomic inlines are BFC? |
303 | 311 |
304 // TODO(kojii): Try to eliminate the wrapping text fragment and use the | 312 // TODO(kojii): Try to eliminate the wrapping text fragment and use the |
305 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow| | 313 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow| |
306 // requires a text fragment. | 314 // requires a text fragment. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 // Margin struts shouldn't need to be passed through like this once we've | 428 // Margin struts shouldn't need to be passed through like this once we've |
421 // removed LayoutInline splitting. | 429 // removed LayoutInline splitting. |
422 if (!container_builder_.BfcOffset()) { | 430 if (!container_builder_.BfcOffset()) { |
423 container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut()); | 431 container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut()); |
424 } | 432 } |
425 | 433 |
426 return container_builder_.ToBoxFragment(); | 434 return container_builder_.ToBoxFragment(); |
427 } | 435 } |
428 | 436 |
429 } // namespace blink | 437 } // namespace blink |
OLD | NEW |