--- base/test/fontconfig_util_linux.cc.orig 2019-04-30 22:22:28 UTC +++ base/test/fontconfig_util_linux.cc @@ -6,24 +6,397 @@ #include -#include - #include "base/base_paths.h" #include "base/environment.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" +#include "base/macros.h" #include "base/path_service.h" +#include "base/strings/string_util.h" namespace base { +namespace { + +const char kFontsConfTemplate[] = R"( + + + + + $1 + + + $2 + + + + + false + + + + + + Times + + + Tinos + + + + + + sans + + + DejaVu Sans + + + + + + sans serif + + + Arimo + + + + + + + Helvetica + + + Arimo + + + + + + sans-serif + + + Arimo + + + + + + serif + + + Tinos + + + + + + mono + + + Cousine + + + + + + monospace + + + Cousine + + + + + + Courier + + + Cousine + + + + + + cursive + + + Comic Sans MS + + + + + + fantasy + + + Impact + + + + + + Monaco + + + Tinos + + + + + + Arial + + + Arimo + + + + + + Courier New + + + Cousine + + + + + + Georgia + + + Gelasio + + + + + + Times New Roman + + + Tinos + + + + + + Verdana + + + + Arimo + + + + + + + NonAntiAliasedSans + + + Arimo + + + false + + + + + + SlightHintedGeorgia + + + Gelasio + + + hintslight + + + + + + NonHintedSans + + + Arimo + + + + hintfull + + + false + + + + + + AutohintedSerif + + + Arimo + + + true + + + hintmedium + + + + + + HintedSerif + + + Arimo + + + false + + + hintmedium + + + + + + FullAndAutoHintedSerif + + + Arimo + + + true + + + hintfull + + + + + + SubpixelEnabledArial + + + Arimo + + + rgb + + + + + + SubpixelDisabledArial + + + Arimo + + + none + + + + + + + SubpixelPositioning + + + Tinos + + + + + + + SubpixelPositioningAhem + + + ahem + + + + + + SlightHintedTimesNewRoman + + + Tinos + + + hintslight + + + + + + + DejaVu Sans + + + + +)"; + +} // namespace + void SetUpFontconfig() { - FilePath dir_module; - CHECK(PathService::Get(DIR_MODULE, &dir_module)); + std::unique_ptr env = Environment::Create(); + if (!env->HasVar("FONTCONFIG_FILE")) { + // fonts.conf must be generated on-the-fly since it contains absolute paths + // which may be different if + // 1. The user moves/renames their build directory (or any parent dirs). + // 2. The build directory is mapped on a swarming bot at a location + // different from the one the buildbot used. + FilePath dir_module; + PathService::Get(DIR_MODULE, &dir_module); + FilePath font_cache = dir_module.Append("fontconfig_caches"); + FilePath test_fonts = dir_module.Append("test_fonts"); + std::string fonts_conf = ReplaceStringPlaceholders( + kFontsConfTemplate, {font_cache.value(), test_fonts.value()}, nullptr); - std::unique_ptr env(Environment::Create()); - // TODO(thomasanderson): This still stat()'s the real /etc/fonts/fonts.conf. - // Prevent fontconfig from doing this. - CHECK(env->SetVar("FONTCONFIG_SYSROOT", dir_module.value().c_str())); + // Write the data to a different file and then atomically rename it to + // fonts.conf. This avoids the file being in a bad state when different + // parallel tests call this function at the same time. + FilePath fonts_conf_file_temp; + if(!CreateTemporaryFileInDir(dir_module, &fonts_conf_file_temp)) + CHECK(CreateTemporaryFile(&fonts_conf_file_temp)); + CHECK( + WriteFile(fonts_conf_file_temp, fonts_conf.c_str(), fonts_conf.size())); + FilePath fonts_conf_file = dir_module.Append("fonts.conf"); + if (ReplaceFile(fonts_conf_file_temp, fonts_conf_file, nullptr)) + env->SetVar("FONTCONFIG_FILE", fonts_conf_file.value()); + else + env->SetVar("FONTCONFIG_FILE", fonts_conf_file_temp.value()); + } } } // namespace base