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 |