Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <climits> | 8 #include <climits> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 | 438 |
| 439 // static | 439 // static |
| 440 RenderText* RenderText::CreateInstanceForEditing() { | 440 RenderText* RenderText::CreateInstanceForEditing() { |
| 441 return new RenderTextHarfBuzz; | 441 return new RenderTextHarfBuzz; |
| 442 } | 442 } |
| 443 | 443 |
| 444 void RenderText::SetText(const base::string16& text) { | 444 void RenderText::SetText(const base::string16& text) { |
| 445 DCHECK(!composition_range_.IsValid()); | 445 DCHECK(!composition_range_.IsValid()); |
| 446 if (text_ == text) | 446 if (text_ == text) |
| 447 return; | 447 return; |
| 448 text_ = text; | 448 text_.clear(); |
| 449 DoAppendText(text); | |
| 449 | 450 |
| 450 // Adjust ranged styles, baselines, and colors to accommodate a new text | 451 // Clear style ranges as they might break new text graphemes and apply |
| 451 // length. Clear style ranges as they might break new text graphemes and apply | |
| 452 // the first style to the whole text instead. | 452 // the first style to the whole text instead. |
| 453 const size_t text_length = text_.length(); | 453 colors_.SetValue(colors_.breaks().begin()->second); |
| 454 colors_.SetMax(text_length); | |
| 455 baselines_.SetValue(baselines_.breaks().begin()->second); | 454 baselines_.SetValue(baselines_.breaks().begin()->second); |
| 456 baselines_.SetMax(text_length); | 455 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 457 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) { | 456 styles_[style].SetValue(styles_[style].breaks().begin()->second); |
| 458 BreakList<bool>& break_list = styles_[style]; | |
| 459 break_list.SetValue(break_list.breaks().begin()->second); | |
| 460 break_list.SetMax(text_length); | |
| 461 } | |
| 462 cached_bounds_and_offset_valid_ = false; | |
| 463 | 457 |
| 464 // Reset selection model. SetText should always followed by SetSelectionModel | 458 // Reset selection model. SetText should always followed by SetSelectionModel |
| 465 // or SetCursorPosition in upper layer. | 459 // or SetCursorPosition in upper layer. |
| 466 SetSelectionModel(SelectionModel()); | 460 SetSelectionModel(SelectionModel()); |
| 467 | 461 |
| 468 // Invalidate the cached text direction if it depends on the text contents. | 462 // Invalidate the cached text direction if it depends on the text contents. |
| 469 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) | 463 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) |
| 470 text_direction_ = base::i18n::UNKNOWN_DIRECTION; | 464 text_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 471 | 465 |
| 472 obscured_reveal_index_ = -1; | |
| 473 OnTextAttributeChanged(); | 466 OnTextAttributeChanged(); |
| 474 } | 467 } |
| 475 | 468 |
| 469 void RenderText::AppendText(const base::string16& text) { | |
| 470 DoAppendText(text); | |
| 471 OnTextAttributeChanged(); | |
| 472 } | |
| 473 | |
| 476 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { | 474 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { |
| 477 if (horizontal_alignment_ != alignment) { | 475 if (horizontal_alignment_ != alignment) { |
| 478 horizontal_alignment_ = alignment; | 476 horizontal_alignment_ = alignment; |
| 479 display_offset_ = Vector2d(); | 477 display_offset_ = Vector2d(); |
| 480 cached_bounds_and_offset_valid_ = false; | 478 cached_bounds_and_offset_valid_ = false; |
| 481 } | 479 } |
| 482 } | 480 } |
| 483 | 481 |
| 484 void RenderText::SetFontList(const FontList& font_list) { | 482 void RenderText::SetFontList(const FontList& font_list) { |
| 485 font_list_ = font_list; | 483 font_list_ = font_list; |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1234 size_t RenderText::TextIndexToGivenTextIndex(const base::string16& given_text, | 1232 size_t RenderText::TextIndexToGivenTextIndex(const base::string16& given_text, |
| 1235 size_t index) { | 1233 size_t index) { |
| 1236 DCHECK(given_text == layout_text() || given_text == display_text()); | 1234 DCHECK(given_text == layout_text() || given_text == display_text()); |
| 1237 DCHECK_LE(index, text().length()); | 1235 DCHECK_LE(index, text().length()); |
| 1238 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; | 1236 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; |
| 1239 CHECK_GE(i, 0); | 1237 CHECK_GE(i, 0); |
| 1240 // Clamp indices to the length of the given layout or display text. | 1238 // Clamp indices to the length of the given layout or display text. |
| 1241 return std::min<size_t>(given_text.length(), i); | 1239 return std::min<size_t>(given_text.length(), i); |
| 1242 } | 1240 } |
| 1243 | 1241 |
| 1242 void RenderText::DoAppendText(const base::string16& text) { | |
| 1243 text_ += text; | |
| 1244 // Adjust ranged styles and colors to accommodate a new text length. | |
| 1245 const size_t text_length = text_.length(); | |
| 1246 colors_.SetMax(text_length); | |
| 1247 baselines_.SetMax(text_length); | |
| 1248 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | |
| 1249 styles_[style].SetMax(text_length); | |
| 1250 cached_bounds_and_offset_valid_ = false; | |
|
msw
2015/03/18 20:20:16
Sorry, I changed my mind here a bit. I think it'd
| |
| 1251 obscured_reveal_index_ = -1; | |
| 1252 } | |
| 1253 | |
| 1244 // static | 1254 // static |
| 1245 bool RenderText::RangeContainsCaret(const Range& range, | 1255 bool RenderText::RangeContainsCaret(const Range& range, |
| 1246 size_t caret_pos, | 1256 size_t caret_pos, |
| 1247 LogicalCursorDirection caret_affinity) { | 1257 LogicalCursorDirection caret_affinity) { |
| 1248 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). | 1258 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). |
| 1249 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? | 1259 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? |
| 1250 caret_pos - 1 : caret_pos + 1; | 1260 caret_pos - 1 : caret_pos + 1; |
| 1251 return range.Contains(Range(caret_pos, adjacent)); | 1261 return range.Contains(Range(caret_pos, adjacent)); |
| 1252 } | 1262 } |
| 1253 | 1263 |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1496 | 1506 |
| 1497 SetDisplayOffset(display_offset_.x() + delta_x); | 1507 SetDisplayOffset(display_offset_.x() + delta_x); |
| 1498 } | 1508 } |
| 1499 | 1509 |
| 1500 void RenderText::DrawSelection(Canvas* canvas) { | 1510 void RenderText::DrawSelection(Canvas* canvas) { |
| 1501 for (const Rect& s : GetSubstringBounds(selection())) | 1511 for (const Rect& s : GetSubstringBounds(selection())) |
| 1502 canvas->FillRect(s, selection_background_focused_color_); | 1512 canvas->FillRect(s, selection_background_focused_color_); |
| 1503 } | 1513 } |
| 1504 | 1514 |
| 1505 } // namespace gfx | 1515 } // namespace gfx |
| OLD | NEW |