Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / gfx / font_fallback_linux.cc
blob5b7e4f10499a4679207b800059880292b704d229
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/gfx/font_fallback.h"
7 #include <fontconfig/fontconfig.h>
9 #include <map>
10 #include <string>
11 #include <vector>
13 #include "base/lazy_instance.h"
15 namespace gfx {
17 namespace {
19 typedef std::map<std::string, std::vector<std::string> > FallbackCache;
20 base::LazyInstance<FallbackCache>::Leaky g_fallback_cache =
21 LAZY_INSTANCE_INITIALIZER;
23 } // namespace
25 std::vector<std::string> GetFallbackFontFamilies(
26 const std::string& font_family) {
27 std::vector<std::string>* fallback_fonts =
28 &g_fallback_cache.Get()[font_family];
29 if (!fallback_fonts->empty())
30 return *fallback_fonts;
32 FcPattern* pattern = FcPatternCreate();
33 FcValue family;
34 family.type = FcTypeString;
35 family.u.s = reinterpret_cast<const FcChar8*>(font_family.c_str());
36 FcPatternAdd(pattern, FC_FAMILY, family, FcFalse);
37 if (FcConfigSubstitute(NULL, pattern, FcMatchPattern) == FcTrue) {
38 FcDefaultSubstitute(pattern);
39 FcResult result;
40 FcFontSet* fonts = FcFontSort(NULL, pattern, FcTrue, NULL, &result);
41 if (fonts) {
42 for (int i = 0; i < fonts->nfont; ++i) {
43 char* name = NULL;
44 FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0,
45 reinterpret_cast<FcChar8**>(&name));
46 // FontConfig returns multiple fonts with the same family name and
47 // different configurations. Check to prevent duplicate family names.
48 if (fallback_fonts->empty() || fallback_fonts->back() != name)
49 fallback_fonts->push_back(std::string(name));
51 FcFontSetDestroy(fonts);
54 FcPatternDestroy(pattern);
56 if (fallback_fonts->empty())
57 fallback_fonts->push_back(font_family);
59 return *fallback_fonts;
62 } // namespace gfx