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 |