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" |
11 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
16 #include "third_party/icu/source/common/unicode/uchar.h" | 16 #include "third_party/icu/source/common/unicode/uchar.h" |
17 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
18 #include "ui/gfx/font_fallback_win.h" | 18 #include "ui/gfx/font_fallback.h" |
19 #include "ui/gfx/font_smoothing_win.h" | 19 #include "ui/gfx/font_smoothing_win.h" |
20 #include "ui/gfx/platform_font_win.h" | 20 #include "ui/gfx/platform_font_win.h" |
21 #include "ui/gfx/utf16_indexing.h" | 21 #include "ui/gfx/utf16_indexing.h" |
22 | 22 |
23 namespace gfx { | 23 namespace gfx { |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 // The maximum length of text supported for Uniscribe layout and display. | 27 // The maximum length of text supported for Uniscribe layout and display. |
28 // This empirically chosen value should prevent major performance degradations. | 28 // This empirically chosen value should prevent major performance degradations. |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 run->width = abc.abcA + abc.abcB + abc.abcC; | 1053 run->width = abc.abcA + abc.abcB + abc.abcC; |
1054 preceding_run_widths += run->width; | 1054 preceding_run_widths += run->width; |
1055 } | 1055 } |
1056 string_width_ = preceding_run_widths; | 1056 string_width_ = preceding_run_widths; |
1057 } | 1057 } |
1058 | 1058 |
1059 void RenderTextWin::LayoutTextRun(internal::TextRun* run) { | 1059 void RenderTextWin::LayoutTextRun(internal::TextRun* run) { |
1060 const size_t run_length = run->range.length(); | 1060 const size_t run_length = run->range.length(); |
1061 const wchar_t* run_text = &(GetLayoutText()[run->range.start()]); | 1061 const wchar_t* run_text = &(GetLayoutText()[run->range.start()]); |
1062 Font original_font = run->font; | 1062 Font original_font = run->font; |
1063 LinkedFontsIterator fonts(original_font); | 1063 std::vector<std::string> fallback_fonts = |
| 1064 GetFallbackFontFamilies(original_font.GetFontName()); |
1064 bool tried_cached_font = false; | 1065 bool tried_cached_font = false; |
1065 bool tried_fallback = false; | 1066 bool tried_fallback = false; |
1066 // Keep track of the font that is able to display the greatest number of | 1067 // Keep track of the font that is able to display the greatest number of |
1067 // characters for which ScriptShape() returned S_OK. This font will be used | 1068 // characters for which ScriptShape() returned S_OK. This font will be used |
1068 // in the case where no font is able to display the entire run. | 1069 // in the case where no font is able to display the entire run. |
1069 int best_partial_font_missing_char_count = INT_MAX; | 1070 int best_partial_font_missing_char_count = INT_MAX; |
1070 Font best_partial_font = original_font; | 1071 Font best_partial_font = original_font; |
1071 Font current_font; | |
1072 | 1072 |
1073 run->logical_clusters.reset(new WORD[run_length]); | 1073 run->logical_clusters.reset(new WORD[run_length]); |
1074 while (fonts.NextFont(¤t_font)) { | 1074 Font current_font; |
1075 HRESULT hr = ShapeTextRunWithFont(run, current_font); | 1075 bool next_font_set = false; |
| 1076 for (size_t i = 0; i < fallback_fonts.size();) { |
| 1077 HRESULT hr = ShapeTextRunWithFont(run, next_font_set ? |
| 1078 current_font : Font(fallback_fonts[i++], original_font.GetFontSize())); |
| 1079 next_font_set = false; |
1076 | 1080 |
1077 bool glyphs_missing = false; | 1081 bool glyphs_missing = false; |
1078 if (hr == USP_E_SCRIPT_NOT_IN_FONT) { | 1082 if (hr == USP_E_SCRIPT_NOT_IN_FONT) { |
1079 glyphs_missing = true; | 1083 glyphs_missing = true; |
1080 } else if (hr == S_OK) { | 1084 } else if (hr == S_OK) { |
1081 // If |hr| is S_OK, there could still be missing glyphs in the output. | 1085 // If |hr| is S_OK, there could still be missing glyphs in the output. |
1082 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564.aspx | 1086 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564.aspx |
1083 const int missing_count = CountCharsWithMissingGlyphs(run); | 1087 const int missing_count = CountCharsWithMissingGlyphs(run); |
1084 // Track the font that produced the least missing glyphs. | 1088 // Track the font that produced the least missing glyphs. |
1085 if (missing_count < best_partial_font_missing_char_count) { | 1089 if (missing_count < best_partial_font_missing_char_count) { |
(...skipping 13 matching lines...) Expand all Loading... |
1099 return; | 1103 return; |
1100 } | 1104 } |
1101 | 1105 |
1102 // First, try the cached font from previous runs, if any. | 1106 // First, try the cached font from previous runs, if any. |
1103 if (!tried_cached_font) { | 1107 if (!tried_cached_font) { |
1104 tried_cached_font = true; | 1108 tried_cached_font = true; |
1105 | 1109 |
1106 std::map<std::string, Font>::const_iterator it = | 1110 std::map<std::string, Font>::const_iterator it = |
1107 successful_substitute_fonts_.find(original_font.GetFontName()); | 1111 successful_substitute_fonts_.find(original_font.GetFontName()); |
1108 if (it != successful_substitute_fonts_.end()) { | 1112 if (it != successful_substitute_fonts_.end()) { |
1109 fonts.SetNextFont(it->second); | 1113 current_font = it->second; |
| 1114 next_font_set = true; |
1110 continue; | 1115 continue; |
1111 } | 1116 } |
1112 } | 1117 } |
1113 | 1118 |
1114 // If there are missing glyphs, first try finding a fallback font using a | 1119 // If there are missing glyphs, first try finding a fallback font using a |
1115 // meta file, if it hasn't yet been attempted for this run. | 1120 // meta file, if it hasn't yet been attempted for this run. |
1116 // TODO(msw|asvitkine): Support RenderText's font_list()? | 1121 // TODO(msw|asvitkine): Support RenderText's font_list()? |
1117 if (!tried_fallback) { | 1122 if (!tried_fallback) { |
1118 tried_fallback = true; | 1123 tried_fallback = true; |
1119 | 1124 |
1120 Font fallback_font; | 1125 Font fallback_font; |
1121 if (ChooseFallbackFont(cached_hdc_, run->font, run_text, run_length, | 1126 if (ChooseFallbackFont(cached_hdc_, run->font, run_text, run_length, |
1122 &fallback_font)) { | 1127 &fallback_font)) { |
1123 fonts.SetNextFont(fallback_font); | 1128 current_font = fallback_font; |
| 1129 next_font_set = true; |
1124 continue; | 1130 continue; |
1125 } | 1131 } |
1126 } | 1132 } |
1127 } | 1133 } |
1128 | 1134 |
1129 // If a font was able to partially display the run, use that now. | 1135 // If a font was able to partially display the run, use that now. |
1130 if (best_partial_font_missing_char_count < static_cast<int>(run_length)) { | 1136 if (best_partial_font_missing_char_count < static_cast<int>(run_length)) { |
1131 // Re-shape the run only if |best_partial_font| differs from the last font. | 1137 // Re-shape the run only if |best_partial_font| differs from the last font. |
1132 if (best_partial_font.GetNativeFont() != run->font.GetNativeFont()) | 1138 if (best_partial_font.GetNativeFont() != run->font.GetNativeFont()) |
1133 ShapeTextRunWithFont(run, best_partial_font); | 1139 ShapeTextRunWithFont(run, best_partial_font); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 size_t position = LayoutIndexToTextIndex(run->range.end()); | 1286 size_t position = LayoutIndexToTextIndex(run->range.end()); |
1281 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 1287 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
1282 return SelectionModel(position, CURSOR_FORWARD); | 1288 return SelectionModel(position, CURSOR_FORWARD); |
1283 } | 1289 } |
1284 | 1290 |
1285 RenderText* RenderText::CreateNativeInstance() { | 1291 RenderText* RenderText::CreateNativeInstance() { |
1286 return new RenderTextWin; | 1292 return new RenderTextWin; |
1287 } | 1293 } |
1288 | 1294 |
1289 } // namespace gfx | 1295 } // namespace gfx |
OLD | NEW |