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

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

Issue 331713003: RenderTextHarfBuzz: Implement font fallback for Win and Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix tests; add placeholder impl for Mac Created 6 years, 6 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
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"
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
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(&current_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
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
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
OLDNEW
« ui/gfx/render_text_harfbuzz.cc ('K') | « ui/gfx/render_text_harfbuzz.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698