OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef UI_GFX_RENDER_TEXT_H_ | 5 #ifndef UI_GFX_RENDER_TEXT_H_ |
6 #define UI_GFX_RENDER_TEXT_H_ | 6 #define UI_GFX_RENDER_TEXT_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <vector> | 10 #include <vector> |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 LINE_BREAK, | 84 LINE_BREAK, |
85 }; | 85 }; |
86 | 86 |
87 // Horizontal text alignment styles. | 87 // Horizontal text alignment styles. |
88 enum HorizontalAlignment { | 88 enum HorizontalAlignment { |
89 ALIGN_LEFT, | 89 ALIGN_LEFT, |
90 ALIGN_CENTER, | 90 ALIGN_CENTER, |
91 ALIGN_RIGHT, | 91 ALIGN_RIGHT, |
92 }; | 92 }; |
93 | 93 |
94 // VisualCursorDirection and LogicalCursorDirection represent directions of | |
95 // motion of the cursor in BiDi text. The combinations that make sense are: | |
96 // | |
97 // base::i18n::TextDirection VisualCursorDirection LogicalCursorDirection | |
98 // LEFT_TO_RIGHT CURSOR_LEFT CURSOR_BACKWARD | |
99 // LEFT_TO_RIGHT CURSOR_RIGHT CURSOR_FORWARD | |
100 // RIGHT_TO_LEFT CURSOR_RIGHT CURSOR_BACKWARD | |
101 // RIGHT_TO_LEFT CURSOR_LEFT CURSOR_FORWARD | |
102 enum VisualCursorDirection { | |
103 CURSOR_LEFT, | |
104 CURSOR_RIGHT | |
105 }; | |
106 enum LogicalCursorDirection { | |
107 CURSOR_BACKWARD, | |
108 CURSOR_FORWARD | |
109 }; | |
110 | |
111 // RenderText represents an abstract model of styled text and its corresponding | 94 // RenderText represents an abstract model of styled text and its corresponding |
112 // visual layout. Support is built in for a cursor, a selection, simple styling, | 95 // visual layout. Support is built in for a cursor, a selection, simple styling, |
113 // complex scripts, and bi-directional text. Implementations provide mechanisms | 96 // complex scripts, and bi-directional text. Implementations provide mechanisms |
114 // for rendering and translation between logical and visual data. | 97 // for rendering and translation between logical and visual data. |
115 class UI_EXPORT RenderText { | 98 class UI_EXPORT RenderText { |
116 public: | 99 public: |
117 virtual ~RenderText(); | 100 virtual ~RenderText(); |
118 | 101 |
119 // Creates a platform-specific RenderText instance. | 102 // Creates a platform-specific RenderText instance. |
120 static RenderText* CreateRenderText(); | 103 static RenderText* CreateRenderText(); |
121 | 104 |
122 const string16& text() const { return text_; } | 105 const string16& text() const { return text_; } |
123 void SetText(const string16& text); | 106 void SetText(const string16& text); |
124 | 107 |
125 HorizontalAlignment horizontal_alignment() const { | 108 HorizontalAlignment horizontal_alignment() const { |
126 return horizontal_alignment_; | 109 return horizontal_alignment_; |
127 } | 110 } |
128 void SetHorizontalAlignment(HorizontalAlignment alignment); | 111 void SetHorizontalAlignment(HorizontalAlignment alignment); |
129 | 112 |
130 const FontList& font_list() const { return font_list_; } | 113 const FontList& font_list() const { return font_list_; } |
131 void SetFontList(const FontList& font_list); | 114 void SetFontList(const FontList& font_list); |
132 | 115 |
133 // Set the font size to |size| in pixels. | 116 // Set the font size to |size| in pixels. |
134 void SetFontSize(int size); | 117 void SetFontSize(int size); |
135 | 118 |
136 // Get the first font in |font_list_|. | 119 // Get the first font in |font_list_|. |
137 const Font& GetFont() const; | 120 const Font& GetFont() const; |
138 | 121 |
139 const SelectionModel& selection_model() const { return selection_model_; } | |
140 | |
141 bool cursor_enabled() const { return cursor_enabled_; } | 122 bool cursor_enabled() const { return cursor_enabled_; } |
142 void SetCursorEnabled(bool cursor_enabled); | 123 void SetCursorEnabled(bool cursor_enabled); |
143 | 124 |
144 bool cursor_visible() const { return cursor_visible_; } | 125 bool cursor_visible() const { return cursor_visible_; } |
145 void set_cursor_visible(bool visible) { cursor_visible_ = visible; } | 126 void set_cursor_visible(bool visible) { cursor_visible_ = visible; } |
146 | 127 |
147 bool insert_mode() const { return insert_mode_; } | 128 bool insert_mode() const { return insert_mode_; } |
148 void ToggleInsertMode(); | 129 void ToggleInsertMode(); |
149 | 130 |
150 SkColor cursor_color() const { return cursor_color_; } | 131 SkColor cursor_color() const { return cursor_color_; } |
(...skipping 15 matching lines...) Expand all Loading... |
166 void set_fade_head(bool fade_head) { fade_head_ = fade_head; } | 147 void set_fade_head(bool fade_head) { fade_head_ = fade_head; } |
167 bool fade_head() const { return fade_head_; } | 148 bool fade_head() const { return fade_head_; } |
168 void set_fade_tail(bool fade_tail) { fade_tail_ = fade_tail; } | 149 void set_fade_tail(bool fade_tail) { fade_tail_ = fade_tail; } |
169 bool fade_tail() const { return fade_tail_; } | 150 bool fade_tail() const { return fade_tail_; } |
170 | 151 |
171 bool background_is_transparent() const { return background_is_transparent_; } | 152 bool background_is_transparent() const { return background_is_transparent_; } |
172 void set_background_is_transparent(bool transparent) { | 153 void set_background_is_transparent(bool transparent) { |
173 background_is_transparent_ = transparent; | 154 background_is_transparent_ = transparent; |
174 } | 155 } |
175 | 156 |
176 // This cursor position corresponds to SelectionModel::selection_end. In | 157 const SelectionModel& selection_model() const { return selection_model_; } |
177 // addition to representing the selection end, it's also where logical text | 158 |
178 // edits take place, and doesn't necessarily correspond to | 159 const ui::Range& selection() const { return selection_model_.selection(); } |
179 // SelectionModel::caret_pos. | 160 |
180 size_t GetCursorPosition() const; | 161 size_t cursor_position() const { return selection_model_.caret_pos(); } |
181 void SetCursorPosition(size_t position); | 162 void SetCursorPosition(size_t position); |
182 | 163 |
183 // Moves the cursor left or right. Cursor movement is visual, meaning that | 164 // Moves the cursor left or right. Cursor movement is visual, meaning that |
184 // left and right are relative to screen, not the directionality of the text. | 165 // left and right are relative to screen, not the directionality of the text. |
185 // If |select| is false, the selection start is moved to the same position. | 166 // If |select| is false, the selection start is moved to the same position. |
186 void MoveCursor(BreakType break_type, | 167 void MoveCursor(BreakType break_type, |
187 VisualCursorDirection direction, | 168 VisualCursorDirection direction, |
188 bool select); | 169 bool select); |
189 | 170 |
190 // Set the selection_model_ to the value of |selection|. | 171 // Set the selection_model_ to the value of |selection|. |
191 // The selection model components are modified if invalid. | 172 // The selection range is clamped to text().length() if out of range. |
192 // Returns true if the cursor position or selection range changed. | 173 // Returns true if the cursor position or selection range changed. |
193 // If |selectin_start_| or |selection_end_| or |caret_pos_| in | 174 // If any index in |selection_model| is not a cursorable position (not on a |
194 // |selection_model| is not a cursorable position (not on grapheme boundary), | 175 // grapheme boundary), it is a no-op and returns false. |
195 // it is a NO-OP and returns false. | |
196 bool MoveCursorTo(const SelectionModel& selection_model); | 176 bool MoveCursorTo(const SelectionModel& selection_model); |
197 | 177 |
198 // Move the cursor to the position associated with the clicked point. | 178 // Move the cursor to the position associated with the clicked point. |
199 // If |select| is false, the selection start is moved to the same position. | 179 // If |select| is false, the selection start is moved to the same position. |
200 // Returns true if the cursor position or selection range changed. | 180 // Returns true if the cursor position or selection range changed. |
201 bool MoveCursorTo(const Point& point, bool select); | 181 bool MoveCursorTo(const Point& point, bool select); |
202 | 182 |
203 // Set the selection_model_ based on |range|. | 183 // Set the selection_model_ based on |range|. |
204 // If the |range| start or end is greater than text length, it is modified | 184 // If the |range| start or end is greater than text length, it is modified |
205 // to be the text length. | 185 // to be the text length. |
206 // If the |range| start or end is not a cursorable position (not on grapheme | 186 // If the |range| start or end is not a cursorable position (not on grapheme |
207 // boundary), it is a NO-OP and returns false. Otherwise, returns true. | 187 // boundary), it is a NO-OP and returns false. Otherwise, returns true. |
208 bool SelectRange(const ui::Range& range); | 188 bool SelectRange(const ui::Range& range); |
209 | 189 |
210 size_t GetSelectionStart() const { | |
211 return selection_model_.selection_start(); | |
212 } | |
213 size_t MinOfSelection() const { | |
214 return std::min(GetSelectionStart(), GetCursorPosition()); | |
215 } | |
216 size_t MaxOfSelection() const { | |
217 return std::max(GetSelectionStart(), GetCursorPosition()); | |
218 } | |
219 bool EmptySelection() const { | |
220 return GetSelectionStart() == GetCursorPosition(); | |
221 } | |
222 | |
223 // Returns true if the local point is over selected text. | 190 // Returns true if the local point is over selected text. |
224 bool IsPointInSelection(const Point& point); | 191 bool IsPointInSelection(const Point& point); |
225 | 192 |
226 // Selects no text, all text, or the word at the current cursor position. | 193 // Selects no text, all text, or the word at the current cursor position. |
227 void ClearSelection(); | 194 void ClearSelection(); |
228 void SelectAll(); | 195 void SelectAll(); |
229 void SelectWord(); | 196 void SelectWord(); |
230 | 197 |
231 const ui::Range& GetCompositionRange() const; | 198 const ui::Range& GetCompositionRange() const; |
232 void SetCompositionRange(const ui::Range& composition_range); | 199 void SetCompositionRange(const ui::Range& composition_range); |
233 | 200 |
234 // Apply |style_range| to the internal style model. | 201 // Apply |style_range| to the internal style model. |
235 void ApplyStyleRange(const StyleRange& style_range); | 202 void ApplyStyleRange(const StyleRange& style_range); |
236 | 203 |
237 // Apply |default_style_| over the entire text range. | 204 // Apply |default_style_| over the entire text range. |
238 void ApplyDefaultStyle(); | 205 void ApplyDefaultStyle(); |
239 | 206 |
240 // Returns the dominant direction of the current text. | 207 // Returns the dominant direction of the current text. |
241 virtual base::i18n::TextDirection GetTextDirection() = 0; | 208 virtual base::i18n::TextDirection GetTextDirection() = 0; |
242 | 209 |
243 // Returns the visual movement direction corresponding to the logical end | 210 // Returns the visual movement direction corresponding to the logical end |
244 // of the text, considering only the dominant direction returned by | 211 // of the text, considering only the dominant direction returned by |
245 // |GetTextDirection()|, not the direction of a particular run. | 212 // |GetTextDirection()|, not the direction of a particular run. |
246 VisualCursorDirection GetVisualDirectionOfLogicalEnd(); | 213 VisualCursorDirection GetVisualDirectionOfLogicalEnd(); |
247 | 214 |
248 // Get the width of the entire string. | 215 // Get the size in pixels of the entire string. |
249 virtual int GetStringWidth() = 0; | 216 virtual Size GetStringSize() = 0; |
250 | 217 |
251 void Draw(Canvas* canvas); | 218 void Draw(Canvas* canvas); |
252 | 219 |
253 // Gets the SelectionModel from a visual point in local coordinates. | 220 // Gets the SelectionModel from a visual point in local coordinates. |
254 virtual SelectionModel FindCursorPosition(const Point& point) = 0; | 221 virtual SelectionModel FindCursorPosition(const Point& point) = 0; |
255 | 222 |
256 // Get the visual bounds of a cursor at |selection|. These bounds typically | 223 // Get the visual bounds of a cursor at |selection|. These bounds typically |
257 // represent a vertical line, but if |insert_mode| is true they contain the | 224 // represent a vertical line, but if |insert_mode| is true they contain the |
258 // bounds of the associated glyph. These bounds are in local coordinates, but | 225 // bounds of the associated glyph. These bounds are in local coordinates, but |
259 // may be outside the visible region if the text is longer than the textfield. | 226 // may be outside the visible region if the text is longer than the textfield. |
260 // Subsequent text, cursor, or bounds changes may invalidate returned values. | 227 // Subsequent text, cursor, or bounds changes may invalidate returned values. |
261 virtual Rect GetCursorBounds(const SelectionModel& selection, | 228 Rect GetCursorBounds(const SelectionModel& selection, bool insert_mode); |
262 bool insert_mode) = 0; | |
263 | 229 |
264 // Compute the current cursor bounds, panning the text to show the cursor in | 230 // Compute the current cursor bounds, panning the text to show the cursor in |
265 // the display rect if necessary. These bounds are in local coordinates. | 231 // the display rect if necessary. These bounds are in local coordinates. |
266 // Subsequent text, cursor, or bounds changes may invalidate returned values. | 232 // Subsequent text, cursor, or bounds changes may invalidate returned values. |
267 const Rect& GetUpdatedCursorBounds(); | 233 const Rect& GetUpdatedCursorBounds(); |
268 | 234 |
269 // Given an |index| in text(), return the next or previous grapheme boundary | 235 // Given an |index| in text(), return the next or previous grapheme boundary |
270 // in logical order (that is, the nearest index for which | 236 // in logical order (that is, the nearest index for which |
271 // |IsCursorablePosition(index)| returns true). The return value is in the | 237 // |IsCursorablePosition(index)| returns true). The return value is in the |
272 // range 0 to text().length() inclusive (the input is clamped if it is out of | 238 // range 0 to text().length() inclusive (the input is clamped if it is out of |
(...skipping 30 matching lines...) Expand all Loading... |
303 VisualCursorDirection direction) = 0; | 269 VisualCursorDirection direction) = 0; |
304 | 270 |
305 // Get the selection model visually left/right of |selection| by one word. | 271 // Get the selection model visually left/right of |selection| by one word. |
306 // The returned value represents a cursor/caret position without a selection. | 272 // The returned value represents a cursor/caret position without a selection. |
307 virtual SelectionModel AdjacentWordSelectionModel( | 273 virtual SelectionModel AdjacentWordSelectionModel( |
308 const SelectionModel& selection, | 274 const SelectionModel& selection, |
309 VisualCursorDirection direction) = 0; | 275 VisualCursorDirection direction) = 0; |
310 | 276 |
311 // Get the SelectionModels corresponding to visual text ends. | 277 // Get the SelectionModels corresponding to visual text ends. |
312 // The returned value represents a cursor/caret position without a selection. | 278 // The returned value represents a cursor/caret position without a selection. |
313 virtual SelectionModel EdgeSelectionModel( | 279 SelectionModel EdgeSelectionModel(VisualCursorDirection direction); |
314 VisualCursorDirection direction) = 0; | |
315 | 280 |
316 // Sets the selection model, the argument is assumed to be valid. | 281 // Sets the selection model, the argument is assumed to be valid. |
317 virtual void SetSelectionModel(const SelectionModel& model); | 282 virtual void SetSelectionModel(const SelectionModel& model); |
318 | 283 |
319 // Get the visual bounds containing the logical substring within |from| to | 284 // Get the height and horizontal bounds (relative to the left of the text, not |
320 // |to|. If |from| equals |to|, the result is empty. These bounds could be | 285 // the view) of the glyph starting at |index|. If the glyph is RTL then |
321 // visually discontinuous if the substring is split by a LTR/RTL level change. | 286 // xspan->is_reversed(). This does not return a Rect because a Rect can't have |
| 287 // a negative width. |
| 288 virtual void GetGlyphBounds(size_t index, ui::Range* xspan, int* height) = 0; |
| 289 |
| 290 // Get the visual bounds containing the logical substring within the |range|. |
| 291 // If |range| is empty, the result is empty. These bounds could be visually |
| 292 // discontinuous if the substring is split by a LTR/RTL level change. |
322 // These bounds are in local coordinates, but may be outside the visible | 293 // These bounds are in local coordinates, but may be outside the visible |
323 // region if the text is longer than the textfield. Subsequent text, cursor, | 294 // region if the text is longer than the textfield. Subsequent text, cursor, |
324 // or bounds changes may invalidate returned values. | 295 // or bounds changes may invalidate returned values. |
325 virtual std::vector<Rect> GetSubstringBounds(size_t from, size_t to) = 0; | 296 virtual std::vector<Rect> GetSubstringBounds(ui::Range range) = 0; |
326 | 297 |
327 // Return true if cursor can appear in front of the character at |position|, | 298 // Return true if cursor can appear in front of the character at |position|, |
328 // which means it is a grapheme boundary or the first character in the text. | 299 // which means it is a grapheme boundary or the first character in the text. |
329 virtual bool IsCursorablePosition(size_t position) = 0; | 300 virtual bool IsCursorablePosition(size_t position) = 0; |
330 | 301 |
331 // Update the layout so that the next draw request can correctly | 302 // Update the layout so that the next draw request can correctly |
332 // render the text and its attributes. | 303 // render the text and its attributes. |
333 virtual void UpdateLayout() = 0; | 304 virtual void UpdateLayout() = 0; |
334 | 305 |
335 // Ensure the text is laid out. | 306 // Ensure the text is laid out. |
(...skipping 24 matching lines...) Expand all Loading... |
360 | 331 |
361 // Returns display offset based on current text alignment. | 332 // Returns display offset based on current text alignment. |
362 Point GetAlignmentOffset(); | 333 Point GetAlignmentOffset(); |
363 | 334 |
364 // Returns the origin point for drawing text via Skia. | 335 // Returns the origin point for drawing text via Skia. |
365 Point GetOriginForSkiaDrawing(); | 336 Point GetOriginForSkiaDrawing(); |
366 | 337 |
367 // Applies fade effects to |renderer|. | 338 // Applies fade effects to |renderer|. |
368 void ApplyFadeEffects(internal::SkiaTextRenderer* renderer); | 339 void ApplyFadeEffects(internal::SkiaTextRenderer* renderer); |
369 | 340 |
| 341 // A convenience function to check whether the glyph attached to the caret |
| 342 // is within the given range. |
| 343 static bool RangeContainsCaret(const ui::Range& range, |
| 344 size_t caret_pos, |
| 345 LogicalCursorDirection caret_affinity); |
| 346 |
370 private: | 347 private: |
371 friend class RenderTextTest; | 348 friend class RenderTextTest; |
372 | 349 |
373 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, DefaultStyle); | 350 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, DefaultStyle); |
374 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, CustomDefaultStyle); | 351 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, CustomDefaultStyle); |
375 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, ApplyStyleRange); | 352 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, ApplyStyleRange); |
376 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, StyleRangesAdjust); | 353 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, StyleRangesAdjust); |
377 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, PasswordCensorship); | 354 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, PasswordCensorship); |
378 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GraphemePositions); | 355 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GraphemePositions); |
379 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, SelectionModels); | 356 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, EdgeSelectionModels); |
380 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, OriginForSkiaDrawing); | 357 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, OriginForSkiaDrawing); |
381 | 358 |
382 // Set the cursor to |position|, with the caret trailing the previous | 359 // Set the cursor to |position|, with the caret trailing the previous |
383 // grapheme, or if there is no previous grapheme, leading the cursor position. | 360 // grapheme, or if there is no previous grapheme, leading the cursor position. |
384 // If |select| is false, the selection start is moved to the same position. | 361 // If |select| is false, the selection start is moved to the same position. |
385 // If the |position| is not a cursorable position (not on grapheme boundary), | 362 // If the |position| is not a cursorable position (not on grapheme boundary), |
386 // it is a NO-OP. | 363 // it is a NO-OP. |
387 void MoveCursorTo(size_t position, bool select); | 364 void MoveCursorTo(size_t position, bool select); |
388 | 365 |
389 // Update the cached bounds and display offset to ensure that the current | 366 // Update the cached bounds and display offset to ensure that the current |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 // The cached bounds and offset are invalidated by changes to the cursor, | 428 // The cached bounds and offset are invalidated by changes to the cursor, |
452 // selection, font, and other operations that adjust the visible text bounds. | 429 // selection, font, and other operations that adjust the visible text bounds. |
453 bool cached_bounds_and_offset_valid_; | 430 bool cached_bounds_and_offset_valid_; |
454 | 431 |
455 DISALLOW_COPY_AND_ASSIGN(RenderText); | 432 DISALLOW_COPY_AND_ASSIGN(RenderText); |
456 }; | 433 }; |
457 | 434 |
458 } // namespace gfx | 435 } // namespace gfx |
459 | 436 |
460 #endif // UI_GFX_RENDER_TEXT_H_ | 437 #endif // UI_GFX_RENDER_TEXT_H_ |
OLD | NEW |