Home | History | Annotate | Download | only in gfx
      1 // Copyright (c) 2012 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_WIN_H_
      6 #define UI_GFX_RENDER_TEXT_WIN_H_
      7 
      8 #include <usp10.h>
      9 
     10 #include <map>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/scoped_vector.h"
     16 #include "ui/gfx/render_text.h"
     17 
     18 namespace gfx {
     19 
     20 namespace internal {
     21 
     22 struct TextRun {
     23   TextRun();
     24   ~TextRun();
     25 
     26   Range range;
     27   Font font;
     28   // A gfx::Font::FontStyle flag to specify bold and italic styles.
     29   // Supersedes |font.GetFontStyle()|. Stored separately to avoid calling
     30   // |font.DeriveFont()|, which is expensive on Windows.
     31   int font_style;
     32 
     33   bool strike;
     34   bool diagonal_strike;
     35   bool underline;
     36 
     37   int width;
     38   // The cumulative widths of preceding runs.
     39   int preceding_run_widths;
     40 
     41   SCRIPT_ANALYSIS script_analysis;
     42 
     43   scoped_ptr<WORD[]> glyphs;
     44   scoped_ptr<WORD[]> logical_clusters;
     45   scoped_ptr<SCRIPT_VISATTR[]> visible_attributes;
     46   int glyph_count;
     47 
     48   scoped_ptr<int[]> advance_widths;
     49   scoped_ptr<GOFFSET[]> offsets;
     50   ABC abc_widths;
     51   SCRIPT_CACHE script_cache;
     52 
     53  private:
     54   DISALLOW_COPY_AND_ASSIGN(TextRun);
     55 };
     56 
     57 }  // namespace internal
     58 
     59 // RenderTextWin is the Windows implementation of RenderText using Uniscribe.
     60 class RenderTextWin : public RenderText {
     61  public:
     62   RenderTextWin();
     63   virtual ~RenderTextWin();
     64 
     65   // Overridden from RenderText:
     66   virtual Size GetStringSize() OVERRIDE;
     67   virtual SelectionModel FindCursorPosition(const Point& point) OVERRIDE;
     68   virtual std::vector<FontSpan> GetFontSpansForTesting() OVERRIDE;
     69 
     70  protected:
     71   // Overridden from RenderText:
     72   virtual int GetLayoutTextBaseline() OVERRIDE;
     73   virtual SelectionModel AdjacentCharSelectionModel(
     74       const SelectionModel& selection,
     75       VisualCursorDirection direction) OVERRIDE;
     76   virtual SelectionModel AdjacentWordSelectionModel(
     77       const SelectionModel& selection,
     78       VisualCursorDirection direction) OVERRIDE;
     79   virtual Range GetGlyphBounds(size_t index) OVERRIDE;
     80   virtual std::vector<Rect> GetSubstringBounds(const Range& range) OVERRIDE;
     81   virtual size_t TextIndexToLayoutIndex(size_t index) const OVERRIDE;
     82   virtual size_t LayoutIndexToTextIndex(size_t index) const OVERRIDE;
     83   virtual bool IsValidCursorIndex(size_t index) OVERRIDE;
     84   virtual void ResetLayout() OVERRIDE;
     85   virtual void EnsureLayout() OVERRIDE;
     86   virtual void DrawVisualText(Canvas* canvas) OVERRIDE;
     87 
     88  private:
     89   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Win_BreakRunsByUnicodeBlocks);
     90   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Win_LogicalClusters);
     91   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_MinWidth);
     92   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_NormalWidth);
     93   FRIEND_TEST_ALL_PREFIXES(RenderTextTest, BreakRunsByUnicodeBlocks);
     94 
     95   void ItemizeLogicalText();
     96   void LayoutVisualText();
     97   void LayoutTextRun(internal::TextRun* run);
     98 
     99   // Helper function that calls |ScriptShape()| on the run, which has logic to
    100   // handle E_OUTOFMEMORY return codes.
    101   HRESULT ShapeTextRunWithFont(internal::TextRun* run, const Font& font);
    102 
    103   // Returns the number of characters in |run| that have missing glyphs.
    104   int CountCharsWithMissingGlyphs(internal::TextRun* run) const;
    105 
    106   // Return the run index that contains the argument; or the length of the
    107   // |runs_| vector if argument exceeds the text length or width.
    108   size_t GetRunContainingCaret(const SelectionModel& caret) const;
    109   size_t GetRunContainingXCoord(int x) const;
    110 
    111   // Given a |run|, returns the SelectionModel that contains the logical first
    112   // or last caret position inside (not at a boundary of) the run.
    113   // The returned value represents a cursor/caret position without a selection.
    114   SelectionModel FirstSelectionModelInsideRun(const internal::TextRun* run);
    115   SelectionModel LastSelectionModelInsideRun(const internal::TextRun* run);
    116 
    117   // Cached HDC for performing Uniscribe API calls.
    118   static HDC cached_hdc_;
    119 
    120   // Cached map from font name to the last successful substitute font used.
    121   // TODO(asvitkine): Move the caching logic to font_fallback_win.cc.
    122   static std::map<std::string, Font> successful_substitute_fonts_;
    123 
    124   SCRIPT_CONTROL script_control_;
    125   SCRIPT_STATE script_state_;
    126 
    127   ScopedVector<internal::TextRun> runs_;
    128 
    129   // Single line width of the layout text.
    130   int string_width_;
    131 
    132   // Wrapped multiline size of the layout text.
    133   Size multiline_string_size_;
    134 
    135   scoped_ptr<int[]> visual_to_logical_;
    136   scoped_ptr<int[]> logical_to_visual_;
    137 
    138   bool needs_layout_;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(RenderTextWin);
    141 };
    142 
    143 }  // namespace gfx
    144 
    145 #endif  // UI_GFX_RENDER_TEXT_WIN_H_
    146