Chromium Code Reviews| Index: ui/gfx/render_text_win.cc |
| =================================================================== |
| --- ui/gfx/render_text_win.cc (revision 145877) |
| +++ ui/gfx/render_text_win.cc (working copy) |
| @@ -679,6 +679,12 @@ |
| size_t linked_font_index = 0; |
| const std::vector<Font>* linked_fonts = NULL; |
| Font original_font = run->font; |
| + // Keep track of the font producing the least missing glyphs for which |
| + // ScriptShape() returned S_OK. This font will be used in the case where |
| + // no font is able to display all the characters in this run. |
| + int least_missing_count = INT_MAX; |
|
msw
2012/07/10 20:52:15
nit: optionally rename this for more context, like
Alexei Svitkine (slow)
2012/07/10 21:16:35
Done.
|
| + Font best_partial_font = run->font; |
| + bool using_best_partial_font = false; |
| // Select the font desired for glyph generation. |
| SelectObject(cached_hdc_, run->font.GetNativeFont()); |
| @@ -711,13 +717,20 @@ |
| } else if (hr == S_OK) { |
| // If |hr| is S_OK, there could still be missing glyphs in the output, |
| // see: http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564.aspx |
| - glyphs_missing = HasMissingGlyphs(run); |
| + const int missing_count = CountCharsWithMissingGlyphs(run); |
| + // Track the font that produced the least missing glyphs. |
| + if (missing_count < least_missing_count) { |
| + least_missing_count = missing_count; |
| + best_partial_font = run->font; |
| + } |
| + glyphs_missing = (missing_count != 0); |
| } |
| - // Skip font substitution if there are no missing glyphs. |
| - if (!glyphs_missing) { |
| + // Skip font substitution if there are no missing glyphs or if the font |
| + // with the least missing glyphs is being used as a last resort. |
| + if (!glyphs_missing || using_best_partial_font) { |
| // Save the successful fallback font that was chosen. |
| - if (tried_fallback) |
| + if (tried_fallback && !using_best_partial_font) |
| successful_substitute_fonts_[original_font.GetFontName()] = run->font; |
| break; |
| } |
| @@ -765,8 +778,25 @@ |
| linked_fonts = GetLinkedFonts(run->font); |
| } |
| - // None of the linked fonts worked, break out of the loop. |
| + // None of the fallback fonts were able to display the entire run. |
| if (linked_font_index == linked_fonts->size()) { |
| + // If there was a font that was able to partially display the run, use |
|
msw
2012/07/10 20:52:15
nit: make one-liner as "If a font could partially
Alexei Svitkine (slow)
2012/07/10 21:16:35
Done.
|
| + // that now. |
| + if (least_missing_count != INT_MAX) { |
| + ApplySubstituteFont(run, best_partial_font); |
| + using_best_partial_font = true; |
| + continue; |
| + } |
| + |
| + // If no font was able to partially display the run, replace all glyphs |
|
msw
2012/07/10 20:52:15
In the bug, you wrote (and I agree that) "In the f
Alexei Svitkine (slow)
2012/07/10 21:16:35
You're right that this is not solving that specifi
msw
2012/07/10 21:40:24
sgtm
|
| + // with |wgDefault| to ensure they don't hold garbage values. |
| + SCRIPT_FONTPROPERTIES properties; |
| + memset(&properties, 0, sizeof(properties)); |
| + properties.cBytes = sizeof(properties); |
| + ScriptGetFontProperties(cached_hdc_, &run->script_cache, &properties); |
| + for (int i = 0; i < run->glyph_count; ++i) |
| + run->glyphs[i] = properties.wgDefault; |
| + |
| // TODO(msw): Don't use SCRIPT_UNDEFINED. Apparently Uniscribe can |
| // crash on certain surrogate pairs with SCRIPT_UNDEFINED. |
| // See https://bugzilla.mozilla.org/show_bug.cgi?id=341500 |
| @@ -841,7 +871,8 @@ |
| SelectObject(cached_hdc_, run->font.GetNativeFont()); |
| } |
| -bool RenderTextWin::HasMissingGlyphs(internal::TextRun* run) const { |
| +int RenderTextWin::CountCharsWithMissingGlyphs(internal::TextRun* run) const { |
| + int chars_not_missing_glyphs = 0; |
|
msw
2012/07/10 20:52:15
Isn't this counting the number glyphs found? (not
Alexei Svitkine (slow)
2012/07/10 21:16:35
It is counting chars, in fact, due to how the loop
|
| SCRIPT_FONTPROPERTIES properties; |
| memset(&properties, 0, sizeof(properties)); |
| properties.cBytes = sizeof(properties); |
| @@ -854,7 +885,7 @@ |
| DCHECK_LT(glyph_index, run->glyph_count); |
| if (run->glyphs[glyph_index] == properties.wgDefault) |
| - return true; |
| + continue; |
| // Windows Vista sometimes returns glyphs equal to wgBlank (instead of |
| // wgDefault), with fZeroWidth set. Treat such cases as having missing |
| @@ -864,11 +895,13 @@ |
| run->visible_attributes[glyph_index].fZeroWidth && |
| !IsWhitespace(run_text[char_index]) && |
| !IsUnicodeBidiControlCharacter(run_text[char_index])) { |
| - return true; |
| + continue; |
| } |
| + |
| + ++chars_not_missing_glyphs; |
| } |
| - return false; |
| + return run->range.length() - chars_not_missing_glyphs; |
|
msw
2012/07/10 20:52:15
Shouldn't this be "return run->glyph_count - glyph
Alexei Svitkine (slow)
2012/07/10 21:16:35
Nope, it shouldn't. See above.
It can't be negati
|
| } |
| const std::vector<Font>* RenderTextWin::GetLinkedFonts(const Font& font) const { |