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