// Copyright 2014 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.

#ifndef UI_GFX_RENDER_TEXT_HARFBUZZ_H_
#define UI_GFX_RENDER_TEXT_HARFBUZZ_H_

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

#include <memory>
#include <string>
#include <vector>

#include "base/macros.h"
#include "third_party/icu/source/common/unicode/ubidi.h"
#include "third_party/icu/source/common/unicode/uscript.h"
#include "ui/gfx/render_text.h"

#include <hb.h>

namespace base {
namespace i18n {
class BreakIterator;
}
}

namespace gfx {

class Range;
class RangeF;
class RenderTextHarfBuzz;

namespace internal {

struct GFX_EXPORT TextRunHarfBuzz {
  // Construct the run with |template_font| since determining the details of a
  // default-constructed gfx::Font is expensive, but it will always be replaced.
  explicit TextRunHarfBuzz(const Font& template_font);
  ~TextRunHarfBuzz();

  // Returns the index of the first glyph that corresponds to the character at
  // |pos|.
  size_t CharToGlyph(size_t pos) const;

  // Returns the corresponding glyph range of the given character range.
  // |range| is in text-space (0 corresponds to |GetDisplayText()[0]|). Returned
  // value is in run-space (0 corresponds to the first glyph in the run).
  Range CharRangeToGlyphRange(const Range& range) const;

  // Returns the number of missing glyphs in the shaped text run.
  size_t CountMissingGlyphs() const;

  // Writes the character and glyph ranges of the cluster containing |pos|.
  void GetClusterAt(size_t pos, Range* chars, Range* glyphs) const;

  // Returns the grapheme bounds at |text_index|. Handles multi-grapheme glyphs.
  // Returned value is the horizontal pixel span in text-space (assumes all runs
  // are on the same line). The returned range is never reversed.
  RangeF GetGraphemeBounds(RenderTextHarfBuzz* render_text,
                           size_t text_index) const;

  // Returns the horizontal span of the given |char_range| handling grapheme
  // boundaries within glyphs. This is a wrapper around one or more calls to
  // GetGraphemeBounds(), returning a range in the same coordinate space.
  RangeF GetGraphemeSpanForCharRange(RenderTextHarfBuzz* render_text,
                                     const Range& char_range) const;

  // Returns the glyph width for the given character range. |char_range| is in
  // text-space (0 corresponds to |GetDisplayText()[0]|).
  SkScalar GetGlyphWidthForCharRange(const Range& char_range) const;

  // Font parameters that may be common to multiple text runs within a text run
  // list.
  struct GFX_EXPORT FontParams {
    // The default constructor for Font is expensive, so always require that a
    // Font be provided.
    explicit FontParams(const Font& template_font);
    ~FontParams();
    FontParams(const FontParams& other);
    FontParams& operator=(const FontParams& other);
    bool operator==(const FontParams& other) const;

    // Populates |render_params|, |font_size| and |baseline_offset| based on
    // |font|.
    void ComputeRenderParamsFontSizeAndBaselineOffset();

    // Populates |font|, |skia_face|, and |render_params|. Returns false if
    // |skia_face| is nullptr. Takes |font|'s family name and rematches this
    // family and the run's weight and style properties to find a new font.
    bool SetRenderParamsRematchFont(const Font& font,
                                    const FontRenderParams& render_params);

    // Populates |font|, |skia_face|, and |render_params|. Returns false if
    // |skia_face| is nullptr. Does not perform rematching but extracts an
    // SkTypeface from the underlying PlatformFont of font. Use this method when
    // configuring the |TextRunHarfBuzz| for shaping with fallback fonts, where
    // it is important to keep the underlying font handle of platform font and
    // not perform rematching as in |SetRenderParamsRematchFont|.
    bool SetRenderParamsOverrideSkiaFaceFromFont(
        const Font& font,
        const FontRenderParams& render_params);

    struct Hash {
      size_t operator()(const FontParams& key) const;
    };

    Font font;
    sk_sp<SkTypeface> skia_face;
    FontRenderParams render_params;
    Font::Weight weight = Font::Weight::NORMAL;
    int font_size = 0;
    int baseline_offset = 0;
    int baseline_type = 0;
    bool italic = false;
    bool strike = false;
    bool underline = false;
    bool heavy_underline = false;
    bool is_rtl = false;
    UBiDiLevel level = 0;
    UScriptCode script = USCRIPT_INVALID_CODE;
  };

  // Parameters that are set by ShapeRunWithFont.
  struct GFX_EXPORT ShapeOutput {
    ShapeOutput();
    ~ShapeOutput();
    ShapeOutput(const ShapeOutput& other);
    ShapeOutput& operator=(const ShapeOutput& other);
    ShapeOutput(ShapeOutput&& other);
    ShapeOutput& operator=(ShapeOutput&& other);

    float width = 0.0;
    float preceding_run_widths = 0.0;
    std::vector<uint16_t> glyphs;
    std::vector<SkPoint> positions;
    // Note that in the context of TextRunHarfBuzz, |glyph_to_char| is indexed
    // based off of the full string (so it is in the same domain as
    // TextRunHarfBuzz::range).
    std::vector<uint32_t> glyph_to_char;
    size_t glyph_count = 0;
    size_t missing_glyph_count = std::numeric_limits<size_t>::max();
  };

  // If |new_shape.missing_glyph_count| is less than that of |shape|, set
  // |font_params| and |shape| to the specified values.
  void UpdateFontParamsAndShape(const FontParams& new_font_params,
                                const ShapeOutput& new_shape);

  Range range;
  FontParams font_params;
  ShapeOutput shape;
  float preceding_run_widths = 0.0;

 private:
  DISALLOW_COPY_AND_ASSIGN(TextRunHarfBuzz);
};

// Manages the list of TextRunHarfBuzz and its logical <-> visual index mapping.
class TextRunList {
 public:
  TextRunList();
  ~TextRunList();

  size_t size() const { return runs_.size(); }

  // Converts the index between logical and visual index.
  size_t visual_to_logical(size_t index) const {
    return visual_to_logical_[index];
  }
  size_t logical_to_visual(size_t index) const {
    return logical_to_visual_[index];
  }

  const std::vector<std::unique_ptr<TextRunHarfBuzz>>& runs() const {
    return runs_;
  }

  // Adds the new |run| to the run list.
  void Add(std::unique_ptr<TextRunHarfBuzz> run) {
    runs_.push_back(std::move(run));
  }

  // Reset the run list.
  void Reset();

  // Initialize the index mapping.
  void InitIndexMap();

  // Precomputes the offsets for all runs.
  void ComputePrecedingRunWidths();

  // Get the total width of runs, as if they were shown on one line.
  // Do not use this when multiline is enabled.
  float width() const { return width_; }

  // Get the run index applicable to |position| (at or preceeding |position|).
  size_t GetRunIndexAt(size_t position) const;

 private:
  // Text runs in logical order.
  std::vector<std::unique_ptr<TextRunHarfBuzz>> runs_;

  // Maps visual run indices to logical run indices and vice versa.
  std::vector<int32_t> visual_to_logical_;
  std::vector<int32_t> logical_to_visual_;

  float width_;

  DISALLOW_COPY_AND_ASSIGN(TextRunList);
};

}  // namespace internal

class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
 public:
  RenderTextHarfBuzz();
  ~RenderTextHarfBuzz() override;

  // RenderText:
  const base::string16& GetDisplayText() override;
  Size GetStringSize() override;
  SizeF GetStringSizeF() override;
  Size GetLineSize(const SelectionModel& caret) override;
  float TotalLineWidth() override;
  SelectionModel FindCursorPosition(const Point& point,
                                    const Point& drag_origin) override;
  bool IsSelectionSupported() const override;
  std::vector<Rect> GetSubstringBounds(const Range& range) override;
  RangeF GetCursorSpan(const Range& text_range) override;
  size_t GetLineContainingCaret(const SelectionModel& caret) override;

  // ICU grapheme iterator for the layout text. Can be null in case of an error.
  base::i18n::BreakIterator* GetGraphemeIterator();

 protected:
  // RenderText:
  int GetDisplayTextBaseline() override;
  SelectionModel AdjacentCharSelectionModel(
      const SelectionModel& selection,
      VisualCursorDirection direction) override;
  SelectionModel AdjacentWordSelectionModel(
      const SelectionModel& selection,
      VisualCursorDirection direction) override;
  SelectionModel AdjacentLineSelectionModel(
      const SelectionModel& selection,
      VisualCursorDirection direction) override;
  bool IsValidCursorIndex(size_t index) override;
  void OnLayoutTextAttributeChanged(bool text_changed) override;
  void OnDisplayTextAttributeChanged() override;
  void EnsureLayout() override;
  void DrawVisualText(internal::SkiaTextRenderer* renderer,
                      const Range& selection) override;

 private:
  friend class test::RenderTextTestApi;
  friend class RenderTextTest;

  // Return the run index that contains the argument; or the length of the
  // |runs_| vector if argument exceeds the text length or width.
  size_t GetRunContainingCaret(const SelectionModel& caret);

  // Given a |run|, returns the SelectionModel that contains the logical first
  // or last caret position inside (not at a boundary of) the run.
  // The returned value represents a cursor/caret position without a selection.
  SelectionModel FirstSelectionModelInsideRun(
      const internal::TextRunHarfBuzz* run);
  SelectionModel LastSelectionModelInsideRun(
      const internal::TextRunHarfBuzz* run);

  using CommonizedRunsMap =
      std::unordered_map<internal::TextRunHarfBuzz::FontParams,
                         std::vector<internal::TextRunHarfBuzz*>,
                         internal::TextRunHarfBuzz::FontParams::Hash>;

  // Break the text into logical runs in |out_run_list|. Populate
  // |out_commonized_run_map| such that each run is present in the vector
  // corresponding to its FontParams.
  void ItemizeTextToRuns(const base::string16& string,
                         internal::TextRunList* out_run_list,
                         CommonizedRunsMap* out_commonized_run_map);

  // Shape the glyphs needed for each run in |runs| within |text|. This method
  // will apply a number of fonts to |base_font_params| and assign to each
  // run's FontParams and ShapeOutput the parameters and resulting shape that
  // had the smallest number of missing glyphs.
  void ShapeRuns(const base::string16& text,
                 const internal::TextRunHarfBuzz::FontParams& base_font_params,
                 std::vector<internal::TextRunHarfBuzz*> runs);

  // Shape the glyphs for |in_out_runs| within |text| using the parameters
  // specified by |font_params|. If, for any run in |*in_out_runs|, the
  // resulting shaping has fewer missing glyphs than the existing shape, then
  // write |font_params| and the resulting ShapeOutput to that run. Remove all
  // runs with no missing glyphs from |in_out_runs| (the caller, ShapeRuns, will
  // terminate when no runs with missing glyphs remain).
  void ShapeRunsWithFont(
      const base::string16& text,
      const internal::TextRunHarfBuzz::FontParams& font_params,
      std::vector<internal::TextRunHarfBuzz*>* in_out_runs);

  // Itemize |text| into runs in |out_run_list|, shape the runs, and populate
  // |out_run_list|'s visual <-> logical maps.
  void ItemizeAndShapeText(const base::string16& text,
                           internal::TextRunList* out_run_list);

  // Makes sure that text runs for layout text are shaped.
  void EnsureLayoutRunList();

  // RenderText:
  internal::TextRunList* GetRunList() override;
  const internal::TextRunList* GetRunList() const override;
  bool GetDecoratedTextForRange(const Range& range,
                                DecoratedText* decorated_text) override;

  // Text run list for |layout_text_| and |display_text_|.
  // |display_run_list_| is created only when the text is elided.
  internal::TextRunList layout_run_list_;
  std::unique_ptr<internal::TextRunList> display_run_list_;

  bool update_layout_run_list_ : 1;
  bool update_display_run_list_ : 1;
  bool update_grapheme_iterator_ : 1;
  bool update_display_text_ : 1;

  // ICU grapheme iterator for the layout text. Use GetGraphemeIterator()
  // to access the iterator.
  std::unique_ptr<base::i18n::BreakIterator> grapheme_iterator_;

  // The total size of the layouted text.
  SizeF total_size_;

  // The process application locale used to configure text rendering.
  std::string locale_;

  DISALLOW_COPY_AND_ASSIGN(RenderTextHarfBuzz);
};

}  // namespace gfx

#endif  // UI_GFX_RENDER_TEXT_HARFBUZZ_H_
