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 { |