Chromium Code Reviews| 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_items_builder.h" | 5 #include "core/layout/ng/inline/ng_inline_items_builder.h" |
| 6 | 6 |
| 7 #include "core/layout/LayoutObject.h" | 7 #include "core/layout/LayoutObject.h" |
| 8 #include "core/layout/ng/inline/ng_inline_node.h" | 8 #include "core/layout/ng/inline/ng_inline_node.h" |
| 9 #include "core/style/ComputedStyle.h" | 9 #include "core/style/ComputedStyle.h" |
| 10 | 10 |
| 11 namespace blink { | 11 namespace blink { |
| 12 | 12 |
| 13 NGInlineItemsBuilder::NGInlineItemsBuilder( | |
| 14 Vector<NGInlineItem>* items, | |
| 15 Vector<Vector<unsigned>>* removed_indexes) | |
| 16 : items_(items), | |
| 17 removed_indexes_(removed_indexes), | |
| 18 input_strings_lengths_(Vector<unsigned>()) { | |
| 19 DCHECK(removed_indexes); | |
| 20 } | |
| 21 | |
| 13 NGInlineItemsBuilder::~NGInlineItemsBuilder() { | 22 NGInlineItemsBuilder::~NGInlineItemsBuilder() { |
| 14 DCHECK_EQ(0u, exits_.size()); | 23 DCHECK_EQ(0u, exits_.size()); |
| 15 DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); | 24 DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); |
| 16 } | 25 } |
| 17 | 26 |
| 18 String NGInlineItemsBuilder::ToString() { | 27 String NGInlineItemsBuilder::ToString() { |
| 19 // Segment Break Transformation Rules[1] defines to keep trailing new lines, | 28 // Segment Break Transformation Rules[1] defines to keep trailing new lines, |
| 20 // but it will be removed in Phase II[2]. We prefer not to add trailing new | 29 // but it will be removed in Phase II[2]. We prefer not to add trailing new |
| 21 // lines and collapsible spaces in Phase I. | 30 // lines and collapsible spaces in Phase I. |
| 22 // [1] https://drafts.csswg.org/css-text-3/#line-break-transform | 31 // [1] https://drafts.csswg.org/css-text-3/#line-break-transform |
| 23 // [2] https://drafts.csswg.org/css-text-3/#white-space-phase-2 | 32 // [2] https://drafts.csswg.org/css-text-3/#white-space-phase-2 |
| 24 unsigned next_start_offset = text_.length(); | 33 unsigned next_start_offset = text_.length(); |
| 25 RemoveTrailingCollapsibleSpaceIfExists(&next_start_offset); | 34 bool trailing_space_removed = |
| 35 RemoveTrailingCollapsibleSpaceIfExists(&next_start_offset); | |
| 36 if (trailing_space_removed && removed_indexes_) { | |
| 37 DCHECK(input_strings_lengths_); | |
| 38 AddLastTrailingSpaceToRemovedIndexes(input_strings_lengths_->back()); | |
| 39 } | |
| 26 | 40 |
| 27 return text_.ToString(); | 41 return text_.ToString(); |
| 28 } | 42 } |
| 29 | 43 |
| 30 // Determine "Ambiguous" East Asian Width is Wide or Narrow. | 44 // Determine "Ambiguous" East Asian Width is Wide or Narrow. |
| 31 // Unicode East Asian Width | 45 // Unicode East Asian Width |
| 32 // http://unicode.org/reports/tr11/ | 46 // http://unicode.org/reports/tr11/ |
| 33 static bool IsAmbiguosEastAsianWidthWide(const ComputedStyle* style) { | 47 static bool IsAmbiguosEastAsianWidthWide(const ComputedStyle* style) { |
| 34 UScriptCode script = style->GetFontDescription().GetScript(); | 48 UScriptCode script = style->GetFontDescription().GetScript(); |
| 35 return script == USCRIPT_KATAKANA_OR_HIRAGANA || | 49 return script == USCRIPT_KATAKANA_OR_HIRAGANA || |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 return c == kSpaceCharacter || c == kTabulationCharacter || | 131 return c == kSpaceCharacter || c == kTabulationCharacter || |
| 118 c == kNewlineCharacter; | 132 c == kNewlineCharacter; |
| 119 } | 133 } |
| 120 | 134 |
| 121 // Characters needing a separate control item than other text items. | 135 // Characters needing a separate control item than other text items. |
| 122 // It makes the line breaker easier to handle. | 136 // It makes the line breaker easier to handle. |
| 123 static inline bool IsControlItemCharacter(UChar c) { | 137 static inline bool IsControlItemCharacter(UChar c) { |
| 124 return c == kTabulationCharacter || c == kNewlineCharacter; | 138 return c == kTabulationCharacter || c == kNewlineCharacter; |
| 125 } | 139 } |
| 126 | 140 |
| 141 // Returns the largest integer in [0, |max|) that is absent in |integers|, or | |
| 142 // kNotFound if such an integer does not exist. | |
| 143 static size_t GetLargestAbsentInteger(const Vector<unsigned>& integers, | |
| 144 unsigned max) { | |
| 145 DCHECK(integers.IsEmpty() || integers.back() < max); | |
| 146 if (!max || integers.size() == max) | |
| 147 return kNotFound; | |
| 148 if (integers.IsEmpty() || integers.back() + 1 < max) | |
| 149 return max - 1; | |
| 150 for (unsigned i = integers.size() - 1; i;) { | |
| 151 DCHECK_LT(integers[i - 1], integers[i]); | |
| 152 if (integers[i - 1] + 1 < integers[i] - 1) | |
| 153 return integers[i] - 1; | |
| 154 --i; | |
| 155 } | |
| 156 DCHECK_GT(integers[0], 0u); | |
| 157 return integers[0] - 1; | |
| 158 } | |
| 159 | |
| 127 void NGInlineItemsBuilder::Append(const String& string, | 160 void NGInlineItemsBuilder::Append(const String& string, |
| 128 const ComputedStyle* style, | 161 const ComputedStyle* style, |
| 129 LayoutObject* layout_object) { | 162 LayoutObject* layout_object) { |
| 163 if (removed_indexes_) { | |
| 164 DCHECK(input_strings_lengths_); | |
| 165 input_strings_lengths_->push_back(string.length()); | |
| 166 removed_indexes_->emplace_back(); | |
| 167 } | |
| 168 | |
| 130 if (string.IsEmpty()) | 169 if (string.IsEmpty()) |
| 131 return; | 170 return; |
| 132 text_.ReserveCapacity(string.length()); | 171 text_.ReserveCapacity(string.length()); |
| 133 | 172 |
| 134 EWhiteSpace whitespace = style->WhiteSpace(); | 173 EWhiteSpace whitespace = style->WhiteSpace(); |
| 135 if (!ComputedStyle::CollapseWhiteSpace(whitespace)) | 174 if (!ComputedStyle::CollapseWhiteSpace(whitespace)) |
| 136 return AppendWithoutWhiteSpaceCollapsing(string, style, layout_object); | 175 return AppendWithoutWhiteSpaceCollapsing(string, style, layout_object); |
| 137 if (ComputedStyle::PreserveNewline(whitespace) && !is_svgtext_) | 176 if (ComputedStyle::PreserveNewline(whitespace) && !is_svgtext_) |
| 138 return AppendWithPreservingNewlines(string, style, layout_object); | 177 return AppendWithPreservingNewlines(string, style, layout_object); |
| 139 | 178 |
| 140 AppendWithWhiteSpaceCollapsing(string, 0, string.length(), style, | 179 AppendWithWhiteSpaceCollapsing(string, 0, string.length(), style, |
| 141 layout_object); | 180 layout_object); |
| 142 } | 181 } |
| 143 | 182 |
| 144 void NGInlineItemsBuilder::AppendWithWhiteSpaceCollapsing( | 183 void NGInlineItemsBuilder::AppendWithWhiteSpaceCollapsing( |
| 145 const String& string, | 184 const String& string, |
| 146 unsigned start, | 185 unsigned start, |
| 147 unsigned end, | 186 unsigned end, |
| 148 const ComputedStyle* style, | 187 const ComputedStyle* style, |
| 149 LayoutObject* layout_object) { | 188 LayoutObject* layout_object) { |
| 150 unsigned start_offset = text_.length(); | 189 unsigned start_offset = text_.length(); |
| 151 for (unsigned i = start; i < end;) { | 190 for (unsigned i = start; i < end;) { |
| 152 UChar c = string[i]; | 191 UChar c = string[i]; |
| 153 if (c == kNewlineCharacter) { | 192 if (c == kNewlineCharacter) { |
| 154 // LayoutBR does not set preserve_newline, but should be preserved. | 193 // LayoutBR does not set preserve_newline, but should be preserved. |
| 155 if (!i && end == 1 && layout_object && layout_object->IsBR()) { | 194 if (!i && end == 1 && layout_object && layout_object->IsBR()) { |
| 156 AppendForcedBreak(style, layout_object); | 195 bool trailing_space_removed = AppendForcedBreak(style, layout_object); |
| 196 if (trailing_space_removed && removed_indexes_) | |
| 197 AddLastTrailingSpaceToRemovedIndexes(i); | |
|
kojii
2017/06/19 05:56:33
Why don't we add to removed_indexes in RemoveTrail
Xiaocheng
2017/06/19 17:53:01
Updating |removed_indexes_| needs the number of ch
| |
| 157 return; | 198 return; |
| 158 } | 199 } |
| 159 | 200 |
| 160 if (last_collapsible_space_ == CollapsibleSpace::kNone) | 201 if (last_collapsible_space_ == CollapsibleSpace::kNone) |
| 161 text_.Append(kSpaceCharacter); | 202 text_.Append(kSpaceCharacter); |
| 203 else if (removed_indexes_) | |
| 204 removed_indexes_->back().push_back(i); | |
| 162 last_collapsible_space_ = CollapsibleSpace::kNewline; | 205 last_collapsible_space_ = CollapsibleSpace::kNewline; |
| 163 i++; | 206 i++; |
| 164 continue; | 207 continue; |
| 165 } | 208 } |
| 166 | 209 |
| 167 if (c == kSpaceCharacter || c == kTabulationCharacter) { | 210 if (c == kSpaceCharacter || c == kTabulationCharacter) { |
| 168 if (last_collapsible_space_ == CollapsibleSpace::kNone) { | 211 if (last_collapsible_space_ == CollapsibleSpace::kNone) { |
| 169 text_.Append(kSpaceCharacter); | 212 text_.Append(kSpaceCharacter); |
| 170 last_collapsible_space_ = CollapsibleSpace::kSpace; | 213 last_collapsible_space_ = CollapsibleSpace::kSpace; |
| 214 } else if (removed_indexes_) { | |
| 215 removed_indexes_->back().push_back(i); | |
| 171 } | 216 } |
| 172 i++; | 217 i++; |
| 173 continue; | 218 continue; |
| 174 } | 219 } |
| 175 | 220 |
| 176 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { | 221 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { |
| 177 RemoveTrailingCollapsibleNewlineIfNeeded(&start_offset, string, i, style); | 222 bool trailing_newline_removed = RemoveTrailingCollapsibleNewlineIfNeeded( |
| 223 &start_offset, string, i, style); | |
| 224 if (trailing_newline_removed && removed_indexes_) | |
| 225 AddLastTrailingSpaceToRemovedIndexes(i); | |
| 178 } | 226 } |
| 179 | 227 |
| 180 size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1); | 228 size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1); |
| 181 if (end_of_non_space == kNotFound) | 229 if (end_of_non_space == kNotFound) |
| 182 end_of_non_space = string.length(); | 230 end_of_non_space = string.length(); |
| 183 text_.Append(string, i, end_of_non_space - i); | 231 text_.Append(string, i, end_of_non_space - i); |
| 184 i = end_of_non_space; | 232 i = end_of_non_space; |
| 185 last_collapsible_space_ = CollapsibleSpace::kNone; | 233 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 186 } | 234 } |
| 187 | 235 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 217 | 265 |
| 218 last_collapsible_space_ = CollapsibleSpace::kNone; | 266 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 219 } | 267 } |
| 220 | 268 |
| 221 void NGInlineItemsBuilder::AppendWithPreservingNewlines( | 269 void NGInlineItemsBuilder::AppendWithPreservingNewlines( |
| 222 const String& string, | 270 const String& string, |
| 223 const ComputedStyle* style, | 271 const ComputedStyle* style, |
| 224 LayoutObject* layout_object) { | 272 LayoutObject* layout_object) { |
| 225 for (unsigned start = 0; start < string.length();) { | 273 for (unsigned start = 0; start < string.length();) { |
| 226 if (string[start] == kNewlineCharacter) { | 274 if (string[start] == kNewlineCharacter) { |
| 227 AppendForcedBreak(style, layout_object); | 275 bool trailing_space_removed = AppendForcedBreak(style, layout_object); |
| 276 if (trailing_space_removed && removed_indexes_) | |
| 277 AddLastTrailingSpaceToRemovedIndexes(start); | |
| 228 start++; | 278 start++; |
| 229 continue; | 279 continue; |
| 230 } | 280 } |
| 231 | 281 |
| 232 size_t end = string.find(kNewlineCharacter, start + 1); | 282 size_t end = string.find(kNewlineCharacter, start + 1); |
| 233 if (end == kNotFound) | 283 if (end == kNotFound) |
| 234 end = string.length(); | 284 end = string.length(); |
| 235 AppendWithWhiteSpaceCollapsing(string, start, end, style, layout_object); | 285 AppendWithWhiteSpaceCollapsing(string, start, end, style, layout_object); |
| 236 start = end; | 286 start = end; |
| 237 } | 287 } |
| 238 } | 288 } |
| 239 | 289 |
| 240 void NGInlineItemsBuilder::AppendForcedBreak(const ComputedStyle* style, | 290 bool NGInlineItemsBuilder::AppendForcedBreak(const ComputedStyle* style, |
| 241 LayoutObject* layout_object) { | 291 LayoutObject* layout_object) { |
| 242 // Remove collapsible spaces immediately before a preserved newline. | 292 // Remove collapsible spaces immediately before a preserved newline. |
| 243 unsigned start_offset = text_.length(); | 293 unsigned start_offset = text_.length(); |
| 244 RemoveTrailingCollapsibleSpaceIfExists(&start_offset); | 294 bool trailing_space_removed = |
| 295 RemoveTrailingCollapsibleSpaceIfExists(&start_offset); | |
| 245 | 296 |
| 246 Append(NGInlineItem::kControl, kNewlineCharacter, style, layout_object); | 297 Append(NGInlineItem::kControl, kNewlineCharacter, style, layout_object); |
| 247 | 298 |
| 248 // Remove collapsible spaces immediately after a preserved newline. | 299 // Remove collapsible spaces immediately after a preserved newline. |
| 249 last_collapsible_space_ = CollapsibleSpace::kSpace; | 300 last_collapsible_space_ = CollapsibleSpace::kSpace; |
| 301 return trailing_space_removed; | |
| 250 } | 302 } |
| 251 | 303 |
| 252 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, | 304 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, |
| 253 UChar character, | 305 UChar character, |
| 254 const ComputedStyle* style, | 306 const ComputedStyle* style, |
| 255 LayoutObject* layout_object) { | 307 LayoutObject* layout_object) { |
| 256 DCHECK_NE(character, kSpaceCharacter); | 308 DCHECK_NE(character, kSpaceCharacter); |
| 257 DCHECK_NE(character, kZeroWidthSpaceCharacter); | 309 DCHECK_NE(character, kZeroWidthSpaceCharacter); |
| 258 | 310 |
| 259 text_.Append(character); | 311 text_.Append(character); |
| 260 unsigned end_offset = text_.length(); | 312 unsigned end_offset = text_.length(); |
| 261 AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object); | 313 AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object); |
| 262 last_collapsible_space_ = CollapsibleSpace::kNone; | 314 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 263 } | 315 } |
| 264 | 316 |
| 265 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, | 317 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, |
| 266 const ComputedStyle* style, | 318 const ComputedStyle* style, |
| 267 LayoutObject* layout_object) { | 319 LayoutObject* layout_object) { |
| 268 unsigned end_offset = text_.length(); | 320 unsigned end_offset = text_.length(); |
| 269 AppendItem(items_, type, end_offset, end_offset, style, layout_object); | 321 AppendItem(items_, type, end_offset, end_offset, style, layout_object); |
| 270 } | 322 } |
| 271 | 323 |
| 272 void NGInlineItemsBuilder::RemoveTrailingCollapsibleNewlineIfNeeded( | 324 bool NGInlineItemsBuilder::RemoveTrailingCollapsibleNewlineIfNeeded( |
| 273 unsigned* next_start_offset, | 325 unsigned* next_start_offset, |
| 274 const String& after, | 326 const String& after, |
| 275 unsigned after_index, | 327 unsigned after_index, |
| 276 const ComputedStyle* after_style) { | 328 const ComputedStyle* after_style) { |
| 277 DCHECK_EQ(last_collapsible_space_, CollapsibleSpace::kNewline); | 329 DCHECK_EQ(last_collapsible_space_, CollapsibleSpace::kNewline); |
| 278 | 330 |
| 279 if (text_.IsEmpty() || text_[text_.length() - 1] != kSpaceCharacter) | 331 if (text_.IsEmpty() || text_[text_.length() - 1] != kSpaceCharacter) |
| 280 return; | 332 return false; |
| 281 | 333 |
| 282 const ComputedStyle* before_style = after_style; | 334 const ComputedStyle* before_style = after_style; |
| 283 if (!items_->IsEmpty()) { | 335 if (!items_->IsEmpty()) { |
| 284 NGInlineItem& item = items_->back(); | 336 NGInlineItem& item = items_->back(); |
| 285 if (text_.length() < item.EndOffset() + 2) | 337 if (text_.length() < item.EndOffset() + 2) |
| 286 before_style = item.Style(); | 338 before_style = item.Style(); |
| 287 } | 339 } |
| 288 | 340 |
| 289 if (ShouldRemoveNewline(text_, before_style, after, after_index, after_style)) | 341 if (!ShouldRemoveNewline(text_, before_style, after, after_index, |
| 290 RemoveTrailingCollapsibleSpace(next_start_offset); | 342 after_style)) |
| 343 return false; | |
| 344 RemoveTrailingCollapsibleSpace(next_start_offset); | |
| 345 return true; | |
| 291 } | 346 } |
| 292 | 347 |
| 293 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpaceIfExists( | 348 bool NGInlineItemsBuilder::RemoveTrailingCollapsibleSpaceIfExists( |
| 294 unsigned* next_start_offset) { | 349 unsigned* next_start_offset) { |
| 295 if (last_collapsible_space_ != CollapsibleSpace::kNone && !text_.IsEmpty() && | 350 if (last_collapsible_space_ == CollapsibleSpace::kNone || text_.IsEmpty() || |
| 296 text_[text_.length() - 1] == kSpaceCharacter) | 351 text_[text_.length() - 1] != kSpaceCharacter) |
| 297 RemoveTrailingCollapsibleSpace(next_start_offset); | 352 return false; |
| 353 RemoveTrailingCollapsibleSpace(next_start_offset); | |
| 354 return true; | |
| 298 } | 355 } |
| 299 | 356 |
| 300 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace( | 357 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace( |
| 301 unsigned* next_start_offset) { | 358 unsigned* next_start_offset) { |
| 302 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); | 359 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); |
| 303 DCHECK(!text_.IsEmpty()); | 360 DCHECK(!text_.IsEmpty()); |
| 304 DCHECK_EQ(text_[text_.length() - 1], kSpaceCharacter); | 361 DCHECK_EQ(text_[text_.length() - 1], kSpaceCharacter); |
| 305 | 362 |
| 306 unsigned new_size = text_.length() - 1; | 363 unsigned new_size = text_.length() - 1; |
| 307 text_.Resize(new_size); | 364 text_.Resize(new_size); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 326 if (!item.Length()) { | 383 if (!item.Length()) { |
| 327 // Trailing spaces can be removed across non-character items. | 384 // Trailing spaces can be removed across non-character items. |
| 328 item.SetOffset(new_size, new_size); | 385 item.SetOffset(new_size, new_size); |
| 329 continue; | 386 continue; |
| 330 } | 387 } |
| 331 NOTREACHED(); | 388 NOTREACHED(); |
| 332 break; | 389 break; |
| 333 } | 390 } |
| 334 } | 391 } |
| 335 | 392 |
| 393 void NGInlineItemsBuilder::AddLastTrailingSpaceToRemovedIndexes( | |
| 394 unsigned last_string_end) { | |
| 395 DCHECK(removed_indexes_); | |
| 396 DCHECK(input_strings_lengths_); | |
| 397 DCHECK_EQ(removed_indexes_->size(), input_strings_lengths_->size()); | |
| 398 for (unsigned i = removed_indexes_->size(); i;) { | |
| 399 Vector<unsigned>& indexes = (*removed_indexes_)[--i]; | |
| 400 size_t last_unremoved = | |
| 401 GetLargestAbsentInteger(indexes, (i + 1) == removed_indexes_->size() | |
| 402 ? last_string_end | |
| 403 : (*input_strings_lengths_)[i]); | |
| 404 if (last_unremoved == kNotFound) | |
| 405 continue; | |
| 406 | |
| 407 indexes.insert( | |
| 408 std::lower_bound(indexes.begin(), indexes.end(), last_unremoved) - | |
| 409 indexes.begin(), | |
| 410 last_unremoved); | |
| 411 return; | |
| 412 } | |
| 413 NOTREACHED(); | |
| 414 } | |
| 415 | |
| 336 void NGInlineItemsBuilder::AppendBidiControl(const ComputedStyle* style, | 416 void NGInlineItemsBuilder::AppendBidiControl(const ComputedStyle* style, |
| 337 UChar ltr, | 417 UChar ltr, |
| 338 UChar rtl) { | 418 UChar rtl) { |
| 339 Append(NGInlineItem::kBidiControl, | 419 Append(NGInlineItem::kBidiControl, |
| 340 style->Direction() == TextDirection::kRtl ? rtl : ltr); | 420 style->Direction() == TextDirection::kRtl ? rtl : ltr); |
| 341 } | 421 } |
| 342 | 422 |
| 343 void NGInlineItemsBuilder::EnterBlock(const ComputedStyle* style) { | 423 void NGInlineItemsBuilder::EnterBlock(const ComputedStyle* style) { |
| 344 // Handle bidi-override on the block itself. | 424 // Handle bidi-override on the block itself. |
| 345 switch (style->GetUnicodeBidi()) { | 425 switch (style->GetUnicodeBidi()) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 } | 502 } |
| 423 | 503 |
| 424 void NGInlineItemsBuilder::Exit(LayoutObject* node) { | 504 void NGInlineItemsBuilder::Exit(LayoutObject* node) { |
| 425 while (!exits_.IsEmpty() && exits_.back().node == node) { | 505 while (!exits_.IsEmpty() && exits_.back().node == node) { |
| 426 Append(NGInlineItem::kBidiControl, exits_.back().character); | 506 Append(NGInlineItem::kBidiControl, exits_.back().character); |
| 427 exits_.pop_back(); | 507 exits_.pop_back(); |
| 428 } | 508 } |
| 429 } | 509 } |
| 430 | 510 |
| 431 } // namespace blink | 511 } // namespace blink |
| OLD | NEW |