// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h"

#include <cmath>
#include <limits>
#include <memory>

#include "SkOSFile.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkFreeType_cobalt.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.h"
#include "starboard/common/string.h"
#include "third_party/skia/src/utils/SkOSPath.h"

namespace {

int MatchScore(const SkFontStyle& pattern, const SkFontStyle& candidate) {
  // This logic is taken from Skia and is based upon the algorithm specified
  // within the spec:
  //   https://www.w3.org/TR/css-fonts-3/#font-matching-algorithm

  int score = 0;

  // CSS style (italic/oblique)
  // Being italic trumps all valid weights which are not italic.
  // Note that newer specs differentiate between italic and oblique.
  if ((pattern.slant() == SkFontStyle::kItalic_Slant) ==
      (candidate.slant() == SkFontStyle::kItalic_Slant)) {
    score += 1001;
  }

  // The 'closer' to the target weight, the higher the score.
  // 1000 is the 'heaviest' recognized weight
  if (pattern.weight() == candidate.weight()) {
    score += 1001;
  } else if (pattern.weight() <= 500) {
    if (400 <= pattern.weight() && pattern.weight() < 450) {
      if (450 <= candidate.weight() && candidate.weight() <= 500) {
        score += 500;
      }
    }
    if (candidate.weight() <= pattern.weight()) {
      score += 1000 - pattern.weight() + candidate.weight();
    } else {
      score += 1000 - candidate.weight();
    }
  } else if (pattern.weight() > 500) {
    if (candidate.weight() > pattern.weight()) {
      score += 1000 + pattern.weight() - candidate.weight();
    } else {
      score += candidate.weight();
    }
  }

  return score;
}

}  // namespace

SkFontStyleSet_Cobalt::SkFontStyleSet_Cobalt(
    const FontFamilyInfo& family_info, const char* base_path,
    SkFileMemoryChunkStreamManager* const local_typeface_stream_manager,
    SkMutex* const manager_owned_mutex, FontFormatSetting font_format_setting)
    : local_typeface_stream_manager_(local_typeface_stream_manager),
      manager_owned_mutex_(manager_owned_mutex),
      is_fallback_family_(family_info.is_fallback_family),
      language_(family_info.language),
      page_ranges_(family_info.page_ranges) {
  TRACE_EVENT0("cobalt::renderer",
               "SkFontStyleSet_Cobalt::SkFontStyleSet_Cobalt()");
  DCHECK(manager_owned_mutex_);

  if (family_info.names.count() == 0) {
    return;
  }

  disable_character_map_ = family_info.disable_caching;

  family_name_ = family_info.names[0];
  SkTHashMap<SkString, int> styles_index_map;

  for (int i = 0; i < family_info.fonts.count(); ++i) {
    const FontFileInfo& font_file = family_info.fonts[i];

    SkString file_path(SkOSPath::Join(base_path, font_file.file_name.c_str()));

    // Validate that the file exists at this location. If it does not, then skip
    // over it; it isn't being added to the set.
    if (!sk_exists(file_path.c_str(), kRead_SkFILE_Flag)) {
      DLOG(INFO) << "Failed to find font file: " << file_path.c_str();
      continue;
    }

    auto file_name = font_file.file_name.c_str();
    auto extension = strrchr(file_name, '.');
    if (!extension) {
      continue;
    }
    ++extension;

    // Only add font formats that match the format setting.
    if (font_format_setting == kTtf) {
      if (SbStringCompareNoCase("ttf", extension) != 0 &&
          SbStringCompareNoCase(extension, "ttc") != 0) {
        continue;
      }
    } else if (font_format_setting == kWoff2 &&
               SbStringCompareNoCase("woff2", extension) != 0) {
      continue;
    }

    SkFontStyle style(font_file.weight, SkFontStyle::kNormal_Width,
                      font_file.style == FontFileInfo::kItalic_FontStyle
                          ? SkFontStyle::kItalic_Slant
                          : SkFontStyle::kUpright_Slant);

    std::string full_font_name;
    if (!font_file.full_font_name.isEmpty()) {
      full_font_name = std::string(font_file.full_font_name.c_str(),
                                   font_file.full_font_name.size());
    }
    std::string postscript_name;
    if (!font_file.postscript_name.isEmpty()) {
      postscript_name = std::string(font_file.postscript_name.c_str(),
                                    font_file.postscript_name.size());
    }

    SkString font_name;
    if (full_font_name.empty()) {
      // If full font name is missing, use file name.
      size_t name_len = font_file.file_name.size() - strlen(extension) - 1;
      font_name = SkString(file_name, name_len);
    } else {
      font_name = SkString(full_font_name.c_str());
    }
    auto font = new SkFontStyleSetEntry_Cobalt(
        file_path, font_file.index, style, full_font_name, postscript_name,
        font_file.disable_synthetic_bolding);
    int* index = styles_index_map.find(font_name);
    if (index != NULL) {
      // If style with name already exists in family, replace it.
      if (font_format_setting == kTtfPreferred &&
          SbStringCompareNoCase("ttf", extension) == 0) {
        styles_[*index].reset(font);
      } else if (font_format_setting == kWoff2Preferred &&
                 SbStringCompareNoCase("woff2", extension) == 0) {
        styles_[*index].reset(font);
      }
    } else {
      int count = styles_.count();
      styles_index_map.set(font_name, count);
      styles_.push_back().reset(font);
    }
  }
}

int SkFontStyleSet_Cobalt::count() {
  SkAutoMutexExclusive scoped_mutex(*manager_owned_mutex_);
  return styles_.count();
}

void SkFontStyleSet_Cobalt::getStyle(int index, SkFontStyle* style,
                                     SkString* name) {
  // SkFontStyleSet_Cobalt does not support publicly interacting with entries
  // via index, as entries can potentially be removed, thereby invalidating the
  // indices.
  NOTREACHED();
}

SkTypeface* SkFontStyleSet_Cobalt::createTypeface(int index) {
  // SkFontStyleSet_Cobalt does not support publicly interacting with entries
  // via index, as entries can potentially be removed, thereby invalidating the
  // indices.
  NOTREACHED();
  return NULL;
}

SkTypeface* SkFontStyleSet_Cobalt::matchStyle(const SkFontStyle& pattern) {
  SkAutoMutexExclusive scoped_mutex(*manager_owned_mutex_);
  return MatchStyleWithoutLocking(pattern);
}

SkTypeface* SkFontStyleSet_Cobalt::MatchStyleWithoutLocking(
    const SkFontStyle& pattern) {
  SkTypeface* typeface = NULL;
  while (typeface == NULL && styles_.count() > 0) {
    typeface = TryRetrieveTypefaceAndRemoveStyleOnFailure(
        GetClosestStyleIndex(pattern));
  }
  return typeface;
}

SkTypeface* SkFontStyleSet_Cobalt::MatchFullFontName(const std::string& name) {
  for (int i = 0; i < styles_.count(); ++i) {
    if (styles_[i]->full_font_name == name) {
      return TryRetrieveTypefaceAndRemoveStyleOnFailure(i);
    }
  }
  return NULL;
}

SkTypeface* SkFontStyleSet_Cobalt::MatchFontPostScriptName(
    const std::string& name) {
  for (int i = 0; i < styles_.count(); ++i) {
    if (styles_[i]->font_postscript_name == name) {
      return TryRetrieveTypefaceAndRemoveStyleOnFailure(i);
    }
  }
  return NULL;
}

SkTypeface* SkFontStyleSet_Cobalt::TryRetrieveTypefaceAndRemoveStyleOnFailure(
    int style_index) {
  DCHECK(style_index >= 0 && style_index < styles_.count());
  SkFontStyleSetEntry_Cobalt* style = styles_[style_index].get();
  // If the typeface doesn't already exist, then attempt to create it.
  if (style->typeface == NULL) {
    CreateStreamProviderTypeface(style, style_index);
    // If the creation attempt failed and the typeface is still NULL, then
    // remove the entry from the set's styles.
    if (style->typeface == NULL) {
      styles_[style_index].swap(styles_.back());
      styles_.pop_back();
      return NULL;
    }
  }
  return SkRef(style->typeface.get());
}

bool SkFontStyleSet_Cobalt::ContainsTypeface(const SkTypeface* typeface) {
  for (int i = 0; i < styles_.count(); ++i) {
    if (styles_[i]->typeface.get() == typeface) {
      return true;
    }
  }
  return false;
}

bool SkFontStyleSet_Cobalt::ContainsCharacter(const SkFontStyle& style,
                                              SkUnichar character) {
  // If page ranges exist for this style set, then verify that this character
  // falls within the ranges. Otherwise, the style set is treated as having a
  // page range containing all characters.
  size_t num_ranges = page_ranges_.count();
  if (num_ranges > 0) {
    int16 page = font_character_map::GetPage(character);

    // Verify that the last page range is not less than the page containing the
    // character. If it's less, then this character can't be contained
    // within the pages. Otherwise, this last range acts as a sentinel for the
    // search.
    if (page_ranges_[num_ranges - 1].second < page) {
      return false;
    }

    int range_index = 0;
    while (page_ranges_[range_index].second < page) {
      ++range_index;
    }

    if (page_ranges_[range_index].first > page) {
      return false;
    }
  }

  // If this point is reached, then the character is contained within one of
  // the font style set's page ranges. Now, verify that the specific character
  // is supported by the font style set.

  // The character map is lazily generated. Generate it now if it isn't already
  // generated.
  int style_index = GetClosestStyleIndex(style);
  if (!character_maps_[style_index]) {
    TRACE_EVENT0("cobalt::renderer",
                 "SkFontStyleSet_Cobalt::ContainsCharacter() and "
                 "!is_character_map_generated_");
    // Attempt to load the closest font style from the set. If it fails to load,
    // it will be removed from the set and, as long as font styles remain in the
    // set, the logic will be attempted again.
    while (styles_.count() > 0) {
      SkFontStyleSetEntry_Cobalt* closest_style = styles_[style_index].get();

      SkFileMemoryChunkStreamProvider* stream_provider =
          local_typeface_stream_manager_->GetStreamProvider(
              closest_style->font_file_path.c_str());

      // Create a snapshot prior to loading any additional memory chunks. In the
      // case where the typeface does not end up being created, this enables the
      // stream provider to purge newly created memory chunks, while retaining
      // any pre-existing ones.
      std::unique_ptr<const SkFileMemoryChunks> memory_chunks_snapshot(
          stream_provider->CreateMemoryChunksSnapshot());

      std::unique_ptr<SkFileMemoryChunkStream> stream(
          stream_provider->OpenStream());
      if (GenerateStyleFaceInfo(closest_style, stream.get(), style_index)) {
        if (CharacterMapContainsCharacter(character,
                                          character_maps_[style_index])) {
          CreateStreamProviderTypeface(closest_style, style_index,
                                       stream_provider);
          return true;
        } else {
          // If a typeface was not created, destroy the stream and purge any
          // newly created memory chunks. The stream must be destroyed first or
          // it will retain references to memory chunks, preventing them from
          // being purged.
          stream.reset(nullptr);
          stream_provider->PurgeUnusedMemoryChunks();
          return false;
        }
      }

      styles_[style_index].swap(styles_.back());
      styles_.pop_back();
    }
  }

  DCHECK(character_maps_[style_index]);
  return CharacterMapContainsCharacter(character, character_maps_[style_index]);
}

bool SkFontStyleSet_Cobalt::CharacterMapContainsCharacter(
    SkUnichar character,
    const scoped_refptr<font_character_map::CharacterMap>& map) {
  font_character_map::Character c = map->Find(character);
  return c.is_set && c.id > 0;
}

bool SkFontStyleSet_Cobalt::GenerateStyleFaceInfo(
    SkFontStyleSetEntry_Cobalt* style, SkStreamAsset* stream, int style_index) {
  if (style->is_face_info_generated) {
    return true;
  }

  // Providing a pointer to the character map will cause it to be generated
  // during ScanFont. Only provide it if it hasn't already been generated.

  font_character_map::CharacterMap* character_map = NULL;
  if (!character_maps_[style_index]) {
    character_maps_[style_index] =
        base::MakeRefCounted<font_character_map::CharacterMap>();
    character_map = character_maps_[style_index].get();
  }

  if (!sk_freetype_cobalt::ScanFont(
          stream, style->face_index, &style->face_name, &style->font_style,
          &style->face_is_fixed_pitch, character_map)) {
    return false;
  }

  style->is_face_info_generated = true;
  return true;
}

int SkFontStyleSet_Cobalt::GetClosestStyleIndex(const SkFontStyle& pattern) {
  int closest_index = 0;
  int max_score = std::numeric_limits<int>::min();
  for (int i = 0; i < styles_.count(); ++i) {
    int score = MatchScore(pattern, styles_[i]->font_style);
    if (score > max_score) {
      closest_index = i;
      max_score = score;
    }
  }
  return closest_index;
}

void SkFontStyleSet_Cobalt::CreateStreamProviderTypeface(
    SkFontStyleSetEntry_Cobalt* style_entry, int style_index,
    SkFileMemoryChunkStreamProvider* stream_provider /*=NULL*/) {
  TRACE_EVENT0("cobalt::renderer",
               "SkFontStyleSet_Cobalt::CreateStreamProviderTypeface()");

  if (!stream_provider) {
    stream_provider = local_typeface_stream_manager_->GetStreamProvider(
        style_entry->font_file_path.c_str());
  }

  std::unique_ptr<SkFileMemoryChunkStream> stream(
      stream_provider->OpenStream());
  if (GenerateStyleFaceInfo(style_entry, stream.get(), style_index)) {
    LOG(INFO) << "Scanned font from file: " << style_entry->face_name.c_str()
              << "(" << style_entry->font_style.weight() << ", "
              << style_entry->font_style.width() << ", "
              << style_entry->font_style.slant() << ")";
    scoped_refptr<font_character_map::CharacterMap> map =
        disable_character_map_ ? NULL : character_maps_[style_index];
    style_entry->typeface.reset(new SkTypeface_CobaltStreamProvider(
        stream_provider, style_entry->face_index, style_entry->font_style,
        style_entry->face_is_fixed_pitch, family_name_,
        style_entry->disable_synthetic_bolding, map));
  } else {
    LOG(ERROR) << "Failed to scan font: "
               << style_entry->font_file_path.c_str();
  }
}

void SkFontStyleSet_Cobalt::PurgeUnreferencedTypefaces() {
  // Walk each of the styles looking for any that have a non-NULL typeface.
  // These are purged if they are unreferenced outside of the style set.
  for (int i = 0; i < styles_.count(); ++i) {
    sk_sp<SkTypeface>& typeface = styles_[i]->typeface;
    if (typeface.get() != NULL && typeface->unique()) {
      typeface.reset(NULL);
    }
  }
}
