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/api/ng_offset_mapping_builder.h" |
8 #include "core/layout/ng/inline/ng_inline_node.h" | 9 #include "core/layout/ng/inline/ng_inline_node.h" |
9 #include "core/style/ComputedStyle.h" | 10 #include "core/style/ComputedStyle.h" |
10 | 11 |
11 namespace blink { | 12 namespace blink { |
12 | 13 |
13 NGInlineItemsBuilder::~NGInlineItemsBuilder() { | 14 NGInlineItemsBuilder::~NGInlineItemsBuilder() { |
14 DCHECK_EQ(0u, exits_.size()); | 15 DCHECK_EQ(0u, exits_.size()); |
15 DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); | 16 DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); |
16 } | 17 } |
17 | 18 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 unsigned start_offset = text_.length(); | 151 unsigned start_offset = text_.length(); |
151 for (unsigned i = start; i < end;) { | 152 for (unsigned i = start; i < end;) { |
152 UChar c = string[i]; | 153 UChar c = string[i]; |
153 if (c == kNewlineCharacter) { | 154 if (c == kNewlineCharacter) { |
154 // LayoutBR does not set preserve_newline, but should be preserved. | 155 // LayoutBR does not set preserve_newline, but should be preserved. |
155 if (!i && end == 1 && layout_object && layout_object->IsBR()) { | 156 if (!i && end == 1 && layout_object && layout_object->IsBR()) { |
156 AppendForcedBreak(style, layout_object); | 157 AppendForcedBreak(style, layout_object); |
157 return; | 158 return; |
158 } | 159 } |
159 | 160 |
160 if (last_collapsible_space_ == CollapsibleSpace::kNone) | 161 if (last_collapsible_space_ == CollapsibleSpace::kNone) { |
161 text_.Append(kSpaceCharacter); | 162 text_.Append(kSpaceCharacter); |
| 163 if (mapping_builder_) |
| 164 mapping_builder_->AppendBijection(1); |
| 165 } else { |
| 166 if (mapping_builder_) |
| 167 mapping_builder_->AppendCollapsed(1); |
| 168 } |
162 last_collapsible_space_ = CollapsibleSpace::kNewline; | 169 last_collapsible_space_ = CollapsibleSpace::kNewline; |
163 i++; | 170 i++; |
164 continue; | 171 continue; |
165 } | 172 } |
166 | 173 |
167 if (c == kSpaceCharacter || c == kTabulationCharacter) { | 174 if (c == kSpaceCharacter || c == kTabulationCharacter) { |
168 if (last_collapsible_space_ == CollapsibleSpace::kNone) { | 175 if (last_collapsible_space_ == CollapsibleSpace::kNone) { |
169 text_.Append(kSpaceCharacter); | 176 text_.Append(kSpaceCharacter); |
170 last_collapsible_space_ = CollapsibleSpace::kSpace; | 177 last_collapsible_space_ = CollapsibleSpace::kSpace; |
| 178 if (mapping_builder_) |
| 179 mapping_builder_->AppendBijection(1); |
| 180 } else { |
| 181 if (mapping_builder_) |
| 182 mapping_builder_->AppendCollapsed(1); |
171 } | 183 } |
172 i++; | 184 i++; |
173 continue; | 185 continue; |
174 } | 186 } |
175 | 187 |
176 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { | 188 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { |
177 RemoveTrailingCollapsibleNewlineIfNeeded(&start_offset, string, i, style); | 189 RemoveTrailingCollapsibleNewlineIfNeeded(&start_offset, string, i, style); |
178 } | 190 } |
179 | 191 |
180 size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1); | 192 size_t end_of_non_space = string.Find(IsCollapsibleSpace, i + 1); |
181 if (end_of_non_space == kNotFound) | 193 if (end_of_non_space == kNotFound) |
182 end_of_non_space = string.length(); | 194 end_of_non_space = string.length(); |
183 text_.Append(string, i, end_of_non_space - i); | 195 text_.Append(string, i, end_of_non_space - i); |
| 196 if (mapping_builder_) |
| 197 mapping_builder_->AppendBijection(end_of_non_space - i); |
184 i = end_of_non_space; | 198 i = end_of_non_space; |
185 last_collapsible_space_ = CollapsibleSpace::kNone; | 199 last_collapsible_space_ = CollapsibleSpace::kNone; |
186 } | 200 } |
187 | 201 |
188 if (text_.length() > start_offset) { | 202 if (text_.length() > start_offset) { |
189 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, | 203 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, |
190 layout_object); | 204 layout_object); |
191 } | 205 } |
192 } | 206 } |
193 | 207 |
(...skipping 15 matching lines...) Expand all Loading... |
209 if (end == kNotFound) | 223 if (end == kNotFound) |
210 end = string.length(); | 224 end = string.length(); |
211 unsigned start_offset = text_.length(); | 225 unsigned start_offset = text_.length(); |
212 text_.Append(string, start, end - start); | 226 text_.Append(string, start, end - start); |
213 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, | 227 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, |
214 layout_object); | 228 layout_object); |
215 start = end; | 229 start = end; |
216 } | 230 } |
217 | 231 |
218 last_collapsible_space_ = CollapsibleSpace::kNone; | 232 last_collapsible_space_ = CollapsibleSpace::kNone; |
| 233 if (mapping_builder_) |
| 234 mapping_builder_->AppendBijection(string.length()); |
219 } | 235 } |
220 | 236 |
221 void NGInlineItemsBuilder::AppendWithPreservingNewlines( | 237 void NGInlineItemsBuilder::AppendWithPreservingNewlines( |
222 const String& string, | 238 const String& string, |
223 const ComputedStyle* style, | 239 const ComputedStyle* style, |
224 LayoutObject* layout_object) { | 240 LayoutObject* layout_object) { |
225 for (unsigned start = 0; start < string.length();) { | 241 for (unsigned start = 0; start < string.length();) { |
226 if (string[start] == kNewlineCharacter) { | 242 if (string[start] == kNewlineCharacter) { |
227 AppendForcedBreak(style, layout_object); | 243 AppendForcedBreak(style, layout_object); |
228 start++; | 244 start++; |
229 continue; | 245 continue; |
230 } | 246 } |
231 | 247 |
232 size_t end = string.find(kNewlineCharacter, start + 1); | 248 size_t end = string.find(kNewlineCharacter, start + 1); |
233 if (end == kNotFound) | 249 if (end == kNotFound) |
234 end = string.length(); | 250 end = string.length(); |
235 AppendWithWhiteSpaceCollapsing(string, start, end, style, layout_object); | 251 AppendWithWhiteSpaceCollapsing(string, start, end, style, layout_object); |
236 start = end; | 252 start = end; |
237 } | 253 } |
238 } | 254 } |
239 | 255 |
240 void NGInlineItemsBuilder::AppendForcedBreak(const ComputedStyle* style, | 256 void NGInlineItemsBuilder::AppendForcedBreak(const ComputedStyle* style, |
241 LayoutObject* layout_object) { | 257 LayoutObject* layout_object) { |
242 // Remove collapsible spaces immediately before a preserved newline. | 258 // Remove collapsible spaces immediately before a preserved newline. |
243 unsigned start_offset = text_.length(); | 259 unsigned start_offset = text_.length(); |
244 RemoveTrailingCollapsibleSpaceIfExists(&start_offset); | 260 RemoveTrailingCollapsibleSpaceIfExists(&start_offset); |
245 | 261 |
246 Append(NGInlineItem::kControl, kNewlineCharacter, style, layout_object); | 262 Append(NGInlineItem::kControl, kNewlineCharacter, style, layout_object); |
| 263 if (mapping_builder_) |
| 264 mapping_builder_->AppendBijection(1); |
247 | 265 |
248 // Remove collapsible spaces immediately after a preserved newline. | 266 // Remove collapsible spaces immediately after a preserved newline. |
249 last_collapsible_space_ = CollapsibleSpace::kSpace; | 267 last_collapsible_space_ = CollapsibleSpace::kSpace; |
250 } | 268 } |
251 | 269 |
252 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, | 270 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, |
253 UChar character, | 271 UChar character, |
254 const ComputedStyle* style, | 272 const ComputedStyle* style, |
255 LayoutObject* layout_object) { | 273 LayoutObject* layout_object) { |
256 DCHECK_NE(character, kSpaceCharacter); | 274 DCHECK_NE(character, kSpaceCharacter); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace( | 318 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace( |
301 unsigned* next_start_offset) { | 319 unsigned* next_start_offset) { |
302 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); | 320 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); |
303 DCHECK(!text_.IsEmpty()); | 321 DCHECK(!text_.IsEmpty()); |
304 DCHECK_EQ(text_[text_.length() - 1], kSpaceCharacter); | 322 DCHECK_EQ(text_[text_.length() - 1], kSpaceCharacter); |
305 | 323 |
306 unsigned new_size = text_.length() - 1; | 324 unsigned new_size = text_.length() - 1; |
307 text_.Resize(new_size); | 325 text_.Resize(new_size); |
308 last_collapsible_space_ = CollapsibleSpace::kNone; | 326 last_collapsible_space_ = CollapsibleSpace::kNone; |
309 | 327 |
| 328 if (mapping_builder_) |
| 329 mapping_builder_->CollapseLastCharacter(); |
| 330 |
310 if (*next_start_offset <= new_size) | 331 if (*next_start_offset <= new_size) |
311 return; | 332 return; |
312 *next_start_offset = new_size; | 333 *next_start_offset = new_size; |
313 | 334 |
314 // Adjust the last item if the removed space is already appended. | 335 // Adjust the last item if the removed space is already appended. |
315 for (unsigned i = items_->size(); i > 0;) { | 336 for (unsigned i = items_->size(); i > 0;) { |
316 NGInlineItem& item = (*items_)[--i]; | 337 NGInlineItem& item = (*items_)[--i]; |
317 DCHECK_EQ(item.EndOffset(), new_size + 1); | 338 DCHECK_EQ(item.EndOffset(), new_size + 1); |
318 if (item.Type() == NGInlineItem::kText) { | 339 if (item.Type() == NGInlineItem::kText) { |
319 DCHECK_GE(item.Length(), 1u); | 340 DCHECK_GE(item.Length(), 1u); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 } | 443 } |
423 | 444 |
424 void NGInlineItemsBuilder::Exit(LayoutObject* node) { | 445 void NGInlineItemsBuilder::Exit(LayoutObject* node) { |
425 while (!exits_.IsEmpty() && exits_.back().node == node) { | 446 while (!exits_.IsEmpty() && exits_.back().node == node) { |
426 Append(NGInlineItem::kBidiControl, exits_.back().character); | 447 Append(NGInlineItem::kBidiControl, exits_.back().character); |
427 exits_.pop_back(); | 448 exits_.pop_back(); |
428 } | 449 } |
429 } | 450 } |
430 | 451 |
431 } // namespace blink | 452 } // namespace blink |
OLD | NEW |