| 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 |