Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: ui/gfx/render_text.h

Issue 9390022: Simplify handling of BiDi cursor movement (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase (no changes) Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « ui/gfx/canvas_skia_skia.cc ('k') | ui/gfx/render_text.cc » ('j') | ui/gfx/render_text_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698