OLD | NEW |
| (Empty) |
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_H_ | |
6 #define UI_GFX_RENDER_TEXT_H_ | |
7 | |
8 #include <algorithm> | |
9 #include <cstring> | |
10 #include <string> | |
11 #include <utility> | |
12 #include <vector> | |
13 | |
14 #include "base/gtest_prod_util.h" | |
15 #include "base/i18n/rtl.h" | |
16 #include "base/memory/scoped_ptr.h" | |
17 #include "base/strings/string16.h" | |
18 #include "skia/ext/refptr.h" | |
19 #include "third_party/skia/include/core/SkColor.h" | |
20 #include "third_party/skia/include/core/SkPaint.h" | |
21 #include "ui/gfx/break_list.h" | |
22 #include "ui/gfx/font_list.h" | |
23 #include "ui/gfx/font_render_params.h" | |
24 #include "ui/gfx/point.h" | |
25 #include "ui/gfx/range/range.h" | |
26 #include "ui/gfx/rect.h" | |
27 #include "ui/gfx/selection_model.h" | |
28 #include "ui/gfx/shadow_value.h" | |
29 #include "ui/gfx/size_f.h" | |
30 #include "ui/gfx/text_constants.h" | |
31 #include "ui/gfx/vector2d.h" | |
32 | |
33 class SkCanvas; | |
34 class SkDrawLooper; | |
35 struct SkPoint; | |
36 class SkShader; | |
37 class SkTypeface; | |
38 | |
39 namespace gfx { | |
40 | |
41 class Canvas; | |
42 class Font; | |
43 class RenderTextTest; | |
44 | |
45 namespace internal { | |
46 | |
47 // Internal helper class used by derived classes to draw text through Skia. | |
48 class SkiaTextRenderer { | |
49 public: | |
50 explicit SkiaTextRenderer(Canvas* canvas); | |
51 ~SkiaTextRenderer(); | |
52 | |
53 void SetDrawLooper(SkDrawLooper* draw_looper); | |
54 void SetFontRenderParams(const FontRenderParams& params, | |
55 bool background_is_transparent); | |
56 void SetTypeface(SkTypeface* typeface); | |
57 void SetTextSize(SkScalar size); | |
58 void SetFontFamilyWithStyle(const std::string& family, int font_style); | |
59 void SetForegroundColor(SkColor foreground); | |
60 void SetShader(SkShader* shader); | |
61 // Sets underline metrics to use if the text will be drawn with an underline. | |
62 // If not set, default values based on the size of the text will be used. The | |
63 // two metrics must be set together. | |
64 void SetUnderlineMetrics(SkScalar thickness, SkScalar position); | |
65 void DrawSelection(const std::vector<Rect>& selection, SkColor color); | |
66 void DrawPosText(const SkPoint* pos, | |
67 const uint16* glyphs, | |
68 size_t glyph_count); | |
69 // Draw underline and strike-through text decorations. | |
70 // Based on |SkCanvas::DrawTextDecorations()| and constants from: | |
71 // third_party/skia/src/core/SkTextFormatParams.h | |
72 void DrawDecorations(int x, int y, int width, bool underline, bool strike, | |
73 bool diagonal_strike); | |
74 // Finishes any ongoing diagonal strike run. | |
75 void EndDiagonalStrike(); | |
76 void DrawUnderline(int x, int y, int width); | |
77 void DrawStrike(int x, int y, int width) const; | |
78 | |
79 private: | |
80 // Helper class to draw a diagonal line with multiple pieces of different | |
81 // lengths and colors; to support text selection appearances. | |
82 class DiagonalStrike { | |
83 public: | |
84 DiagonalStrike(Canvas* canvas, Point start, const SkPaint& paint); | |
85 ~DiagonalStrike(); | |
86 | |
87 void AddPiece(int length, SkColor color); | |
88 void Draw(); | |
89 | |
90 private: | |
91 typedef std::pair<int, SkColor> Piece; | |
92 | |
93 Canvas* canvas_; | |
94 const Point start_; | |
95 SkPaint paint_; | |
96 int total_length_; | |
97 std::vector<Piece> pieces_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(DiagonalStrike); | |
100 }; | |
101 | |
102 Canvas* canvas_; | |
103 SkCanvas* canvas_skia_; | |
104 SkPaint paint_; | |
105 SkScalar underline_thickness_; | |
106 SkScalar underline_position_; | |
107 scoped_ptr<DiagonalStrike> diagonal_; | |
108 | |
109 DISALLOW_COPY_AND_ASSIGN(SkiaTextRenderer); | |
110 }; | |
111 | |
112 // Internal helper class used by derived classes to iterate colors and styles. | |
113 class StyleIterator { | |
114 public: | |
115 StyleIterator(const BreakList<SkColor>& colors, | |
116 const std::vector<BreakList<bool> >& styles); | |
117 ~StyleIterator(); | |
118 | |
119 // Get the colors and styles at the current iterator position. | |
120 SkColor color() const { return color_->second; } | |
121 bool style(TextStyle s) const { return style_[s]->second; } | |
122 | |
123 // Get the intersecting range of the current iterator set. | |
124 Range GetRange() const; | |
125 | |
126 // Update the iterator to point to colors and styles applicable at |position|. | |
127 void UpdatePosition(size_t position); | |
128 | |
129 private: | |
130 BreakList<SkColor> colors_; | |
131 std::vector<BreakList<bool> > styles_; | |
132 | |
133 BreakList<SkColor>::const_iterator color_; | |
134 std::vector<BreakList<bool>::const_iterator> style_; | |
135 | |
136 DISALLOW_COPY_AND_ASSIGN(StyleIterator); | |
137 }; | |
138 | |
139 // Line segments are slices of the layout text to be rendered on a single line. | |
140 struct LineSegment { | |
141 LineSegment(); | |
142 ~LineSegment(); | |
143 | |
144 // X coordinates of this line segment in text space. | |
145 Range x_range; | |
146 | |
147 // The character range this segment corresponds to. | |
148 Range char_range; | |
149 | |
150 // Index of the text run that generated this segment. | |
151 size_t run; | |
152 }; | |
153 | |
154 // A line of layout text, comprised of a line segment list and some metrics. | |
155 struct Line { | |
156 Line(); | |
157 ~Line(); | |
158 | |
159 // Segments that make up this line in visual order. | |
160 std::vector<LineSegment> segments; | |
161 | |
162 // The sum of segment widths and the maximum of segment heights. | |
163 SizeF size; | |
164 | |
165 // Sum of preceding lines' heights. | |
166 int preceding_heights; | |
167 | |
168 // Maximum baseline of all segments on this line. | |
169 int baseline; | |
170 }; | |
171 | |
172 // Creates an SkTypeface from a font |family| name and a |gfx::Font::FontStyle|. | |
173 // May return NULL. | |
174 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const std::string& family, | |
175 int style); | |
176 | |
177 // Applies the given FontRenderParams to a Skia |paint|. | |
178 void ApplyRenderParams(const FontRenderParams& params, | |
179 bool background_is_transparent, | |
180 SkPaint* paint); | |
181 | |
182 } // namespace internal | |
183 | |
184 // RenderText represents an abstract model of styled text and its corresponding | |
185 // visual layout. Support is built in for a cursor, a selection, simple styling, | |
186 // complex scripts, and bi-directional text. Implementations provide mechanisms | |
187 // for rendering and translation between logical and visual data. | |
188 class GFX_EXPORT RenderText { | |
189 public: | |
190 virtual ~RenderText(); | |
191 | |
192 // Creates a platform-specific or cross-platform RenderText instance. | |
193 static RenderText* CreateInstance(); | |
194 | |
195 const base::string16& text() const { return text_; } | |
196 void SetText(const base::string16& text); | |
197 | |
198 HorizontalAlignment horizontal_alignment() const { | |
199 return horizontal_alignment_; | |
200 } | |
201 void SetHorizontalAlignment(HorizontalAlignment alignment); | |
202 | |
203 const FontList& font_list() const { return font_list_; } | |
204 void SetFontList(const FontList& font_list); | |
205 | |
206 bool cursor_enabled() const { return cursor_enabled_; } | |
207 void SetCursorEnabled(bool cursor_enabled); | |
208 | |
209 bool cursor_visible() const { return cursor_visible_; } | |
210 void set_cursor_visible(bool visible) { cursor_visible_ = visible; } | |
211 | |
212 bool insert_mode() const { return insert_mode_; } | |
213 void ToggleInsertMode(); | |
214 | |
215 SkColor cursor_color() const { return cursor_color_; } | |
216 void set_cursor_color(SkColor color) { cursor_color_ = color; } | |
217 | |
218 SkColor selection_color() const { return selection_color_; } | |
219 void set_selection_color(SkColor color) { selection_color_ = color; } | |
220 | |
221 SkColor selection_background_focused_color() const { | |
222 return selection_background_focused_color_; | |
223 } | |
224 void set_selection_background_focused_color(SkColor color) { | |
225 selection_background_focused_color_ = color; | |
226 } | |
227 | |
228 bool focused() const { return focused_; } | |
229 void set_focused(bool focused) { focused_ = focused; } | |
230 | |
231 bool clip_to_display_rect() const { return clip_to_display_rect_; } | |
232 void set_clip_to_display_rect(bool clip) { clip_to_display_rect_ = clip; } | |
233 | |
234 // In an obscured (password) field, all text is drawn as asterisks or bullets. | |
235 bool obscured() const { return obscured_; } | |
236 void SetObscured(bool obscured); | |
237 | |
238 // Makes a char in obscured text at |index| to be revealed. |index| should be | |
239 // a UTF16 text index. If there is a previous revealed index, the previous one | |
240 // is cleared and only the last set index will be revealed. If |index| is -1 | |
241 // or out of range, no char will be revealed. The revealed index is also | |
242 // cleared when SetText or SetObscured is called. | |
243 void SetObscuredRevealIndex(int index); | |
244 | |
245 // Set whether newline characters should be replaced with newline symbols. | |
246 void SetReplaceNewlineCharsWithSymbols(bool replace); | |
247 | |
248 // TODO(ckocagil): Multiline text rendering is currently only supported on | |
249 // Windows. Support other platforms. | |
250 bool multiline() const { return multiline_; } | |
251 void SetMultiline(bool multiline); | |
252 | |
253 // Set the maximum length of the displayed layout text, not the actual text. | |
254 // A |length| of 0 forgoes a hard limit, but does not guarantee proper | |
255 // functionality of very long strings. Applies to subsequent SetText calls. | |
256 // WARNING: Only use this for system limits, it lacks complex text support. | |
257 void set_truncate_length(size_t length) { truncate_length_ = length; } | |
258 | |
259 // The layout text will be elided to fit |display_rect| using this behavior. | |
260 // The layout text may be shortened further by the truncate length. | |
261 void SetElideBehavior(ElideBehavior elide_behavior); | |
262 ElideBehavior elide_behavior() const { return elide_behavior_; } | |
263 | |
264 const base::string16& layout_text() const { return layout_text_; } | |
265 | |
266 const Rect& display_rect() const { return display_rect_; } | |
267 void SetDisplayRect(const Rect& r); | |
268 | |
269 bool background_is_transparent() const { return background_is_transparent_; } | |
270 void set_background_is_transparent(bool transparent) { | |
271 background_is_transparent_ = transparent; | |
272 } | |
273 | |
274 const SelectionModel& selection_model() const { return selection_model_; } | |
275 | |
276 const Range& selection() const { return selection_model_.selection(); } | |
277 | |
278 size_t cursor_position() const { return selection_model_.caret_pos(); } | |
279 void SetCursorPosition(size_t position); | |
280 | |
281 // Moves the cursor left or right. Cursor movement is visual, meaning that | |
282 // left and right are relative to screen, not the directionality of the text. | |
283 // If |select| is false, the selection start is moved to the same position. | |
284 void MoveCursor(BreakType break_type, | |
285 VisualCursorDirection direction, | |
286 bool select); | |
287 | |
288 // Set the selection_model_ to the value of |selection|. | |
289 // The selection range is clamped to text().length() if out of range. | |
290 // Returns true if the cursor position or selection range changed. | |
291 // If any index in |selection_model| is not a cursorable position (not on a | |
292 // grapheme boundary), it is a no-op and returns false. | |
293 bool MoveCursorTo(const SelectionModel& selection_model); | |
294 | |
295 // Set the selection_model_ based on |range|. | |
296 // If the |range| start or end is greater than text length, it is modified | |
297 // to be the text length. | |
298 // If the |range| start or end is not a cursorable position (not on grapheme | |
299 // boundary), it is a NO-OP and returns false. Otherwise, returns true. | |
300 bool SelectRange(const Range& range); | |
301 | |
302 // Returns true if the local point is over selected text. | |
303 bool IsPointInSelection(const Point& point); | |
304 | |
305 // Selects no text, keeping the current cursor position and caret affinity. | |
306 void ClearSelection(); | |
307 | |
308 // Select the entire text range. If |reversed| is true, the range will end at | |
309 // the logical beginning of the text; this generally shows the leading portion | |
310 // of text that overflows its display area. | |
311 void SelectAll(bool reversed); | |
312 | |
313 // Selects the word at the current cursor position. If there is a non-empty | |
314 // selection, the selection bounds are extended to their nearest word | |
315 // boundaries. | |
316 void SelectWord(); | |
317 | |
318 const Range& GetCompositionRange() const; | |
319 void SetCompositionRange(const Range& composition_range); | |
320 | |
321 // Set the text color over the entire text or a logical character range. | |
322 // The |range| should be valid, non-reversed, and within [0, text().length()]. | |
323 void SetColor(SkColor value); | |
324 void ApplyColor(SkColor value, const Range& range); | |
325 | |
326 // Set various text styles over the entire text or a logical character range. | |
327 // The respective |style| is applied if |value| is true, or removed if false. | |
328 // The |range| should be valid, non-reversed, and within [0, text().length()]. | |
329 void SetStyle(TextStyle style, bool value); | |
330 void ApplyStyle(TextStyle style, bool value, const Range& range); | |
331 | |
332 // Returns whether this style is enabled consistently across the entire | |
333 // RenderText. | |
334 bool GetStyle(TextStyle style) const; | |
335 | |
336 // Set or get the text directionality mode and get the text direction yielded. | |
337 void SetDirectionalityMode(DirectionalityMode mode); | |
338 DirectionalityMode directionality_mode() const { | |
339 return directionality_mode_; | |
340 } | |
341 base::i18n::TextDirection GetTextDirection(); | |
342 | |
343 // Returns the visual movement direction corresponding to the logical end | |
344 // of the text, considering only the dominant direction returned by | |
345 // |GetTextDirection()|, not the direction of a particular run. | |
346 VisualCursorDirection GetVisualDirectionOfLogicalEnd(); | |
347 | |
348 // Returns the size required to display the current string (which is the | |
349 // wrapped size in multiline mode). The returned size does not include space | |
350 // reserved for the cursor or the offset text shadows. | |
351 virtual Size GetStringSize() = 0; | |
352 | |
353 // This is same as GetStringSize except that fractional size is returned. | |
354 // The default implementation is same as GetStringSize. Certain platforms that | |
355 // compute the text size as floating-point values, like Mac, will override | |
356 // this method. | |
357 // See comment in Canvas::GetStringWidthF for its usage. | |
358 virtual SizeF GetStringSizeF(); | |
359 | |
360 // Returns the width of the content (which is the wrapped width in multiline | |
361 // mode). Reserves room for the cursor if |cursor_enabled_| is true. | |
362 float GetContentWidth(); | |
363 | |
364 // Returns the common baseline of the text. The return value is the vertical | |
365 // offset from the top of |display_rect_| to the text baseline, in pixels. | |
366 // The baseline is determined from the font list and display rect, and does | |
367 // not depend on the text. | |
368 int GetBaseline(); | |
369 | |
370 void Draw(Canvas* canvas); | |
371 | |
372 // Draws a cursor at |position|. | |
373 void DrawCursor(Canvas* canvas, const SelectionModel& position); | |
374 | |
375 // Gets the SelectionModel from a visual point in local coordinates. | |
376 virtual SelectionModel FindCursorPosition(const Point& point) = 0; | |
377 | |
378 // Returns true if the position is a valid logical index into text(), and is | |
379 // also a valid grapheme boundary, which may be used as a cursor position. | |
380 virtual bool IsValidCursorIndex(size_t index) = 0; | |
381 | |
382 // Returns true if the position is a valid logical index into text(). Indices | |
383 // amid multi-character graphemes are allowed here, unlike IsValidCursorIndex. | |
384 virtual bool IsValidLogicalIndex(size_t index); | |
385 | |
386 // Get the visual bounds of a cursor at |caret|. These bounds typically | |
387 // represent a vertical line if |insert_mode| is true. Pass false for | |
388 // |insert_mode| to retrieve the bounds of the associated glyph. These bounds | |
389 // are in local coordinates, but may be outside the visible region if the text | |
390 // is longer than the textfield. Subsequent text, cursor, or bounds changes | |
391 // may invalidate returned values. Note that |caret| must be placed at | |
392 // grapheme boundary, i.e. caret.caret_pos() must be a cursorable position. | |
393 Rect GetCursorBounds(const SelectionModel& caret, bool insert_mode); | |
394 | |
395 // Compute the current cursor bounds, panning the text to show the cursor in | |
396 // the display rect if necessary. These bounds are in local coordinates. | |
397 // Subsequent text, cursor, or bounds changes may invalidate returned values. | |
398 const Rect& GetUpdatedCursorBounds(); | |
399 | |
400 // Given an |index| in text(), return the next or previous grapheme boundary | |
401 // in logical order (i.e. the nearest cursorable index). The return value is | |
402 // in the range 0 to text().length() inclusive (the input is clamped if it is | |
403 // out of that range). Always moves by at least one character index unless the | |
404 // supplied index is already at the boundary of the string. | |
405 size_t IndexOfAdjacentGrapheme(size_t index, | |
406 LogicalCursorDirection direction); | |
407 | |
408 // Return a SelectionModel with the cursor at the current selection's start. | |
409 // The returned value represents a cursor/caret position without a selection. | |
410 SelectionModel GetSelectionModelForSelectionStart(); | |
411 | |
412 // Sets shadows to drawn with text. | |
413 void set_shadows(const ShadowValues& shadows) { shadows_ = shadows; } | |
414 const ShadowValues& shadows() { return shadows_; } | |
415 | |
416 typedef std::pair<Font, Range> FontSpan; | |
417 // For testing purposes, returns which fonts were chosen for which parts of | |
418 // the text by returning a vector of Font and Range pairs, where each range | |
419 // specifies the character range for which the corresponding font has been | |
420 // chosen. | |
421 virtual std::vector<FontSpan> GetFontSpansForTesting() = 0; | |
422 | |
423 // Gets the horizontal bounds (relative to the left of the text, not the view) | |
424 // of the glyph starting at |index|. If the glyph is RTL then the returned | |
425 // Range will have is_reversed() true. (This does not return a Rect because a | |
426 // Rect can't have a negative width.) | |
427 virtual Range GetGlyphBounds(size_t index) = 0; | |
428 | |
429 const Vector2d& GetUpdatedDisplayOffset(); | |
430 void SetDisplayOffset(int horizontal_offset); | |
431 | |
432 protected: | |
433 RenderText(); | |
434 | |
435 const BreakList<SkColor>& colors() const { return colors_; } | |
436 const std::vector<BreakList<bool> >& styles() const { return styles_; } | |
437 | |
438 const std::vector<internal::Line>& lines() const { return lines_; } | |
439 void set_lines(std::vector<internal::Line>* lines) { lines_.swap(*lines); } | |
440 | |
441 // Returns the baseline of the current text. The return value depends on | |
442 // the text and its layout while the return value of GetBaseline() doesn't. | |
443 // GetAlignmentOffset() takes into account the difference between them. | |
444 // | |
445 // We'd like a RenderText to show the text always on the same baseline | |
446 // regardless of the text, so the text does not jump up or down depending | |
447 // on the text. However, underlying layout engines return different baselines | |
448 // depending on the text. In general, layout engines determine the minimum | |
449 // bounding box for the text and return the baseline from the top of the | |
450 // bounding box. So the baseline changes depending on font metrics used to | |
451 // layout the text. | |
452 // | |
453 // For example, suppose there are FontA and FontB and the baseline of FontA | |
454 // is smaller than the one of FontB. If the text is laid out only with FontA, | |
455 // then the baseline of FontA may be returned. If the text includes some | |
456 // characters which are laid out with FontB, then the baseline of FontB may | |
457 // be returned. | |
458 // | |
459 // GetBaseline() returns the fixed baseline regardless of the text. | |
460 // GetLayoutTextBaseline() returns the baseline determined by the underlying | |
461 // layout engine, and it changes depending on the text. GetAlignmentOffset() | |
462 // returns the difference between them. | |
463 virtual int GetLayoutTextBaseline() = 0; | |
464 | |
465 void set_cached_bounds_and_offset_valid(bool valid) { | |
466 cached_bounds_and_offset_valid_ = valid; | |
467 } | |
468 | |
469 // Get the selection model that visually neighbors |position| by |break_type|. | |
470 // The returned value represents a cursor/caret position without a selection. | |
471 SelectionModel GetAdjacentSelectionModel(const SelectionModel& current, | |
472 BreakType break_type, | |
473 VisualCursorDirection direction); | |
474 | |
475 // Get the selection model visually left/right of |selection| by one grapheme. | |
476 // The returned value represents a cursor/caret position without a selection. | |
477 virtual SelectionModel AdjacentCharSelectionModel( | |
478 const SelectionModel& selection, | |
479 VisualCursorDirection direction) = 0; | |
480 | |
481 // Get the selection model visually left/right of |selection| by one word. | |
482 // The returned value represents a cursor/caret position without a selection. | |
483 virtual SelectionModel AdjacentWordSelectionModel( | |
484 const SelectionModel& selection, | |
485 VisualCursorDirection direction) = 0; | |
486 | |
487 // Get the SelectionModels corresponding to visual text ends. | |
488 // The returned value represents a cursor/caret position without a selection. | |
489 SelectionModel EdgeSelectionModel(VisualCursorDirection direction); | |
490 | |
491 // Sets the selection model, the argument is assumed to be valid. | |
492 virtual void SetSelectionModel(const SelectionModel& model); | |
493 | |
494 // Get the visual bounds containing the logical substring within the |range|. | |
495 // If |range| is empty, the result is empty. These bounds could be visually | |
496 // discontinuous if the substring is split by a LTR/RTL level change. | |
497 // These bounds are in local coordinates, but may be outside the visible | |
498 // region if the text is longer than the textfield. Subsequent text, cursor, | |
499 // or bounds changes may invalidate returned values. | |
500 virtual std::vector<Rect> GetSubstringBounds(const Range& range) = 0; | |
501 | |
502 // Convert between indices into |text_| and indices into |obscured_text_|, | |
503 // which differ when the text is obscured. Regardless of whether or not the | |
504 // text is obscured, the character (code point) offsets always match. | |
505 virtual size_t TextIndexToLayoutIndex(size_t index) const = 0; | |
506 virtual size_t LayoutIndexToTextIndex(size_t index) const = 0; | |
507 | |
508 // Reset the layout to be invalid. | |
509 virtual void ResetLayout() = 0; | |
510 | |
511 // Ensure the text is laid out, lines are computed, and |lines_| is valid. | |
512 virtual void EnsureLayout() = 0; | |
513 | |
514 // Draw the text. | |
515 virtual void DrawVisualText(Canvas* canvas) = 0; | |
516 | |
517 // Returns the text used for layout, which may be obscured or truncated. | |
518 const base::string16& GetLayoutText() const; | |
519 | |
520 // Returns layout text positions that are suitable for breaking lines. | |
521 const BreakList<size_t>& GetLineBreaks(); | |
522 | |
523 // Apply (and undo) temporary composition underlines and selection colors. | |
524 void ApplyCompositionAndSelectionStyles(); | |
525 void UndoCompositionAndSelectionStyles(); | |
526 | |
527 // Returns the line offset from the origin after applying the text alignment | |
528 // and the display offset. | |
529 Vector2d GetLineOffset(size_t line_number); | |
530 | |
531 // Convert points from the text space to the view space and back. Handles the | |
532 // display area, display offset, application LTR/RTL mode and multiline. | |
533 Point ToTextPoint(const Point& point); | |
534 Point ToViewPoint(const Point& point); | |
535 | |
536 // Convert a text space x-coordinate range to rects in view space. | |
537 std::vector<Rect> TextBoundsToViewBounds(const Range& x); | |
538 | |
539 // Get the alignment, resolving ALIGN_TO_HEAD with the current text direction. | |
540 HorizontalAlignment GetCurrentHorizontalAlignment(); | |
541 | |
542 // Returns the line offset from the origin, accounts for text alignment only. | |
543 Vector2d GetAlignmentOffset(size_t line_number); | |
544 | |
545 // Applies fade effects to |renderer|. | |
546 void ApplyFadeEffects(internal::SkiaTextRenderer* renderer); | |
547 | |
548 // Applies text shadows to |renderer|. | |
549 void ApplyTextShadows(internal::SkiaTextRenderer* renderer); | |
550 | |
551 // A convenience function to check whether the glyph attached to the caret | |
552 // is within the given range. | |
553 static bool RangeContainsCaret(const Range& range, | |
554 size_t caret_pos, | |
555 LogicalCursorDirection caret_affinity); | |
556 | |
557 private: | |
558 friend class RenderTextTest; | |
559 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, DefaultStyle); | |
560 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, SetColorAndStyle); | |
561 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, ApplyColorAndStyle); | |
562 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, ObscuredText); | |
563 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, RevealObscuredText); | |
564 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, ElidedText); | |
565 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, ElidedObscuredText); | |
566 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, TruncatedText); | |
567 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, TruncatedObscuredText); | |
568 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GraphemePositions); | |
569 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, EdgeSelectionModels); | |
570 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GetTextOffset); | |
571 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL); | |
572 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_MinWidth); | |
573 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_NormalWidth); | |
574 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_SufficientWidth); | |
575 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Multiline_Newline); | |
576 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, GlyphBounds); | |
577 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_GlyphBounds); | |
578 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, | |
579 MoveCursorLeftRight_MeiryoUILigatures); | |
580 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, Win_LogicalClusters); | |
581 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, SameFontForParentheses); | |
582 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, BreakRunsByUnicodeBlocks); | |
583 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, PangoAttributes); | |
584 FRIEND_TEST_ALL_PREFIXES(RenderTextTest, StringFitsOwnWidth); | |
585 | |
586 // Creates a platform-specific RenderText instance. | |
587 static RenderText* CreateNativeInstance(); | |
588 | |
589 // Set the cursor to |position|, with the caret trailing the previous | |
590 // grapheme, or if there is no previous grapheme, leading the cursor position. | |
591 // If |select| is false, the selection start is moved to the same position. | |
592 // If the |position| is not a cursorable position (not on grapheme boundary), | |
593 // it is a NO-OP. | |
594 void MoveCursorTo(size_t position, bool select); | |
595 | |
596 // Updates |layout_text_| if the text is obscured or truncated. | |
597 void UpdateLayoutText(); | |
598 | |
599 // Elides |text| as needed to fit in the |available_width| using |behavior|. | |
600 base::string16 Elide(const base::string16& text, | |
601 float available_width, | |
602 ElideBehavior behavior); | |
603 | |
604 // Elides |email| as needed to fit the |available_width|. | |
605 base::string16 ElideEmail(const base::string16& email, float available_width); | |
606 | |
607 // Update the cached bounds and display offset to ensure that the current | |
608 // cursor is within the visible display area. | |
609 void UpdateCachedBoundsAndOffset(); | |
610 | |
611 // Draw the selection. | |
612 void DrawSelection(Canvas* canvas); | |
613 | |
614 // Logical UTF-16 string data to be drawn. | |
615 base::string16 text_; | |
616 | |
617 // Horizontal alignment of the text with respect to |display_rect_|. The | |
618 // default is to align left if the application UI is LTR and right if RTL. | |
619 HorizontalAlignment horizontal_alignment_; | |
620 | |
621 // The text directionality mode, defaults to DIRECTIONALITY_FROM_TEXT. | |
622 DirectionalityMode directionality_mode_; | |
623 | |
624 // The cached text direction, potentially computed from the text or UI locale. | |
625 // Use GetTextDirection(), do not use this potentially invalid value directly! | |
626 base::i18n::TextDirection text_direction_; | |
627 | |
628 // A list of fonts used to render |text_|. | |
629 FontList font_list_; | |
630 | |
631 // Logical selection range and visual cursor position. | |
632 SelectionModel selection_model_; | |
633 | |
634 // The cached cursor bounds; get these bounds with GetUpdatedCursorBounds. | |
635 Rect cursor_bounds_; | |
636 | |
637 // Specifies whether the cursor is enabled. If disabled, no space is reserved | |
638 // for the cursor when positioning text. | |
639 bool cursor_enabled_; | |
640 | |
641 // The cursor visibility and insert mode. | |
642 bool cursor_visible_; | |
643 bool insert_mode_; | |
644 | |
645 // The color used for the cursor. | |
646 SkColor cursor_color_; | |
647 | |
648 // The color used for drawing selected text. | |
649 SkColor selection_color_; | |
650 | |
651 // The background color used for drawing the selection when focused. | |
652 SkColor selection_background_focused_color_; | |
653 | |
654 // The focus state of the text. | |
655 bool focused_; | |
656 | |
657 // Composition text range. | |
658 Range composition_range_; | |
659 | |
660 // Color and style breaks, used to color and stylize ranges of text. | |
661 // BreakList positions are stored with text indices, not layout indices. | |
662 // TODO(msw): Expand to support cursor, selection, background, etc. colors. | |
663 BreakList<SkColor> colors_; | |
664 std::vector<BreakList<bool> > styles_; | |
665 | |
666 // Breaks saved without temporary composition and selection styling. | |
667 BreakList<SkColor> saved_colors_; | |
668 BreakList<bool> saved_underlines_; | |
669 bool composition_and_selection_styles_applied_; | |
670 | |
671 // A flag to obscure actual text with asterisks for password fields. | |
672 bool obscured_; | |
673 // The index at which the char should be revealed in the obscured text. | |
674 int obscured_reveal_index_; | |
675 | |
676 // The maximum length of text to display, 0 forgoes a hard limit. | |
677 size_t truncate_length_; | |
678 | |
679 // The behavior for eliding, fading, or truncating. | |
680 ElideBehavior elide_behavior_; | |
681 | |
682 // The obscured and/or truncated text that will be displayed. | |
683 base::string16 layout_text_; | |
684 | |
685 // Whether newline characters should be replaced with newline symbols. | |
686 bool replace_newline_chars_with_symbols_; | |
687 | |
688 // Whether the text should be broken into multiple lines. Uses the width of | |
689 // |display_rect_| as the width cap. | |
690 bool multiline_; | |
691 | |
692 // Is the background transparent (either partially or fully)? | |
693 bool background_is_transparent_; | |
694 | |
695 // The local display area for rendering the text. | |
696 Rect display_rect_; | |
697 | |
698 // Flag to work around a Skia bug with the PDF path (http://crbug.com/133548) | |
699 // that results in incorrect clipping when drawing to the document margins. | |
700 // This field allows disabling clipping to work around the issue. | |
701 // TODO(asvitkine): Remove this when the underlying Skia bug is fixed. | |
702 bool clip_to_display_rect_; | |
703 | |
704 // The offset for the text to be drawn, relative to the display area. | |
705 // Get this point with GetUpdatedDisplayOffset (or risk using a stale value). | |
706 Vector2d display_offset_; | |
707 | |
708 // The baseline of the text. This is determined from the height of the | |
709 // display area and the cap height of the font list so the text is vertically | |
710 // centered. | |
711 int baseline_; | |
712 | |
713 // The cached bounds and offset are invalidated by changes to the cursor, | |
714 // selection, font, and other operations that adjust the visible text bounds. | |
715 bool cached_bounds_and_offset_valid_; | |
716 | |
717 // Text shadows to be drawn. | |
718 ShadowValues shadows_; | |
719 | |
720 // A list of valid layout text line break positions. | |
721 BreakList<size_t> line_breaks_; | |
722 | |
723 // Lines computed by EnsureLayout. These should be invalidated with | |
724 // ResetLayout and on |display_rect_| changes. | |
725 std::vector<internal::Line> lines_; | |
726 | |
727 DISALLOW_COPY_AND_ASSIGN(RenderText); | |
728 }; | |
729 | |
730 } // namespace gfx | |
731 | |
732 #endif // UI_GFX_RENDER_TEXT_H_ | |
OLD | NEW |