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

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

Issue 252563003: Fix Views inline autocomplete with multi-char graphemes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Extrapolate on the comment. Created 6 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 | Annotate | Revision Log
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | ui/views/controls/textfield/textfield.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_win.h" 5 #include "ui/gfx/render_text_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/i18n/break_iterator.h" 9 #include "base/i18n/break_iterator.h"
10 #include "base/i18n/char_iterator.h" 10 #include "base/i18n/char_iterator.h"
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 }; 497 };
498 498
499 } // namespace internal 499 } // namespace internal
500 500
501 // static 501 // static
502 HDC RenderTextWin::cached_hdc_ = NULL; 502 HDC RenderTextWin::cached_hdc_ = NULL;
503 503
504 // static 504 // static
505 std::map<std::string, Font> RenderTextWin::successful_substitute_fonts_; 505 std::map<std::string, Font> RenderTextWin::successful_substitute_fonts_;
506 506
507 RenderTextWin::RenderTextWin() 507 RenderTextWin::RenderTextWin() : RenderText(), needs_layout_(false) {
508 : RenderText(),
509 needs_layout_(false) {
510 set_truncate_length(kMaxUniscribeTextLength); 508 set_truncate_length(kMaxUniscribeTextLength);
511
512 memset(&script_control_, 0, sizeof(script_control_)); 509 memset(&script_control_, 0, sizeof(script_control_));
513 memset(&script_state_, 0, sizeof(script_state_)); 510 memset(&script_state_, 0, sizeof(script_state_));
514
515 MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT)); 511 MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT));
516 } 512 }
517 513
518 RenderTextWin::~RenderTextWin() { 514 RenderTextWin::~RenderTextWin() {}
519 }
520 515
521 Size RenderTextWin::GetStringSize() { 516 Size RenderTextWin::GetStringSize() {
522 EnsureLayout(); 517 EnsureLayout();
523 return multiline_string_size_; 518 return multiline_string_size_;
524 } 519 }
525 520
526 SelectionModel RenderTextWin::FindCursorPosition(const Point& point) { 521 SelectionModel RenderTextWin::FindCursorPosition(const Point& point) {
527 if (text().empty()) 522 if (text().empty())
528 return SelectionModel(); 523 return SelectionModel();
529 524
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 } 704 }
710 for (size_t i = 0; i < bounds.size(); ++i) { 705 for (size_t i = 0; i < bounds.size(); ++i) {
711 std::vector<Rect> current_rects = TextBoundsToViewBounds(bounds[i]); 706 std::vector<Rect> current_rects = TextBoundsToViewBounds(bounds[i]);
712 rects.insert(rects.end(), current_rects.begin(), current_rects.end()); 707 rects.insert(rects.end(), current_rects.begin(), current_rects.end());
713 } 708 }
714 return rects; 709 return rects;
715 } 710 }
716 711
717 size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const { 712 size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const {
718 DCHECK_LE(index, text().length()); 713 DCHECK_LE(index, text().length());
719 ptrdiff_t i = obscured() ? gfx::UTF16IndexToOffset(text(), 0, index) : index; 714 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index;
720 CHECK_GE(i, 0); 715 CHECK_GE(i, 0);
721 // Clamp layout indices to the length of the text actually used for layout. 716 // Clamp layout indices to the length of the text actually used for layout.
722 return std::min<size_t>(GetLayoutText().length(), i); 717 return std::min<size_t>(GetLayoutText().length(), i);
723 } 718 }
724 719
725 size_t RenderTextWin::LayoutIndexToTextIndex(size_t index) const { 720 size_t RenderTextWin::LayoutIndexToTextIndex(size_t index) const {
726 if (!obscured()) 721 if (!obscured())
727 return index; 722 return index;
728 723
729 DCHECK_LE(index, GetLayoutText().length()); 724 DCHECK_LE(index, GetLayoutText().length());
730 const size_t text_index = gfx::UTF16OffsetToIndex(text(), 0, index); 725 const size_t text_index = UTF16OffsetToIndex(text(), 0, index);
731 DCHECK_LE(text_index, text().length()); 726 DCHECK_LE(text_index, text().length());
732 return text_index; 727 return text_index;
733 } 728 }
734 729
735 bool RenderTextWin::IsCursorablePosition(size_t position) { 730 bool RenderTextWin::IsValidCursorIndex(size_t index) {
736 if (position == 0 || position == text().length()) 731 if (index == 0 || index == text().length())
737 return true; 732 return true;
733 if (!IsValidLogicalIndex(index))
734 return false;
738 EnsureLayout(); 735 EnsureLayout();
739 736 // Disallow indices amid multi-character graphemes by checking glyph bounds.
740 // Check that the index is at a valid code point (not mid-surrgate-pair), 737 // These characters are not surrogate-pairs, but may yield a single glyph:
741 // that it is not truncated from layout text (its glyph is shown on screen), 738 // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
742 // and that its glyph has distinct bounds (not mid-multi-character-grapheme). 739 // \x0e08\x0e33 - (cho chan + sara am) - a Thai consonant and vowel pair.
743 // An example of a multi-character-grapheme that is not a surrogate-pair is: 740 return GetGlyphBounds(index) != GetGlyphBounds(index - 1);
744 // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
745 return gfx::IsValidCodePointIndex(text(), position) &&
746 position < LayoutIndexToTextIndex(GetLayoutText().length()) &&
747 GetGlyphBounds(position) != GetGlyphBounds(position - 1);
748 } 741 }
749 742
750 void RenderTextWin::ResetLayout() { 743 void RenderTextWin::ResetLayout() {
751 // Layout is performed lazily as needed for drawing/metrics. 744 // Layout is performed lazily as needed for drawing/metrics.
752 needs_layout_ = true; 745 needs_layout_ = true;
753 } 746 }
754 747
755 void RenderTextWin::EnsureLayout() { 748 void RenderTextWin::EnsureLayout() {
756 if (needs_layout_) { 749 if (needs_layout_) {
757 // TODO(msw): Skip complex processing if ScriptIsComplex returns false. 750 // TODO(msw): Skip complex processing if ScriptIsComplex returns false.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 renderer.SetFontFamilyWithStyle(run->font.GetFontName(), run->font_style); 846 renderer.SetFontFamilyWithStyle(run->font.GetFontName(), run->font_style);
854 847
855 for (BreakList<SkColor>::const_iterator it = 848 for (BreakList<SkColor>::const_iterator it =
856 colors().GetBreak(segment->char_range.start()); 849 colors().GetBreak(segment->char_range.start());
857 it != colors().breaks().end() && 850 it != colors().breaks().end() &&
858 it->first < segment->char_range.end(); 851 it->first < segment->char_range.end();
859 ++it) { 852 ++it) {
860 const Range intersection = 853 const Range intersection =
861 colors().GetRange(it).Intersect(segment->char_range); 854 colors().GetRange(it).Intersect(segment->char_range);
862 const Range colored_glyphs = CharRangeToGlyphRange(*run, intersection); 855 const Range colored_glyphs = CharRangeToGlyphRange(*run, intersection);
856 // The range may be empty if a portion of a multi-character grapheme is
857 // selected, yielding two colors for a single glyph. For now, this just
858 // paints the glyph with a single style, but it should paint it twice,
859 // clipped according to selection bounds. See http://crbug.com/366786
860 if (colored_glyphs.is_empty())
861 continue;
863 DCHECK(glyph_range.Contains(colored_glyphs)); 862 DCHECK(glyph_range.Contains(colored_glyphs));
864 DCHECK(!colored_glyphs.is_empty());
865 const SkPoint& start_pos = 863 const SkPoint& start_pos =
866 pos[colored_glyphs.start() - glyph_range.start()]; 864 pos[colored_glyphs.start() - glyph_range.start()];
867 const SkPoint& end_pos = 865 const SkPoint& end_pos =
868 pos[colored_glyphs.end() - glyph_range.start()]; 866 pos[colored_glyphs.end() - glyph_range.start()];
869 867
870 renderer.SetForegroundColor(it->second); 868 renderer.SetForegroundColor(it->second);
871 renderer.DrawPosText(&start_pos, &run->glyphs[colored_glyphs.start()], 869 renderer.DrawPosText(&start_pos, &run->glyphs[colored_glyphs.start()],
872 colored_glyphs.length()); 870 colored_glyphs.length());
873 renderer.DrawDecorations(start_pos.x(), text_offset.y(), 871 renderer.DrawDecorations(start_pos.x(), text_offset.y(),
874 SkScalarCeilToInt(end_pos.x() - start_pos.x()), 872 SkScalarCeilToInt(end_pos.x() - start_pos.x()),
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 size_t position = LayoutIndexToTextIndex(run->range.end()); 1271 size_t position = LayoutIndexToTextIndex(run->range.end());
1274 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); 1272 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD);
1275 return SelectionModel(position, CURSOR_FORWARD); 1273 return SelectionModel(position, CURSOR_FORWARD);
1276 } 1274 }
1277 1275
1278 RenderText* RenderText::CreateInstance() { 1276 RenderText* RenderText::CreateInstance() {
1279 return new RenderTextWin; 1277 return new RenderTextWin;
1280 } 1278 }
1281 1279
1282 } // namespace gfx 1280 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | ui/views/controls/textfield/textfield.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698