Index: ui/gfx/font_render_params_linux.cc |
diff --git a/ui/gfx/font_render_params_linux.cc b/ui/gfx/font_render_params_linux.cc |
index ea0bac8c333819524e0a69f7c7198aeaeac3d607..09fd3dccff84aeaa3c8741f355a3653e33b1de94 100644 |
--- a/ui/gfx/font_render_params_linux.cc |
+++ b/ui/gfx/font_render_params_linux.cc |
@@ -12,6 +12,7 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
#include "base/macros.h" |
+#include "base/memory/scoped_ptr.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
#include "base/synchronization/lock.h" |
@@ -96,84 +97,97 @@ FontRenderParams::SubpixelRendering ConvertFontconfigRgba(int rgba) { |
bool QueryFontconfig(const FontRenderParamsQuery& query, |
FontRenderParams* params_out, |
std::string* family_out) { |
- FcPattern* query_pattern = FcPatternCreate(); |
+ struct FcPatternDeleter { |
+ void operator()(FcPattern* ptr) const { FcPatternDestroy(ptr); } |
+ }; |
+ typedef scoped_ptr<FcPattern, FcPatternDeleter> ScopedFcPattern; |
+ |
+ ScopedFcPattern query_pattern(FcPatternCreate()); |
CHECK(query_pattern); |
- FcPatternAddBool(query_pattern, FC_SCALABLE, FcTrue); |
+ FcPatternAddBool(query_pattern.get(), FC_SCALABLE, FcTrue); |
for (std::vector<std::string>::const_iterator it = query.families.begin(); |
it != query.families.end(); ++it) { |
- FcPatternAddString(query_pattern, |
+ FcPatternAddString(query_pattern.get(), |
FC_FAMILY, reinterpret_cast<const FcChar8*>(it->c_str())); |
} |
if (query.pixel_size > 0) |
- FcPatternAddDouble(query_pattern, FC_PIXEL_SIZE, query.pixel_size); |
+ FcPatternAddDouble(query_pattern.get(), FC_PIXEL_SIZE, query.pixel_size); |
if (query.point_size > 0) |
- FcPatternAddInteger(query_pattern, FC_SIZE, query.point_size); |
+ FcPatternAddInteger(query_pattern.get(), FC_SIZE, query.point_size); |
if (query.style >= 0) { |
- FcPatternAddInteger(query_pattern, FC_SLANT, |
+ FcPatternAddInteger(query_pattern.get(), FC_SLANT, |
(query.style & Font::ITALIC) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); |
- FcPatternAddInteger(query_pattern, FC_WEIGHT, |
+ FcPatternAddInteger(query_pattern.get(), FC_WEIGHT, |
(query.style & Font::BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); |
} |
- FcConfigSubstitute(NULL, query_pattern, FcMatchPattern); |
- FcDefaultSubstitute(query_pattern); |
+ FcConfigSubstitute(NULL, query_pattern.get(), FcMatchPattern); |
+ FcDefaultSubstitute(query_pattern.get()); |
- // If the query was non-empty, match a specific font and destroy the query |
- // pattern. Otherwise, just use the query pattern. |
- FcPattern* result_pattern = query_pattern; |
- if (!query.is_empty()) { |
+ ScopedFcPattern result_pattern; |
+ if (query.is_empty()) { |
+ // If the query was empty, call FcConfigSubstituteWithPat() to get |
+ // non-family-specific configuration so it can be used as the default. |
+ result_pattern.reset(FcPatternDuplicate(query_pattern.get())); |
+ if (!result_pattern) |
+ return false; |
+ FcPatternDel(result_pattern.get(), FC_FAMILY); |
+ FcConfigSubstituteWithPat(NULL, result_pattern.get(), query_pattern.get(), |
+ FcMatchFont); |
+ } else { |
FcResult result; |
- result_pattern = FcFontMatch(NULL, query_pattern, &result); |
- FcPatternDestroy(query_pattern); |
- query_pattern = NULL; |
+ result_pattern.reset(FcFontMatch(NULL, query_pattern.get(), &result)); |
if (!result_pattern) |
return false; |
} |
+ DCHECK(result_pattern); |
if (family_out) { |
FcChar8* family = NULL; |
- FcPatternGetString(result_pattern, FC_FAMILY, 0, &family); |
+ FcPatternGetString(result_pattern.get(), FC_FAMILY, 0, &family); |
if (family) |
family_out->assign(reinterpret_cast<const char*>(family)); |
} |
if (params_out) { |
FcBool fc_antialias = 0; |
- if (FcPatternGetBool(result_pattern, FC_ANTIALIAS, 0, &fc_antialias) == |
- FcResultMatch) { |
+ if (FcPatternGetBool(result_pattern.get(), FC_ANTIALIAS, 0, |
+ &fc_antialias) == FcResultMatch) { |
params_out->antialiasing = fc_antialias; |
} |
FcBool fc_autohint = 0; |
- if (FcPatternGetBool(result_pattern, FC_AUTOHINT, 0, &fc_autohint) == |
+ if (FcPatternGetBool(result_pattern.get(), FC_AUTOHINT, 0, &fc_autohint) == |
FcResultMatch) { |
params_out->autohinter = fc_autohint; |
} |
FcBool fc_bitmap = 0; |
- if (FcPatternGetBool(result_pattern, FC_EMBEDDED_BITMAP, 0, &fc_bitmap) == |
+ if (FcPatternGetBool(result_pattern.get(), FC_EMBEDDED_BITMAP, 0, |
+ &fc_bitmap) == |
FcResultMatch) { |
params_out->use_bitmaps = fc_bitmap; |
} |
FcBool fc_hinting = 0; |
- if (FcPatternGetBool(result_pattern, FC_HINTING, 0, &fc_hinting) == |
+ if (FcPatternGetBool(result_pattern.get(), FC_HINTING, 0, &fc_hinting) == |
FcResultMatch) { |
int fc_hint_style = FC_HINT_NONE; |
- if (fc_hinting) |
- FcPatternGetInteger(result_pattern, FC_HINT_STYLE, 0, &fc_hint_style); |
+ if (fc_hinting) { |
+ FcPatternGetInteger( |
+ result_pattern.get(), FC_HINT_STYLE, 0, &fc_hint_style); |
+ } |
params_out->hinting = ConvertFontconfigHintStyle(fc_hint_style); |
} |
int fc_rgba = FC_RGBA_NONE; |
- if (FcPatternGetInteger(result_pattern, FC_RGBA, 0, &fc_rgba) == |
+ if (FcPatternGetInteger(result_pattern.get(), FC_RGBA, 0, &fc_rgba) == |
FcResultMatch) |
params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); |
} |
- FcPatternDestroy(result_pattern); |
return true; |
} |