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

Side by Side Diff: ui/gfx/render_text.cc

Issue 1953133002: [WIP: not for review] Reduce re-layout Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/gfx/render_text.h" 5 #include "ui/gfx/render_text.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <climits> 10 #include <climits>
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 return new RenderTextMac; 427 return new RenderTextMac;
428 #endif // defined(OS_MACOSX) 428 #endif // defined(OS_MACOSX)
429 return new RenderTextHarfBuzz; 429 return new RenderTextHarfBuzz;
430 } 430 }
431 431
432 // static 432 // static
433 RenderText* RenderText::CreateInstanceForEditing() { 433 RenderText* RenderText::CreateInstanceForEditing() {
434 return new RenderTextHarfBuzz; 434 return new RenderTextHarfBuzz;
435 } 435 }
436 436
437 std::unique_ptr<RenderText> RenderText::CreateInstanceOfSameStyle(
438 const base::string16& text) const {
439 std::unique_ptr<RenderText> render_text = CreateInstanceOfSameType();
440 // |SetText()| must be called before styles are set.
441 render_text->directionality_mode_ = directionality_mode_;
442 render_text->cursor_enabled_ = cursor_enabled_;
443 render_text->set_truncate_length(truncate_length_);
444 render_text->font_list_ = font_list_;
445 render_text->text_ = text;
446 render_text->styles_ = styles_;
447 render_text->baselines_ = baselines_;
448 render_text->colors_ = colors_;
449 render_text->multiline_ = multiline_;
450 render_text->SetDisplayRect(display_rect_);
451 render_text->OnTextAttributeChanged();
452 return render_text;
453 }
454
437 void RenderText::SetText(const base::string16& text) { 455 void RenderText::SetText(const base::string16& text) {
438 DCHECK(!composition_range_.IsValid()); 456 DCHECK(!composition_range_.IsValid());
439 if (text_ == text) 457 if (text_ == text)
440 return; 458 return;
441 text_ = text; 459 text_ = text;
442 UpdateStyleLengths(); 460 UpdateStyleLengths();
443 461
444 // Clear style ranges as they might break new text graphemes and apply 462 // Clear style ranges as they might break new text graphemes and apply
445 // the first style to the whole text instead. 463 // the first style to the whole text instead.
446 colors_.SetValue(colors_.breaks().begin()->second); 464 colors_.SetValue(colors_.breaks().begin()->second);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 536
519 void RenderText::SetMultiline(bool multiline) { 537 void RenderText::SetMultiline(bool multiline) {
520 if (multiline != multiline_) { 538 if (multiline != multiline_) {
521 multiline_ = multiline; 539 multiline_ = multiline;
522 cached_bounds_and_offset_valid_ = false; 540 cached_bounds_and_offset_valid_ = false;
523 lines_.clear(); 541 lines_.clear();
524 OnTextAttributeChanged(); 542 OnTextAttributeChanged();
525 } 543 }
526 } 544 }
527 545
546 void RenderText::SetMaxLines(size_t max_lines) {
547 max_lines_ = max_lines;
548 OnDisplayTextAttributeChanged();
549 }
550
551 size_t RenderText::GetNumLines() {
552 return lines_.size();
553 }
554
528 void RenderText::SetWordWrapBehavior(WordWrapBehavior behavior) { 555 void RenderText::SetWordWrapBehavior(WordWrapBehavior behavior) {
529 if (word_wrap_behavior_ == behavior) 556 if (word_wrap_behavior_ == behavior)
530 return; 557 return;
531 word_wrap_behavior_ = behavior; 558 word_wrap_behavior_ = behavior;
532 if (multiline_) { 559 if (multiline_) {
533 cached_bounds_and_offset_valid_ = false; 560 cached_bounds_and_offset_valid_ = false;
534 lines_.clear(); 561 lines_.clear();
535 OnTextAttributeChanged(); 562 OnTextAttributeChanged();
536 } 563 }
537 } 564 }
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 baselines_(NORMAL_BASELINE), 1002 baselines_(NORMAL_BASELINE),
976 styles_(NUM_TEXT_STYLES), 1003 styles_(NUM_TEXT_STYLES),
977 composition_and_selection_styles_applied_(false), 1004 composition_and_selection_styles_applied_(false),
978 obscured_(false), 1005 obscured_(false),
979 obscured_reveal_index_(-1), 1006 obscured_reveal_index_(-1),
980 truncate_length_(0), 1007 truncate_length_(0),
981 elide_behavior_(NO_ELIDE), 1008 elide_behavior_(NO_ELIDE),
982 text_elided_(false), 1009 text_elided_(false),
983 min_line_height_(0), 1010 min_line_height_(0),
984 multiline_(false), 1011 multiline_(false),
1012 max_lines_(0),
985 word_wrap_behavior_(IGNORE_LONG_WORDS), 1013 word_wrap_behavior_(IGNORE_LONG_WORDS),
986 replace_newline_chars_with_symbols_(true), 1014 replace_newline_chars_with_symbols_(true),
987 subpixel_rendering_suppressed_(false), 1015 subpixel_rendering_suppressed_(false),
988 clip_to_display_rect_(true), 1016 clip_to_display_rect_(true),
989 baseline_(kInvalidBaseline), 1017 baseline_(kInvalidBaseline),
990 cached_bounds_and_offset_valid_(false) { 1018 cached_bounds_and_offset_valid_(false) {}
991 }
992 1019
993 SelectionModel RenderText::GetAdjacentSelectionModel( 1020 SelectionModel RenderText::GetAdjacentSelectionModel(
994 const SelectionModel& current, 1021 const SelectionModel& current,
995 BreakType break_type, 1022 BreakType break_type,
996 VisualCursorDirection direction) { 1023 VisualCursorDirection direction) {
997 EnsureLayout(); 1024 EnsureLayout();
998 1025
999 if (break_type == LINE_BREAK || text().empty()) 1026 if (break_type == LINE_BREAK || text().empty())
1000 return EdgeSelectionModel(direction); 1027 return EdgeSelectionModel(direction);
1001 if (break_type == CHARACTER_BREAK) 1028 if (break_type == CHARACTER_BREAK)
(...skipping 12 matching lines...) Expand all
1014 void RenderText::SetSelectionModel(const SelectionModel& model) { 1041 void RenderText::SetSelectionModel(const SelectionModel& model) {
1015 DCHECK_LE(model.selection().GetMax(), text().length()); 1042 DCHECK_LE(model.selection().GetMax(), text().length());
1016 selection_model_ = model; 1043 selection_model_ = model;
1017 cached_bounds_and_offset_valid_ = false; 1044 cached_bounds_and_offset_valid_ = false;
1018 } 1045 }
1019 1046
1020 void RenderText::OnTextColorChanged() { 1047 void RenderText::OnTextColorChanged() {
1021 } 1048 }
1022 1049
1023 void RenderText::UpdateDisplayText(float text_width) { 1050 void RenderText::UpdateDisplayText(float text_width) {
1024 // TODO(oshima): Consider support eliding for multi-line text. 1051 // TODO(krb): Consider other elision modes for multiline.
1025 // This requires max_line support first. 1052 if ((multiline_ && (!max_lines_ || elide_behavior() != ELIDE_TAIL)) ||
1026 if (multiline_ || 1053 elide_behavior() == NO_ELIDE || elide_behavior() == FADE_TAIL ||
1027 elide_behavior() == NO_ELIDE || 1054 (text_width > 0 && text_width < display_rect_.width()) ||
1028 elide_behavior() == FADE_TAIL ||
1029 text_width < display_rect_.width() ||
1030 layout_text_.empty()) { 1055 layout_text_.empty()) {
1031 text_elided_ = false; 1056 text_elided_ = false;
1032 display_text_.clear(); 1057 display_text_.clear();
1033 return; 1058 return;
1034 } 1059 }
1035 1060
1036 // This doesn't trim styles so ellipsis may get rendered as a different 1061 if (!multiline_) {
1037 // style than the preceding text. See crbug.com/327850. 1062 // This doesn't trim styles so ellipsis may get rendered as a different
1038 display_text_.assign(Elide(layout_text_, 1063 // style than the preceding text. See crbug.com/327850.
1039 text_width, 1064 display_text_.assign(Elide(layout_text_, text_width,
1040 static_cast<float>(display_rect_.width()), 1065 static_cast<float>(display_rect_.width()),
1041 elide_behavior_)); 1066 elide_behavior_));
1067 } else {
1068 bool was_elided = text_elided_;
1069 text_elided_ = false;
1070 display_text_.clear();
1042 1071
1072 std::unique_ptr<RenderText> render_text(
1073 CreateInstanceOfSameStyle(layout_text_));
1074 //render_text->SetMultiline(true);
1075 //render_text->SetDisplayRect(display_rect_);
1076 // Have it arrange words on |lines_|.
1077 //render_text->OnLayoutTextAttributeChanged(false);
1078 render_text->EnsureLayout();
1079
1080 if (render_text->lines_.size() > max_lines_) {
1081 size_t start_of_elision = render_text->lines_[max_lines_ - 1]
1082 .segments.front()
1083 .char_range.start();
1084 base::string16 text_to_elide = layout_text_.substr(start_of_elision);
1085 display_text_.assign(layout_text_.substr(0, start_of_elision) +
1086 Elide(text_to_elide, 0,
1087 static_cast<float>(display_rect_.width()),
1088 ELIDE_TAIL));
1089 // Have GetLineBreaks() re-calculate.
1090 line_breaks_.SetMax(0);
1091 } else {
1092 // If elision changed, re-calculate.
1093 if (was_elided)
1094 line_breaks_.SetMax(0);
1095 // Initial state above is fine.
1096 return;
1097 }
1098 }
1043 text_elided_ = display_text_ != layout_text_; 1099 text_elided_ = display_text_ != layout_text_;
1044 if (!text_elided_) 1100 if (!text_elided_)
1045 display_text_.clear(); 1101 display_text_.clear();
1046 } 1102 }
1047 1103
1048 const BreakList<size_t>& RenderText::GetLineBreaks() { 1104 const BreakList<size_t>& RenderText::GetLineBreaks() {
1049 if (line_breaks_.max() != 0) 1105 if (line_breaks_.max() != 0)
1050 return line_breaks_; 1106 return line_breaks_;
1051 1107
1052 const base::string16& layout_text = GetDisplayText(); 1108 const base::string16& layout_text = GetDisplayText();
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 if (available_width <= 0 || text.empty()) 1400 if (available_width <= 0 || text.empty())
1345 return base::string16(); 1401 return base::string16();
1346 if (behavior == ELIDE_EMAIL) 1402 if (behavior == ELIDE_EMAIL)
1347 return ElideEmail(text, available_width); 1403 return ElideEmail(text, available_width);
1348 if (text_width > 0 && text_width < available_width) 1404 if (text_width > 0 && text_width < available_width)
1349 return text; 1405 return text;
1350 1406
1351 TRACE_EVENT0("ui", "RenderText::Elide"); 1407 TRACE_EVENT0("ui", "RenderText::Elide");
1352 1408
1353 // Create a RenderText copy with attributes that affect the rendering width. 1409 // Create a RenderText copy with attributes that affect the rendering width.
1354 std::unique_ptr<RenderText> render_text = CreateInstanceOfSameType(); 1410 bool orig_multiline = multiline_;
1355 render_text->SetFontList(font_list_); 1411 multiline_ = false;
1356 render_text->SetDirectionalityMode(directionality_mode_); 1412 std::unique_ptr<RenderText> render_text = CreateInstanceOfSameStyle(text);
1357 render_text->SetCursorEnabled(cursor_enabled_); 1413 multiline_ = orig_multiline;
1358 render_text->set_truncate_length(truncate_length_);
1359 render_text->styles_ = styles_;
1360 render_text->baselines_ = baselines_;
1361 render_text->colors_ = colors_;
1362 if (text_width == 0) { 1414 if (text_width == 0) {
1363 render_text->SetText(text);
1364 text_width = render_text->GetContentWidthF(); 1415 text_width = render_text->GetContentWidthF();
1365 } 1416 }
1366 if (text_width <= available_width) 1417 if (text_width <= available_width)
1367 return text; 1418 return text;
1368 1419
1369 const base::string16 ellipsis = base::string16(kEllipsisUTF16); 1420 const base::string16 ellipsis = base::string16(kEllipsisUTF16);
1370 const bool insert_ellipsis = (behavior != TRUNCATE); 1421 const bool insert_ellipsis = (behavior != TRUNCATE);
1371 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); 1422 const bool elide_in_middle = (behavior == ELIDE_MIDDLE);
1372 const bool elide_at_beginning = (behavior == ELIDE_HEAD); 1423 const bool elide_at_beginning = (behavior == ELIDE_HEAD);
1373 1424
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 1566
1516 SetDisplayOffset(display_offset_.x() + delta_x); 1567 SetDisplayOffset(display_offset_.x() + delta_x);
1517 } 1568 }
1518 1569
1519 void RenderText::DrawSelection(Canvas* canvas) { 1570 void RenderText::DrawSelection(Canvas* canvas) {
1520 for (const Rect& s : GetSubstringBounds(selection())) 1571 for (const Rect& s : GetSubstringBounds(selection()))
1521 canvas->FillRect(s, selection_background_focused_color_); 1572 canvas->FillRect(s, selection_background_focused_color_);
1522 } 1573 }
1523 1574
1524 } // namespace gfx 1575 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698