| 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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 #endif | 405 #endif |
| 406 } | 406 } |
| 407 | 407 |
| 408 void RenderText::SetText(const base::string16& text) { | 408 void RenderText::SetText(const base::string16& text) { |
| 409 DCHECK(!composition_range_.IsValid()); | 409 DCHECK(!composition_range_.IsValid()); |
| 410 if (text_ == text) | 410 if (text_ == text) |
| 411 return; | 411 return; |
| 412 text_ = text; | 412 text_ = text; |
| 413 | 413 |
| 414 // Adjust ranged styles and colors to accommodate a new text length. | 414 // Adjust ranged styles and colors to accommodate a new text length. |
| 415 // Clear style ranges as they might break new text graphemes and apply |
| 416 // the first style to the whole text instead. |
| 415 const size_t text_length = text_.length(); | 417 const size_t text_length = text_.length(); |
| 416 colors_.SetMax(text_length); | 418 colors_.SetMax(text_length); |
| 417 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 419 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) { |
| 418 styles_[style].SetMax(text_length); | 420 BreakList<bool>& break_list = styles_[style]; |
| 421 break_list.SetValue(break_list.breaks().begin()->second); |
| 422 break_list.SetMax(text_length); |
| 423 } |
| 419 cached_bounds_and_offset_valid_ = false; | 424 cached_bounds_and_offset_valid_ = false; |
| 420 | 425 |
| 421 // Reset selection model. SetText should always followed by SetSelectionModel | 426 // Reset selection model. SetText should always followed by SetSelectionModel |
| 422 // or SetCursorPosition in upper layer. | 427 // or SetCursorPosition in upper layer. |
| 423 SetSelectionModel(SelectionModel()); | 428 SetSelectionModel(SelectionModel()); |
| 424 | 429 |
| 425 // Invalidate the cached text direction if it depends on the text contents. | 430 // Invalidate the cached text direction if it depends on the text contents. |
| 426 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) | 431 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) |
| 427 text_direction_ = base::i18n::UNKNOWN_DIRECTION; | 432 text_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 428 | 433 |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 } | 649 } |
| 645 | 650 |
| 646 void RenderText::SetStyle(TextStyle style, bool value) { | 651 void RenderText::SetStyle(TextStyle style, bool value) { |
| 647 styles_[style].SetValue(value); | 652 styles_[style].SetValue(value); |
| 648 | 653 |
| 649 cached_bounds_and_offset_valid_ = false; | 654 cached_bounds_and_offset_valid_ = false; |
| 650 ResetLayout(); | 655 ResetLayout(); |
| 651 } | 656 } |
| 652 | 657 |
| 653 void RenderText::ApplyStyle(TextStyle style, bool value, const Range& range) { | 658 void RenderText::ApplyStyle(TextStyle style, bool value, const Range& range) { |
| 654 styles_[style].ApplyValue(value, range); | 659 // Do not change styles mid-grapheme to avoid breaking ligatures. |
| 660 const size_t start = IsValidCursorIndex(range.start()) ? range.start() : |
| 661 IndexOfAdjacentGrapheme(range.start(), CURSOR_BACKWARD); |
| 662 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : |
| 663 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); |
| 664 styles_[style].ApplyValue(value, Range(start, end)); |
| 655 | 665 |
| 656 cached_bounds_and_offset_valid_ = false; | 666 cached_bounds_and_offset_valid_ = false; |
| 657 ResetLayout(); | 667 ResetLayout(); |
| 658 } | 668 } |
| 659 | 669 |
| 660 bool RenderText::GetStyle(TextStyle style) const { | 670 bool RenderText::GetStyle(TextStyle style) const { |
| 661 return (styles_[style].breaks().size() == 1) && | 671 return (styles_[style].breaks().size() == 1) && |
| 662 styles_[style].breaks().front().second; | 672 styles_[style].breaks().front().second; |
| 663 } | 673 } |
| 664 | 674 |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 SetDisplayOffset(display_offset_.x() + delta_x); | 1378 SetDisplayOffset(display_offset_.x() + delta_x); |
| 1369 } | 1379 } |
| 1370 | 1380 |
| 1371 void RenderText::DrawSelection(Canvas* canvas) { | 1381 void RenderText::DrawSelection(Canvas* canvas) { |
| 1372 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1382 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
| 1373 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1383 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
| 1374 canvas->FillRect(*i, selection_background_focused_color_); | 1384 canvas->FillRect(*i, selection_background_focused_color_); |
| 1375 } | 1385 } |
| 1376 | 1386 |
| 1377 } // namespace gfx | 1387 } // namespace gfx |
| OLD | NEW |