Commit faf4a063 authored by derat's avatar derat Committed by Commit bot

Avoid extra FontRenderParams queries in RenderTextHarfBuzz.

gfx::Font already contains a FontRenderParams struct. Make
RenderTextHarfBuzz use it when possible instead of always
querying for a new struct.

BUG=none

Review URL: https://codereview.chromium.org/674683003

Cr-Commit-Position: refs/heads/master@{#301101}
parent c5bdcca1
...@@ -1070,82 +1070,83 @@ void RenderTextHarfBuzz::ItemizeText() { ...@@ -1070,82 +1070,83 @@ void RenderTextHarfBuzz::ItemizeText() {
ubidi_reorderLogical(&levels[0], num_runs, &logical_to_visual_[0]); ubidi_reorderLogical(&levels[0], num_runs, &logical_to_visual_[0]);
} }
bool RenderTextHarfBuzz::CompareFamily(
internal::TextRunHarfBuzz* run,
const std::string& family,
const gfx::FontRenderParams& render_params,
std::string* best_family,
gfx::FontRenderParams* best_render_params,
size_t* best_missing_glyphs) {
if (!ShapeRunWithFont(run, family, render_params))
return false;
const size_t missing_glyphs = run->CountMissingGlyphs();
if (missing_glyphs < *best_missing_glyphs) {
*best_family = family;
*best_render_params = render_params;
*best_missing_glyphs = missing_glyphs;
}
return missing_glyphs == 0;
}
void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) {
const Font& primary_font = font_list().GetPrimaryFont(); const Font& primary_font = font_list().GetPrimaryFont();
const std::string primary_font_name = primary_font.GetFontName();
run->font_size = primary_font.GetFontSize(); run->font_size = primary_font.GetFontSize();
size_t best_font_missing = std::numeric_limits<size_t>::max(); std::string best_family;
std::string best_font; FontRenderParams best_render_params;
std::string current_font; size_t best_missing_glyphs = std::numeric_limits<size_t>::max();
// Try shaping with |primary_font|. if (CompareFamily(run, primary_font.GetFontName(),
if (ShapeRunWithFont(run, primary_font_name)) { primary_font.GetFontRenderParams(),
current_font = primary_font_name; &best_family, &best_render_params, &best_missing_glyphs))
size_t current_missing = run->CountMissingGlyphs(); return;
if (current_missing == 0)
return;
if (current_missing < best_font_missing) {
best_font_missing = current_missing;
best_font = current_font;
}
}
#if defined(OS_WIN) #if defined(OS_WIN)
Font uniscribe_font; Font uniscribe_font;
const base::char16* run_text = &(GetLayoutText()[run->range.start()]); const base::char16* run_text = &(GetLayoutText()[run->range.start()]);
if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(), if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(),
&uniscribe_font) && &uniscribe_font) &&
ShapeRunWithFont(run, uniscribe_font.GetFontName())) { CompareFamily(run, uniscribe_font.GetFontName(),
current_font = uniscribe_font.GetFontName(); uniscribe_font.GetFontRenderParams(),
size_t current_missing = run->CountMissingGlyphs(); &best_family, &best_render_params, &best_missing_glyphs))
if (current_missing == 0) return;
return;
if (current_missing < best_font_missing) {
best_font_missing = current_missing;
best_font = current_font;
}
}
#endif #endif
// Try shaping with the fonts in the fallback list except the first, which is // Skip the first fallback font, which is |primary_font|.
// |primary_font|. std::vector<std::string> fallback_families =
std::vector<std::string> fonts = GetFallbackFontFamilies(primary_font_name); GetFallbackFontFamilies(primary_font.GetFontName());
for (size_t i = 1; i < fonts.size(); ++i) { for (size_t i = 1; i < fallback_families.size(); ++i) {
if (!ShapeRunWithFont(run, fonts[i])) FontRenderParamsQuery query(false);
continue; query.families.push_back(fallback_families[i]);
current_font = fonts[i]; query.pixel_size = run->font_size;
size_t current_missing = run->CountMissingGlyphs(); query.style = run->font_style;
if (current_missing == 0) FontRenderParams fallback_render_params = GetFontRenderParams(query, NULL);
if (CompareFamily(run, fallback_families[i], fallback_render_params,
&best_family, &best_render_params, &best_missing_glyphs))
return; return;
if (current_missing < best_font_missing) {
best_font_missing = current_missing;
best_font = current_font;
}
} }
if (!best_font.empty() && if (!best_family.empty() &&
(best_font == current_font || ShapeRunWithFont(run, best_font))) { (best_family == run->family ||
ShapeRunWithFont(run, best_family, best_render_params)))
return; return;
}
run->glyph_count = 0; run->glyph_count = 0;
run->width = 0.0f; run->width = 0.0f;
} }
bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run, bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run,
const std::string& font_family) { const std::string& font_family,
const FontRenderParams& params) {
const base::string16& text = GetLayoutText(); const base::string16& text = GetLayoutText();
skia::RefPtr<SkTypeface> skia_face = skia::RefPtr<SkTypeface> skia_face =
internal::CreateSkiaTypeface(font_family, run->font_style); internal::CreateSkiaTypeface(font_family, run->font_style);
if (skia_face == NULL) if (skia_face == NULL)
return false; return false;
run->skia_face = skia_face; run->skia_face = skia_face;
FontRenderParamsQuery query(false); run->family = font_family;
query.families.push_back(font_family); run->render_params = params;
query.pixel_size = run->font_size;
query.style = run->font_style;
run->render_params = GetFontRenderParams(query, NULL);
hb_font_t* harfbuzz_font = CreateHarfBuzzFont( hb_font_t* harfbuzz_font = CreateHarfBuzzFont(
run->skia_face.get(), SkIntToScalar(run->font_size), run->render_params, run->skia_face.get(), SkIntToScalar(run->font_size), run->render_params,
background_is_transparent()); background_is_transparent());
......
...@@ -60,6 +60,7 @@ struct GFX_EXPORT TextRunHarfBuzz { ...@@ -60,6 +60,7 @@ struct GFX_EXPORT TextRunHarfBuzz {
std::vector<uint32> glyph_to_char; std::vector<uint32> glyph_to_char;
size_t glyph_count; size_t glyph_count;
std::string family;
skia::RefPtr<SkTypeface> skia_face; skia::RefPtr<SkTypeface> skia_face;
FontRenderParams render_params; FontRenderParams render_params;
int font_size; int font_size;
...@@ -127,10 +128,23 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText { ...@@ -127,10 +128,23 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
// Break the text into logical runs and populate the visual <-> logical maps. // Break the text into logical runs and populate the visual <-> logical maps.
void ItemizeText(); void ItemizeText();
// Helper method for ShapeRun() that calls ShapeRunWithFont() with |run|,
// |family|, and |render_params|, returning true if the family provides all
// needed glyphs and false otherwise. Additionally updates |best_family|,
// |best_render_params|, and |best_missing_glyphs| if |family| has fewer than
// |best_missing_glyphs| missing glyphs.
bool CompareFamily(internal::TextRunHarfBuzz* run,
const std::string& family,
const gfx::FontRenderParams& render_params,
std::string* best_family,
gfx::FontRenderParams* best_render_params,
size_t* best_missing_glyphs);
// Shape the glyphs needed for the text |run|. // Shape the glyphs needed for the text |run|.
void ShapeRun(internal::TextRunHarfBuzz* run); void ShapeRun(internal::TextRunHarfBuzz* run);
bool ShapeRunWithFont(internal::TextRunHarfBuzz* run, bool ShapeRunWithFont(internal::TextRunHarfBuzz* run,
const std::string& font); const std::string& font_family,
const FontRenderParams& params);
// Text runs in logical order. // Text runs in logical order.
ScopedVector<internal::TextRunHarfBuzz> runs_; ScopedVector<internal::TextRunHarfBuzz> runs_;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/break_list.h" #include "ui/gfx/break_list.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/gfx/render_text_harfbuzz.h" #include "ui/gfx/render_text_harfbuzz.h"
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -2287,7 +2288,8 @@ TEST_F(RenderTextTest, HarfBuzz_NonExistentFont) { ...@@ -2287,7 +2288,8 @@ TEST_F(RenderTextTest, HarfBuzz_NonExistentFont) {
render_text.EnsureLayout(); render_text.EnsureLayout();
ASSERT_EQ(1U, render_text.runs_.size()); ASSERT_EQ(1U, render_text.runs_.size());
internal::TextRunHarfBuzz* run = render_text.runs_[0]; internal::TextRunHarfBuzz* run = render_text.runs_[0];
render_text.ShapeRunWithFont(run, "TheFontThatDoesntExist"); render_text.ShapeRunWithFont(
run, "TheFontThatDoesntExist", FontRenderParams());
} }
// Ensure an empty run returns sane values to queries. // Ensure an empty run returns sane values to queries.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment