// Copyright 2017 Google Inc. 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 <ft2build.h>
#include FT_FREETYPE_H

#include <cmath>
#include <limits>

#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.h"
#include "SkOSFile.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.isItalic() == candidate.isItalic()) {
    score += 1001;
  }

  // The 'closer' to the target weight, the higher the score.
  // 1000 is the 'heaviest' recognized weight
  if (pattern.weight() == candidate.weight()) {
    score += 1000;
  } 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

// These functions are used by FreeType during FT_Open_Face.
extern "C" {

static unsigned long sk_cobalt_ft_stream_io(FT_Stream ftStream,
                                            unsigned long offset,
                                            unsigned char* buffer,
                                            unsigned long count) {
  SkStreamAsset* stream =
      static_cast<SkStreamAsset*>(ftStream->descriptor.pointer);
  stream->seek(offset);
  return stream->read(buffer, count);
}

static void sk_cobalt_ft_stream_close(FT_Stream) {}
}

SkFontStyleSet_Cobalt::SkFontStyleSet_Cobalt(
    const FontFamilyInfo& family_info, const char* base_path,
    SkFileMemoryChunkStreamManager* const local_typeface_stream_manager,
    SkMutex* const manager_owned_mutex)
    : 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),
      is_character_map_generated_(!is_fallback_family_) {
  TRACE_EVENT0("cobalt::renderer",
               "SkFontStyleSet_Cobalt::SkFontStyleSet_Cobalt()");
  DCHECK(manager_owned_mutex_);

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

  family_name_ = family_info.names[0];

  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;
    }

    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());
    }

    styles_.push_back().reset(
        SkNEW_ARGS(SkFontStyleSetEntry_Cobalt,
                   (file_path, font_file.index, style, full_font_name,
                    postscript_name, font_file.disable_synthetic_bolding)));
  }
}

int SkFontStyleSet_Cobalt::count() {
  SkAutoMutexAcquire 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) {
  SkAutoMutexAcquire 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];
  // If the typeface doesn't already exist, then attempt to create it.
  if (style->typeface == NULL) {
    CreateStreamProviderTypeface(style);
    // 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 == 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.
  if (!is_character_map_generated_) {
    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) {
      int style_index = GetClosestStyleIndex(style);
      SkFontStyleSetEntry_Cobalt* closest_style = styles_[style_index];

      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.
      scoped_ptr<const SkFileMemoryChunks> memory_chunks_snapshot(
          stream_provider->CreateMemoryChunksSnapshot());

      SkAutoTUnref<SkFileMemoryChunkStream> stream(
          stream_provider->OpenStream());
      if (GenerateStyleFaceInfo(closest_style, stream)) {
        if (CharacterMapContainsCharacter(character)) {
          CreateStreamProviderTypeface(closest_style, 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(NULL);
          stream_provider->PurgeUnusedMemoryChunks();
          return false;
        }
      }

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

    is_character_map_generated_ = true;
  }

  return CharacterMapContainsCharacter(character);
}

bool SkFontStyleSet_Cobalt::CharacterMapContainsCharacter(SkUnichar character) {
  font_character_map::CharacterMap::iterator page_iterator =
      character_map_.find(font_character_map::GetPage(character));
  return page_iterator != character_map_.end() &&
         page_iterator->second.test(
             font_character_map::GetPageCharacterIndex(character));
}

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

  TRACE_EVENT0("cobalt::renderer", "GenerateStyleFaceInfo()");

  FT_Library freetype_lib;
  if (FT_Init_FreeType(&freetype_lib) != 0) {
    return false;
  }

  FT_StreamRec streamRec;
  memset(&streamRec, 0, sizeof(streamRec));
  streamRec.size = stream->getLength();
  streamRec.descriptor.pointer = stream;
  streamRec.read = sk_cobalt_ft_stream_io;
  streamRec.close = sk_cobalt_ft_stream_close;

  FT_Open_Args args;
  memset(&args, 0, sizeof(args));
  args.flags = FT_OPEN_STREAM;
  args.stream = &streamRec;

  FT_Face face;
  FT_Error err = FT_Open_Face(freetype_lib, &args, style->face_index, &face);
  if (err) {
    FT_Done_FreeType(freetype_lib);
    return false;
  }

  int face_style = SkTypeface::kNormal;
  if (face->style_flags & FT_STYLE_FLAG_BOLD) {
    face_style |= SkTypeface::kBold;
  }
  if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
    face_style |= SkTypeface::kItalic;
  }

  style->face_name.set(face->family_name);
  style->face_style = static_cast<SkTypeface::Style>(face_style);
  style->face_is_fixed_pitch = FT_IS_FIXED_WIDTH(face);
  style->is_face_info_generated = true;

  // Map out this family's characters if they haven't been generated yet.
  if (!is_character_map_generated_) {
    FT_UInt glyph_index;

    int last_page = -1;
    font_character_map::PageCharacters* page_characters = NULL;

    SkUnichar code_point = FT_Get_First_Char(face, &glyph_index);
    while (glyph_index) {
      int page = font_character_map::GetPage(code_point);
      if (page != last_page) {
        page_characters = &character_map_[page];
        last_page = page;
      }
      page_characters->set(
          font_character_map::GetPageCharacterIndex(code_point));

      code_point = FT_Get_Next_Char(face, code_point, &glyph_index);
    }

    is_character_map_generated_ = true;
  }

  // release this font.
  FT_Done_Face(face);

  // shut down FreeType.
  FT_Done_FreeType(freetype_lib);
  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,
    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());
  }

  SkAutoTUnref<SkFileMemoryChunkStream> stream(stream_provider->OpenStream());
  if (GenerateStyleFaceInfo(style_entry, stream)) {
    LOG(INFO) << "Scanned font from file: " << style_entry->face_name.c_str()
              << "(" << style_entry->face_style << ")";
    style_entry->typeface.reset(
        SkNEW_ARGS(SkTypeface_CobaltStreamProvider,
                   (stream_provider, style_entry->face_index,
                    style_entry->face_style, style_entry->face_is_fixed_pitch,
                    family_name_, style_entry->disable_synthetic_bolding)));
  } 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) {
    SkAutoTUnref<SkTypeface>& typeface = styles_[i]->typeface;
    if (typeface.get() != NULL && typeface->getRefCnt() == 1) {
      typeface.reset(NULL);
    }
  }
}
