 Chromium Code Reviews
 Chromium Code Reviews Issue 371413002:
  Don't split text runs on underline style change  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 371413002:
  Don't split text runs on underline style change  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| 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_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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 } | 285 } | 
| 286 | 286 | 
| 287 } // namespace | 287 } // namespace | 
| 288 | 288 | 
| 289 namespace internal { | 289 namespace internal { | 
| 290 | 290 | 
| 291 TextRun::TextRun() | 291 TextRun::TextRun() | 
| 292 : font_style(0), | 292 : font_style(0), | 
| 293 strike(false), | 293 strike(false), | 
| 294 diagonal_strike(false), | 294 diagonal_strike(false), | 
| 295 underline(false), | |
| 296 width(0), | 295 width(0), | 
| 297 preceding_run_widths(0), | 296 preceding_run_widths(0), | 
| 298 glyph_count(0), | 297 glyph_count(0), | 
| 299 script_cache(NULL) { | 298 script_cache(NULL) { | 
| 300 memset(&script_analysis, 0, sizeof(script_analysis)); | 299 memset(&script_analysis, 0, sizeof(script_analysis)); | 
| 301 memset(&abc_widths, 0, sizeof(abc_widths)); | 300 memset(&abc_widths, 0, sizeof(abc_widths)); | 
| 302 } | 301 } | 
| 303 | 302 | 
| 304 TextRun::~TextRun() { | 303 TextRun::~TextRun() { | 
| 305 ScriptFreeCache(&script_cache); | 304 ScriptFreeCache(&script_cache); | 
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 continue; | 881 continue; | 
| 883 DCHECK(glyph_range.Contains(colored_glyphs)); | 882 DCHECK(glyph_range.Contains(colored_glyphs)); | 
| 884 const SkPoint& start_pos = | 883 const SkPoint& start_pos = | 
| 885 pos[colored_glyphs.start() - glyph_range.start()]; | 884 pos[colored_glyphs.start() - glyph_range.start()]; | 
| 886 const SkPoint& end_pos = | 885 const SkPoint& end_pos = | 
| 887 pos[colored_glyphs.end() - glyph_range.start()]; | 886 pos[colored_glyphs.end() - glyph_range.start()]; | 
| 888 | 887 | 
| 889 renderer.SetForegroundColor(it->second); | 888 renderer.SetForegroundColor(it->second); | 
| 890 renderer.DrawPosText(&start_pos, &run->glyphs[colored_glyphs.start()], | 889 renderer.DrawPosText(&start_pos, &run->glyphs[colored_glyphs.start()], | 
| 891 colored_glyphs.length()); | 890 colored_glyphs.length()); | 
| 892 renderer.DrawDecorations(start_pos.x(), text_offset.y(), | 891 | 
| 893 SkScalarCeilToInt(end_pos.x() - start_pos.x()), | 892 const BreakList<bool>& underline_breaks = styles()[UNDERLINE]; | 
| 894 run->underline, run->strike, | 893 for (size_t position = intersection.start(); | 
| 895 run->diagonal_strike); | 894 position < intersection.end(); ) { | 
| 
msw
2014/07/08 17:20:53
nit: the indent here should match the inside of th
 
Tomasz Moniuszko
2014/07/16 10:35:45
Done.
 | |
| 895 const BreakList<bool>::const_iterator underline = | |
| 896 underline_breaks.GetBreak(position); | |
| 897 const Range underline_range = | |
| 898 underline_breaks.GetRange(underline).Intersect(intersection); | |
| 899 Range decorated_glyphs = CharRangeToGlyphRange(*run, underline_range); | |
| 900 if (decorated_glyphs.is_empty()) | |
| 
msw
2014/07/08 17:20:53
nit: add {}
 
msw
2014/07/08 17:20:53
Why do we get an empty glyph range for something t
 
Tomasz Moniuszko
2014/07/16 10:35:45
Done.
 
Tomasz Moniuszko
2014/07/16 10:35:45
We can get empty glyph range for non-empty charact
 
msw
2014/07/16 19:52:38
I suspect that RenderTextWin::CharRangeToGlyphRang
 | |
| 901 if (run->script_analysis.fRTL) | |
| 902 decorated_glyphs.set_start(decorated_glyphs.end() - 1); | |
| 
msw
2014/07/08 17:20:53
Hmm, adjusting the range by one glyph seems odd, w
 
Tomasz Moniuszko
2014/07/16 10:35:45
Yes, I agree. The issue is that BreakList contains
 | |
| 903 else | |
| 904 decorated_glyphs.set_end(decorated_glyphs.start() + 1); | |
| 905 const SkPoint& decorations_start_pos = | |
| 906 pos[decorated_glyphs.start() - glyph_range.start()]; | |
| 907 const SkPoint& decorations_end_pos = | |
| 908 pos[decorated_glyphs.end() - glyph_range.start()]; | |
| 909 const int decorations_width = SkScalarCeilToInt( | |
| 910 decorations_end_pos.x() - decorations_start_pos.x()); | |
| 911 renderer.DrawDecorations(decorations_start_pos.x(), text_offset.y(), | |
| 912 decorations_width, | |
| 913 underline->second, | |
| 914 run->strike, | |
| 915 run->diagonal_strike); | |
| 916 position = underline_range.end(); | |
| 917 } | |
| 896 } | 918 } | 
| 897 | 919 | 
| 898 preceding_segment_widths += segment_width; | 920 preceding_segment_widths += segment_width; | 
| 899 } | 921 } | 
| 900 | 922 | 
| 901 renderer.EndDiagonalStrike(); | 923 renderer.EndDiagonalStrike(); | 
| 902 } | 924 } | 
| 903 | 925 | 
| 904 UndoCompositionAndSelectionStyles(); | 926 UndoCompositionAndSelectionStyles(); | 
| 905 } | 927 } | 
| (...skipping 30 matching lines...) Expand all Loading... | |
| 936 if (!SUCCEEDED(hr) || script_items_count <= 0) | 958 if (!SUCCEEDED(hr) || script_items_count <= 0) | 
| 937 return; | 959 return; | 
| 938 | 960 | 
| 939 // Temporarily apply composition underlines and selection colors. | 961 // Temporarily apply composition underlines and selection colors. | 
| 940 ApplyCompositionAndSelectionStyles(); | 962 ApplyCompositionAndSelectionStyles(); | 
| 941 | 963 | 
| 942 // Build the list of runs from the script items and ranged styles. Use an | 964 // Build the list of runs from the script items and ranged styles. Use an | 
| 943 // empty color BreakList to avoid breaking runs at color boundaries. | 965 // empty color BreakList to avoid breaking runs at color boundaries. | 
| 944 BreakList<SkColor> empty_colors; | 966 BreakList<SkColor> empty_colors; | 
| 945 empty_colors.SetMax(layout_text_length); | 967 empty_colors.SetMax(layout_text_length); | 
| 946 internal::StyleIterator style(empty_colors, styles()); | 968 std::vector<BreakList<bool> > breaking_styles = styles(); | 
| 
msw
2014/07/08 17:20:53
nit: add a comment like the one above for colors (
 | |
| 969 size_t underline_max = breaking_styles[UNDERLINE].max(); | |
| 970 breaking_styles[UNDERLINE].SetValue(false); | |
| 971 breaking_styles[UNDERLINE].SetMax(underline_max); | |
| 972 internal::StyleIterator style(empty_colors, breaking_styles); | |
| 947 SCRIPT_ITEM* script_item = &script_items[0]; | 973 SCRIPT_ITEM* script_item = &script_items[0]; | 
| 948 const size_t max_run_length = kMaxGlyphs / 2; | 974 const size_t max_run_length = kMaxGlyphs / 2; | 
| 949 for (size_t run_break = 0; run_break < layout_text_length;) { | 975 for (size_t run_break = 0; run_break < layout_text_length;) { | 
| 950 internal::TextRun* run = new internal::TextRun(); | 976 internal::TextRun* run = new internal::TextRun(); | 
| 951 run->range.set_start(run_break); | 977 run->range.set_start(run_break); | 
| 952 run->font = font_list().GetPrimaryFont(); | 978 run->font = font_list().GetPrimaryFont(); | 
| 953 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | | 979 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | | 
| 954 (style.style(ITALIC) ? Font::ITALIC : 0); | 980 (style.style(ITALIC) ? Font::ITALIC : 0); | 
| 955 DeriveFontIfNecessary(run->font.GetFontSize(), run->font.GetHeight(), | 981 DeriveFontIfNecessary(run->font.GetFontSize(), run->font.GetHeight(), | 
| 956 run->font_style, &run->font); | 982 run->font_style, &run->font); | 
| 957 run->strike = style.style(STRIKE); | 983 run->strike = style.style(STRIKE); | 
| 958 run->diagonal_strike = style.style(DIAGONAL_STRIKE); | 984 run->diagonal_strike = style.style(DIAGONAL_STRIKE); | 
| 959 run->underline = style.style(UNDERLINE); | |
| 960 run->script_analysis = script_item->a; | 985 run->script_analysis = script_item->a; | 
| 961 | 986 | 
| 962 // Find the next break and advance the iterators as needed. | 987 // Find the next break and advance the iterators as needed. | 
| 963 const size_t script_item_break = (script_item + 1)->iCharPos; | 988 const size_t script_item_break = (script_item + 1)->iCharPos; | 
| 964 run_break = std::min(script_item_break, | 989 run_break = std::min(script_item_break, | 
| 965 TextIndexToLayoutIndex(style.GetRange().end())); | 990 TextIndexToLayoutIndex(style.GetRange().end())); | 
| 966 | 991 | 
| 967 // Clamp run lengths to avoid exceeding the maximum supported glyph count. | 992 // Clamp run lengths to avoid exceeding the maximum supported glyph count. | 
| 968 if ((run_break - run->range.start()) > max_run_length) { | 993 if ((run_break - run->range.start()) > max_run_length) { | 
| 969 run_break = run->range.start() + max_run_length; | 994 run_break = run->range.start() + max_run_length; | 
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1280 size_t position = LayoutIndexToTextIndex(run->range.end()); | 1305 size_t position = LayoutIndexToTextIndex(run->range.end()); | 
| 1281 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 1306 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 
| 1282 return SelectionModel(position, CURSOR_FORWARD); | 1307 return SelectionModel(position, CURSOR_FORWARD); | 
| 1283 } | 1308 } | 
| 1284 | 1309 | 
| 1285 RenderText* RenderText::CreateNativeInstance() { | 1310 RenderText* RenderText::CreateNativeInstance() { | 
| 1286 return new RenderTextWin; | 1311 return new RenderTextWin; | 
| 1287 } | 1312 } | 
| 1288 | 1313 | 
| 1289 } // namespace gfx | 1314 } // namespace gfx | 
| OLD | NEW |