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