123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- // Copyright 2014 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_HARFBUZZ_H_
- #define UI_GFX_RENDER_TEXT_HARFBUZZ_H_
- #include <hb.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <limits>
- #include <memory>
- #include <string>
- #include <unordered_map>
- #include <utility>
- #include <vector>
- #include "third_party/icu/source/common/unicode/ubidi.h"
- #include "third_party/icu/source/common/unicode/uscript.h"
- #include "ui/gfx/render_text.h"
- namespace gfx {
- class Range;
- class RangeF;
- class RenderTextHarfBuzz;
- namespace internal {
- struct GFX_EXPORT TextRunHarfBuzz {
- // Construct the run with |template_font| since determining the details of a
- // default-constructed gfx::Font is expensive, but it will always be replaced.
- explicit TextRunHarfBuzz(const Font& template_font);
- TextRunHarfBuzz(const TextRunHarfBuzz&) = delete;
- TextRunHarfBuzz& operator=(const TextRunHarfBuzz&) = delete;
- ~TextRunHarfBuzz();
- // Returns the corresponding glyph range of the given character range.
- // |range| is in text-space (0 corresponds to |GetDisplayText()[0]|). Returned
- // value is in run-space (0 corresponds to the first glyph in the run).
- Range CharRangeToGlyphRange(const Range& range) const;
- // Returns the number of missing glyphs in the shaped text run.
- size_t CountMissingGlyphs() const;
- // Writes the character and glyph ranges of the cluster containing |pos|.
- void GetClusterAt(size_t pos, Range* chars, Range* glyphs) const;
- // Returns the grapheme bounds at |text_index|. Handles multi-grapheme glyphs.
- // Returned value is the horizontal pixel span in text-space (assumes all runs
- // are on the same line). The returned range is never reversed.
- RangeF GetGraphemeBounds(RenderTextHarfBuzz* render_text,
- size_t text_index) const;
- // Returns the horizontal span of the given |char_range| handling grapheme
- // boundaries within glyphs. This is a wrapper around one or more calls to
- // GetGraphemeBounds(), returning a range in the same coordinate space.
- RangeF GetGraphemeSpanForCharRange(RenderTextHarfBuzz* render_text,
- const Range& char_range) const;
- // Returns the glyph width for the given character range. |char_range| is in
- // text-space (0 corresponds to |GetDisplayText()[0]|).
- SkScalar GetGlyphWidthForCharRange(const Range& char_range) const;
- // Font parameters that may be common to multiple text runs within a text run
- // list.
- struct GFX_EXPORT FontParams {
- // The default constructor for Font is expensive, so always require that a
- // Font be provided.
- explicit FontParams(const Font& template_font);
- ~FontParams();
- FontParams(const FontParams& other);
- FontParams& operator=(const FontParams& other);
- bool operator==(const FontParams& other) const;
- // Populates |render_params|, |font_size| and |baseline_offset| based on
- // |font|.
- void ComputeRenderParamsFontSizeAndBaselineOffset();
- // Populates |font|, |skia_face|, and |render_params|. Returns false if
- // |skia_face| is nullptr. Takes |font|'s family name and rematches this
- // family and the run's weight and style properties to find a new font.
- bool SetRenderParamsRematchFont(const Font& font,
- const FontRenderParams& render_params);
- // Populates |font|, |skia_face|, and |render_params|. Returns false if
- // |skia_face| is nullptr. Does not perform rematching but extracts an
- // SkTypeface from the underlying PlatformFont of font. Use this method when
- // configuring the |TextRunHarfBuzz| for shaping with fallback fonts, where
- // it is important to keep the underlying font handle of platform font and
- // not perform rematching as in |SetRenderParamsRematchFont|.
- bool SetRenderParamsOverrideSkiaFaceFromFont(
- const Font& font,
- const FontRenderParams& render_params);
- struct Hash {
- size_t operator()(const FontParams& key) const;
- };
- Font font;
- sk_sp<SkTypeface> skia_face;
- FontRenderParams render_params;
- Font::Weight weight = Font::Weight::NORMAL;
- int font_size = 0;
- int baseline_offset = 0;
- int baseline_type = 0;
- bool italic = false;
- bool strike = false;
- bool underline = false;
- bool heavy_underline = false;
- bool is_rtl = false;
- UBiDiLevel level = 0;
- UScriptCode script = USCRIPT_INVALID_CODE;
- };
- // Parameters that are set by ShapeRunWithFont.
- struct GFX_EXPORT ShapeOutput {
- ShapeOutput();
- ~ShapeOutput();
- ShapeOutput(const ShapeOutput& other);
- ShapeOutput& operator=(const ShapeOutput& other);
- ShapeOutput(ShapeOutput&& other);
- ShapeOutput& operator=(ShapeOutput&& other);
- float width = 0.0;
- std::vector<uint16_t> glyphs;
- std::vector<SkPoint> positions;
- // Note that in the context of TextRunHarfBuzz, |glyph_to_char| is indexed
- // based off of the full string (so it is in the same domain as
- // TextRunHarfBuzz::range).
- std::vector<uint32_t> glyph_to_char;
- size_t glyph_count = 0;
- size_t missing_glyph_count = std::numeric_limits<size_t>::max();
- };
- // If |new_shape.missing_glyph_count| is less than that of |shape|, set
- // |font_params| and |shape| to the specified values.
- void UpdateFontParamsAndShape(const FontParams& new_font_params,
- const ShapeOutput& new_shape);
- Range range;
- FontParams font_params;
- ShapeOutput shape;
- float preceding_run_widths = 0.0;
- };
- // Manages the list of TextRunHarfBuzz and its logical <-> visual index mapping.
- class TextRunList {
- public:
- TextRunList();
- TextRunList(const TextRunList&) = delete;
- TextRunList& operator=(const TextRunList&) = delete;
- ~TextRunList();
- size_t size() const { return runs_.size(); }
- // Converts the index between logical and visual index.
- size_t visual_to_logical(size_t index) const {
- return visual_to_logical_[index];
- }
- size_t logical_to_visual(size_t index) const {
- return logical_to_visual_[index];
- }
- const std::vector<std::unique_ptr<TextRunHarfBuzz>>& runs() const {
- return runs_;
- }
- // Adds the new |run| to the run list.
- void Add(std::unique_ptr<TextRunHarfBuzz> run) {
- runs_.push_back(std::move(run));
- }
- // Reset the run list.
- void Reset();
- // Initialize the index mapping.
- void InitIndexMap();
- // Precomputes the offsets for all runs.
- void ComputePrecedingRunWidths();
- // Get the total width of runs, as if they were shown on one line.
- // Do not use this when multiline is enabled.
- float width() const { return width_; }
- // Get the run index applicable to |position| (at or preceeding |position|).
- size_t GetRunIndexAt(size_t position) const;
- private:
- // Text runs in logical order.
- std::vector<std::unique_ptr<TextRunHarfBuzz>> runs_;
- // Maps visual run indices to logical run indices and vice versa.
- std::vector<int32_t> visual_to_logical_;
- std::vector<int32_t> logical_to_visual_;
- float width_;
- };
- } // namespace internal
- class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
- public:
- RenderTextHarfBuzz();
- RenderTextHarfBuzz(const RenderTextHarfBuzz&) = delete;
- RenderTextHarfBuzz& operator=(const RenderTextHarfBuzz&) = delete;
- ~RenderTextHarfBuzz() override;
- // RenderText:
- const std::u16string& GetDisplayText() override;
- SizeF GetStringSizeF() override;
- SizeF GetLineSizeF(const SelectionModel& caret) override;
- std::vector<Rect> GetSubstringBounds(const Range& range) override;
- RangeF GetCursorSpan(const Range& text_range) override;
- size_t GetLineContainingCaret(const SelectionModel& caret) override;
- protected:
- // RenderText:
- SelectionModel AdjacentCharSelectionModel(
- const SelectionModel& selection,
- VisualCursorDirection direction) override;
- SelectionModel AdjacentWordSelectionModel(
- const SelectionModel& selection,
- VisualCursorDirection direction) override;
- SelectionModel AdjacentLineSelectionModel(
- const SelectionModel& selection,
- VisualCursorDirection direction) override;
- void OnLayoutTextAttributeChanged(bool text_changed) override;
- void OnDisplayTextAttributeChanged() override;
- void EnsureLayout() override;
- void DrawVisualText(internal::SkiaTextRenderer* renderer,
- const std::vector<Range>& selections) override;
- private:
- friend class test::RenderTextTestApi;
- friend class RenderTextTest;
- // Return the run index that contains the argument; or the length of the
- // |runs_| vector if argument exceeds the text length or width.
- size_t GetRunContainingCaret(const SelectionModel& caret);
- // Given a |run|, returns the SelectionModel that contains the logical first
- // or last caret position inside (not at a boundary of) the run.
- // The returned value represents a cursor/caret position without a selection.
- SelectionModel FirstSelectionModelInsideRun(
- const internal::TextRunHarfBuzz* run);
- SelectionModel LastSelectionModelInsideRun(
- const internal::TextRunHarfBuzz* run);
- using CommonizedRunsMap =
- std::unordered_map<internal::TextRunHarfBuzz::FontParams,
- std::vector<internal::TextRunHarfBuzz*>,
- internal::TextRunHarfBuzz::FontParams::Hash>;
- // Break the text into logical runs in |out_run_list|. Populate
- // |out_commonized_run_map| such that each run is present in the vector
- // corresponding to its FontParams.
- void ItemizeTextToRuns(const std::u16string& string,
- internal::TextRunList* out_run_list,
- CommonizedRunsMap* out_commonized_run_map);
- // Shape the glyphs needed for each run in |runs| within |text|. This method
- // will apply a number of fonts to |base_font_params| and assign to each
- // run's FontParams and ShapeOutput the parameters and resulting shape that
- // had the smallest number of missing glyphs.
- void ShapeRuns(const std::u16string& text,
- const internal::TextRunHarfBuzz::FontParams& base_font_params,
- std::vector<internal::TextRunHarfBuzz*> runs);
- // Shape the glyphs for |in_out_runs| within |text| using the parameters
- // specified by |font_params|. If, for any run in |*in_out_runs|, the
- // resulting shaping has fewer missing glyphs than the existing shape, then
- // write |font_params| and the resulting ShapeOutput to that run. Remove all
- // runs with no missing glyphs from |in_out_runs| (the caller, ShapeRuns, will
- // terminate when no runs with missing glyphs remain).
- void ShapeRunsWithFont(
- const std::u16string& text,
- const internal::TextRunHarfBuzz::FontParams& font_params,
- std::vector<internal::TextRunHarfBuzz*>* in_out_runs);
- // Itemize |text| into runs in |out_run_list|, shape the runs, and populate
- // |out_run_list|'s visual <-> logical maps.
- void ItemizeAndShapeText(const std::u16string& text,
- internal::TextRunList* out_run_list);
- // Makes sure that text runs for layout text are shaped.
- void EnsureLayoutRunList();
- // Returns whether the display range is still a valid range after the eliding
- // pass.
- bool IsValidDisplayRange(Range display_range);
- // RenderText:
- internal::TextRunList* GetRunList() override;
- const internal::TextRunList* GetRunList() const override;
- bool GetDecoratedTextForRange(const Range& range,
- DecoratedText* decorated_text) override;
- // Text run list for |layout_text_| and |display_text_|.
- // |display_run_list_| is created only when the text is elided.
- internal::TextRunList layout_run_list_;
- std::unique_ptr<internal::TextRunList> display_run_list_;
- bool update_layout_run_list_ : 1;
- bool update_display_run_list_ : 1;
- bool update_display_text_ : 1;
- // The device scale factor for which the text was laid out.
- float device_scale_factor_ = 1.0f;
- // The total size of the layouted text.
- SizeF total_size_;
- // The process application locale used to configure text rendering.
- std::string locale_;
- };
- } // namespace gfx
- #endif // UI_GFX_RENDER_TEXT_HARFBUZZ_H_
|