| 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/layout/ng/inline/ng_offset_mapping_builder.h" |
| 9 #include "core/style/ComputedStyle.h" | 10 #include "core/style/ComputedStyle.h" |
| 10 | 11 |
| 11 namespace blink { | 12 namespace blink { |
| 12 | 13 |
| 13 template <typename OffsetMappingBuilder> | 14 template <typename OffsetMappingBuilder> |
| 14 NGInlineItemsBuilderTemplate< | 15 NGInlineItemsBuilderTemplate< |
| 15 OffsetMappingBuilder>::~NGInlineItemsBuilderTemplate() { | 16 OffsetMappingBuilder>::~NGInlineItemsBuilderTemplate() { |
| 16 DCHECK_EQ(0u, exits_.size()); | 17 DCHECK_EQ(0u, exits_.size()); |
| 17 DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); | 18 DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); |
| 18 } | 19 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 unsigned start_offset = text_.length(); | 156 unsigned start_offset = text_.length(); |
| 156 for (unsigned i = start; i < end;) { | 157 for (unsigned i = start; i < end;) { |
| 157 UChar c = string[i]; | 158 UChar c = string[i]; |
| 158 if (c == kNewlineCharacter) { | 159 if (c == kNewlineCharacter) { |
| 159 // LayoutBR does not set preserve_newline, but should be preserved. | 160 // LayoutBR does not set preserve_newline, but should be preserved. |
| 160 if (!i && end == 1 && layout_object && layout_object->IsBR()) { | 161 if (!i && end == 1 && layout_object && layout_object->IsBR()) { |
| 161 AppendForcedBreak(style, layout_object); | 162 AppendForcedBreak(style, layout_object); |
| 162 return; | 163 return; |
| 163 } | 164 } |
| 164 | 165 |
| 165 if (last_collapsible_space_ == CollapsibleSpace::kNone) | 166 if (last_collapsible_space_ == CollapsibleSpace::kNone) { |
| 166 text_.Append(kSpaceCharacter); | 167 text_.Append(kSpaceCharacter); |
| 168 mapping_builder_.AppendIdentityMapping(1); |
| 169 } else { |
| 170 mapping_builder_.AppendCollapsedMapping(1); |
| 171 } |
| 167 last_collapsible_space_ = CollapsibleSpace::kNewline; | 172 last_collapsible_space_ = CollapsibleSpace::kNewline; |
| 168 i++; | 173 i++; |
| 169 continue; | 174 continue; |
| 170 } | 175 } |
| 171 | 176 |
| 172 if (c == kSpaceCharacter || c == kTabulationCharacter) { | 177 if (c == kSpaceCharacter || c == kTabulationCharacter) { |
| 173 if (last_collapsible_space_ == CollapsibleSpace::kNone) { | 178 if (last_collapsible_space_ == CollapsibleSpace::kNone) { |
| 174 text_.Append(kSpaceCharacter); | 179 text_.Append(kSpaceCharacter); |
| 175 last_collapsible_space_ = CollapsibleSpace::kSpace; | 180 last_collapsible_space_ = CollapsibleSpace::kSpace; |
| 181 mapping_builder_.AppendIdentityMapping(1); |
| 182 } else { |
| 183 mapping_builder_.AppendCollapsedMapping(1); |
| 176 } | 184 } |
| 177 i++; | 185 i++; |
| 178 continue; | 186 continue; |
| 179 } | 187 } |
| 180 | 188 |
| 181 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { | 189 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { |
| 182 RemoveTrailingCollapsibleNewlineIfNeeded(string, i, style); | 190 RemoveTrailingCollapsibleNewlineIfNeeded(string, i, style); |
| 183 start_offset = std::min(start_offset, text_.length()); | 191 start_offset = std::min(start_offset, text_.length()); |
| 184 } | 192 } |
| 185 | 193 |
| 186 size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1); | 194 size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1); |
| 187 if (end_of_non_space == kNotFound) | 195 if (end_of_non_space == kNotFound) |
| 188 end_of_non_space = string.length(); | 196 end_of_non_space = string.length(); |
| 189 text_.Append(string, i, end_of_non_space - i); | 197 text_.Append(string, i, end_of_non_space - i); |
| 198 mapping_builder_.AppendIdentityMapping(end_of_non_space - i); |
| 190 i = end_of_non_space; | 199 i = end_of_non_space; |
| 191 last_collapsible_space_ = CollapsibleSpace::kNone; | 200 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 192 } | 201 } |
| 193 | 202 |
| 194 if (text_.length() > start_offset) { | 203 if (text_.length() > start_offset) { |
| 195 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, | 204 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, |
| 196 layout_object); | 205 layout_object); |
| 197 } | 206 } |
| 198 } | 207 } |
| 199 | 208 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 210 Append(NGInlineItem::kControl, c, style, layout_object); | 219 Append(NGInlineItem::kControl, c, style, layout_object); |
| 211 start++; | 220 start++; |
| 212 continue; | 221 continue; |
| 213 } | 222 } |
| 214 | 223 |
| 215 size_t end = string.Find(IsControlItemCharacter, start + 1); | 224 size_t end = string.Find(IsControlItemCharacter, start + 1); |
| 216 if (end == kNotFound) | 225 if (end == kNotFound) |
| 217 end = string.length(); | 226 end = string.length(); |
| 218 unsigned start_offset = text_.length(); | 227 unsigned start_offset = text_.length(); |
| 219 text_.Append(string, start, end - start); | 228 text_.Append(string, start, end - start); |
| 229 mapping_builder_.AppendIdentityMapping(end - start); |
| 220 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, | 230 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, |
| 221 layout_object); | 231 layout_object); |
| 222 start = end; | 232 start = end; |
| 223 } | 233 } |
| 224 | 234 |
| 225 last_collapsible_space_ = CollapsibleSpace::kNone; | 235 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 226 } | 236 } |
| 227 | 237 |
| 228 template <typename OffsetMappingBuilder> | 238 template <typename OffsetMappingBuilder> |
| 229 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: | 239 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 template <typename OffsetMappingBuilder> | 271 template <typename OffsetMappingBuilder> |
| 262 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append( | 272 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append( |
| 263 NGInlineItem::NGInlineItemType type, | 273 NGInlineItem::NGInlineItemType type, |
| 264 UChar character, | 274 UChar character, |
| 265 const ComputedStyle* style, | 275 const ComputedStyle* style, |
| 266 LayoutObject* layout_object) { | 276 LayoutObject* layout_object) { |
| 267 DCHECK_NE(character, kSpaceCharacter); | 277 DCHECK_NE(character, kSpaceCharacter); |
| 268 DCHECK_NE(character, kZeroWidthSpaceCharacter); | 278 DCHECK_NE(character, kZeroWidthSpaceCharacter); |
| 269 | 279 |
| 270 text_.Append(character); | 280 text_.Append(character); |
| 281 mapping_builder_.AppendIdentityMapping(1); |
| 271 unsigned end_offset = text_.length(); | 282 unsigned end_offset = text_.length(); |
| 272 AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object); | 283 AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object); |
| 273 last_collapsible_space_ = CollapsibleSpace::kNone; | 284 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 274 } | 285 } |
| 275 | 286 |
| 276 template <typename OffsetMappingBuilder> | 287 template <typename OffsetMappingBuilder> |
| 277 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( | 288 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( |
| 278 NGInlineItem::NGInlineItemType type, | 289 NGInlineItem::NGInlineItemType type, |
| 279 UChar character) { | 290 UChar character) { |
| 280 text_.Append(character); | 291 text_.Append(character); |
| 292 mapping_builder_.AppendIdentityMapping(1); |
| 281 unsigned end_offset = text_.length(); | 293 unsigned end_offset = text_.length(); |
| 282 AppendItem(items_, type, end_offset - 1, end_offset, nullptr, nullptr); | 294 AppendItem(items_, type, end_offset - 1, end_offset, nullptr, nullptr); |
| 283 } | 295 } |
| 284 | 296 |
| 285 template <typename OffsetMappingBuilder> | 297 template <typename OffsetMappingBuilder> |
| 286 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( | 298 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendOpaque( |
| 287 NGInlineItem::NGInlineItemType type, | 299 NGInlineItem::NGInlineItemType type, |
| 288 const ComputedStyle* style, | 300 const ComputedStyle* style, |
| 289 LayoutObject* layout_object) { | 301 LayoutObject* layout_object) { |
| 290 unsigned end_offset = text_.length(); | 302 unsigned end_offset = text_.length(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 // Removes the collapsible space at the specified index. | 353 // Removes the collapsible space at the specified index. |
| 342 template <typename OffsetMappingBuilder> | 354 template <typename OffsetMappingBuilder> |
| 343 void NGInlineItemsBuilderTemplate< | 355 void NGInlineItemsBuilderTemplate< |
| 344 OffsetMappingBuilder>::RemoveTrailingCollapsibleSpace(unsigned index) { | 356 OffsetMappingBuilder>::RemoveTrailingCollapsibleSpace(unsigned index) { |
| 345 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); | 357 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); |
| 346 DCHECK(!text_.IsEmpty()); | 358 DCHECK(!text_.IsEmpty()); |
| 347 DCHECK_EQ(text_[index], kSpaceCharacter); | 359 DCHECK_EQ(text_[index], kSpaceCharacter); |
| 348 | 360 |
| 349 text_.erase(index); | 361 text_.erase(index); |
| 350 last_collapsible_space_ = CollapsibleSpace::kNone; | 362 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 363 mapping_builder_.CollapseTrailingSpace(text_.length() - index); |
| 351 | 364 |
| 352 // Adjust items if the removed space is already included. | 365 // Adjust items if the removed space is already included. |
| 353 for (unsigned i = items_->size(); i > 0;) { | 366 for (unsigned i = items_->size(); i > 0;) { |
| 354 NGInlineItem& item = (*items_)[--i]; | 367 NGInlineItem& item = (*items_)[--i]; |
| 355 if (index >= item.EndOffset()) | 368 if (index >= item.EndOffset()) |
| 356 return; | 369 return; |
| 357 if (item.StartOffset() <= index) { | 370 if (item.StartOffset() <= index) { |
| 358 if (item.Length() == 1) { | 371 if (item.Length() == 1) { |
| 359 DCHECK_EQ(item.StartOffset(), index); | 372 DCHECK_EQ(item.StartOffset(), index); |
| 360 DCHECK_EQ(item.Type(), NGInlineItem::kText); | 373 DCHECK_EQ(item.Type(), NGInlineItem::kText); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Exit( | 488 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Exit( |
| 476 LayoutObject* node) { | 489 LayoutObject* node) { |
| 477 while (!exits_.IsEmpty() && exits_.back().node == node) { | 490 while (!exits_.IsEmpty() && exits_.back().node == node) { |
| 478 AppendOpaque(NGInlineItem::kBidiControl, exits_.back().character); | 491 AppendOpaque(NGInlineItem::kBidiControl, exits_.back().character); |
| 479 exits_.pop_back(); | 492 exits_.pop_back(); |
| 480 } | 493 } |
| 481 } | 494 } |
| 482 | 495 |
| 483 template class CORE_TEMPLATE_EXPORT | 496 template class CORE_TEMPLATE_EXPORT |
| 484 NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; | 497 NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; |
| 498 template class CORE_TEMPLATE_EXPORT |
| 499 NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>; |
| 485 | 500 |
| 486 } // namespace blink | 501 } // namespace blink |
| OLD | NEW |