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 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <climits> | 10 #include <climits> |
11 | 11 |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/i18n/break_iterator.h" | 13 #include "base/i18n/break_iterator.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
18 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
20 #include "third_party/icu/source/common/unicode/rbbi.h" | 20 #include "third_party/icu/source/common/unicode/rbbi.h" |
21 #include "third_party/icu/source/common/unicode/utf16.h" | 21 #include "third_party/icu/source/common/unicode/utf16.h" |
22 #include "third_party/skia/include/core/SkDrawLooper.h" | 22 #include "third_party/skia/include/core/SkDrawLooper.h" |
| 23 #include "third_party/skia/include/core/SkFontStyle.h" |
23 #include "third_party/skia/include/core/SkTypeface.h" | 24 #include "third_party/skia/include/core/SkTypeface.h" |
24 #include "third_party/skia/include/effects/SkGradientShader.h" | 25 #include "third_party/skia/include/effects/SkGradientShader.h" |
25 #include "ui/gfx/canvas.h" | 26 #include "ui/gfx/canvas.h" |
26 #include "ui/gfx/geometry/insets.h" | 27 #include "ui/gfx/geometry/insets.h" |
27 #include "ui/gfx/geometry/safe_integer_conversions.h" | 28 #include "ui/gfx/geometry/safe_integer_conversions.h" |
28 #include "ui/gfx/platform_font.h" | 29 #include "ui/gfx/platform_font.h" |
29 #include "ui/gfx/render_text_harfbuzz.h" | 30 #include "ui/gfx/render_text_harfbuzz.h" |
30 #include "ui/gfx/scoped_canvas.h" | 31 #include "ui/gfx/scoped_canvas.h" |
31 #include "ui/gfx/skia_util.h" | 32 #include "ui/gfx/skia_util.h" |
32 #include "ui/gfx/switches.h" | 33 #include "ui/gfx/switches.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // Some platforms don't support getting the cap height, and simply return | 84 // Some platforms don't support getting the cap height, and simply return |
84 // the entire font ascent from GetCapHeight(). Centering the ascent makes | 85 // the entire font ascent from GetCapHeight(). Centering the ascent makes |
85 // the font look too low, so if GetCapHeight() returns the ascent, center | 86 // the font look too low, so if GetCapHeight() returns the ascent, center |
86 // the entire font height instead. | 87 // the entire font height instead. |
87 const int space = | 88 const int space = |
88 display_height - ((internal_leading != 0) ? cap_height : font_height); | 89 display_height - ((internal_leading != 0) ? cap_height : font_height); |
89 const int baseline_shift = space / 2 - internal_leading; | 90 const int baseline_shift = space / 2 - internal_leading; |
90 return baseline + std::max(min_shift, std::min(max_shift, baseline_shift)); | 91 return baseline + std::max(min_shift, std::min(max_shift, baseline_shift)); |
91 } | 92 } |
92 | 93 |
93 #if !defined(OS_MACOSX) | |
94 // Converts |Font::FontStyle| flags to |SkTypeface::Style| flags. | |
95 SkTypeface::Style ConvertFontStyleToSkiaTypefaceStyle(int font_style) { | |
96 int skia_style = SkTypeface::kNormal; | |
97 skia_style |= (font_style & Font::BOLD) ? SkTypeface::kBold : 0; | |
98 skia_style |= (font_style & Font::ITALIC) ? SkTypeface::kItalic : 0; | |
99 return static_cast<SkTypeface::Style>(skia_style); | |
100 } | |
101 #endif | |
102 | |
103 int round(float value) { | 94 int round(float value) { |
104 return static_cast<int>(floor(value + 0.5f)); | 95 return static_cast<int>(floor(value + 0.5f)); |
105 } | 96 } |
106 | 97 |
107 // Given |font| and |display_width|, returns the width of the fade gradient. | 98 // Given |font| and |display_width|, returns the width of the fade gradient. |
108 int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { | 99 int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { |
109 // Fade in/out about 3 characters of the beginning/end of the string. | 100 // Fade in/out about 3 characters of the beginning/end of the string. |
110 // Use a 1/3 of the display width if the display width is very short. | 101 // Use a 1/3 of the display width if the display width is very short. |
111 const int narrow_width = font_list.GetExpectedTextWidth(3); | 102 const int narrow_width = font_list.GetExpectedTextWidth(3); |
112 const int gradient_width = std::min(narrow_width, round(display_width / 3.f)); | 103 const int gradient_width = std::min(narrow_width, round(display_width / 3.f)); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 } | 237 } |
247 | 238 |
248 void SkiaTextRenderer::SetTypeface(SkTypeface* typeface) { | 239 void SkiaTextRenderer::SetTypeface(SkTypeface* typeface) { |
249 paint_.setTypeface(typeface); | 240 paint_.setTypeface(typeface); |
250 } | 241 } |
251 | 242 |
252 void SkiaTextRenderer::SetTextSize(SkScalar size) { | 243 void SkiaTextRenderer::SetTextSize(SkScalar size) { |
253 paint_.setTextSize(size); | 244 paint_.setTextSize(size); |
254 } | 245 } |
255 | 246 |
256 void SkiaTextRenderer::SetFontWithStyle(const Font& font, int style) { | 247 void SkiaTextRenderer::SetFont(const Font& font, |
257 skia::RefPtr<SkTypeface> typeface = CreateSkiaTypeface(font, style); | 248 bool italic, |
| 249 gfx::Font::Weight weight) { |
| 250 skia::RefPtr<SkTypeface> typeface = CreateSkiaTypeface(font, italic, weight); |
258 if (typeface) { | 251 if (typeface) { |
259 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. | 252 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. |
260 SetTypeface(typeface.get()); | 253 SetTypeface(typeface.get()); |
261 | 254 |
262 // Enable fake bold text if bold style is needed but new typeface does not | 255 // Enable fake bold text if bold style is needed but new typeface does not |
263 // have it. | 256 // have it. |
264 paint_.setFakeBoldText((style & Font::BOLD) && !typeface->isBold()); | 257 paint_.setFakeBoldText(weight >= gfx::Font::Weight::SEMIBOLD && |
| 258 !typeface->isBold()); |
265 } | 259 } |
266 } | 260 } |
267 | 261 |
268 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { | 262 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { |
269 paint_.setColor(foreground); | 263 paint_.setColor(foreground); |
270 } | 264 } |
271 | 265 |
272 void SkiaTextRenderer::SetShader(SkShader* shader) { | 266 void SkiaTextRenderer::SetShader(SkShader* shader) { |
273 paint_.setShader(shader); | 267 paint_.setShader(shader); |
274 } | 268 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 | 371 |
378 if (clipped) | 372 if (clipped) |
379 canvas_->Restore(); | 373 canvas_->Restore(); |
380 | 374 |
381 x += pieces_[i].first; | 375 x += pieces_[i].first; |
382 } | 376 } |
383 } | 377 } |
384 | 378 |
385 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, | 379 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, |
386 const BreakList<BaselineStyle>& baselines, | 380 const BreakList<BaselineStyle>& baselines, |
| 381 const BreakList<gfx::Font::Weight>& weights, |
387 const std::vector<BreakList<bool>>& styles) | 382 const std::vector<BreakList<bool>>& styles) |
388 : colors_(colors), baselines_(baselines), styles_(styles) { | 383 : colors_(colors), |
| 384 baselines_(baselines), |
| 385 weights_(weights), |
| 386 styles_(styles) { |
389 color_ = colors_.breaks().begin(); | 387 color_ = colors_.breaks().begin(); |
390 baseline_ = baselines_.breaks().begin(); | 388 baseline_ = baselines_.breaks().begin(); |
| 389 weight_ = weights_.breaks().begin(); |
391 for (size_t i = 0; i < styles_.size(); ++i) | 390 for (size_t i = 0; i < styles_.size(); ++i) |
392 style_.push_back(styles_[i].breaks().begin()); | 391 style_.push_back(styles_[i].breaks().begin()); |
393 } | 392 } |
394 | 393 |
395 StyleIterator::~StyleIterator() {} | 394 StyleIterator::~StyleIterator() {} |
396 | 395 |
397 Range StyleIterator::GetRange() const { | 396 Range StyleIterator::GetRange() const { |
398 Range range(colors_.GetRange(color_)); | 397 Range range(colors_.GetRange(color_)); |
399 range = range.Intersect(baselines_.GetRange(baseline_)); | 398 range = range.Intersect(baselines_.GetRange(baseline_)); |
| 399 range = range.Intersect(weights_.GetRange(weight_)); |
400 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 400 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
401 range = range.Intersect(styles_[i].GetRange(style_[i])); | 401 range = range.Intersect(styles_[i].GetRange(style_[i])); |
402 return range; | 402 return range; |
403 } | 403 } |
404 | 404 |
405 void StyleIterator::UpdatePosition(size_t position) { | 405 void StyleIterator::UpdatePosition(size_t position) { |
406 color_ = colors_.GetBreak(position); | 406 color_ = colors_.GetBreak(position); |
407 baseline_ = baselines_.GetBreak(position); | 407 baseline_ = baselines_.GetBreak(position); |
| 408 weight_ = weights_.GetBreak(position); |
408 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 409 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
409 style_[i] = styles_[i].GetBreak(position); | 410 style_[i] = styles_[i].GetBreak(position); |
410 } | 411 } |
411 | 412 |
412 LineSegment::LineSegment() : run(0) {} | 413 LineSegment::LineSegment() : run(0) {} |
413 | 414 |
414 LineSegment::~LineSegment() {} | 415 LineSegment::~LineSegment() {} |
415 | 416 |
416 Line::Line() : preceding_heights(0), baseline(0) {} | 417 Line::Line() : preceding_heights(0), baseline(0) {} |
417 | 418 |
418 Line::Line(const Line& other) = default; | 419 Line::Line(const Line& other) = default; |
419 | 420 |
420 Line::~Line() {} | 421 Line::~Line() {} |
421 | 422 |
422 #if !defined(OS_MACOSX) | 423 #if !defined(OS_MACOSX) |
423 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const gfx::Font& font, int style) { | 424 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const gfx::Font& font, |
424 SkTypeface::Style skia_style = ConvertFontStyleToSkiaTypefaceStyle(style); | 425 bool italic, |
| 426 gfx::Font::Weight weight) { |
| 427 SkFontStyle skia_style( |
| 428 static_cast<int>(weight), SkFontStyle::kNormal_Width, |
| 429 italic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant); |
425 return skia::AdoptRef( | 430 return skia::AdoptRef( |
426 SkTypeface::CreateFromName(font.GetFontName().c_str(), skia_style)); | 431 SkTypeface::CreateFromName(font.GetFontName().c_str(), skia_style)); |
427 } | 432 } |
428 #endif | 433 #endif |
429 | 434 |
430 void ApplyRenderParams(const FontRenderParams& params, | 435 void ApplyRenderParams(const FontRenderParams& params, |
431 bool subpixel_rendering_suppressed, | 436 bool subpixel_rendering_suppressed, |
432 SkPaint* paint) { | 437 SkPaint* paint) { |
433 paint->setAntiAlias(params.antialiasing); | 438 paint->setAntiAlias(params.antialiasing); |
434 paint->setLCDRenderText(!subpixel_rendering_suppressed && | 439 paint->setLCDRenderText(!subpixel_rendering_suppressed && |
(...skipping 29 matching lines...) Expand all Loading... |
464 DCHECK(!composition_range_.IsValid()); | 469 DCHECK(!composition_range_.IsValid()); |
465 if (text_ == text) | 470 if (text_ == text) |
466 return; | 471 return; |
467 text_ = text; | 472 text_ = text; |
468 UpdateStyleLengths(); | 473 UpdateStyleLengths(); |
469 | 474 |
470 // Clear style ranges as they might break new text graphemes and apply | 475 // Clear style ranges as they might break new text graphemes and apply |
471 // the first style to the whole text instead. | 476 // the first style to the whole text instead. |
472 colors_.SetValue(colors_.breaks().begin()->second); | 477 colors_.SetValue(colors_.breaks().begin()->second); |
473 baselines_.SetValue(baselines_.breaks().begin()->second); | 478 baselines_.SetValue(baselines_.breaks().begin()->second); |
| 479 weights_.SetValue(weights_.breaks().begin()->second); |
474 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 480 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
475 styles_[style].SetValue(styles_[style].breaks().begin()->second); | 481 styles_[style].SetValue(styles_[style].breaks().begin()->second); |
476 cached_bounds_and_offset_valid_ = false; | 482 cached_bounds_and_offset_valid_ = false; |
477 | 483 |
478 // Reset selection model. SetText should always followed by SetSelectionModel | 484 // Reset selection model. SetText should always followed by SetSelectionModel |
479 // or SetCursorPosition in upper layer. | 485 // or SetCursorPosition in upper layer. |
480 SetSelectionModel(SelectionModel()); | 486 SetSelectionModel(SelectionModel()); |
481 | 487 |
482 // Invalidate the cached text direction if it depends on the text contents. | 488 // Invalidate the cached text direction if it depends on the text contents. |
483 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) | 489 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) |
(...skipping 15 matching lines...) Expand all Loading... |
499 if (horizontal_alignment_ != alignment) { | 505 if (horizontal_alignment_ != alignment) { |
500 horizontal_alignment_ = alignment; | 506 horizontal_alignment_ = alignment; |
501 display_offset_ = Vector2d(); | 507 display_offset_ = Vector2d(); |
502 cached_bounds_and_offset_valid_ = false; | 508 cached_bounds_and_offset_valid_ = false; |
503 } | 509 } |
504 } | 510 } |
505 | 511 |
506 void RenderText::SetFontList(const FontList& font_list) { | 512 void RenderText::SetFontList(const FontList& font_list) { |
507 font_list_ = font_list; | 513 font_list_ = font_list; |
508 const int font_style = font_list.GetFontStyle(); | 514 const int font_style = font_list.GetFontStyle(); |
509 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); | 515 weights_.SetValue(font_list.GetFontWeight()); |
510 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); | 516 styles_[ITALIC].SetValue((font_style & gfx::Font::ITALIC) != 0); |
511 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); | 517 styles_[UNDERLINE].SetValue((font_style & gfx::Font::UNDERLINE) != 0); |
512 baseline_ = kInvalidBaseline; | 518 baseline_ = kInvalidBaseline; |
513 cached_bounds_and_offset_valid_ = false; | 519 cached_bounds_and_offset_valid_ = false; |
514 OnLayoutTextAttributeChanged(false); | 520 OnLayoutTextAttributeChanged(false); |
515 } | 521 } |
516 | 522 |
517 void RenderText::SetCursorEnabled(bool cursor_enabled) { | 523 void RenderText::SetCursorEnabled(bool cursor_enabled) { |
518 cursor_enabled_ = cursor_enabled; | 524 cursor_enabled_ = cursor_enabled; |
519 cached_bounds_and_offset_valid_ = false; | 525 cached_bounds_and_offset_valid_ = false; |
520 } | 526 } |
521 | 527 |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : | 767 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : |
762 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); | 768 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); |
763 styles_[style].ApplyValue(value, Range(start, end)); | 769 styles_[style].ApplyValue(value, Range(start, end)); |
764 | 770 |
765 cached_bounds_and_offset_valid_ = false; | 771 cached_bounds_and_offset_valid_ = false; |
766 // TODO(oshima|msw): Not all style change requires layout changes. | 772 // TODO(oshima|msw): Not all style change requires layout changes. |
767 // Consider optimizing based on the type of change. | 773 // Consider optimizing based on the type of change. |
768 OnLayoutTextAttributeChanged(false); | 774 OnLayoutTextAttributeChanged(false); |
769 } | 775 } |
770 | 776 |
| 777 void RenderText::SetWeight(gfx::Font::Weight weight) { |
| 778 weights_.SetValue(weight); |
| 779 |
| 780 cached_bounds_and_offset_valid_ = false; |
| 781 OnLayoutTextAttributeChanged(false); |
| 782 } |
| 783 |
| 784 void RenderText::ApplyWeight(gfx::Font::Weight weight, const Range& range) { |
| 785 weights_.ApplyValue(weight, range); |
| 786 |
| 787 cached_bounds_and_offset_valid_ = false; |
| 788 OnLayoutTextAttributeChanged(false); |
| 789 } |
| 790 |
771 bool RenderText::GetStyle(TextStyle style) const { | 791 bool RenderText::GetStyle(TextStyle style) const { |
772 return (styles_[style].breaks().size() == 1) && | 792 return (styles_[style].breaks().size() == 1) && |
773 styles_[style].breaks().front().second; | 793 styles_[style].breaks().front().second; |
774 } | 794 } |
775 | 795 |
776 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { | 796 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { |
777 if (mode == directionality_mode_) | 797 if (mode == directionality_mode_) |
778 return; | 798 return; |
779 | 799 |
780 directionality_mode_ = mode; | 800 directionality_mode_ = mode; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 cursor_enabled_(true), | 1012 cursor_enabled_(true), |
993 cursor_visible_(false), | 1013 cursor_visible_(false), |
994 insert_mode_(true), | 1014 insert_mode_(true), |
995 cursor_color_(kDefaultColor), | 1015 cursor_color_(kDefaultColor), |
996 selection_color_(kDefaultColor), | 1016 selection_color_(kDefaultColor), |
997 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 1017 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
998 focused_(false), | 1018 focused_(false), |
999 composition_range_(Range::InvalidRange()), | 1019 composition_range_(Range::InvalidRange()), |
1000 colors_(kDefaultColor), | 1020 colors_(kDefaultColor), |
1001 baselines_(NORMAL_BASELINE), | 1021 baselines_(NORMAL_BASELINE), |
| 1022 weights_(gfx::Font::Weight::NORMAL), |
1002 styles_(NUM_TEXT_STYLES), | 1023 styles_(NUM_TEXT_STYLES), |
1003 composition_and_selection_styles_applied_(false), | 1024 composition_and_selection_styles_applied_(false), |
1004 obscured_(false), | 1025 obscured_(false), |
1005 obscured_reveal_index_(-1), | 1026 obscured_reveal_index_(-1), |
1006 truncate_length_(0), | 1027 truncate_length_(0), |
1007 elide_behavior_(NO_ELIDE), | 1028 elide_behavior_(NO_ELIDE), |
1008 text_elided_(false), | 1029 text_elided_(false), |
1009 min_line_height_(0), | 1030 min_line_height_(0), |
1010 multiline_(false), | 1031 multiline_(false), |
1011 word_wrap_behavior_(IGNORE_LONG_WORDS), | 1032 word_wrap_behavior_(IGNORE_LONG_WORDS), |
1012 replace_newline_chars_with_symbols_(true), | 1033 replace_newline_chars_with_symbols_(true), |
1013 subpixel_rendering_suppressed_(false), | 1034 subpixel_rendering_suppressed_(false), |
1014 clip_to_display_rect_(true), | 1035 clip_to_display_rect_(true), |
1015 baseline_(kInvalidBaseline), | 1036 baseline_(kInvalidBaseline), |
1016 cached_bounds_and_offset_valid_(false) { | 1037 cached_bounds_and_offset_valid_(false) {} |
1017 } | |
1018 | 1038 |
1019 SelectionModel RenderText::GetAdjacentSelectionModel( | 1039 SelectionModel RenderText::GetAdjacentSelectionModel( |
1020 const SelectionModel& current, | 1040 const SelectionModel& current, |
1021 BreakType break_type, | 1041 BreakType break_type, |
1022 VisualCursorDirection direction) { | 1042 VisualCursorDirection direction) { |
1023 EnsureLayout(); | 1043 EnsureLayout(); |
1024 | 1044 |
1025 if (break_type == LINE_BREAK || text().empty()) | 1045 if (break_type == LINE_BREAK || text().empty()) |
1026 return EdgeSelectionModel(direction); | 1046 return EdgeSelectionModel(direction); |
1027 if (break_type == CHARACTER_BREAK) | 1047 if (break_type == CHARACTER_BREAK) |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; | 1298 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; |
1279 CHECK_GE(i, 0); | 1299 CHECK_GE(i, 0); |
1280 // Clamp indices to the length of the given layout or display text. | 1300 // Clamp indices to the length of the given layout or display text. |
1281 return std::min<size_t>(given_text.length(), i); | 1301 return std::min<size_t>(given_text.length(), i); |
1282 } | 1302 } |
1283 | 1303 |
1284 void RenderText::UpdateStyleLengths() { | 1304 void RenderText::UpdateStyleLengths() { |
1285 const size_t text_length = text_.length(); | 1305 const size_t text_length = text_.length(); |
1286 colors_.SetMax(text_length); | 1306 colors_.SetMax(text_length); |
1287 baselines_.SetMax(text_length); | 1307 baselines_.SetMax(text_length); |
| 1308 weights_.SetMax(text_length); |
1288 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1309 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
1289 styles_[style].SetMax(text_length); | 1310 styles_[style].SetMax(text_length); |
1290 } | 1311 } |
1291 | 1312 |
1292 // static | 1313 // static |
1293 bool RenderText::RangeContainsCaret(const Range& range, | 1314 bool RenderText::RangeContainsCaret(const Range& range, |
1294 size_t caret_pos, | 1315 size_t caret_pos, |
1295 LogicalCursorDirection caret_affinity) { | 1316 LogicalCursorDirection caret_affinity) { |
1296 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). | 1317 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). |
1297 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? | 1318 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 | 1402 |
1382 // Create a RenderText copy with attributes that affect the rendering width. | 1403 // Create a RenderText copy with attributes that affect the rendering width. |
1383 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); | 1404 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); |
1384 render_text->SetFontList(font_list_); | 1405 render_text->SetFontList(font_list_); |
1385 render_text->SetDirectionalityMode(directionality_mode_); | 1406 render_text->SetDirectionalityMode(directionality_mode_); |
1386 render_text->SetCursorEnabled(cursor_enabled_); | 1407 render_text->SetCursorEnabled(cursor_enabled_); |
1387 render_text->set_truncate_length(truncate_length_); | 1408 render_text->set_truncate_length(truncate_length_); |
1388 render_text->styles_ = styles_; | 1409 render_text->styles_ = styles_; |
1389 render_text->baselines_ = baselines_; | 1410 render_text->baselines_ = baselines_; |
1390 render_text->colors_ = colors_; | 1411 render_text->colors_ = colors_; |
| 1412 render_text->weights_ = weights_; |
1391 if (text_width == 0) { | 1413 if (text_width == 0) { |
1392 render_text->SetText(text); | 1414 render_text->SetText(text); |
1393 text_width = render_text->GetContentWidthF(); | 1415 text_width = render_text->GetContentWidthF(); |
1394 } | 1416 } |
1395 if (text_width <= available_width) | 1417 if (text_width <= available_width) |
1396 return text; | 1418 return text; |
1397 | 1419 |
1398 const base::string16 ellipsis = base::string16(kEllipsisUTF16); | 1420 const base::string16 ellipsis = base::string16(kEllipsisUTF16); |
1399 const bool insert_ellipsis = (behavior != TRUNCATE); | 1421 const bool insert_ellipsis = (behavior != TRUNCATE); |
1400 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); | 1422 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 new_text += base::i18n::kRightToLeftMark; | 1460 new_text += base::i18n::kRightToLeftMark; |
1439 } | 1461 } |
1440 render_text->SetText(new_text); | 1462 render_text->SetText(new_text); |
1441 } | 1463 } |
1442 | 1464 |
1443 // Restore styles and baselines without breaking multi-character graphemes. | 1465 // Restore styles and baselines without breaking multi-character graphemes. |
1444 render_text->styles_ = styles_; | 1466 render_text->styles_ = styles_; |
1445 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1467 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
1446 RestoreBreakList(render_text.get(), &render_text->styles_[style]); | 1468 RestoreBreakList(render_text.get(), &render_text->styles_[style]); |
1447 RestoreBreakList(render_text.get(), &render_text->baselines_); | 1469 RestoreBreakList(render_text.get(), &render_text->baselines_); |
| 1470 RestoreBreakList(render_text.get(), &render_text->weights_); |
1448 | 1471 |
1449 // We check the width of the whole desired string at once to ensure we | 1472 // We check the width of the whole desired string at once to ensure we |
1450 // handle kerning/ligatures/etc. correctly. | 1473 // handle kerning/ligatures/etc. correctly. |
1451 const float guess_width = render_text->GetContentWidthF(); | 1474 const float guess_width = render_text->GetContentWidthF(); |
1452 if (guess_width == available_width) | 1475 if (guess_width == available_width) |
1453 break; | 1476 break; |
1454 if (guess_width > available_width) { | 1477 if (guess_width > available_width) { |
1455 hi = guess - 1; | 1478 hi = guess - 1; |
1456 // Move back on the loop terminating condition when the guess is too wide. | 1479 // Move back on the loop terminating condition when the guess is too wide. |
1457 if (hi < lo) | 1480 if (hi < lo) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1544 | 1567 |
1545 SetDisplayOffset(display_offset_.x() + delta_x); | 1568 SetDisplayOffset(display_offset_.x() + delta_x); |
1546 } | 1569 } |
1547 | 1570 |
1548 void RenderText::DrawSelection(Canvas* canvas) { | 1571 void RenderText::DrawSelection(Canvas* canvas) { |
1549 for (const Rect& s : GetSubstringBounds(selection())) | 1572 for (const Rect& s : GetSubstringBounds(selection())) |
1550 canvas->FillRect(s, selection_background_focused_color_); | 1573 canvas->FillRect(s, selection_background_focused_color_); |
1551 } | 1574 } |
1552 | 1575 |
1553 } // namespace gfx | 1576 } // namespace gfx |
OLD | NEW |