+ size_t best_font_missing = std::numeric_limits<size_t>::max();
+ std::string best_font;
+ std::string current_font;
+
+ // Try shaping with |primary_font|.
+ 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 = current_font;
+ }
+ }
+
+#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())) {
+ current_font = uniscribe_font.GetFontName();
+ size_t current_missing = run->CountMissingGlyphs();
+ if (current_missing == 0)
+ return;
+ if (current_missing < best_font_missing) {
+ best_font_missing = current_missing;
+ best_font = current_font;
+ }
+ }
+#endif
+
+ // Try shaping with the fonts in the fallback list except the first, which is
+ // |primary_font|.
+ std::vector<std::string> fonts = GetFallbackFontFamilies(primary_font_name);
+ for (size_t i = 1; i < fonts.size(); ++i) {
+ if (!ShapeRunWithFont(run, fonts[i]))
+ continue;
+ current_font = fonts[i];
+ size_t current_missing = run->CountMissingGlyphs();
+ if (current_missing == 0)
+ return;
+ if (current_missing < best_font_missing) {
+ best_font_missing = current_missing;
+ best_font = current_font;
+ }
+ }
+
+ if (!best_font.empty() &&
+ (best_font == current_font || ShapeRunWithFont(run, best_font))) {
+ return;
+ }
+
+ run->glyph_count = 0;
+ run->width = 0.0f;
+}
+
+bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run,
+ const std::string& font_family) {
+ const base::string16& text = GetLayoutText();
+ skia::RefPtr<SkTypeface> skia_face =
+ internal::CreateSkiaTypeface(font_family, run->font_style);
+ if (skia_face == NULL)
+ return false;
+ run->skia_face = skia_face;