// Copyright 2016 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/text_shaper.h"

#include <algorithm>
#include <limits>

#include "base/i18n/char_iterator.h"
#include "base/i18n/icu_string_conversions.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/unicode/character.h"
#include "cobalt/base/unicode/character_values.h"
#include "cobalt/renderer/rasterizer/skia/glyph_buffer.h"
#include "cobalt/renderer/rasterizer/skia/harfbuzz_font.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace skia {
namespace {

// A simple implementation of FontProvider where a single font is always used.
class SingleFontFontProvider : public render_tree::FontProvider {
 public:
  explicit SingleFontFontProvider(const scoped_refptr<render_tree::Font>& font)
      : size_(base::polymorphic_downcast<Font*>(font.get())->size()),
        font_(font) {}

  const render_tree::FontStyle& style() const override { return style_; }
  float size() const override { return size_; }

  const scoped_refptr<render_tree::Font>& GetCharacterFont(
      int32 utf32_character, render_tree::GlyphIndex* glyph_index) override {
    *glyph_index = font_->GetGlyphForCharacter(utf32_character);
    return font_;
  }

 private:
  render_tree::FontStyle style_;
  float size_;
  scoped_refptr<render_tree::Font> font_;
};

void TryAddFontToUsedFonts(Font* font,
                           render_tree::FontVector* maybe_used_fonts) {
  if (!maybe_used_fonts) {
    return;
  }

  // Verify that the font has not already been added to the used fonts, before
  // adding it to the end.
  for (int i = 0; i < maybe_used_fonts->size(); ++i) {
    if ((*maybe_used_fonts)[i] == font) {
      return;
    }
  }

  maybe_used_fonts->push_back(font);
}

bool ShouldFakeBoldText(const render_tree::FontProvider* font_provider,
                        const Font* font) {
  // A font-weight greater than 500 indicates bold if it is available. Use
  // synthetic bolding if this is a bold weight and the selected font
  // synthesizes bold.
  // https://www.w3.org/TR/css-fonts-3/#font-weight-prop
  // https://www.w3.org/TR/css-fonts-3/#font-style-matching
  if (font_provider->style().weight > 500) {
    const sk_sp<SkTypeface_Cobalt>& typeface(font->GetSkTypeface());
    return typeface->synthesizes_bold();
  }
  return false;
}

}  // namespace

TextShaper::TextShaper()
    : local_glyph_array_size_(0), local_text_buffer_size_(0) {}

scoped_refptr<GlyphBuffer> TextShaper::CreateGlyphBuffer(
    const char16* text_buffer, size_t text_length, const std::string& language,
    bool is_rtl, render_tree::FontProvider* font_provider) {
  math::RectF bounds;
  SkTextBlobBuilder builder;
  ShapeText(text_buffer, text_length, language, is_rtl, font_provider, &builder,
            &bounds, NULL);
  return make_scoped_refptr(new GlyphBuffer(bounds, &builder));
}

scoped_refptr<GlyphBuffer> TextShaper::CreateGlyphBuffer(
    const std::string& utf8_string,
    const scoped_refptr<render_tree::Font>& font) {
  string16 utf16_string;
  base::CodepageToUTF16(utf8_string, base::kCodepageUTF8,
                        base::OnStringConversionError::SUBSTITUTE,
                        &utf16_string);
  SingleFontFontProvider font_provider(font);
  return CreateGlyphBuffer(utf16_string.c_str(), utf16_string.size(), "en-US",
                           false, &font_provider);
}

float TextShaper::GetTextWidth(const char16* text_buffer, size_t text_length,
                               const std::string& language, bool is_rtl,
                               render_tree::FontProvider* font_provider,
                               render_tree::FontVector* maybe_used_fonts) {
  return ShapeText(text_buffer, text_length, language, is_rtl, font_provider,
                   NULL, NULL, maybe_used_fonts);
}

void TextShaper::PurgeCaches() {
  base::AutoLock lock(shaping_mutex_);
  harfbuzz_font_provider_.PurgeCaches();
}

float TextShaper::ShapeText(const char16* text_buffer, size_t text_length,
                            const std::string& language, bool is_rtl,
                            render_tree::FontProvider* font_provider,
                            SkTextBlobBuilder* maybe_builder,
                            math::RectF* maybe_bounds,
                            render_tree::FontVector* maybe_used_fonts) {
  base::AutoLock lock(shaping_mutex_);
  float total_width = 0;
  VerticalBounds vertical_bounds;
  // Only set |maybe_vertical_bounds| to a non-NULL value when |maybe_bounds| is
  // non-NULL. Otherwise, the text bounds are not being calculated.
  VerticalBounds* maybe_vertical_bounds =
      maybe_bounds ? &vertical_bounds : NULL;

  // Check for if the text contains a complex script, meaning that it requires
  // HarfBuzz. If it does, then attempt to collect the scripts. In the event
  // that this fails, fall back to the simple shaper.
  ScriptRuns script_runs;
  if (base::unicode::ContainsComplexScript(text_buffer, text_length) &&
      CollectScriptRuns(text_buffer, text_length, font_provider,
                        &script_runs)) {
    // If the direction is RTL, then reverse the script runs, so that the glyphs
    // will be added in the correct order.
    if (is_rtl) {
      std::reverse(script_runs.begin(), script_runs.end());
    }

    for (int i = 0; i < script_runs.size(); ++i) {
      ScriptRun& run = script_runs[i];
      const char16* script_run_text_buffer = text_buffer + run.start_index;

      // Check to see if the script run requires HarfBuzz. Because HarfBuzz
      // shaping is much slower than simple shaping, we only want to run
      // HarfBuzz shaping on the bare minimum possible, so any script run
      // that doesn't contain complex scripts will be simply shaped.
      if (base::unicode::ContainsComplexScript(script_run_text_buffer,
                                               run.length)) {
        ShapeComplexRun(script_run_text_buffer, run, language, is_rtl,
                        font_provider, maybe_builder, maybe_vertical_bounds,
                        maybe_used_fonts, &total_width);
      } else {
        ShapeSimpleRunWithDirection(script_run_text_buffer, run.length, is_rtl,
                                    font_provider, maybe_builder,
                                    maybe_vertical_bounds, maybe_used_fonts,
                                    &total_width);
      }
    }
  } else {
    ShapeSimpleRunWithDirection(text_buffer, text_length, is_rtl, font_provider,
                                maybe_builder, maybe_vertical_bounds,
                                maybe_used_fonts, &total_width);
  }

  // If |maybe_bounds| has been provided, then update the width of the bounds
  // with the total width of all of the shaped glyphs. The height is already
  // correct.
  if (maybe_bounds) {
    *maybe_bounds = math::RectF(0, vertical_bounds.GetY(), total_width,
                                vertical_bounds.GetHeight());
  }

  return total_width;
}

bool TextShaper::CollectScriptRuns(const char16* text_buffer,
                                   size_t text_length,
                                   render_tree::FontProvider* font_provider,
                                   ScriptRuns* runs) {
  // Initialize the next data with the first character. This allows us to avoid
  // checking for the first character case within the while loop.
  int32 next_character = base::unicode::NormalizeSpaces(
      base::i18n::UTF16CharIterator(text_buffer, text_length).get());
  render_tree::GlyphIndex next_glyph = render_tree::kInvalidGlyphIndex;
  Font* next_font = base::polymorphic_downcast<Font*>(
      font_provider->GetCharacterFont(next_character, &next_glyph).get());

  UErrorCode error_code = U_ZERO_ERROR;
  UScriptCode next_script = uscript_getScript(next_character, &error_code);
  // If we're unable to determine the script of a character, we failed to
  // successfully collect the script runs. Return failure.
  if (U_FAILURE(error_code)) {
    return false;
  }

  // Iterate for as long as the current index has not reached the end index.
  unsigned int current_index = 0;
  unsigned int end_index = text_length;
  while (current_index < end_index) {
    Font* current_font = next_font;
    UScriptCode current_script = next_script;

    // Create an iterator starting at the current index and containing the
    // remaining length.
    base::i18n::UTF16CharIterator iter(text_buffer + current_index,
                                       end_index - current_index);
    // Skip over the first character. It's already set as our current font
    // and current script.
    iter.Advance();
    size_t next_index_offset = iter.array_pos();

    for (; !iter.end(); iter.Advance(), next_index_offset = iter.array_pos()) {
      // Normalize spaces within the current character, so that we are
      // guaranteed that they will map to a consistent font and glyph.
      next_character = base::unicode::NormalizeSpaces(iter.get());
      if (next_character == base::unicode::kZeroWidthSpaceCharacter) {
        continue;
      }

      // Check for mark characters. If this is a mark character and the current
      // font contains a glyph for it, then simply add it to the current run.
      // Doing so ensures that combining character sequences will be shaped in
      // one font run if possible.
      if ((U_GET_GC_MASK(next_character) & U_GC_M_MASK) &&
          (current_font->GetGlyphForCharacter(next_character) !=
           render_tree::kInvalidGlyphIndex)) {
        continue;
      }

      next_font = base::polymorphic_downcast<Font*>(
          font_provider->GetCharacterFont(next_character, &next_glyph).get());

      next_script = uscript_getScript(next_character, &error_code);
      // If we're unable to determine the script of a character, we failed to
      // successfully collect the script runs. Return failure.
      if (U_FAILURE(error_code)) {
        return false;
      }

      // We've reached the end of the script run in two cases:
      //   1. If the characters use different fonts.
      //   2. If the characters use different scripts, the next script isn't
      //      inherited, and the next character doesn't support the current
      //      script.
      if ((current_font != next_font) ||
          ((current_script != next_script) &&
           (next_script != USCRIPT_INHERITED) &&
           (!uscript_hasScript(next_character, current_script)))) {
        break;
      }

      // If the script is inherited, then simply retain the current script.
      if (next_script == USCRIPT_INHERITED) {
        next_script = current_script;
      }
    }

    runs->push_back(ScriptRun(current_font, current_script, current_index,
                              next_index_offset));

    // Update the index where we're starting the next script run.
    current_index += next_index_offset;
  }

  return true;
}

void TextShaper::ShapeComplexRun(const char16* text_buffer,
                                 const ScriptRun& script_run,
                                 const std::string& language, bool is_rtl,
                                 render_tree::FontProvider* font_provider,
                                 SkTextBlobBuilder* maybe_builder,
                                 VerticalBounds* maybe_vertical_bounds,
                                 render_tree::FontVector* maybe_used_fonts,
                                 float* total_width) {
  TryAddFontToUsedFonts(script_run.font, maybe_used_fonts);

  hb_font_t* harfbuzz_font =
      harfbuzz_font_provider_.GetHarfBuzzFont(script_run.font);

  // Ensure that the local text buffer is large enough to hold the normalized
  // string.
  EnsureLocalTextBufferHasSize(script_run.length);

  // Normalize the spaces in the run before providing it to HarfBuzz.
  bool error = false;
  unsigned int normalized_buffer_length = 0;
  unsigned int buffer_position = 0;
  while (buffer_position < script_run.length) {
    UChar32 character;
    U16_NEXT(text_buffer, buffer_position, script_run.length, character);
    character = base::unicode::NormalizeSpacesInComplexScript(character);
    U16_APPEND(local_text_buffer_.get(), normalized_buffer_length,
               script_run.length, character, error);
  }

  // Create a HarfBuzz buffer and add the string to be shaped. The HarfBuzz
  // buffer holds our text, run information to be used by the shaping engine,
  // and the resulting glyph data.
  hb_buffer_t* buffer = hb_buffer_create();
  hb_buffer_add_utf16(buffer, (const uint16_t*)local_text_buffer_.get(),
                      normalized_buffer_length, 0, normalized_buffer_length);
  hb_buffer_set_script(buffer, hb_icu_script_to_script(script_run.script));
  hb_buffer_set_direction(buffer, is_rtl ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
  hb_buffer_set_language(
      buffer, hb_language_from_string(language.c_str(), language.length()));

  // Shape the text.
  hb_shape(harfbuzz_font, buffer, NULL, 0);

  // Populate the run fields with the resulting glyph data in the buffer.
  unsigned int glyph_count = 0;

  hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(buffer, &glyph_count);
  hb_glyph_position_t* hb_positions =
      hb_buffer_get_glyph_positions(buffer, NULL);

  // If |maybe_builder| has been provided, the allocate enough memory within
  // the builder for the shaped glyphs.
  const SkTextBlobBuilder::RunBuffer* run_buffer = NULL;
  if (maybe_builder) {
    SkPaint paint = script_run.font->GetSkPaint();
    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
    paint.setFakeBoldText(ShouldFakeBoldText(font_provider, script_run.font));
    run_buffer = &(maybe_builder->allocRunPos(paint, glyph_count));
  }

  // Walk each of the shaped glyphs.
  size_t pos_index = 0;
  for (size_t i = 0; i < glyph_count; ++i) {
    DCHECK_LE(infos[i].codepoint, std::numeric_limits<uint16_t>::max());
    // If |run_buffer| has been allocated, then we're populating it with the
    // glyph and position data.
    if (run_buffer) {
      run_buffer->glyphs[i] = static_cast<uint16_t>(infos[i].codepoint);
      run_buffer->pos[pos_index++] =
          *total_width + SkFixedToScalar(hb_positions[i].x_offset);
      run_buffer->pos[pos_index++] = -SkFixedToScalar(hb_positions[i].y_offset);
    }

    // If |maybe_vertical_bounds| has been provided, then we're updating it with
    // the vertical bounds of all of the shaped glyphs.
    if (maybe_vertical_bounds) {
      const math::RectF& glyph_bounds =
          script_run.font->GetGlyphBounds(infos[i].codepoint);
      float min_y =
          glyph_bounds.y() - SkFixedToScalar(hb_positions[i].y_offset);
      float max_y = min_y + glyph_bounds.height();
      maybe_vertical_bounds->IncludeRange(min_y, max_y);
    }

    // Include the shaped glyph within the total width.
    *total_width += SkFixedToFloat(hb_positions[i].x_advance);
  }

  hb_buffer_destroy(buffer);
  hb_font_destroy(harfbuzz_font);
}

void TextShaper::ShapeSimpleRunWithDirection(
    const char16* text_buffer, size_t text_length, bool is_rtl,
    render_tree::FontProvider* font_provider, SkTextBlobBuilder* maybe_builder,
    VerticalBounds* maybe_vertical_bounds,
    render_tree::FontVector* maybe_used_fonts, float* total_width) {
  // If the text has an RTL direction and a builder was provided, then reverse
  // the text. This ensures that the glyphs will appear in the proper order
  // within the glyph buffer. The width and bounds do not rely on the direction
  // of the text, so in the case where there is no builder, reversing the text
  // is not necessary.
  if (maybe_builder && is_rtl) {
    // Ensure that the local text buffer is large enough to hold the reversed
    // string.
    EnsureLocalTextBufferHasSize(text_length);

    // Both reverse the text and replace mirror characters so that characters
    // such as parentheses will appear in the proper direction.
    bool error = false;
    unsigned int reversed_buffer_length = 0;
    unsigned int buffer_position = text_length;
    while (buffer_position > 0) {
      UChar32 character;
      U16_PREV(text_buffer, 0, buffer_position, character);
      character = u_charMirror(character);
      U16_APPEND(local_text_buffer_.get(), reversed_buffer_length, text_length,
                 character, error);
    }

    ShapeSimpleRun(local_text_buffer_.get(), reversed_buffer_length,
                   font_provider, maybe_builder, maybe_vertical_bounds,
                   maybe_used_fonts, total_width);
  } else {
    ShapeSimpleRun(text_buffer, text_length, font_provider, maybe_builder,
                   maybe_vertical_bounds, maybe_used_fonts, total_width);
  }
}

void TextShaper::ShapeSimpleRun(const char16* text_buffer, size_t text_length,
                                render_tree::FontProvider* font_provider,
                                SkTextBlobBuilder* maybe_builder,
                                VerticalBounds* maybe_vertical_bounds,
                                render_tree::FontVector* maybe_used_fonts,
                                float* total_width) {
  // If there's a builder (meaning that a glyph buffer is being generated), then
  // ensure that the local arrays are large enough to hold all of the glyphs
  // within the simple run.
  if (maybe_builder) {
    EnsureLocalGlyphArraysHaveSize(text_length);
  }

  int glyph_count = 0;
  Font* last_font = NULL;

  // Walk through each character within the run.
  for (base::i18n::UTF16CharIterator iter(text_buffer, text_length);
       !iter.end(); iter.Advance()) {
    // Retrieve the current character and normalize spaces and zero width
    // spaces before processing it.
    int32 character = base::unicode::NormalizeSpaces(iter.get());
    render_tree::GlyphIndex glyph = render_tree::kInvalidGlyphIndex;

    // If a space character is encountered, simply add to the width and continue
    // on. As an optimization, we don't add space character glyphs to the glyph
    // buffer.
    if (character == base::unicode::kSpaceCharacter) {
      *total_width += font_provider->GetCharacterFont(character, &glyph)
                          ->GetGlyphWidth(glyph);
      continue;
      // If a zero width space character is encountered, simply continue on. It
      // doesn't impact the width or shaping data.
    } else if (character == base::unicode::kZeroWidthSpaceCharacter) {
      continue;
    }

    // Look up the font and glyph for the current character.
    Font* current_font = base::polymorphic_downcast<Font*>(
        font_provider->GetCharacterFont(character, &glyph).get());

    // If there's a builder (meaning that a glyph buffer is being generated),
    // then we need to update the glyph buffer data for the new glyph.
    if (maybe_builder) {
      // If at least one glyph has previously been added and the font has
      // changed, then the current run has ended and we need to add the font run
      // into the glyph buffer.
      if (glyph_count > 0 && last_font != current_font) {
        TryAddFontToUsedFonts(last_font, maybe_used_fonts);
        AddFontRunToGlyphBuffer(font_provider, last_font, glyph_count,
                                maybe_builder);
        glyph_count = 0;
      }

      local_glyphs_[glyph_count] = glyph;
      local_positions_[glyph_count] = *total_width;
    }

    const math::RectF& glyph_bounds = current_font->GetGlyphBounds(glyph);
    *total_width += glyph_bounds.width();

    // If |maybe_vertical_bounds| has been provided, then we're updating it with
    // the vertical bounds of all of the shaped glyphs.
    if (maybe_vertical_bounds) {
      maybe_vertical_bounds->IncludeRange(glyph_bounds.y(),
                                          glyph_bounds.bottom());
    }

    ++glyph_count;
    last_font = current_font;
  }

  // If there's a builder (meaning that a glyph buffer is being generated), and
  // at least one glyph was generated, then we need to add the final font run
  // into the glyph buffer.
  if (maybe_builder && glyph_count > 0) {
    TryAddFontToUsedFonts(last_font, maybe_used_fonts);
    AddFontRunToGlyphBuffer(font_provider, last_font, glyph_count,
                            maybe_builder);
  }
}

void TextShaper::AddFontRunToGlyphBuffer(
    const render_tree::FontProvider* font_provider, const Font* font,
    const int glyph_count, SkTextBlobBuilder* builder) {
  SkPaint paint = font->GetSkPaint();
  paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
  paint.setFakeBoldText(ShouldFakeBoldText(font_provider, font));

  // Allocate space within the text blob for the glyphs and copy them into the
  // blob.
  const SkTextBlobBuilder::RunBuffer& buffer =
      builder->allocRunPosH(paint, glyph_count, 0);
  std::copy(&local_glyphs_[0], &local_glyphs_[0] + glyph_count, buffer.glyphs);
  std::copy(&local_positions_[0], &local_positions_[0] + glyph_count,
            buffer.pos);
}

void TextShaper::EnsureLocalGlyphArraysHaveSize(size_t size) {
  if (local_glyph_array_size_ < size) {
    local_glyph_array_size_ = size;
    local_glyphs_.reset(new render_tree::GlyphIndex[size]);
    local_positions_.reset(new SkScalar[size]);
  }
}

void TextShaper::EnsureLocalTextBufferHasSize(size_t size) {
  if (local_text_buffer_size_ < size) {
    local_text_buffer_size_ = size;
    local_text_buffer_.reset(new char16[size]);
  }
}

}  // namespace skia
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
