Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc

Issue 2745973002: [LayoutNG] Implement atomic inlines for LayoutNGInline (Closed)
Patch Set: WIP Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/ng_inline_node.h" 5 #include "core/layout/ng/ng_inline_node.h"
6 6
7 #include "core/layout/LayoutBlockFlow.h" 7 #include "core/layout/LayoutBlockFlow.h"
8 #include "core/layout/LayoutObject.h" 8 #include "core/layout/LayoutObject.h"
9 #include "core/layout/LayoutText.h" 9 #include "core/layout/LayoutText.h"
10 #include "core/layout/ng/ng_bidi_paragraph.h" 10 #include "core/layout/ng/ng_bidi_paragraph.h"
(...skipping 12 matching lines...) Expand all
23 #include "platform/fonts/shaping/CachingWordShaper.h" 23 #include "platform/fonts/shaping/CachingWordShaper.h"
24 #include "platform/fonts/shaping/HarfBuzzShaper.h" 24 #include "platform/fonts/shaping/HarfBuzzShaper.h"
25 #include "platform/fonts/shaping/ShapeResultBuffer.h" 25 #include "platform/fonts/shaping/ShapeResultBuffer.h"
26 #include "wtf/text/CharacterNames.h" 26 #include "wtf/text/CharacterNames.h"
27 27
28 namespace blink { 28 namespace blink {
29 29
30 NGInlineNode::NGInlineNode(LayoutObject* start_inline, LayoutBlockFlow* block) 30 NGInlineNode::NGInlineNode(LayoutObject* start_inline, LayoutBlockFlow* block)
31 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline), 31 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline),
32 start_inline_(start_inline), 32 start_inline_(start_inline),
33 block_(block) { 33 block_(block),
34 has_atomic_inlines_(false),
35 is_bidi_enabled_(false) {
34 DCHECK(start_inline); 36 DCHECK(start_inline);
35 DCHECK(block); 37 DCHECK(block);
36 } 38 }
37 39
38 NGInlineNode::NGInlineNode() 40 NGInlineNode::NGInlineNode()
39 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline), 41 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline),
40 start_inline_(nullptr), 42 start_inline_(nullptr),
41 block_(nullptr) {} 43 block_(nullptr),
44 has_atomic_inlines_(false),
45 is_bidi_enabled_(false) {}
42 46
43 NGInlineNode::~NGInlineNode() {} 47 NGInlineNode::~NGInlineNode() {}
44 48
45 NGLayoutInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) { 49 NGLayoutInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) {
46 return NGLayoutInlineItemRange(&items_, start, end); 50 return NGLayoutInlineItemRange(&items_, start, end);
47 } 51 }
48 52
49 void NGInlineNode::InvalidatePrepareLayout() { 53 void NGInlineNode::InvalidatePrepareLayout() {
50 text_content_ = String(); 54 text_content_ = String();
51 items_.clear(); 55 items_.clear();
56 has_atomic_inlines_ = false;
52 } 57 }
53 58
54 void NGInlineNode::PrepareLayout() { 59 void NGInlineNode::PrepareLayout() {
55 // Scan list of siblings collecting all in-flow non-atomic inlines. A single 60 // Scan list of siblings collecting all in-flow non-atomic inlines. A single
56 // NGInlineNode represent a collection of adjacent non-atomic inlines. 61 // NGInlineNode represent a collection of adjacent non-atomic inlines.
57 CollectInlines(start_inline_, block_); 62 CollectInlines(start_inline_, block_);
58 if (is_bidi_enabled_) 63 if (is_bidi_enabled_)
59 SegmentText(); 64 SegmentText();
60 ShapeText(); 65 ShapeText();
61 } 66 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 // A block box found. End inline and transit to block layout. 105 // A block box found. End inline and transit to block layout.
101 return node; 106 return node;
102 107
103 } else { 108 } else {
104 builder->EnterInline(node); 109 builder->EnterInline(node);
105 110
106 // For atomic inlines add a unicode "object replacement character" to 111 // For atomic inlines add a unicode "object replacement character" to
107 // signal the presence of a non-text object to the unicode bidi algorithm. 112 // signal the presence of a non-text object to the unicode bidi algorithm.
108 if (node->isAtomicInlineLevel()) { 113 if (node->isAtomicInlineLevel()) {
109 builder->Append(objectReplacementCharacter, nullptr, node); 114 builder->Append(objectReplacementCharacter, nullptr, node);
115 has_atomic_inlines_ = true;
110 } 116 }
111 117
112 // Otherwise traverse to children if they exist. 118 // Otherwise traverse to children if they exist.
113 else if (LayoutObject* child = node->slowFirstChild()) { 119 else if (LayoutObject* child = node->slowFirstChild()) {
114 node = child; 120 node = child;
115 continue; 121 continue;
116 122
117 } else { 123 } else {
118 // An empty inline node. 124 // An empty inline node.
119 node->clearNeedsLayout(); 125 node->clearNeedsLayout();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return InlineSize(start_offset_, end_offset_); 218 return InlineSize(start_offset_, end_offset_);
213 } 219 }
214 220
215 LayoutUnit NGLayoutInlineItem::InlineSize(unsigned start, unsigned end) const { 221 LayoutUnit NGLayoutInlineItem::InlineSize(unsigned start, unsigned end) const {
216 DCHECK(start >= StartOffset() && start <= end && end <= EndOffset()); 222 DCHECK(start >= StartOffset() && start <= end && end <= EndOffset());
217 223
218 if (start == end) 224 if (start == end)
219 return LayoutUnit(); 225 return LayoutUnit();
220 226
221 if (!style_ || !shape_result_) { 227 if (!style_ || !shape_result_) {
222 // Bidi controls do not have widths. 228 DCHECK(start == start_offset_ && end == end_offset_);
223 // TODO(kojii): Atomic inline not supported yet. 229 if (layout_result_) {
230 DCHECK(layout_object_ && layout_object_->isAtomicInlineLevel() &&
231 !layout_object_->isFloatingOrOutOfFlowPositioned());
232 // TODO(kojii): Store parent's isHorizontalWritingMode in
233 // NGLayoutInlineItem.
234 if (!isHorizontalWritingMode(
235 layout_object_->parent()->styleRef().getWritingMode()))
236 return layout_result_->PhysicalFragment()->Height();
237 return layout_result_->PhysicalFragment()->Width();
238 }
239 DCHECK(!layout_object_ ||
240 layout_object_->isFloatingOrOutOfFlowPositioned());
241 // Bidi controls and out-of-flow objects do not have in-flow widths.
224 return LayoutUnit(); 242 return LayoutUnit();
225 } 243 }
226 244
227 if (start == start_offset_ && end == end_offset_) 245 if (start == start_offset_ && end == end_offset_)
228 return LayoutUnit(shape_result_->width()); 246 return LayoutUnit(shape_result_->width());
229 247
230 return LayoutUnit(ShapeResultBuffer::getCharacterRange( 248 return LayoutUnit(ShapeResultBuffer::getCharacterRange(
231 shape_result_, Direction(), shape_result_->width(), 249 shape_result_, Direction(), shape_result_->width(),
232 start - StartOffset(), end - StartOffset()) 250 start - StartOffset(), end - StartOffset())
233 .width()); 251 .width());
234 } 252 }
235 253
236 void NGLayoutInlineItem::GetFallbackFonts( 254 void NGLayoutInlineItem::GetFallbackFonts(
237 HashSet<const SimpleFontData*>* fallback_fonts, 255 HashSet<const SimpleFontData*>* fallback_fonts,
238 unsigned start, 256 unsigned start,
239 unsigned end) const { 257 unsigned end) const {
240 DCHECK(start >= StartOffset() && start <= end && end <= EndOffset()); 258 DCHECK(start >= StartOffset() && start <= end && end <= EndOffset());
241 259
242 // TODO(kojii): Implement |start| and |end|. 260 // TODO(kojii): Implement |start| and |end|.
243 shape_result_->fallbackFonts(fallback_fonts); 261 shape_result_->fallbackFonts(fallback_fonts);
244 } 262 }
245 263
246 void NGInlineNode::ShapeText() { 264 void NGInlineNode::ShapeText() {
247 // TODO(eae): Add support for shaping latin-1 text? 265 // TODO(eae): Add support for shaping latin-1 text?
248 text_content_.ensure16Bit(); 266 text_content_.ensure16Bit();
249 267
250 // Shape each item with the full context of the entire node. 268 // Shape each item with the full context of the entire node.
251 HarfBuzzShaper shaper(text_content_.characters16(), text_content_.length()); 269 HarfBuzzShaper shaper(text_content_.characters16(), text_content_.length());
252 for (auto& item : items_) { 270 for (auto& item : items_) {
253 // Skip object replacement characters and bidi control characters. 271 // Skip non-text items; e.g., bidi controls, atomic inlines, out-of-flow
272 // objects.
254 if (!item.style_) 273 if (!item.style_)
255 continue; 274 continue;
256 275
257 item.shape_result_ = shaper.shape(&item.Style()->font(), item.Direction(), 276 item.shape_result_ = shaper.shape(&item.Style()->font(), item.Direction(),
258 item.StartOffset(), item.EndOffset()); 277 item.StartOffset(), item.EndOffset());
259 } 278 }
260 } 279 }
261 280
262 RefPtr<NGLayoutResult> NGInlineNode::Layout(NGConstraintSpace*, NGBreakToken*) { 281 RefPtr<NGLayoutResult> NGInlineNode::Layout(NGConstraintSpace*, NGBreakToken*) {
263 ASSERT_NOT_REACHED(); 282 ASSERT_NOT_REACHED();
264 return nullptr; 283 return nullptr;
265 } 284 }
266 285
286 void NGInlineNode::LayoutAtomicInlines(
287 const NGConstraintSpace& parent_constraint_space) {
288 NGConstraintSpaceBuilder constraint_space_builder(&parent_constraint_space);
289 constraint_space_builder.SetIsNewFormattingContext(true).SetIsShrinkToFit(
290 true);
291 for (auto& item : items_) {
292 if (item.style_)
293 continue;
294 LayoutObject* layout_object = item.layout_object_;
295 if (layout_object && layout_object->isAtomicInlineLevel() &&
296 !layout_object->isFloatingOrOutOfFlowPositioned() &&
297 (!item.layout_result_ || layout_object->needsLayout())) {
298 NGBlockNode* node = new NGBlockNode(layout_object);
299 const ComputedStyle& style = node->Style();
300 RefPtr<NGConstraintSpace> constraint_space =
301 constraint_space_builder.SetTextDirection(style.direction())
302 .ToConstraintSpace(
303 FromPlatformWritingMode(style.getWritingMode()));
304 item.layout_result_ = node->Layout(constraint_space.get());
305 DCHECK(!layout_object->needsLayout());
306 // TODO(kojii): Figure out what to do with OOF and unpositioned floats.
307 }
308 }
309 }
310
267 void NGInlineNode::LayoutInline(NGConstraintSpace* constraint_space, 311 void NGInlineNode::LayoutInline(NGConstraintSpace* constraint_space,
268 NGLineBuilder* line_builder) { 312 NGLineBuilder* line_builder) {
269 if (!IsPrepareLayoutFinished()) 313 if (!IsPrepareLayoutFinished())
270 PrepareLayout(); 314 PrepareLayout();
271 315
272 if (text_content_.isEmpty()) 316 if (text_content_.isEmpty())
273 return; 317 return;
274 318
319 if (has_atomic_inlines_)
320 LayoutAtomicInlines(*constraint_space);
ikilpatrick 2017/03/15 16:39:41 We need to decide if we are going to support fragm
kojii 2017/03/15 17:30:28 It'd be great if we can, though I acknowledge it's
mstensho (USE GERRIT) 2017/03/16 09:20:14 Lines are monolithic, which means that we shouldn'
321
275 NGTextLayoutAlgorithm(this, constraint_space).LayoutInline(line_builder); 322 NGTextLayoutAlgorithm(this, constraint_space).LayoutInline(line_builder);
276 } 323 }
277 324
278 MinMaxContentSize NGInlineNode::ComputeMinMaxContentSize() { 325 MinMaxContentSize NGInlineNode::ComputeMinMaxContentSize() {
279 // Compute the max of inline sizes of all line boxes with 0 available inline 326 // Compute the max of inline sizes of all line boxes with 0 available inline
280 // size. This gives the min-content, the width where lines wrap at every break 327 // size. This gives the min-content, the width where lines wrap at every break
281 // opportunity. 328 // opportunity.
282 NGWritingMode writing_mode = 329 NGWritingMode writing_mode =
283 FromPlatformWritingMode(BlockStyle()->getWritingMode()); 330 FromPlatformWritingMode(BlockStyle()->getWritingMode());
284 RefPtr<NGConstraintSpace> constraint_space = 331 RefPtr<NGConstraintSpace> constraint_space =
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 Vector<NGLayoutInlineItem>* items, 400 Vector<NGLayoutInlineItem>* items,
354 unsigned start_index, 401 unsigned start_index,
355 unsigned end_index) 402 unsigned end_index)
356 : start_item_(&(*items)[start_index]), 403 : start_item_(&(*items)[start_index]),
357 size_(end_index - start_index), 404 size_(end_index - start_index),
358 start_index_(start_index) { 405 start_index_(start_index) {
359 RELEASE_ASSERT(start_index <= end_index && end_index <= items->size()); 406 RELEASE_ASSERT(start_index <= end_index && end_index <= items->size());
360 } 407 }
361 408
362 } // namespace blink 409 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698