// 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/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/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_;

  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<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; }
  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<Font::Weight> weights_;
  std::vector<BreakList<bool> > styles_;

  BreakList<SkColor>::const_iterator color_;
  BreakList<BaselineStyle>::const_iterator baseline_;
  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 PaintFlags.
void ApplyRenderParams(const FontRenderParams& params,
                       bool subpixel_rendering_suppressed,
                       cc::PaintFlags* flags);

}  // 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 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.
  bool MoveCursorToPoint(const gfx::Point& point, bool select);

  // 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);

  // 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()].
  void SetBaselineStyle(BaselineStyle value);
  void ApplyBaselineStyle(BaselineStyle value, 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.
  virtual SelectionModel FindCursorPosition(const Point& 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;

  // 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 GetDecoratedWordAtPoint(const Point& point,
                               DecoratedText* decorated_word,
                               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<Font::Weight>& weights() const { return weights_; }
  const std::vector<BreakList<bool> >& styles() const { return styles_; }
  SkScalar strike_thickness_factor() const { return strike_thickness_factor_; }

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

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

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