Home | History | Annotate | Download | only in gfx
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef UI_GFX_RENDER_TEXT_HARFBUZZ_H_
      6 #define UI_GFX_RENDER_TEXT_HARFBUZZ_H_
      7 
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/memory/scoped_vector.h"
     10 #include "third_party/harfbuzz-ng/src/hb.h"
     11 #include "third_party/icu/source/common/unicode/ubidi.h"
     12 #include "third_party/icu/source/common/unicode/uscript.h"
     13 #include "ui/gfx/render_text.h"
     14 
     15 namespace base {
     16 namespace i18n {
     17 class BreakIterator;
     18 }
     19 }
     20 
     21 namespace gfx {
     22 
     23 namespace internal {
     24 
     25 struct GFX_EXPORT TextRunHarfBuzz {
     26   TextRunHarfBuzz();
     27   ~TextRunHarfBuzz();
     28 
     29   // Returns the index of the first glyph that corresponds to the character at
     30   // |pos|.
     31   size_t CharToGlyph(size_t pos) const;
     32 
     33   // Returns the corresponding glyph range of the given character range.
     34   // |range| is in text-space (0 corresponds to |GetLayoutText()[0]|). Returned
     35   // value is in run-space (0 corresponds to the first glyph in the run).
     36   Range CharRangeToGlyphRange(const Range& range) const;
     37 
     38   // Returns the number of missing glyphs in the shaped text run.
     39   size_t CountMissingGlyphs() const;
     40 
     41   // Writes the character and glyph ranges of the cluster containing |pos|.
     42   void GetClusterAt(size_t pos, Range* chars, Range* glyphs) const;
     43 
     44   // Returns the grapheme bounds at |text_index|. Handles multi-grapheme glyphs.
     45   Range GetGraphemeBounds(base::i18n::BreakIterator* grapheme_iterator,
     46                           size_t text_index);
     47 
     48   // Returns whether the given shaped run contains any missing glyphs.
     49   bool HasMissingGlyphs() const;
     50 
     51   float width;
     52   float preceding_run_widths;
     53   Range range;
     54   bool is_rtl;
     55   UBiDiLevel level;
     56   UScriptCode script;
     57 
     58   scoped_ptr<uint16[]> glyphs;
     59   scoped_ptr<SkPoint[]> positions;
     60   std::vector<uint32> glyph_to_char;
     61   size_t glyph_count;
     62 
     63   skia::RefPtr<SkTypeface> skia_face;
     64   FontRenderParams render_params;
     65   int font_size;
     66   int font_style;
     67   bool strike;
     68   bool diagonal_strike;
     69   bool underline;
     70 
     71  private:
     72   DISALLOW_COPY_AND_ASSIGN(TextRunHarfBuzz);
     73 };
     74 
     75 }  // namespace internal
     76 
     77 class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
     78  public:
     79   RenderTextHarfBuzz();
     80   virtual ~RenderTextHarfBuzz();
     81 
     82   // Overridden from RenderText.
     83   virtual Size GetStringSize() OVERRIDE;
     84   virtual SizeF GetStringSizeF() OVERRIDE;
     85   virtual SelectionModel FindCursorPosition(const Point& point) OVERRIDE;
     86   virtual std::vector<FontSpan> GetFontSpansForTesting() OVERRIDE;
     87   virtual Range GetGlyphBounds(size_t index) OVERRIDE;
     88 
     89  protected:
     90   // Overridden from RenderText.
     91   virtual int GetLayoutTextBaseline() OVERRIDE;
     92   virtual SelectionModel AdjacentCharSelectionModel(
     93       const SelectionModel& selection,
     94       VisualCursorDirection direction) OVERRIDE;
     95   virtual SelectionModel AdjacentWordSelectionModel(
     96       const SelectionModel& selection,
     97       VisualCursorDirection direction) OVERRIDE;
     98   virtual std::vector<Rect> GetSubstringBounds(const Range& range) OVERRIDE;
     99   virtual size_t TextIndexToLayoutIndex(size_t index) const OVERRIDE;
    100   virtual size_t LayoutIndexToTextIndex(size_t index) const OVERRIDE;
    101   virtual bool IsValidCursorIndex(size_t index) OVERRIDE;
    102   virtual void ResetLayout() OVERRIDE;
    103   virtual void EnsureLayout() OVERRIDE;
    104   virtual void DrawVisualText(Canvas* canvas) OVERRIDE;
    105 
    106  private:
    107   friend class RenderTextTest;
    108   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_RunDirection);
    109   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks);
    110   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_SubglyphGraphemeCases);
    111   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_SubglyphGraphemePartition);
    112   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_NonExistentFont);
    113 
    114   // Return the run index that contains the argument; or the length of the
    115   // |runs_| vector if argument exceeds the text length or width.
    116   size_t GetRunContainingCaret(const SelectionModel& caret) const;
    117   size_t GetRunContainingXCoord(int x, int* offset) const;
    118 
    119   // Given a |run|, returns the SelectionModel that contains the logical first
    120   // or last caret position inside (not at a boundary of) the run.
    121   // The returned value represents a cursor/caret position without a selection.
    122   SelectionModel FirstSelectionModelInsideRun(
    123       const internal::TextRunHarfBuzz* run);
    124   SelectionModel LastSelectionModelInsideRun(
    125       const internal::TextRunHarfBuzz* run);
    126 
    127   // Break the text into logical runs and populate the visual <-> logical maps.
    128   void ItemizeText();
    129 
    130   // Shape the glyphs needed for the text |run|.
    131   void ShapeRun(internal::TextRunHarfBuzz* run);
    132   bool ShapeRunWithFont(internal::TextRunHarfBuzz* run,
    133                         const std::string& font);
    134 
    135   // Text runs in logical order.
    136   ScopedVector<internal::TextRunHarfBuzz> runs_;
    137 
    138   // Maps visual run indices to logical run indices and vice versa.
    139   std::vector<int32_t> visual_to_logical_;
    140   std::vector<int32_t> logical_to_visual_;
    141 
    142   bool needs_layout_;
    143 
    144   // ICU grapheme iterator for the layout text. Valid when |!needs_layout_|. Can
    145   // be NULL in case of an error.
    146   scoped_ptr<base::i18n::BreakIterator> grapheme_iterator_;
    147 
    148   DISALLOW_COPY_AND_ASSIGN(RenderTextHarfBuzz);
    149 };
    150 
    151 }  // namespace gfx
    152 
    153 #endif  // UI_GFX_RENDER_TEXT_HARFBUZZ_H_
    154