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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 #if !defined(OS_MACOSX) |
94 // Converts |Font::FontStyle| flags to |SkTypeface::Style| flags. | 95 // Converts |Font::FontStyle| flags to |SkTypeface::Style| flags. |
95 SkTypeface::Style ConvertFontStyleToSkiaTypefaceStyle(int font_style) { | 96 SkTypeface::Style ConvertFontStyleToSkiaTypefaceStyle(int font_style) { |
msw
2016/03/22 01:53:44
Remove this function if it's no longer used.
Mikus
2016/03/22 14:19:51
Done.
| |
96 int skia_style = SkTypeface::kNormal; | 97 int skia_style = SkTypeface::kNormal; |
97 skia_style |= (font_style & Font::BOLD) ? SkTypeface::kBold : 0; | 98 // skia_style |= (font_style & Font::BOLD) ? SkTypeface::kBold : 0; |
msw
2016/03/22 01:53:44
Remove this
Mikus
2016/03/22 14:19:51
Done.
| |
98 skia_style |= (font_style & Font::ITALIC) ? SkTypeface::kItalic : 0; | 99 skia_style |= (font_style & Font::ITALIC) ? SkTypeface::kItalic : 0; |
99 return static_cast<SkTypeface::Style>(skia_style); | 100 return static_cast<SkTypeface::Style>(skia_style); |
100 } | 101 } |
101 #endif | 102 #endif |
102 | 103 |
103 int round(float value) { | 104 int round(float value) { |
104 return static_cast<int>(floor(value + 0.5f)); | 105 return static_cast<int>(floor(value + 0.5f)); |
105 } | 106 } |
106 | 107 |
107 // Given |font| and |display_width|, returns the width of the fade gradient. | 108 // Given |font| and |display_width|, returns the width of the fade gradient. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 } | 247 } |
247 | 248 |
248 void SkiaTextRenderer::SetTypeface(SkTypeface* typeface) { | 249 void SkiaTextRenderer::SetTypeface(SkTypeface* typeface) { |
249 paint_.setTypeface(typeface); | 250 paint_.setTypeface(typeface); |
250 } | 251 } |
251 | 252 |
252 void SkiaTextRenderer::SetTextSize(SkScalar size) { | 253 void SkiaTextRenderer::SetTextSize(SkScalar size) { |
253 paint_.setTextSize(size); | 254 paint_.setTextSize(size); |
254 } | 255 } |
255 | 256 |
256 void SkiaTextRenderer::SetFontWithStyle(const Font& font, int style) { | 257 void SkiaTextRenderer::SetFontWithStyle(const Font& font, |
257 skia::RefPtr<SkTypeface> typeface = CreateSkiaTypeface(font, style); | 258 int style, |
259 gfx::Font::FontWeight weight) { | |
260 skia::RefPtr<SkTypeface> typeface = CreateSkiaTypeface(font, style, weight); | |
258 if (typeface) { | 261 if (typeface) { |
259 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. | 262 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. |
260 SetTypeface(typeface.get()); | 263 SetTypeface(typeface.get()); |
261 | 264 |
262 // Enable fake bold text if bold style is needed but new typeface does not | 265 // Enable fake bold text if bold style is needed but new typeface does not |
263 // have it. | 266 // have it. |
264 paint_.setFakeBoldText((style & Font::BOLD) && !typeface->isBold()); | 267 paint_.setFakeBoldText(weight >= gfx::Font::WEIGHT_SEMIBOLD && |
268 !typeface->isBold()); | |
265 } | 269 } |
266 } | 270 } |
267 | 271 |
268 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { | 272 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { |
269 paint_.setColor(foreground); | 273 paint_.setColor(foreground); |
270 } | 274 } |
271 | 275 |
272 void SkiaTextRenderer::SetShader(SkShader* shader) { | 276 void SkiaTextRenderer::SetShader(SkShader* shader) { |
273 paint_.setShader(shader); | 277 paint_.setShader(shader); |
274 } | 278 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 | 381 |
378 if (clipped) | 382 if (clipped) |
379 canvas_->Restore(); | 383 canvas_->Restore(); |
380 | 384 |
381 x += pieces_[i].first; | 385 x += pieces_[i].first; |
382 } | 386 } |
383 } | 387 } |
384 | 388 |
385 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, | 389 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, |
386 const BreakList<BaselineStyle>& baselines, | 390 const BreakList<BaselineStyle>& baselines, |
391 const BreakList<gfx::Font::FontWeight>& weights, | |
387 const std::vector<BreakList<bool>>& styles) | 392 const std::vector<BreakList<bool>>& styles) |
388 : colors_(colors), baselines_(baselines), styles_(styles) { | 393 : colors_(colors), |
394 baselines_(baselines), | |
395 weights_(weights), | |
396 styles_(styles) { | |
389 color_ = colors_.breaks().begin(); | 397 color_ = colors_.breaks().begin(); |
390 baseline_ = baselines_.breaks().begin(); | 398 baseline_ = baselines_.breaks().begin(); |
399 weight_ = weights_.breaks().begin(); | |
391 for (size_t i = 0; i < styles_.size(); ++i) | 400 for (size_t i = 0; i < styles_.size(); ++i) |
392 style_.push_back(styles_[i].breaks().begin()); | 401 style_.push_back(styles_[i].breaks().begin()); |
393 } | 402 } |
394 | 403 |
395 StyleIterator::~StyleIterator() {} | 404 StyleIterator::~StyleIterator() {} |
396 | 405 |
397 Range StyleIterator::GetRange() const { | 406 Range StyleIterator::GetRange() const { |
398 Range range(colors_.GetRange(color_)); | 407 Range range(colors_.GetRange(color_)); |
399 range = range.Intersect(baselines_.GetRange(baseline_)); | 408 range = range.Intersect(baselines_.GetRange(baseline_)); |
409 range = range.Intersect(weights_.GetRange(weight_)); | |
400 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 410 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
401 range = range.Intersect(styles_[i].GetRange(style_[i])); | 411 range = range.Intersect(styles_[i].GetRange(style_[i])); |
402 return range; | 412 return range; |
403 } | 413 } |
404 | 414 |
405 void StyleIterator::UpdatePosition(size_t position) { | 415 void StyleIterator::UpdatePosition(size_t position) { |
406 color_ = colors_.GetBreak(position); | 416 color_ = colors_.GetBreak(position); |
407 baseline_ = baselines_.GetBreak(position); | 417 baseline_ = baselines_.GetBreak(position); |
418 weight_ = weights_.GetBreak(position); | |
408 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 419 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
409 style_[i] = styles_[i].GetBreak(position); | 420 style_[i] = styles_[i].GetBreak(position); |
410 } | 421 } |
411 | 422 |
412 LineSegment::LineSegment() : run(0) {} | 423 LineSegment::LineSegment() : run(0) {} |
413 | 424 |
414 LineSegment::~LineSegment() {} | 425 LineSegment::~LineSegment() {} |
415 | 426 |
416 Line::Line() : preceding_heights(0), baseline(0) {} | 427 Line::Line() : preceding_heights(0), baseline(0) {} |
417 | 428 |
418 Line::Line(const Line& other) = default; | 429 Line::Line(const Line& other) = default; |
419 | 430 |
420 Line::~Line() {} | 431 Line::~Line() {} |
421 | 432 |
422 #if !defined(OS_MACOSX) | 433 #if !defined(OS_MACOSX) |
423 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const gfx::Font& font, int style) { | 434 skia::RefPtr<SkTypeface> CreateSkiaTypeface(const gfx::Font& font, |
424 SkTypeface::Style skia_style = ConvertFontStyleToSkiaTypefaceStyle(style); | 435 int style, |
425 return skia::AdoptRef( | 436 gfx::Font::FontWeight weight) { |
426 SkTypeface::CreateFromName(font.GetFontName().c_str(), skia_style)); | 437 SkFontStyle skia_style(weight, SkFontStyle::kNormal_Width, |
438 style & gfx::Font::ITALIC | |
msw
2016/03/22 01:53:44
nit: if |style| only handles italic, make it a boo
Mikus
2016/03/22 14:19:51
Done.
| |
439 ? SkFontStyle::kItalic_Slant | |
440 : SkFontStyle::kUpright_Slant); | |
441 return skia::AdoptRef(SkTypeface::CreateFromNameAndStyle( | |
442 font.GetFontName().c_str(), skia_style)); | |
427 } | 443 } |
444 | |
428 #endif | 445 #endif |
429 | 446 |
430 void ApplyRenderParams(const FontRenderParams& params, | 447 void ApplyRenderParams(const FontRenderParams& params, |
431 bool subpixel_rendering_suppressed, | 448 bool subpixel_rendering_suppressed, |
432 SkPaint* paint) { | 449 SkPaint* paint) { |
433 paint->setAntiAlias(params.antialiasing); | 450 paint->setAntiAlias(params.antialiasing); |
434 paint->setLCDRenderText(!subpixel_rendering_suppressed && | 451 paint->setLCDRenderText(!subpixel_rendering_suppressed && |
435 params.subpixel_rendering != FontRenderParams::SUBPIXEL_RENDERING_NONE); | 452 params.subpixel_rendering != FontRenderParams::SUBPIXEL_RENDERING_NONE); |
436 paint->setSubpixelText(params.subpixel_positioning); | 453 paint->setSubpixelText(params.subpixel_positioning); |
437 paint->setAutohinted(params.autohinter); | 454 paint->setAutohinted(params.autohinter); |
(...skipping 26 matching lines...) Expand all Loading... | |
464 DCHECK(!composition_range_.IsValid()); | 481 DCHECK(!composition_range_.IsValid()); |
465 if (text_ == text) | 482 if (text_ == text) |
466 return; | 483 return; |
467 text_ = text; | 484 text_ = text; |
468 UpdateStyleLengths(); | 485 UpdateStyleLengths(); |
469 | 486 |
470 // Clear style ranges as they might break new text graphemes and apply | 487 // Clear style ranges as they might break new text graphemes and apply |
471 // the first style to the whole text instead. | 488 // the first style to the whole text instead. |
472 colors_.SetValue(colors_.breaks().begin()->second); | 489 colors_.SetValue(colors_.breaks().begin()->second); |
473 baselines_.SetValue(baselines_.breaks().begin()->second); | 490 baselines_.SetValue(baselines_.breaks().begin()->second); |
491 weights_.SetValue(weights_.breaks().begin()->second); | |
474 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 492 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
475 styles_[style].SetValue(styles_[style].breaks().begin()->second); | 493 styles_[style].SetValue(styles_[style].breaks().begin()->second); |
476 cached_bounds_and_offset_valid_ = false; | 494 cached_bounds_and_offset_valid_ = false; |
477 | 495 |
478 // Reset selection model. SetText should always followed by SetSelectionModel | 496 // Reset selection model. SetText should always followed by SetSelectionModel |
479 // or SetCursorPosition in upper layer. | 497 // or SetCursorPosition in upper layer. |
480 SetSelectionModel(SelectionModel()); | 498 SetSelectionModel(SelectionModel()); |
481 | 499 |
482 // Invalidate the cached text direction if it depends on the text contents. | 500 // Invalidate the cached text direction if it depends on the text contents. |
483 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) | 501 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) |
(...skipping 15 matching lines...) Expand all Loading... | |
499 if (horizontal_alignment_ != alignment) { | 517 if (horizontal_alignment_ != alignment) { |
500 horizontal_alignment_ = alignment; | 518 horizontal_alignment_ = alignment; |
501 display_offset_ = Vector2d(); | 519 display_offset_ = Vector2d(); |
502 cached_bounds_and_offset_valid_ = false; | 520 cached_bounds_and_offset_valid_ = false; |
503 } | 521 } |
504 } | 522 } |
505 | 523 |
506 void RenderText::SetFontList(const FontList& font_list) { | 524 void RenderText::SetFontList(const FontList& font_list) { |
507 font_list_ = font_list; | 525 font_list_ = font_list; |
508 const int font_style = font_list.GetFontStyle(); | 526 const int font_style = font_list.GetFontStyle(); |
509 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); | 527 weights_.SetValue(font_list.GetFontWeight()); |
510 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); | 528 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); |
511 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); | 529 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); |
512 baseline_ = kInvalidBaseline; | 530 baseline_ = kInvalidBaseline; |
513 cached_bounds_and_offset_valid_ = false; | 531 cached_bounds_and_offset_valid_ = false; |
514 OnLayoutTextAttributeChanged(false); | 532 OnLayoutTextAttributeChanged(false); |
515 } | 533 } |
516 | 534 |
517 void RenderText::SetCursorEnabled(bool cursor_enabled) { | 535 void RenderText::SetCursorEnabled(bool cursor_enabled) { |
518 cursor_enabled_ = cursor_enabled; | 536 cursor_enabled_ = cursor_enabled; |
519 cached_bounds_and_offset_valid_ = false; | 537 cached_bounds_and_offset_valid_ = false; |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
761 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : | 779 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : |
762 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); | 780 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); |
763 styles_[style].ApplyValue(value, Range(start, end)); | 781 styles_[style].ApplyValue(value, Range(start, end)); |
764 | 782 |
765 cached_bounds_and_offset_valid_ = false; | 783 cached_bounds_and_offset_valid_ = false; |
766 // TODO(oshima|msw): Not all style change requires layout changes. | 784 // TODO(oshima|msw): Not all style change requires layout changes. |
767 // Consider optimizing based on the type of change. | 785 // Consider optimizing based on the type of change. |
768 OnLayoutTextAttributeChanged(false); | 786 OnLayoutTextAttributeChanged(false); |
769 } | 787 } |
770 | 788 |
789 void RenderText::SetWeight(gfx::Font::FontWeight weight) { | |
790 weights_.SetValue(weight); | |
791 | |
792 cached_bounds_and_offset_valid_ = false; | |
793 OnLayoutTextAttributeChanged(false); | |
794 } | |
795 | |
796 void RenderText::ApplyWeight(gfx::Font::FontWeight weight, const Range& range) { | |
797 weights_.ApplyValue(weight, range); | |
798 | |
799 cached_bounds_and_offset_valid_ = false; | |
800 OnLayoutTextAttributeChanged(false); | |
801 } | |
802 | |
771 bool RenderText::GetStyle(TextStyle style) const { | 803 bool RenderText::GetStyle(TextStyle style) const { |
772 return (styles_[style].breaks().size() == 1) && | 804 return (styles_[style].breaks().size() == 1) && |
773 styles_[style].breaks().front().second; | 805 styles_[style].breaks().front().second; |
774 } | 806 } |
775 | 807 |
776 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { | 808 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { |
777 if (mode == directionality_mode_) | 809 if (mode == directionality_mode_) |
778 return; | 810 return; |
779 | 811 |
780 directionality_mode_ = mode; | 812 directionality_mode_ = mode; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
992 cursor_enabled_(true), | 1024 cursor_enabled_(true), |
993 cursor_visible_(false), | 1025 cursor_visible_(false), |
994 insert_mode_(true), | 1026 insert_mode_(true), |
995 cursor_color_(kDefaultColor), | 1027 cursor_color_(kDefaultColor), |
996 selection_color_(kDefaultColor), | 1028 selection_color_(kDefaultColor), |
997 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 1029 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
998 focused_(false), | 1030 focused_(false), |
999 composition_range_(Range::InvalidRange()), | 1031 composition_range_(Range::InvalidRange()), |
1000 colors_(kDefaultColor), | 1032 colors_(kDefaultColor), |
1001 baselines_(NORMAL_BASELINE), | 1033 baselines_(NORMAL_BASELINE), |
1034 weights_(gfx::Font::WEIGHT_NORMAL), | |
1002 styles_(NUM_TEXT_STYLES), | 1035 styles_(NUM_TEXT_STYLES), |
1003 composition_and_selection_styles_applied_(false), | 1036 composition_and_selection_styles_applied_(false), |
1004 obscured_(false), | 1037 obscured_(false), |
1005 obscured_reveal_index_(-1), | 1038 obscured_reveal_index_(-1), |
1006 truncate_length_(0), | 1039 truncate_length_(0), |
1007 elide_behavior_(NO_ELIDE), | 1040 elide_behavior_(NO_ELIDE), |
1008 text_elided_(false), | 1041 text_elided_(false), |
1009 min_line_height_(0), | 1042 min_line_height_(0), |
1010 multiline_(false), | 1043 multiline_(false), |
1011 word_wrap_behavior_(IGNORE_LONG_WORDS), | 1044 word_wrap_behavior_(IGNORE_LONG_WORDS), |
1012 replace_newline_chars_with_symbols_(true), | 1045 replace_newline_chars_with_symbols_(true), |
1013 subpixel_rendering_suppressed_(false), | 1046 subpixel_rendering_suppressed_(false), |
1014 clip_to_display_rect_(true), | 1047 clip_to_display_rect_(true), |
1015 baseline_(kInvalidBaseline), | 1048 baseline_(kInvalidBaseline), |
1016 cached_bounds_and_offset_valid_(false) { | 1049 cached_bounds_and_offset_valid_(false) {} |
1017 } | |
1018 | 1050 |
1019 SelectionModel RenderText::GetAdjacentSelectionModel( | 1051 SelectionModel RenderText::GetAdjacentSelectionModel( |
1020 const SelectionModel& current, | 1052 const SelectionModel& current, |
1021 BreakType break_type, | 1053 BreakType break_type, |
1022 VisualCursorDirection direction) { | 1054 VisualCursorDirection direction) { |
1023 EnsureLayout(); | 1055 EnsureLayout(); |
1024 | 1056 |
1025 if (break_type == LINE_BREAK || text().empty()) | 1057 if (break_type == LINE_BREAK || text().empty()) |
1026 return EdgeSelectionModel(direction); | 1058 return EdgeSelectionModel(direction); |
1027 if (break_type == CHARACTER_BREAK) | 1059 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; | 1310 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; |
1279 CHECK_GE(i, 0); | 1311 CHECK_GE(i, 0); |
1280 // Clamp indices to the length of the given layout or display text. | 1312 // Clamp indices to the length of the given layout or display text. |
1281 return std::min<size_t>(given_text.length(), i); | 1313 return std::min<size_t>(given_text.length(), i); |
1282 } | 1314 } |
1283 | 1315 |
1284 void RenderText::UpdateStyleLengths() { | 1316 void RenderText::UpdateStyleLengths() { |
1285 const size_t text_length = text_.length(); | 1317 const size_t text_length = text_.length(); |
1286 colors_.SetMax(text_length); | 1318 colors_.SetMax(text_length); |
1287 baselines_.SetMax(text_length); | 1319 baselines_.SetMax(text_length); |
1320 weights_.SetMax(text_length); | |
1288 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1321 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
1289 styles_[style].SetMax(text_length); | 1322 styles_[style].SetMax(text_length); |
1290 } | 1323 } |
1291 | 1324 |
1292 // static | 1325 // static |
1293 bool RenderText::RangeContainsCaret(const Range& range, | 1326 bool RenderText::RangeContainsCaret(const Range& range, |
1294 size_t caret_pos, | 1327 size_t caret_pos, |
1295 LogicalCursorDirection caret_affinity) { | 1328 LogicalCursorDirection caret_affinity) { |
1296 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). | 1329 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). |
1297 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? | 1330 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1381 | 1414 |
1382 // Create a RenderText copy with attributes that affect the rendering width. | 1415 // Create a RenderText copy with attributes that affect the rendering width. |
1383 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); | 1416 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); |
1384 render_text->SetFontList(font_list_); | 1417 render_text->SetFontList(font_list_); |
1385 render_text->SetDirectionalityMode(directionality_mode_); | 1418 render_text->SetDirectionalityMode(directionality_mode_); |
1386 render_text->SetCursorEnabled(cursor_enabled_); | 1419 render_text->SetCursorEnabled(cursor_enabled_); |
1387 render_text->set_truncate_length(truncate_length_); | 1420 render_text->set_truncate_length(truncate_length_); |
1388 render_text->styles_ = styles_; | 1421 render_text->styles_ = styles_; |
1389 render_text->baselines_ = baselines_; | 1422 render_text->baselines_ = baselines_; |
1390 render_text->colors_ = colors_; | 1423 render_text->colors_ = colors_; |
1424 render_text->weights_ = weights_; | |
1391 if (text_width == 0) { | 1425 if (text_width == 0) { |
1392 render_text->SetText(text); | 1426 render_text->SetText(text); |
1393 text_width = render_text->GetContentWidthF(); | 1427 text_width = render_text->GetContentWidthF(); |
1394 } | 1428 } |
1395 if (text_width <= available_width) | 1429 if (text_width <= available_width) |
1396 return text; | 1430 return text; |
1397 | 1431 |
1398 const base::string16 ellipsis = base::string16(kEllipsisUTF16); | 1432 const base::string16 ellipsis = base::string16(kEllipsisUTF16); |
1399 const bool insert_ellipsis = (behavior != TRUNCATE); | 1433 const bool insert_ellipsis = (behavior != TRUNCATE); |
1400 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); | 1434 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; | 1472 new_text += base::i18n::kRightToLeftMark; |
1439 } | 1473 } |
1440 render_text->SetText(new_text); | 1474 render_text->SetText(new_text); |
1441 } | 1475 } |
1442 | 1476 |
1443 // Restore styles and baselines without breaking multi-character graphemes. | 1477 // Restore styles and baselines without breaking multi-character graphemes. |
1444 render_text->styles_ = styles_; | 1478 render_text->styles_ = styles_; |
1445 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1479 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
1446 RestoreBreakList(render_text.get(), &render_text->styles_[style]); | 1480 RestoreBreakList(render_text.get(), &render_text->styles_[style]); |
1447 RestoreBreakList(render_text.get(), &render_text->baselines_); | 1481 RestoreBreakList(render_text.get(), &render_text->baselines_); |
1482 RestoreBreakList(render_text.get(), &render_text->weights_); | |
1448 | 1483 |
1449 // We check the width of the whole desired string at once to ensure we | 1484 // We check the width of the whole desired string at once to ensure we |
1450 // handle kerning/ligatures/etc. correctly. | 1485 // handle kerning/ligatures/etc. correctly. |
1451 const float guess_width = render_text->GetContentWidthF(); | 1486 const float guess_width = render_text->GetContentWidthF(); |
1452 if (guess_width == available_width) | 1487 if (guess_width == available_width) |
1453 break; | 1488 break; |
1454 if (guess_width > available_width) { | 1489 if (guess_width > available_width) { |
1455 hi = guess - 1; | 1490 hi = guess - 1; |
1456 // Move back on the loop terminating condition when the guess is too wide. | 1491 // Move back on the loop terminating condition when the guess is too wide. |
1457 if (hi < lo) | 1492 if (hi < lo) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1544 | 1579 |
1545 SetDisplayOffset(display_offset_.x() + delta_x); | 1580 SetDisplayOffset(display_offset_.x() + delta_x); |
1546 } | 1581 } |
1547 | 1582 |
1548 void RenderText::DrawSelection(Canvas* canvas) { | 1583 void RenderText::DrawSelection(Canvas* canvas) { |
1549 for (const Rect& s : GetSubstringBounds(selection())) | 1584 for (const Rect& s : GetSubstringBounds(selection())) |
1550 canvas->FillRect(s, selection_background_focused_color_); | 1585 canvas->FillRect(s, selection_background_focused_color_); |
1551 } | 1586 } |
1552 | 1587 |
1553 } // namespace gfx | 1588 } // namespace gfx |
OLD | NEW |