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

#ifndef UI_GFX_RENDER_TEXT_H_
#define UI_GFX_RENDER_TEXT_H_

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

#include <algorithm>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/i18n/rtl.h"
#include "base/macros.h"
#include "base/strings/string16.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gfx/break_list.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/range/range.h"
#include "ui/gfx/range/range_f.h"
#include "ui/gfx/selection_model.h"
#include "ui/gfx/shadow_value.h"
#include "ui/gfx/text_constants.h"

class SkDrawLooper;
struct SkPoint;
class SkTypeface;

namespace gfx {
namespace test {
class RenderTextTestApi;
}

class Canvas;
struct DecoratedText;
class Font;

namespace internal {

class TextRunList;

// Internal helper class used by derived classes to draw text through Skia.
class GFX_EXPORT SkiaTextRenderer {
 public:
  explicit SkiaTextRenderer(Canvas* canvas);
  virtual ~SkiaTextRenderer();

  void SetDrawLooper(sk_sp<SkDrawLooper> draw_looper);
  void SetFontRenderParams(const FontRenderParams& params,
                           bool subpixel_rendering_suppressed);
  void SetTypeface(sk_sp<SkTypeface> typeface);
  void SetTextSize(SkScalar size);
  void SetForegroundColor(SkColor foreground);
  void SetShader(sk_sp<cc::PaintShader> shader);
  void DrawSelection(const std::vector<Rect>& selection, SkColor color);
  // TODO(vmpstr): Change this API to mimic SkCanvas::drawTextBlob instead.
  virtual void DrawPosText(const SkPoint* pos,
                           const uint16_t* glyphs,
                           size_t glyph_count);
  void DrawUnderline(int x, int y, int width, SkScalar thickness_factor = 1.0);
  void DrawStrike(int x, int y, int width, SkScalar thickness_factor);

 private:
  friend class test::RenderTextTestApi;

  Canvas* canvas_;
  cc::PaintCanvas* canvas_skia_;
  cc::PaintFlags flags_;
  SkFont font_;

  DISALLOW_COPY_AND_ASSIGN(SkiaTextRenderer);
};

// Internal helper class used to iterate colors, baselines, and styles.
class StyleIterator {
 public:
  StyleIterator(const BreakList<SkColor>& colors,
                const BreakList<BaselineStyle>& baselines,
                const BreakList<int>& font_size_overrides,
                const BreakList<Font::Weight>& weights,
                const std::vector<BreakList<bool>>& styles);
  ~StyleIterator();

  // Get the colors and styles at the current iterator position.
  SkColor color() const { return color_->second; }
  BaselineStyle baseline() const { return baseline_->second; }
  int font_size_override() const { return font_size_override_->second; }
  bool style(TextStyle s) const { return style_[s]->second; }
  Font::Weight weight() const { return weight_->second; }

  // Get the intersecting range of the current iterator set.
  Range GetRange() const;

  // Update the iterator to point to colors and styles applicable at |position|.
  void UpdatePosition(size_t position);

 private:
  BreakList<SkColor> colors_;
  BreakList<BaselineStyle> baselines_;
  BreakList<int> font_size_overrides_;
  BreakList<Font::Weight> weights_;
  std::vector<BreakList<bool> > styles_;

  BreakList<SkColor>::const_iterator color_;
  BreakList<BaselineStyle>::const_iterator baseline_;
  BreakList<int>::const_iterator font_size_override_;
  BreakList<Font::Weight>::const_iterator weight_;
  std::vector<BreakList<bool>::const_iterator> style_;

  DISALLOW_COPY_AND_ASSIGN(StyleIterator);
};

// Line segments are slices of the display text to be rendered on a single line.
struct LineSegment {
  LineSegment();
  ~LineSegment();

  // X coordinates of this line segment in text space.
  RangeF x_range;

  // The character range this segment corresponds to.
  Range char_range;

  // Index of the text run that generated this segment.
  size_t run;

  // Returns the width of this line segment in text space.
  float width() const { return x_range.length(); }
};

// A line of display text, comprised of a line segment list and some metrics.
struct Line {
  Line();
  Line(const Line& other);
  ~Line();

  // Segments that make up this line in visual order.
  std::vector<LineSegment> segments;

  // The sum of segment widths and the maximum of segment heights.
  SizeF size;

  // Sum of preceding lines' heights.
  int preceding_heights;

  // Maximum baseline of all segments on this line.
  int baseline;
};

// Creates an SkTypeface from a font, |italic| and a desired |weight|.
// May return null.
sk_sp<SkTypeface> CreateSkiaTypeface(const Font& font,
                                     bool italic,
                                     Font::Weight weight);

// Applies the given FontRenderParams to the SkFont.
void ApplyRenderParams(const FontRenderParams& params,
                       bool subpixel_rendering_suppressed,
                       SkFont* font);

}  // namespace internal

// RenderText represents an abstract model of styled text and its corresponding
// visual layout. Support is built in for a cursor, a selection, simple styling,
// complex scripts, and bi-directional text. Implementations provide mechanisms
// for rendering and translation between logical and visual data.
class GFX_EXPORT RenderText {
 public:
#if defined(OS_MACOSX)
  // On Mac, while selecting text if the cursor is outside the vertical text
  // bounds, drag to the end of the text.
  static constexpr bool kDragToEndIfOutsideVerticalBounds = true;
  // Mac supports a selection that is "undirected". When undirected, the cursor
  // doesn't know which end of the selection it's at until it first moves.
  static constexpr bool kSelectionIsAlwaysDirected = false;
#else
  static constexpr bool kDragToEndIfOutsideVerticalBounds = false;
  static constexpr bool kSelectionIsAlwaysDirected = true;
#endif

  // The character used for displaying obscured text. Use a bullet character.
  // TODO(pbos): This is highly font dependent, consider replacing the character
  // with a vector glyph.
  static constexpr base::char16 kPasswordReplacementChar = 0x2022;

  virtual ~RenderText();

  // Creates an instance that renders using HarfBuzz.
  static std::unique_ptr<RenderText> CreateHarfBuzzInstance();

  // Creates an instance by matching a gfx::Typesetter constant to the current
  // build and runtime configuration. E.g. the result may use CoreText on Mac,
  // which is the only supported native typesetter.
  static std::unique_ptr<RenderText> CreateFor(Typesetter typesetter);

  // Returns CreateFor(Typesetter::BROWSER), but indicates a caller that does
  // not know whether the text will eventually be drawn by the native typesetter
  // or by a RenderText instance.
  // TODO(tapted): Delete this.
  static std::unique_ptr<RenderText> CreateInstanceDeprecated();

  // Creates another instance of the same concrete class.
  virtual std::unique_ptr<RenderText> CreateInstanceOfSameType() const = 0;

  // Like above but copies all style settings too.
  std::unique_ptr<RenderText> CreateInstanceOfSameStyle(
      const base::string16& text) const;

  const base::string16& text() const { return text_; }
  void SetText(const base::string16& text);
  void AppendText(const base::string16& text);

  HorizontalAlignment horizontal_alignment() const {
    return horizontal_alignment_;
  }
  void SetHorizontalAlignment(HorizontalAlignment alignment);

  const FontList& font_list() const { return font_list_; }
  virtual void SetFontList(const FontList& font_list);

  bool cursor_enabled() const { return cursor_enabled_; }
  void SetCursorEnabled(bool cursor_enabled);

  SkColor selection_color() const { return selection_color_; }
  void set_selection_color(SkColor color) { selection_color_ = color; }

  SkColor selection_background_focused_color() const {
    return selection_background_focused_color_;
  }
  void set_selection_background_focused_color(SkColor color) {
    selection_background_focused_color_ = color;
  }

  bool symmetric_selection_visual_bounds() const {
    return symmetric_selection_visual_bounds_;
  }
  void set_symmetric_selection_visual_bounds(bool symmetric) {
    symmetric_selection_visual_bounds_ = symmetric;
  }

  bool focused() const { return focused_; }
  void set_focused(bool focused) { focused_ = focused; }

  bool clip_to_display_rect() const { return clip_to_display_rect_; }
  void set_clip_to_display_rect(bool clip) { clip_to_display_rect_ = clip; }

  int glyph_spacing() const { return glyph_spacing_; }
  void set_glyph_spacing(int spacing) { glyph_spacing_ = spacing; }

  // In an obscured (password) field, all text is drawn as bullets.
  bool obscured() const { return obscured_; }
  void SetObscured(bool obscured);

  // Makes a char in obscured text at |index| to be revealed. |index| should be
  // a UTF16 text index. If there is a previous revealed index, the previous one
  // is cleared and only the last set index will be revealed. If |index| is -1
  // or out of range, no char will be revealed. The revealed index is also
  // cleared when SetText or SetObscured is called.
  void SetObscuredRevealIndex(int index);

  // TODO(ckocagil): Multiline text rendering is not supported on Mac.
  bool multiline() const { return multiline_; }
  void SetMultiline(bool multiline);

  // If multiline, a non-zero value will cap the number of lines rendered,
  // and elide the rest (currently only ELIDE_TAIL supported.)
  void SetMaxLines(size_t max_lines);
  size_t max_lines() const { return max_lines_; }

  // Returns the actual number of lines, broken by |lines_|.
  size_t GetNumLines();

  // TODO(mukai): ELIDE_LONG_WORDS is not supported.
  WordWrapBehavior word_wrap_behavior() const { return word_wrap_behavior_; }
  void SetWordWrapBehavior(WordWrapBehavior behavior);

  // Set whether newline characters should be replaced with newline symbols.
  void SetReplaceNewlineCharsWithSymbols(bool replace);

  // Returns true if this instance supports multiline rendering.
  virtual bool MultilineSupported() const = 0;

  // TODO(ckocagil): Add vertical alignment and line spacing support instead.
  int min_line_height() const { return min_line_height_; }
  void SetMinLineHeight(int line_height);

  // Set the maximum length of the layout text, not the actual text.
  // A |length| of 0 forgoes a hard limit, but does not guarantee proper
  // functionality of very long strings. Applies to subsequent SetText calls.
  // WARNING: Only use this for system limits, it lacks complex text support.
  void set_truncate_length(size_t length) { truncate_length_ = length; }

  // The display text will be elided to fit |display_rect| using this behavior.
  void SetElideBehavior(ElideBehavior elide_behavior);
  ElideBehavior elide_behavior() const { return elide_behavior_; }

  const Rect& display_rect() const { return display_rect_; }
  void SetDisplayRect(const Rect& r);

  bool subpixel_rendering_suppressed() const {
    return subpixel_rendering_suppressed_;
  }
  void set_subpixel_rendering_suppressed(bool suppressed) {
    subpixel_rendering_suppressed_ = suppressed;
  }

  const SelectionModel& selection_model() const { return selection_model_; }
  const Range& selection() const { return selection_model_.selection(); }
  size_t cursor_position() const { return selection_model_.caret_pos(); }

  // Set the cursor to |position|, with the caret affinity trailing the previous
  // grapheme, or if there is no previous grapheme, leading the cursor position.
  // See SelectionModel::caret_affinity_ for details.
  void SetCursorPosition(size_t position);

  // Moves the cursor left or right. Cursor movement is visual, meaning that
  // left and right are relative to screen, not the directionality of the text.
  // |selection_behavior| determines whether a selection is to be made and it's
  // behavior.
  void MoveCursor(BreakType break_type,
                  VisualCursorDirection direction,
                  SelectionBehavior selection_behavior);

  // Set the selection_model_ to the value of |selection|.
  // The selection range is clamped to text().length() if out of range.
  // Returns true if the cursor position or selection range changed.
  // If any index in |selection_model| is not a cursorable position (not on a
  // grapheme boundary), it is a no-op and returns false.
  bool SetSelection(const SelectionModel& selection);

  // Moves the cursor to the text index corresponding to |point|. If |select| is
  // true, a selection is made with the current selection start index. If the
  // resultant text indices do not lie on valid grapheme boundaries, it is a no-
  // op and returns false. If this move is happening because of a drag causing a
  // selection change, and |drag_origin| is not the zero point, then
  // |drag_origin| overrides the default origin for a select-to-drag
  // (usually the existing text insertion cursor).
  bool MoveCursorToPoint(const gfx::Point& point,
                         bool select,
                         const gfx::Point& drag_origin = gfx::Point());

  // Set the selection_model_ based on |range|.
  // If the |range| start or end is greater than text length, it is modified
  // to be the text length.
  // If the |range| start or end is not a cursorable position (not on grapheme
  // boundary), it is a NO-OP and returns false. Otherwise, returns true.
  bool SelectRange(const Range& range);

  // Returns true if the local point is over selected text.
  bool IsPointInSelection(const Point& point);

  // Selects no text, keeping the current cursor position and caret affinity.
  void ClearSelection();

  // Select the entire text range. If |reversed| is true, the range will end at
  // the logical beginning of the text; this generally shows the leading portion
  // of text that overflows its display area.
  void SelectAll(bool reversed);

  // Selects the word at the current cursor position. If there is a non-empty
  // selection, the selection bounds are extended to their nearest word
  // boundaries.
  void SelectWord();

  void SetCompositionRange(const Range& composition_range);

  // Set the text color over the entire text or a logical character range.
  // The |range| should be valid, non-reversed, and within [0, text().length()].
  void SetColor(SkColor value);
  void ApplyColor(SkColor value, const Range& range);

  // DEPRECATED.
  // Set the baseline style over the entire text or a logical character range.
  // The |range| should be valid, non-reversed, and within [0, text().length()].
  // TODO(tapted): Remove this. The only client is moving to
  // ApplyFontSizeOverride.
  void SetBaselineStyle(BaselineStyle value);
  void ApplyBaselineStyle(BaselineStyle value, const Range& range);

  // Alters the font size in |range|.
  void ApplyFontSizeOverride(int font_size_override, const Range& range);

  // Set various text styles over the entire text or a logical character range.
  // The respective |style| is applied if |value| is true, or removed if false.
  // The |range| should be valid, non-reversed, and within [0, text().length()].
  void SetStyle(TextStyle style, bool value);
  void ApplyStyle(TextStyle style, bool value, const Range& range);

  void SetWeight(Font::Weight weight);
  void ApplyWeight(Font::Weight weight, const Range& range);

  // Returns whether this style is enabled consistently across the entire
  // RenderText.
  bool GetStyle(TextStyle style) const;

  // Set or get the text directionality mode and get the text direction yielded.
  void SetDirectionalityMode(DirectionalityMode mode);
  DirectionalityMode directionality_mode() const {
      return directionality_mode_;
  }
  base::i18n::TextDirection GetDisplayTextDirection();

  // Returns the visual movement direction corresponding to the logical
  // end/beginning of the text, considering only the dominant direction returned
  // by |GetDisplayTextDirection()|, not the direction of a particular run.
  VisualCursorDirection GetVisualDirectionOfLogicalEnd();
  VisualCursorDirection GetVisualDirectionOfLogicalBeginning();

  // Returns the text used to display, which may be obscured, truncated or
  // elided. The subclass may compute elided text on the fly, or use
  // precomputed the elided text.
  virtual const base::string16& GetDisplayText() = 0;

  // Returns the size required to display the current string (which is the
  // wrapped size in multiline mode). The returned size does not include space
  // reserved for the cursor or the offset text shadows.
  virtual Size GetStringSize() = 0;

  // This is same as GetStringSize except that fractional size is returned.
  // The default implementation is same as GetStringSize. Certain platforms that
  // compute the text size as floating-point values, like Mac, will override
  // this method.
  // See comment in Canvas::GetStringWidthF for its usage.
  virtual SizeF GetStringSizeF();

  // Returns the width of the content (which is the wrapped width in multiline
  // mode). Reserves room for the cursor if |cursor_enabled_| is true.
  float GetContentWidthF();

  // Same as GetContentWidthF with the width rounded up.
  int GetContentWidth();

  // Returns the common baseline of the text. The return value is the vertical
  // offset from the top of |display_rect_| to the text baseline, in pixels.
  // The baseline is determined from the font list and display rect, and does
  // not depend on the text.
  int GetBaseline();

  void Draw(Canvas* canvas);

  // Gets the SelectionModel from a visual point in local coordinates. If
  // |drag_origin| is nonzero, it is used as the baseline for
  // out-of-vertical-bounds drags on platforms that have them, instead of the
  // default origin (the insertion cursor's position).
  virtual SelectionModel FindCursorPosition(
      const Point& point,
      const Point& drag_origin = gfx::Point()) = 0;

  // Returns true if the position is a valid logical index into text(), and is
  // also a valid grapheme boundary, which may be used as a cursor position.
  virtual bool IsValidCursorIndex(size_t index) = 0;

  // Returns true if the position is a valid logical index into text(). Indices
  // amid multi-character graphemes are allowed here, unlike IsValidCursorIndex.
  virtual bool IsValidLogicalIndex(size_t index) const;

  // Returns true if this instance supports text selection.
  virtual bool IsSelectionSupported() const = 0;

  // Get the visual bounds of a cursor at |caret|. These bounds typically
  // represent a vertical line if |insert_mode| is true. Pass false for
  // |insert_mode| to retrieve the bounds of the associated glyph. These bounds
  // are in local coordinates, but may be outside the visible region if the text
  // is longer than the textfield. Subsequent text, cursor, or bounds changes
  // may invalidate returned values. Note that |caret| must be placed at
  // grapheme boundary, i.e. caret.caret_pos() must be a cursorable position.
  // TODO(crbug.com/248597): Add multiline support.
  Rect GetCursorBounds(const SelectionModel& caret, bool insert_mode);

  // Compute the current cursor bounds, panning the text to show the cursor in
  // the display rect if necessary. These bounds are in local coordinates.
  // Subsequent text, cursor, or bounds changes may invalidate returned values.
  const Rect& GetUpdatedCursorBounds();

  // Given an |index| in text(), return the next or previous grapheme boundary
  // in logical order (i.e. the nearest cursorable index). The return value is
  // in the range 0 to text().length() inclusive (the input is clamped if it is
  // out of that range). Always moves by at least one character index unless the
  // supplied index is already at the boundary of the string.
  size_t IndexOfAdjacentGrapheme(size_t index,
                                 LogicalCursorDirection direction);

  // Return a SelectionModel with the cursor at the current selection's start.
  // The returned value represents a cursor/caret position without a selection.
  SelectionModel GetSelectionModelForSelectionStart() const;

  // Sets shadows to drawn with text.
  void set_shadows(const ShadowValues& shadows) { shadows_ = shadows; }
  const ShadowValues& shadows() const { return shadows_; }

  typedef std::pair<Font, Range> FontSpan;
  // For testing purposes, returns which fonts were chosen for which parts of
  // the text by returning a vector of Font and Range pairs, where each range
  // specifies the character range for which the corresponding font has been
  // chosen.
  virtual std::vector<FontSpan> GetFontSpansForTesting() = 0;

  // Returns rectangle surrounding the current string (from origin to size)
  RectF GetStringRect();

  // Get the visual bounds containing the logical substring within the |range|.
  // If |range| is empty, the result is empty. These bounds could be visually
  // discontinuous if the substring is split by a LTR/RTL level change.
  // These bounds are in local coordinates, but may be outside the visible
  // region if the text is longer than the textfield. Subsequent text, cursor,
  // or bounds changes may invalidate returned values.
  virtual std::vector<Rect> GetSubstringBounds(const Range& range) = 0;

  // Gets the horizontal span (relative to the left of the text, not the view)
  // of the sequence of glyphs in |text_range|, over which the cursor will
  // jump when breaking by characters. If the glyphs are RTL then the returned
  // Range will have is_reversed() true.  (This does not return a Rect because a
  // Rect can't have a negative width.)
  virtual Range GetCursorSpan(const Range& text_range) = 0;

  const Vector2d& GetUpdatedDisplayOffset();
  void SetDisplayOffset(int horizontal_offset);

  // Returns the line offset from the origin after applying the text alignment
  // and the display offset.
  Vector2d GetLineOffset(size_t line_number);

  // Retrieves the word displayed at the given |point| along with its styling
  // information. |point| is in the view's coordinates. If no word is displayed
  // at the point, returns a nearby word. |baseline_point| should correspond to
  // the baseline point of the leftmost glyph of the |word| in the view's
  // coordinates. Returns false, if no word can be retrieved.
  bool GetWordLookupDataAtPoint(const Point& point,
                                DecoratedText* decorated_word,
                                Point* baseline_point);

  // Retrieves the text at |range| along with its styling information.
  // |baseline_point| should correspond to the baseline point of
  // the leftmost glyph of the text in the view's coordinates. If the text
  // spans multiple lines, |baseline_point| will correspond with the leftmost
  // glyph on the first line in the range. Returns false, if no text can be
  // retrieved.
  bool GetLookupDataForRange(const Range& range,
                             DecoratedText* decorated_text,
                             Point* baseline_point);

  // Retrieves the text in the given |range|.
  base::string16 GetTextFromRange(const Range& range) const;

  void set_strike_thickness_factor(SkScalar f) { strike_thickness_factor_ = f; }

 protected:
  RenderText();

  // NOTE: The value of these accessors may be stale. Please make sure
  // that these fields are up to date before accessing them.
  const base::string16& layout_text() const { return layout_text_; }
  const base::string16& display_text() const { return display_text_; }
  bool text_elided() const { return text_elided_; }

  const BreakList<SkColor>& colors() const { return colors_; }
  const BreakList<BaselineStyle>& baselines() const { return baselines_; }
  const BreakList<int>& font_size_overrides() const {
    return font_size_overrides_;
  }
  const BreakList<Font::Weight>& weights() const { return weights_; }
  const std::vector<BreakList<bool> >& styles() const { return styles_; }
  SkScalar strike_thickness_factor() const { return strike_thickness_factor_; }

  // Whether all the BreakLists have only one break.
  bool IsHomogeneous() const;

  const std::vector<internal::Line>& lines() const { return lines_; }
  void set_lines(std::vector<internal::Line>* lines) { lines_.swap(*lines); }

  // Returns the baseline of the current text.  The return value depends on
  // the text and its layout while the return value of GetBaseline() doesn't.
  // GetAlignmentOffset() takes into account the difference between them.
  //
  // We'd like a RenderText to show the text always on the same baseline
  // regardless of the text, so the text does not jump up or down depending
  // on the text.  However, underlying layout engines return different baselines
  // depending on the text.  In general, layout engines determine the minimum
  // bounding box for the text and return the baseline from the top of the
  // bounding box.  So the baseline changes depending on font metrics used to
  // layout the text.
  //
  // For example, suppose there are FontA and FontB and the baseline of FontA
  // is smaller than the one of FontB.  If the text is laid out only with FontA,
  // then the baseline of FontA may be returned.  If the text includes some
  // characters which are laid out with FontB, then the baseline of FontB may
  // be returned.
  //
  // GetBaseline() returns the fixed baseline regardless of the text.
  // GetDisplayTextBaseline() returns the baseline determined by the underlying
  // layout engine, and it changes depending on the text.  GetAlignmentOffset()
  // returns the difference between them.
  virtual int GetDisplayTextBaseline() = 0;

  void set_cached_bounds_and_offset_valid(bool valid) {
    cached_bounds_and_offset_valid_ = valid;
  }

  // Get the selection model that visually neighbors |position| by |break_type|.
  // The returned value represents a cursor/caret position without a selection.
  SelectionModel GetAdjacentSelectionModel(const SelectionModel& current,
                                           BreakType break_type,
                                           VisualCursorDirection direction);

  // Get the selection model visually left/right of |selection| by one grapheme.
  // The returned value represents a cursor/caret position without a selection.
  virtual SelectionModel AdjacentCharSelectionModel(
      const SelectionModel& selection,
      VisualCursorDirection direction) = 0;

  // Get the selection model visually left/right of |selection| by one word.
  // The returned value represents a cursor/caret position without a selection.
  virtual SelectionModel AdjacentWordSelectionModel(
      const SelectionModel& selection,
      VisualCursorDirection direction) = 0;

  // Get the selection model corresponding to visual text ends.
  // The returned value represents a cursor/caret position without a selection.
  SelectionModel EdgeSelectionModel(VisualCursorDirection direction);

  // Get the selection model corresponding to visual text ends for |line_index|.
  // The returned value represents a cursor/caret position without a selection.
  SelectionModel LineSelectionModel(size_t line_index,
                                    gfx::VisualCursorDirection direction);

  // Sets the selection model, |model| is assumed to be valid.
  void SetSelectionModel(const SelectionModel& model);

  // Convert between indices into |text_| and indices into
  // GetDisplayText(), which differ when the text is obscured,
  // truncated or elided. Regardless of whether or not the text is
  // obscured, the character (code point) offsets always match.
  virtual size_t TextIndexToDisplayIndex(size_t index) = 0;
  virtual size_t DisplayIndexToTextIndex(size_t index) = 0;

  // Notifies that layout text, or attributes that affect the layout text
  // shape have changed. |text_changed| is true if the content of the
  // |layout_text_| has changed, not just attributes.
  virtual void OnLayoutTextAttributeChanged(bool text_changed) = 0;

  // Notifies that attributes that affect the display text shape have changed.
  virtual void OnDisplayTextAttributeChanged() = 0;

  // Called when the text color changes.
  virtual void OnTextColorChanged();

  // Ensure the text is laid out, lines are computed, and |lines_| is valid.
  virtual void EnsureLayout() = 0;

  // Draw the text.
  virtual void DrawVisualText(internal::SkiaTextRenderer* renderer) = 0;

  // Update the display text.
  void UpdateDisplayText(float text_width);

  // Returns display text positions that are suitable for breaking lines.
  const BreakList<size_t>& GetLineBreaks();

  // Apply (and undo) temporary composition underlines and selection colors.
  void ApplyCompositionAndSelectionStyles();
  void UndoCompositionAndSelectionStyles();

  // Convert points from the text space to the view space. Handles the display
  // area, display offset, application LTR/RTL mode and multiline.
  Point ToViewPoint(const Point& point);

  // Get the alignment, resolving ALIGN_TO_HEAD with the current text direction.
  HorizontalAlignment GetCurrentHorizontalAlignment();

  // Returns the line offset from the origin, accounts for text alignment only.
  Vector2d GetAlignmentOffset(size_t line_number);

  // Applies fade effects to |renderer|.
  void ApplyFadeEffects(internal::SkiaTextRenderer* renderer);

  // Applies text shadows to |renderer|.
  void ApplyTextShadows(internal::SkiaTextRenderer* renderer);

  // Get the text direction for the current directionality mode and given
  // |text|.
  base::i18n::TextDirection GetTextDirection(const base::string16& text);

  // Convert an index in |text_| to the index in |given_text|. The
  // |given_text| should be either |display_text_| or |layout_text_|
  // depending on the elide state.
  size_t TextIndexToGivenTextIndex(const base::string16& given_text,
                                   size_t index) const;

  // Adjust ranged styles to accommodate a new text length.
  void UpdateStyleLengths();

  // Returns the line index for the given argument. |text_y| is relative to
  // the text bounds. Returns -1 if |text_y| is above the text and
  // lines().size() if |text_y| is below it.
  int GetLineContainingYCoord(float text_y);

  // A convenience function to check whether the glyph attached to the caret
  // is within the given range.
  static bool RangeContainsCaret(const Range& range,
                                 size_t caret_pos,
                                 LogicalCursorDirection caret_affinity);

  // Returns the baseline, with which the text best appears vertically centered.
  static int DetermineBaselineCenteringText(const int display_height,
                                            const FontList& font_list);

  // Returns an expanded version of |rect| that is vertically symmetric with
  // respect to the center of |display_rect|.
  static gfx::Rect ExpandToBeVerticallySymmetric(const gfx::Rect& rect,
                                                 const gfx::Rect& display_rect);

 private:
  friend class test::RenderTextTestApi;

  // Updates |layout_text_| and |display_text_| as needed (or marks them dirty).
  void OnTextAttributeChanged();

  // Elides |text| as needed to fit in the |available_width| using |behavior|.
  // |text_width| is the pre-calculated width of the text shaped by this render
  // text, or pass 0 if the width is unknown.
  base::string16 Elide(const base::string16& text,
                       float text_width,
                       float available_width,
                       ElideBehavior behavior);

  // Elides |email| as needed to fit the |available_width|.
  base::string16 ElideEmail(const base::string16& email, float available_width);

  // Update the cached bounds and display offset to ensure that the current
  // cursor is within the visible display area.
  void UpdateCachedBoundsAndOffset();

  // Draw the selection.
  void DrawSelection(Canvas* canvas);

  // Returns the nearest word start boundary for |index|. First searches in the
  // CURSOR_BACKWARD direction, then in the CURSOR_FORWARD direction. Returns
  // the text length if no valid boundary is found.
  size_t GetNearestWordStartBoundary(size_t index) const;

  // Expands |range| to its nearest word boundaries and returns the resulting
  // range. Maintains directionality of |range|.
  Range ExpandRangeToWordBoundary(const Range& range) const;

  // Returns an implementation-specific run list, if implemented.
  virtual internal::TextRunList* GetRunList();
  virtual const internal::TextRunList* GetRunList() const;

  // Returns the decorated text corresponding to |range|. Returns false if the
  // text cannot be retrieved, e.g. if the text is obscured.
  virtual bool GetDecoratedTextForRange(const Range& range,
                                        DecoratedText* decorated_text) = 0;

  // Specify the width of a glyph for test. The width of glyphs is very
  // platform-dependent and environment-dependent. Otherwise multiline text
  // will become really flaky.
  virtual void SetGlyphWidthForTest(float test_width);

  // Logical UTF-16 string data to be drawn.
  base::string16 text_;

  // Horizontal alignment of the text with respect to |display_rect_|.  The
  // default is to align left if the application UI is LTR and right if RTL.
  HorizontalAlignment horizontal_alignment_;

  // The text directionality mode, defaults to DIRECTIONALITY_FROM_TEXT.
  DirectionalityMode directionality_mode_;

  // The cached text direction, potentially computed from the text or UI locale.
  // Use GetTextDirection(), do not use this potentially invalid value directly!
  base::i18n::TextDirection text_direction_;

  // A list of fonts used to render |text_|.
  FontList font_list_;

  // Logical selection range and visual cursor position.
  SelectionModel selection_model_;

  // The cached cursor bounds; get these bounds with GetUpdatedCursorBounds.
  Rect cursor_bounds_;

  // Specifies whether the cursor is enabled. If disabled, no space is reserved
  // for the cursor when positioning text.
  bool cursor_enabled_;

  // Whether the current selection has a known direction. That is, whether a
  // directional input (e.g. arrow key) has been received for the current
  // selection to indicate which end of the selection has the caret. When true,
  // directed inputs preserve (rather than replace) the selection affinity.
  bool has_directed_selection_;

  // The color used for drawing selected text.
  SkColor selection_color_;

  // The background color used for drawing the selection when focused.
  SkColor selection_background_focused_color_;

  // Whether the selection visual bounds should be expanded vertically to be
  // vertically symmetric with respect to the display rect. Note this flag has
  // no effect on multi-line text.
  bool symmetric_selection_visual_bounds_ = false;

  // The focus state of the text.
  bool focused_;

  // Composition text range.
  Range composition_range_;

  // Color, baseline, and style breaks, used to modify ranges of text.
  // BreakList positions are stored with text indices, not display indices.
  // TODO(msw): Expand to support cursor, selection, background, etc. colors.
  BreakList<SkColor> colors_;
  BreakList<BaselineStyle> baselines_;
  BreakList<int> font_size_overrides_;
  BreakList<Font::Weight> weights_;
  std::vector<BreakList<bool> > styles_;

  // Breaks saved without temporary composition and selection styling.
  BreakList<SkColor> saved_colors_;
  BreakList<bool> saved_underlines_;
  bool composition_and_selection_styles_applied_;

  // A flag to obscure actual text with asterisks for password fields.
  bool obscured_;
  // The index at which the char should be revealed in the obscured text.
  int obscured_reveal_index_;

  // The maximum length of text to display, 0 forgoes a hard limit.
  size_t truncate_length_;

  // The obscured and/or truncated text used to layout the text to display.
  base::string16 layout_text_;

  // The elided text displayed visually. This is empty if the text
  // does not have to be elided, or became empty as a result of eliding.
  // TODO(oshima): When the text is elided, painting can be done only with
  // display text info, so it should be able to clear the |layout_text_| and
  // associated information.
  base::string16 display_text_;

  // The behavior for eliding, fading, or truncating.
  ElideBehavior elide_behavior_;

  // True if the text is elided given the current behavior and display area.
  bool text_elided_;

  // The minimum height a line should have.
  int min_line_height_;

  // Whether the text should be broken into multiple lines. Uses the width of
  // |display_rect_| as the width cap.
  bool multiline_;

  // If multiple lines, the maximum number of lines to render, or 0.
  size_t max_lines_;

  // The wrap behavior when the text is broken into lines. Do nothing unless
  // |multiline_| is set. The default value is IGNORE_LONG_WORDS.
  WordWrapBehavior word_wrap_behavior_;

  // Whether newline characters should be replaced with newline symbols.
  bool replace_newline_chars_with_symbols_;

  // Set to true to suppress subpixel rendering due to non-font reasons (eg.
  // if the background is transparent). The default value is false.
  bool subpixel_rendering_suppressed_;

  // The local display area for rendering the text.
  Rect display_rect_;

  // Flag to work around a Skia bug with the PDF path (http://crbug.com/133548)
  // that results in incorrect clipping when drawing to the document margins.
  // This field allows disabling clipping to work around the issue.
  // TODO(asvitkine): Remove this when the underlying Skia bug is fixed.
  bool clip_to_display_rect_;

  // The offset for the text to be drawn, relative to the display area.
  // Get this point with GetUpdatedDisplayOffset (or risk using a stale value).
  Vector2d display_offset_;

  // The baseline of the text.  This is determined from the height of the
  // display area and the cap height of the font list so the text is vertically
  // centered.
  int baseline_;

  // The cached bounds and offset are invalidated by changes to the cursor,
  // selection, font, and other operations that adjust the visible text bounds.
  bool cached_bounds_and_offset_valid_;

  // Text shadows to be drawn.
  ShadowValues shadows_;

  // A list of valid display text line break positions.
  BreakList<size_t> line_breaks_;

  // Lines computed by EnsureLayout. These should be invalidated upon
  // OnLayoutTextAttributeChanged and OnDisplayTextAttributeChanged calls.
  std::vector<internal::Line> lines_;

  // The ratio of strike-through line thickness to text height.
  SkScalar strike_thickness_factor_;

  // Extra spacing placed between glyphs; used for obscured text styling.
  int glyph_spacing_ = 0;

  DISALLOW_COPY_AND_ASSIGN(RenderText);
};

}  // namespace gfx

#endif  // UI_GFX_RENDER_TEXT_H_
