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

Unified Diff: ui/gfx/render_text_win.cc

Issue 10702126: RenderTextWin: Use a font that can at least partially display the run, if possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/render_text_win.cc
===================================================================
--- ui/gfx/render_text_win.cc (revision 145906)
+++ 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 that is able to display the greatest number of
+ // characters for which ScriptShape() returned S_OK. This font will be used
+ // in the case where no font is able to display the entire run.
+ int best_partial_font_missing_char_count = INT_MAX;
+ 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 < best_partial_font_missing_char_count) {
+ best_partial_font_missing_char_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,24 @@
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 a font was able to partially display the run, use that now.
+ if (best_partial_font_missing_char_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
+ // 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 +870,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;
SCRIPT_FONTPROPERTIES properties;
memset(&properties, 0, sizeof(properties));
properties.cBytes = sizeof(properties);
@@ -854,7 +884,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 +894,14 @@
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;
+ DCHECK_LE(chars_not_missing_glyphs, static_cast<int>(run->range.length()));
+ return run->range.length() - chars_not_missing_glyphs;
}
const std::vector<Font>* RenderTextWin::GetLinkedFonts(const Font& font) const {
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698