Index: ui/gfx/render_text_harfbuzz.cc |
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc |
index 5c2ecb3755c929683c1e1e34fba82ce457c11330..88b184255170672c0c5c7166f96f4e455b5a532b 100644 |
--- a/ui/gfx/render_text_harfbuzz.cc |
+++ b/ui/gfx/render_text_harfbuzz.cc |
@@ -454,6 +454,12 @@ void TextRunHarfBuzz::GetClusterAt(size_t pos, |
DCHECK(chars); |
DCHECK(glyphs); |
+ if (glyph_count == 0) { |
+ *chars = range; |
+ *glyphs = Range(); |
+ return; |
+ } |
+ |
if (is_rtl) { |
GetClusterAtImpl(pos, range, glyph_to_char.rbegin(), glyph_to_char.rend(), |
true, chars, glyphs); |
@@ -491,6 +497,8 @@ Range TextRunHarfBuzz::GetGraphemeBounds( |
base::i18n::BreakIterator* grapheme_iterator, |
size_t text_index) { |
DCHECK_LT(text_index, range.end()); |
+ if (glyph_count == 0) |
+ return Range(preceding_run_widths, preceding_run_widths + width); |
Range chars; |
Range glyphs; |
@@ -1008,19 +1016,29 @@ void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { |
const std::string primary_font_name = primary_font.GetFontName(); |
run->font_size = primary_font.GetFontSize(); |
+ size_t best_font_missing = std::numeric_limits<size_t>::max(); |
+ std::string best_font; |
+ std::string current_font; |
+ |
// Try shaping with |primary_font|. |
- ShapeRunWithFont(run, primary_font_name); |
- size_t best_font_missing = run->CountMissingGlyphs(); |
- if (best_font_missing == 0) |
- return; |
- std::string best_font = primary_font_name; |
+ if (ShapeRunWithFont(run, primary_font_name)) { |
+ current_font = primary_font_name; |
+ size_t current_missing = run->CountMissingGlyphs(); |
+ if (current_missing == 0) |
+ return; |
+ if (current_missing < best_font_missing) { |
+ best_font_missing = current_missing; |
+ best_font = primary_font_name; |
msw
2014/08/02 18:05:33
nit: s/primary_font_name/current_font/
ckocagil
2014/08/03 03:36:54
Done.
|
+ } |
+ } |
#if defined(OS_WIN) |
Font uniscribe_font; |
const base::char16* run_text = &(GetLayoutText()[run->range.start()]); |
if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(), |
- &uniscribe_font)) { |
- ShapeRunWithFont(run, uniscribe_font.GetFontName()); |
+ &uniscribe_font) && |
+ ShapeRunWithFont(run, uniscribe_font.GetFontName())) { |
+ current_font = uniscribe_font.GetFontName(); |
size_t current_missing = run->CountMissingGlyphs(); |
if (current_missing == 0) |
return; |
@@ -1035,7 +1053,9 @@ void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { |
// |primary_font|. |
std::vector<std::string> fonts = GetFallbackFontFamilies(primary_font_name); |
for (size_t i = 1; i < fonts.size(); ++i) { |
- ShapeRunWithFont(run, fonts[i]); |
+ if (!ShapeRunWithFont(run, fonts[i])) |
+ continue; |
+ current_font = fonts[i]; |
size_t current_missing = run->CountMissingGlyphs(); |
if (current_missing == 0) |
return; |
@@ -1045,13 +1065,23 @@ void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { |
} |
} |
- ShapeRunWithFont(run, best_font); |
+ if (!best_font.empty() && |
+ (best_font == current_font || ShapeRunWithFont(run, best_font))) { |
+ return; |
+ } |
+ |
+ run->glyph_count = 0; |
+ run->width = 0; |
} |
-void RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run, |
+bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run, |
const std::string& font_family) { |
const base::string16& text = GetLayoutText(); |
- run->skia_face = internal::CreateSkiaTypeface(font_family, run->font_style); |
+ skia::RefPtr<SkTypeface> skia_face = |
+ internal::CreateSkiaTypeface(font_family, run->font_style); |
+ if (skia_face == NULL) |
+ return false; |
+ run->skia_face = skia_face; |
hb_font_t* harfbuzz_font = CreateHarfBuzzFont(run->skia_face.get(), |
run->font_size); |
@@ -1094,6 +1124,7 @@ void RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run, |
hb_buffer_destroy(buffer); |
hb_font_destroy(harfbuzz_font); |
+ return true; |
} |
} // namespace gfx |