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. 4 5#include "ui/gfx/font_fallback.h" 6 7#include <fontconfig/fontconfig.h> 8 9#include <map> 10#include <string> 11#include <vector> 12 13#include "base/lazy_instance.h" 14 15namespace gfx { 16 17namespace { 18 19typedef std::map<std::string, std::vector<std::string> > FallbackCache; 20base::LazyInstance<FallbackCache>::Leaky g_fallback_cache = 21 LAZY_INSTANCE_INITIALIZER; 22 23} // namespace 24 25std::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; 31 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)); 50 } 51 FcFontSetDestroy(fonts); 52 } 53 } 54 FcPatternDestroy(pattern); 55 56 if (fallback_fonts->empty()) 57 fallback_fonts->push_back(font_family); 58 59 return *fallback_fonts; 60} 61 62} // namespace gfx 63