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

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

Issue 2943573002: Make NGInlineItemsBuilder construct whitespace-collapsed offset mapping (Closed)
Patch Set: Tue Jun 27 15:22:36 PDT 2017 Created 3 years, 5 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/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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 unsigned start_offset = text_.length(); 150 unsigned start_offset = text_.length();
150 for (unsigned i = start; i < end;) { 151 for (unsigned i = start; i < end;) {
151 UChar c = string[i]; 152 UChar c = string[i];
152 if (c == kNewlineCharacter) { 153 if (c == kNewlineCharacter) {
153 // LayoutBR does not set preserve_newline, but should be preserved. 154 // LayoutBR does not set preserve_newline, but should be preserved.
154 if (!i && end == 1 && layout_object && layout_object->IsBR()) { 155 if (!i && end == 1 && layout_object && layout_object->IsBR()) {
155 AppendForcedBreak(style, layout_object); 156 AppendForcedBreak(style, layout_object);
156 return; 157 return;
157 } 158 }
158 159
159 if (last_collapsible_space_ == CollapsibleSpace::kNone) 160 if (last_collapsible_space_ == CollapsibleSpace::kNone) {
160 text_.Append(kSpaceCharacter); 161 text_.Append(kSpaceCharacter);
162 if (mapping_builder_)
163 mapping_builder_->AppendIdentityMapping(1);
164 } else {
165 if (mapping_builder_)
166 mapping_builder_->AppendCollapsedMapping(1);
167 }
161 last_collapsible_space_ = CollapsibleSpace::kNewline; 168 last_collapsible_space_ = CollapsibleSpace::kNewline;
162 i++; 169 i++;
163 continue; 170 continue;
164 } 171 }
165 172
166 if (c == kSpaceCharacter || c == kTabulationCharacter) { 173 if (c == kSpaceCharacter || c == kTabulationCharacter) {
167 if (last_collapsible_space_ == CollapsibleSpace::kNone) { 174 if (last_collapsible_space_ == CollapsibleSpace::kNone) {
168 text_.Append(kSpaceCharacter); 175 text_.Append(kSpaceCharacter);
169 last_collapsible_space_ = CollapsibleSpace::kSpace; 176 last_collapsible_space_ = CollapsibleSpace::kSpace;
177 if (mapping_builder_)
178 mapping_builder_->AppendIdentityMapping(1);
179 } else {
180 if (mapping_builder_)
181 mapping_builder_->AppendCollapsedMapping(1);
170 } 182 }
171 i++; 183 i++;
172 continue; 184 continue;
173 } 185 }
174 186
175 if (last_collapsible_space_ == CollapsibleSpace::kNewline) { 187 if (last_collapsible_space_ == CollapsibleSpace::kNewline) {
176 RemoveTrailingCollapsibleNewlineIfNeeded(string, i, style); 188 RemoveTrailingCollapsibleNewlineIfNeeded(string, i, style);
177 start_offset = std::min(start_offset, text_.length()); 189 start_offset = std::min(start_offset, text_.length());
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_->AppendIdentityMapping(end_of_non_space - i);
yosin_UTC9 2017/06/28 01:44:21 So, do we call mapping builder for every word?
Xiaocheng 2017/06/28 02:05:20 Yes. To decouple the mapping builder with impl det
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
194 // Even when without whitespace collapsing, control characters (newlines and 208 // Even when without whitespace collapsing, control characters (newlines and
195 // tabs) are in their own control items to make the line breaker easier. 209 // tabs) are in their own control items to make the line breaker easier.
196 void NGInlineItemsBuilder::AppendWithoutWhiteSpaceCollapsing( 210 void NGInlineItemsBuilder::AppendWithoutWhiteSpaceCollapsing(
197 const String& string, 211 const String& string,
198 const ComputedStyle* style, 212 const ComputedStyle* style,
199 LayoutObject* layout_object) { 213 LayoutObject* layout_object) {
200 for (unsigned start = 0; start < string.length();) { 214 for (unsigned start = 0; start < string.length();) {
201 UChar c = string[start]; 215 UChar c = string[start];
202 if (IsControlItemCharacter(c)) { 216 if (IsControlItemCharacter(c)) {
203 Append(NGInlineItem::kControl, c, style, layout_object); 217 Append(NGInlineItem::kControl, c, style, layout_object);
204 start++; 218 start++;
205 continue; 219 continue;
206 } 220 }
207 221
208 size_t end = string.Find(IsControlItemCharacter, start + 1); 222 size_t end = string.Find(IsControlItemCharacter, start + 1);
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);
227 if (mapping_builder_)
228 mapping_builder_->AppendIdentityMapping(end - start);
213 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, 229 AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style,
214 layout_object); 230 layout_object);
215 start = end; 231 start = end;
216 } 232 }
217 233
218 last_collapsible_space_ = CollapsibleSpace::kNone; 234 last_collapsible_space_ = CollapsibleSpace::kNone;
219 } 235 }
220 236
221 void NGInlineItemsBuilder::AppendWithPreservingNewlines( 237 void NGInlineItemsBuilder::AppendWithPreservingNewlines(
222 const String& string, 238 const String& string,
(...skipping 26 matching lines...) Expand all
249 } 265 }
250 266
251 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, 267 void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type,
252 UChar character, 268 UChar character,
253 const ComputedStyle* style, 269 const ComputedStyle* style,
254 LayoutObject* layout_object) { 270 LayoutObject* layout_object) {
255 DCHECK_NE(character, kSpaceCharacter); 271 DCHECK_NE(character, kSpaceCharacter);
256 DCHECK_NE(character, kZeroWidthSpaceCharacter); 272 DCHECK_NE(character, kZeroWidthSpaceCharacter);
257 273
258 text_.Append(character); 274 text_.Append(character);
275 if (mapping_builder_)
276 mapping_builder_->AppendIdentityMapping(1);
259 unsigned end_offset = text_.length(); 277 unsigned end_offset = text_.length();
260 AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object); 278 AppendItem(items_, type, end_offset - 1, end_offset, style, layout_object);
261 last_collapsible_space_ = CollapsibleSpace::kNone; 279 last_collapsible_space_ = CollapsibleSpace::kNone;
262 } 280 }
263 281
264 void NGInlineItemsBuilder::AppendOpaque(NGInlineItem::NGInlineItemType type, 282 void NGInlineItemsBuilder::AppendOpaque(NGInlineItem::NGInlineItemType type,
265 UChar character) { 283 UChar character) {
266 text_.Append(character); 284 text_.Append(character);
285 if (mapping_builder_)
286 mapping_builder_->AppendIdentityMapping(1);
267 unsigned end_offset = text_.length(); 287 unsigned end_offset = text_.length();
268 AppendItem(items_, type, end_offset - 1, end_offset, nullptr, nullptr); 288 AppendItem(items_, type, end_offset - 1, end_offset, nullptr, nullptr);
269 } 289 }
270 290
271 void NGInlineItemsBuilder::AppendOpaque(NGInlineItem::NGInlineItemType type, 291 void NGInlineItemsBuilder::AppendOpaque(NGInlineItem::NGInlineItemType type,
272 const ComputedStyle* style, 292 const ComputedStyle* style,
273 LayoutObject* layout_object) { 293 LayoutObject* layout_object) {
274 unsigned end_offset = text_.length(); 294 unsigned end_offset = text_.length();
275 AppendItem(items_, type, end_offset, end_offset, style, layout_object); 295 AppendItem(items_, type, end_offset, end_offset, style, layout_object);
276 } 296 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 340 }
321 341
322 // Removes the collapsible space at the specified index. 342 // Removes the collapsible space at the specified index.
323 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace(unsigned index) { 343 void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace(unsigned index) {
324 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); 344 DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone);
325 DCHECK(!text_.IsEmpty()); 345 DCHECK(!text_.IsEmpty());
326 DCHECK_EQ(text_[index], kSpaceCharacter); 346 DCHECK_EQ(text_[index], kSpaceCharacter);
327 347
328 text_.erase(index); 348 text_.erase(index);
329 last_collapsible_space_ = CollapsibleSpace::kNone; 349 last_collapsible_space_ = CollapsibleSpace::kNone;
350 if (mapping_builder_)
351 mapping_builder_->CollapseTrailingSpace(text_.length() - index);
330 352
331 // Adjust items if the removed space is already included. 353 // Adjust items if the removed space is already included.
332 for (unsigned i = items_->size(); i > 0;) { 354 for (unsigned i = items_->size(); i > 0;) {
333 NGInlineItem& item = (*items_)[--i]; 355 NGInlineItem& item = (*items_)[--i];
334 if (index >= item.EndOffset()) 356 if (index >= item.EndOffset())
335 return; 357 return;
336 if (item.StartOffset() <= index) { 358 if (item.StartOffset() <= index) {
337 if (item.Length() == 1) { 359 if (item.Length() == 1) {
338 DCHECK_EQ(item.StartOffset(), index); 360 DCHECK_EQ(item.StartOffset(), index);
339 DCHECK_EQ(item.Type(), NGInlineItem::kText); 361 DCHECK_EQ(item.Type(), NGInlineItem::kText);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 } 461 }
440 462
441 void NGInlineItemsBuilder::Exit(LayoutObject* node) { 463 void NGInlineItemsBuilder::Exit(LayoutObject* node) {
442 while (!exits_.IsEmpty() && exits_.back().node == node) { 464 while (!exits_.IsEmpty() && exits_.back().node == node) {
443 AppendOpaque(NGInlineItem::kBidiControl, exits_.back().character); 465 AppendOpaque(NGInlineItem::kBidiControl, exits_.back().character);
444 exits_.pop_back(); 466 exits_.pop_back();
445 } 467 }
446 } 468 }
447 469
448 } // namespace blink 470 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698