// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/font_render_params.h"

#include <fontconfig/fontconfig.h>
#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/command_line.h"
#include "base/containers/mru_cache.h"
#include "base/hash/hash.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "ui/gfx/font.h"
#include "ui/gfx/linux/fontconfig_util.h"
#include "ui/gfx/skia_font_delegate.h"
#include "ui/gfx/switches.h"

namespace gfx {

namespace {

int FontWeightToFCWeight(Font::Weight weight) {
  const int weight_number = static_cast<int>(weight);
  if (weight_number <= (static_cast<int>(Font::Weight::THIN) +
                        static_cast<int>(Font::Weight::EXTRA_LIGHT)) /
                           2)
    return FC_WEIGHT_THIN;
  else if (weight_number <= (static_cast<int>(Font::Weight::EXTRA_LIGHT) +
                             static_cast<int>(Font::Weight::LIGHT)) /
                                2)
    return FC_WEIGHT_ULTRALIGHT;
  else if (weight_number <= (static_cast<int>(Font::Weight::LIGHT) +
                             static_cast<int>(Font::Weight::NORMAL)) /
                                2)
    return FC_WEIGHT_LIGHT;
  else if (weight_number <= (static_cast<int>(Font::Weight::NORMAL) +
                             static_cast<int>(Font::Weight::MEDIUM)) /
                                2)
    return FC_WEIGHT_NORMAL;
  else if (weight_number <= (static_cast<int>(Font::Weight::MEDIUM) +
                             static_cast<int>(Font::Weight::SEMIBOLD)) /
                                2)
    return FC_WEIGHT_MEDIUM;
  else if (weight_number <= (static_cast<int>(Font::Weight::SEMIBOLD) +
                             static_cast<int>(Font::Weight::BOLD)) /
                                2)
    return FC_WEIGHT_DEMIBOLD;
  else if (weight_number <= (static_cast<int>(Font::Weight::BOLD) +
                             static_cast<int>(Font::Weight::EXTRA_BOLD)) /
                                2)
    return FC_WEIGHT_BOLD;
  else if (weight_number <= (static_cast<int>(Font::Weight::EXTRA_BOLD) +
                             static_cast<int>(Font::Weight::BLACK)) /
                                2)
    return FC_WEIGHT_ULTRABOLD;
  else
    return FC_WEIGHT_BLACK;
}

// A device scale factor used to determine if subpixel positioning
// should be used.
float device_scale_factor_ = 1.0f;

// Number of recent GetFontRenderParams() results to cache.
const size_t kCacheSize = 256;

// Cached result from a call to GetFontRenderParams().
struct QueryResult {
  QueryResult(const FontRenderParams& params, const std::string& family)
      : params(params),
        family(family) {
  }
  ~QueryResult() {}

  FontRenderParams params;
  std::string family;
};

// Keyed by hashes of FontRenderParamQuery structs from
// HashFontRenderParamsQuery().
typedef base::MRUCache<uint32_t, QueryResult> Cache;

// A cache and the lock that must be held while accessing it.
// GetFontRenderParams() is called by both the UI thread and the sandbox IPC
// thread.
struct SynchronizedCache {
  SynchronizedCache() : cache(kCacheSize) {}

  base::Lock lock;
  Cache cache;
};

base::LazyInstance<SynchronizedCache>::Leaky g_synchronized_cache =
    LAZY_INSTANCE_INITIALIZER;

// Queries Fontconfig for rendering settings and updates |params_out| and
// |family_out| (if non-NULL). Returns false on failure.
bool QueryFontconfig(const FontRenderParamsQuery& query,
                     FontRenderParams* params_out,
                     std::string* family_out) {
  TRACE_EVENT0("fonts", "gfx::QueryFontconfig");

  ScopedFcPattern query_pattern(FcPatternCreate());
  CHECK(query_pattern);

  FcPatternAddBool(query_pattern.get(), FC_SCALABLE, FcTrue);

  for (auto it = query.families.begin(); it != query.families.end(); ++it) {
    FcPatternAddString(query_pattern.get(),
        FC_FAMILY, reinterpret_cast<const FcChar8*>(it->c_str()));
  }
  if (query.pixel_size > 0)
    FcPatternAddDouble(query_pattern.get(), FC_PIXEL_SIZE, query.pixel_size);
  if (query.point_size > 0)
    FcPatternAddInteger(query_pattern.get(), FC_SIZE, query.point_size);
  if (query.style >= 0) {
    FcPatternAddInteger(query_pattern.get(), FC_SLANT,
        (query.style & Font::ITALIC) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
  }
  if (query.weight != Font::Weight::INVALID) {
    FcPatternAddInteger(query_pattern.get(), FC_WEIGHT,
                        FontWeightToFCWeight(query.weight));
  }

  FcConfig* config = GetGlobalFontConfig();
  FcConfigSubstitute(config, query_pattern.get(), FcMatchPattern);
  FcDefaultSubstitute(query_pattern.get());

  ScopedFcPattern result_pattern;
  if (query.is_empty()) {
    // If the query was empty, call FcConfigSubstituteWithPat() to get a
    // non-family- or size-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);
    FcPatternDel(result_pattern.get(), FC_PIXEL_SIZE);
    FcPatternDel(result_pattern.get(), FC_SIZE);
    FcConfigSubstituteWithPat(config, result_pattern.get(), query_pattern.get(),
                              FcMatchFont);
  } else {
    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("fonts"), "FcFontMatch");
    FcResult result;
    result_pattern.reset(FcFontMatch(config, query_pattern.get(), &result));
    if (!result_pattern)
      return false;
  }
  DCHECK(result_pattern);

  if (family_out) {
    FcChar8* family = NULL;
    FcPatternGetString(result_pattern.get(), FC_FAMILY, 0, &family);
    if (family)
      family_out->assign(reinterpret_cast<const char*>(family));
  }

  if (params_out)
    GetFontRenderParamsFromFcPattern(result_pattern.get(), params_out);

  return true;
}

// Serialize |query| into a string and hash it to a value suitable for use as a
// cache key.
uint32_t HashFontRenderParamsQuery(const FontRenderParamsQuery& query) {
  return base::Hash(base::StringPrintf(
      "%d|%d|%d|%d|%s|%f", query.pixel_size, query.point_size, query.style,
      static_cast<int>(query.weight),
      base::JoinString(query.families, ",").c_str(),
      query.device_scale_factor));
}

}  // namespace

FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query,
                                     std::string* family_out) {
  TRACE_EVENT0("fonts", "gfx::GetFontRenderParams");

  FontRenderParamsQuery actual_query(query);
  if (actual_query.device_scale_factor == 0)
    actual_query.device_scale_factor = device_scale_factor_;

  const uint32_t hash = HashFontRenderParamsQuery(actual_query);
  SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer();

  {
    // Try to find a cached result so Fontconfig doesn't need to be queried.
    base::AutoLock lock(synchronized_cache->lock);
    Cache::const_iterator it = synchronized_cache->cache.Get(hash);
    if (it != synchronized_cache->cache.end()) {
      DVLOG(1) << "Returning cached params for " << hash;
      const QueryResult& result = it->second;
      if (family_out)
        *family_out = result.family;
      return result.params;
    }
  }

  DVLOG(1) << "Computing params for " << hash;
  if (family_out)
    family_out->clear();

  // Start with the delegate's settings, but let Fontconfig have the final say.
  FontRenderParams params;
  const SkiaFontDelegate* delegate = SkiaFontDelegate::instance();
  if (delegate)
    params = delegate->GetDefaultFontRenderParams();
  QueryFontconfig(actual_query, &params, family_out);
  if (!params.antialiasing) {
    // Cairo forces full hinting when antialiasing is disabled, since anything
    // less than that looks awful; do the same here. Requesting subpixel
    // rendering or positioning doesn't make sense either.
    params.hinting = FontRenderParams::HINTING_FULL;
    params.subpixel_rendering = FontRenderParams::SUBPIXEL_RENDERING_NONE;
    params.subpixel_positioning = false;
  } else if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
                 switches::kDisableFontSubpixelPositioning)) {
#if !defined(OS_CHROMEOS)
    params.subpixel_positioning = actual_query.device_scale_factor > 1.0f;
#else
    // We want to enable subpixel positioning for fractional dsf.
    params.subpixel_positioning =
        std::abs(std::round(actual_query.device_scale_factor) -
                 actual_query.device_scale_factor) >
        std::numeric_limits<float>::epsilon();
#endif  // !defined(OS_CHROMEOS)

    // To enable subpixel positioning, we need to disable hinting.
    if (params.subpixel_positioning)
      params.hinting = FontRenderParams::HINTING_NONE;
  }

  // Use the first family from the list if Fontconfig didn't suggest a family.
  if (family_out && family_out->empty() && !actual_query.families.empty())
    *family_out = actual_query.families[0];

  {
    // Store the result. It's fine if this overwrites a result that was cached
    // by a different thread in the meantime; the values should be identical.
    base::AutoLock lock(synchronized_cache->lock);
    synchronized_cache->cache.Put(hash,
        QueryResult(params, family_out ? *family_out : std::string()));
  }

  return params;
}

void ClearFontRenderParamsCacheForTest() {
  SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer();
  base::AutoLock lock(synchronized_cache->lock);
  synchronized_cache->cache.Clear();
}

float GetFontRenderParamsDeviceScaleFactor() {
  return device_scale_factor_;
}

void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) {
  device_scale_factor_ = device_scale_factor;
}

}  // namespace gfx
