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 gfx {
     16 
     17 namespace internal {
     18 
     19 struct GFX_EXPORT TextRunHarfBuzz {
     20   TextRunHarfBuzz();
     21   ~TextRunHarfBuzz();
     22 
     23   // Returns the index of the first glyph that corresponds to the character at
     24   // |pos|.
     25   size_t CharToGlyph(size_t pos) const;
     26 
     27   // Returns the corresponding glyph range of the given character range.
     28   // |range| is in text-space (0 corresponds to |GetLayoutText()[0]|). Returned
     29   // value is in run-space (0 corresponds to the first glyph in the run).
     30   Range CharRangeToGlyphRange(const Range& range) const;
     31 
     32   // Returns whether the given shaped run contains any missing glyphs.
     33   bool HasMissingGlyphs() const;
     34 
     35   // Returns the X coordinate of the leading or |trailing| edge of the glyph
     36   // starting at |text_index|, relative to the left of the text (not the view).
     37   int GetGlyphXBoundary(size_t text_index, bool trailing) const;
     38 
     39   int width;
     40   int preceding_run_widths;
     41   Range range;
     42   bool is_rtl;
     43   UBiDiLevel level;
     44   UScriptCode script;
     45 
     46   scoped_ptr<uint16[]> glyphs;
     47   scoped_ptr<SkPoint[]> positions;
     48   scoped_ptr<uint32[]> glyph_to_char;
     49   size_t glyph_count;
     50 
     51   skia::RefPtr<SkTypeface> skia_face;
     52   int font_size;
     53   int font_style;
     54   bool strike;
     55   bool diagonal_strike;
     56   bool underline;
     57 
     58  private:
     59   DISALLOW_COPY_AND_ASSIGN(TextRunHarfBuzz);
     60 };
     61 
     62 }  // namespace internal
     63 
     64 class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
     65  public:
     66   RenderTextHarfBuzz();
     67   virtual ~RenderTextHarfBuzz();
     68 
     69   // Overridden from RenderText.
     70   virtual Size GetStringSize() OVERRIDE;
     71   virtual SelectionModel FindCursorPosition(const Point& point) OVERRIDE;
     72   virtual std::vector<FontSpan> GetFontSpansForTesting() OVERRIDE;
     73 
     74  protected:
     75   // Overridden from RenderText.
     76   virtual int GetLayoutTextBaseline() OVERRIDE;
     77   virtual SelectionModel AdjacentCharSelectionModel(
     78       const SelectionModel& selection,
     79       VisualCursorDirection direction) OVERRIDE;
     80   virtual SelectionModel AdjacentWordSelectionModel(
     81       const SelectionModel& selection,
     82       VisualCursorDirection direction) OVERRIDE;
     83   virtual Range GetGlyphBounds(size_t index) OVERRIDE;
     84   virtual std::vector<Rect> GetSubstringBounds(const Range& range) OVERRIDE;
     85   virtual size_t TextIndexToLayoutIndex(size_t index) const OVERRIDE;
     86   virtual size_t LayoutIndexToTextIndex(size_t index) const OVERRIDE;
     87   virtual bool IsValidCursorIndex(size_t index) OVERRIDE;
     88   virtual void ResetLayout() OVERRIDE;
     89   virtual void EnsureLayout() OVERRIDE;
     90   virtual void DrawVisualText(Canvas* canvas) OVERRIDE;
     91 
     92  private:
     93   friend class RenderTextTest;
     94   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_RunDirection);
     95   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks);
     96 
     97   // Return the run index that contains the argument; or the length of the
     98   // |runs_| vector if argument exceeds the text length or width.
     99   size_t GetRunContainingCaret(const SelectionModel& caret) const;
    100   size_t GetRunContainingXCoord(int x, int* offset) const;
    101 
    102   // Given a |run|, returns the SelectionModel that contains the logical first
    103   // or last caret position inside (not at a boundary of) the run.
    104   // The returned value represents a cursor/caret position without a selection.
    105   SelectionModel FirstSelectionModelInsideRun(
    106       const internal::TextRunHarfBuzz* run);
    107   SelectionModel LastSelectionModelInsideRun(
    108       const internal::TextRunHarfBuzz* run);
    109 
    110   // Break the text into logical runs and populate the visual <-> logical maps.
    111   void ItemizeText();
    112 
    113   // Shape the glyphs needed for the text |run|.
    114   void ShapeRun(internal::TextRunHarfBuzz* run);
    115 
    116   // Text runs in logical order.
    117   ScopedVector<internal::TextRunHarfBuzz> runs_;
    118 
    119   // Maps visual run indices to logical run indices and vice versa.
    120   std::vector<int32_t> visual_to_logical_;
    121   std::vector<int32_t> logical_to_visual_;
    122 
    123   bool needs_layout_;
    124 
    125   DISALLOW_COPY_AND_ASSIGN(RenderTextHarfBuzz);
    126 };
    127 
    128 }  // namespace gfx
    129 
    130 #endif  // UI_GFX_RENDER_TEXT_HARFBUZZ_H_
    131