Skip to content
This repository was archived by the owner on Apr 3, 2020. It is now read-only.

Commit 4939383

Browse files
RenderTextWin: Unroll the loop in LayoutTextRun for clarity
BUG= R=msw TBR=asvitkine Review URL: https://codereview.chromium.org/382793004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282550 0039d316-1c4b-4281-b951-d872f2087c98
1 parent fa18b3c commit 4939383

File tree

2 files changed

+62
-55
lines changed

2 files changed

+62
-55
lines changed

ui/gfx/render_text_win.cc

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,68 +1056,66 @@ void RenderTextWin::LayoutTextRun(internal::TextRun* run) {
10561056
const wchar_t* run_text = &(GetLayoutText()[run->range.start()]);
10571057
Font original_font = run->font;
10581058
LinkedFontsIterator fonts(original_font);
1059-
bool tried_cached_font = false;
1060-
bool tried_fallback = false;
1059+
1060+
run->logical_clusters.reset(new WORD[run_length]);
1061+
1062+
// Try to shape with the first font in the fallback list, which is
1063+
// |original_font|.
1064+
Font current_font;
1065+
fonts.NextFont(&current_font);
1066+
int missing_count = CountCharsWithMissingGlyphs(run,
1067+
ShapeTextRunWithFont(run, current_font));
1068+
if (missing_count == 0)
1069+
return;
1070+
10611071
// Keep track of the font that is able to display the greatest number of
10621072
// characters for which ScriptShape() returned S_OK. This font will be used
10631073
// in the case where no font is able to display the entire run.
1064-
int best_partial_font_missing_char_count = INT_MAX;
1065-
Font best_partial_font = original_font;
1066-
Font current_font;
1067-
1068-
run->logical_clusters.reset(new WORD[run_length]);
1069-
while (fonts.NextFont(&current_font)) {
1070-
HRESULT hr = ShapeTextRunWithFont(run, current_font);
1071-
1072-
bool glyphs_missing = false;
1073-
if (hr == USP_E_SCRIPT_NOT_IN_FONT) {
1074-
glyphs_missing = true;
1075-
} else if (hr == S_OK) {
1076-
// If |hr| is S_OK, there could still be missing glyphs in the output.
1077-
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564.aspx
1078-
const int missing_count = CountCharsWithMissingGlyphs(run);
1079-
// Track the font that produced the least missing glyphs.
1080-
if (missing_count < best_partial_font_missing_char_count) {
1081-
best_partial_font_missing_char_count = missing_count;
1082-
best_partial_font = run->font;
1083-
}
1084-
glyphs_missing = (missing_count != 0);
1085-
} else {
1086-
NOTREACHED() << hr;
1074+
int best_partial_font_missing_char_count = missing_count;
1075+
Font best_partial_font = current_font;
1076+
1077+
// Try to shape with the cached font from previous runs, if any.
1078+
std::map<std::string, Font>::const_iterator it =
1079+
successful_substitute_fonts_.find(original_font.GetFontName());
1080+
if (it != successful_substitute_fonts_.end()) {
1081+
current_font = it->second;
1082+
missing_count = CountCharsWithMissingGlyphs(run,
1083+
ShapeTextRunWithFont(run, current_font));
1084+
if (missing_count == 0)
1085+
return;
1086+
if (missing_count < best_partial_font_missing_char_count) {
1087+
best_partial_font_missing_char_count = missing_count;
1088+
best_partial_font = current_font;
10871089
}
1090+
}
10881091

1089-
// Use the font if it had glyphs for all characters.
1090-
if (!glyphs_missing) {
1091-
// Save the successful fallback font that was chosen.
1092-
if (tried_fallback)
1093-
successful_substitute_fonts_[original_font.GetFontName()] = run->font;
1092+
// Try finding a fallback font using a meta file.
1093+
// TODO(msw|asvitkine): Support RenderText's font_list()?
1094+
if (ChooseFallbackFont(cached_hdc_, run->font, run_text, run_length,
1095+
&current_font)) {
1096+
missing_count = CountCharsWithMissingGlyphs(run,
1097+
ShapeTextRunWithFont(run, current_font));
1098+
if (missing_count == 0) {
1099+
successful_substitute_fonts_[original_font.GetFontName()] = current_font;
10941100
return;
10951101
}
1096-
1097-
// First, try the cached font from previous runs, if any.
1098-
if (!tried_cached_font) {
1099-
tried_cached_font = true;
1100-
1101-
std::map<std::string, Font>::const_iterator it =
1102-
successful_substitute_fonts_.find(original_font.GetFontName());
1103-
if (it != successful_substitute_fonts_.end()) {
1104-
fonts.SetNextFont(it->second);
1105-
continue;
1106-
}
1102+
if (missing_count < best_partial_font_missing_char_count) {
1103+
best_partial_font_missing_char_count = missing_count;
1104+
best_partial_font = current_font;
11071105
}
1106+
}
11081107

1109-
// If there are missing glyphs, first try finding a fallback font using a
1110-
// meta file, if it hasn't yet been attempted for this run.
1111-
// TODO(msw|asvitkine): Support RenderText's font_list()?
1112-
if (!tried_fallback) {
1113-
tried_fallback = true;
1114-
1115-
Font fallback_font;
1116-
if (ChooseFallbackFont(cached_hdc_, run->font, run_text, run_length,
1117-
&fallback_font)) {
1118-
fonts.SetNextFont(fallback_font);
1119-
continue;
1120-
}
1108+
// Try the rest of fonts in the fallback list.
1109+
while (fonts.NextFont(&current_font)) {
1110+
missing_count = CountCharsWithMissingGlyphs(run,
1111+
ShapeTextRunWithFont(run, current_font));
1112+
if (missing_count == 0) {
1113+
successful_substitute_fonts_[original_font.GetFontName()] = current_font;
1114+
return;
1115+
}
1116+
if (missing_count < best_partial_font_missing_char_count) {
1117+
best_partial_font_missing_char_count = missing_count;
1118+
best_partial_font = current_font;
11211119
}
11221120
}
11231121

@@ -1208,7 +1206,15 @@ HRESULT RenderTextWin::ShapeTextRunWithFont(internal::TextRun* run,
12081206
return hr;
12091207
}
12101208

1211-
int RenderTextWin::CountCharsWithMissingGlyphs(internal::TextRun* run) const {
1209+
int RenderTextWin::CountCharsWithMissingGlyphs(internal::TextRun* run,
1210+
HRESULT shaping_result) const {
1211+
if (shaping_result != S_OK) {
1212+
DCHECK_EQ(shaping_result, USP_E_SCRIPT_NOT_IN_FONT);
1213+
return INT_MAX;
1214+
}
1215+
1216+
// If |hr| is S_OK, there could still be missing glyphs in the output.
1217+
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564.aspx
12121218
int chars_not_missing_glyphs = 0;
12131219
SCRIPT_FONTPROPERTIES properties;
12141220
memset(&properties, 0, sizeof(properties));

ui/gfx/render_text_win.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class RenderTextWin : public RenderText {
100100
HRESULT ShapeTextRunWithFont(internal::TextRun* run, const Font& font);
101101

102102
// Returns the number of characters in |run| that have missing glyphs.
103-
int CountCharsWithMissingGlyphs(internal::TextRun* run) const;
103+
int CountCharsWithMissingGlyphs(internal::TextRun* run,
104+
HRESULT shaping_result) const;
104105

105106
// Return the run index that contains the argument; or the length of the
106107
// |runs_| vector if argument exceeds the text length or width.

0 commit comments

Comments
 (0)