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

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

Issue 1819753003: Allow various font weights in gfx. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a lost comment and modify a render text unittest to not test black because of test env font con… Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/render_text_harfbuzz.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 360
360 if (clipped) 361 if (clipped)
361 canvas_->Restore(); 362 canvas_->Restore();
362 363
363 x += pieces_[i].first; 364 x += pieces_[i].first;
364 } 365 }
365 } 366 }
366 367
367 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, 368 StyleIterator::StyleIterator(const BreakList<SkColor>& colors,
368 const BreakList<BaselineStyle>& baselines, 369 const BreakList<BaselineStyle>& baselines,
370 const BreakList<Font::Weight>& weights,
369 const std::vector<BreakList<bool>>& styles) 371 const std::vector<BreakList<bool>>& styles)
370 : colors_(colors), baselines_(baselines), styles_(styles) { 372 : colors_(colors),
373 baselines_(baselines),
374 weights_(weights),
375 styles_(styles) {
371 color_ = colors_.breaks().begin(); 376 color_ = colors_.breaks().begin();
372 baseline_ = baselines_.breaks().begin(); 377 baseline_ = baselines_.breaks().begin();
378 weight_ = weights_.breaks().begin();
373 for (size_t i = 0; i < styles_.size(); ++i) 379 for (size_t i = 0; i < styles_.size(); ++i)
374 style_.push_back(styles_[i].breaks().begin()); 380 style_.push_back(styles_[i].breaks().begin());
375 } 381 }
376 382
377 StyleIterator::~StyleIterator() {} 383 StyleIterator::~StyleIterator() {}
378 384
379 Range StyleIterator::GetRange() const { 385 Range StyleIterator::GetRange() const {
380 Range range(colors_.GetRange(color_)); 386 Range range(colors_.GetRange(color_));
381 range = range.Intersect(baselines_.GetRange(baseline_)); 387 range = range.Intersect(baselines_.GetRange(baseline_));
388 range = range.Intersect(weights_.GetRange(weight_));
382 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) 389 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
383 range = range.Intersect(styles_[i].GetRange(style_[i])); 390 range = range.Intersect(styles_[i].GetRange(style_[i]));
384 return range; 391 return range;
385 } 392 }
386 393
387 void StyleIterator::UpdatePosition(size_t position) { 394 void StyleIterator::UpdatePosition(size_t position) {
388 color_ = colors_.GetBreak(position); 395 color_ = colors_.GetBreak(position);
389 baseline_ = baselines_.GetBreak(position); 396 baseline_ = baselines_.GetBreak(position);
397 weight_ = weights_.GetBreak(position);
390 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) 398 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
391 style_[i] = styles_[i].GetBreak(position); 399 style_[i] = styles_[i].GetBreak(position);
392 } 400 }
393 401
394 LineSegment::LineSegment() : run(0) {} 402 LineSegment::LineSegment() : run(0) {}
395 403
396 LineSegment::~LineSegment() {} 404 LineSegment::~LineSegment() {}
397 405
398 Line::Line() : preceding_heights(0), baseline(0) {} 406 Line::Line() : preceding_heights(0), baseline(0) {}
399 407
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 std::unique_ptr<RenderText> render_text = CreateInstanceOfSameType(); 447 std::unique_ptr<RenderText> render_text = CreateInstanceOfSameType();
440 // |SetText()| must be called before styles are set. 448 // |SetText()| must be called before styles are set.
441 render_text->SetText(text); 449 render_text->SetText(text);
442 render_text->SetFontList(font_list_); 450 render_text->SetFontList(font_list_);
443 render_text->SetDirectionalityMode(directionality_mode_); 451 render_text->SetDirectionalityMode(directionality_mode_);
444 render_text->SetCursorEnabled(cursor_enabled_); 452 render_text->SetCursorEnabled(cursor_enabled_);
445 render_text->set_truncate_length(truncate_length_); 453 render_text->set_truncate_length(truncate_length_);
446 render_text->styles_ = styles_; 454 render_text->styles_ = styles_;
447 render_text->baselines_ = baselines_; 455 render_text->baselines_ = baselines_;
448 render_text->colors_ = colors_; 456 render_text->colors_ = colors_;
457 render_text->weights_ = weights_;
449 return render_text; 458 return render_text;
450 } 459 }
451 460
452 void RenderText::SetText(const base::string16& text) { 461 void RenderText::SetText(const base::string16& text) {
453 DCHECK(!composition_range_.IsValid()); 462 DCHECK(!composition_range_.IsValid());
454 if (text_ == text) 463 if (text_ == text)
455 return; 464 return;
456 text_ = text; 465 text_ = text;
457 UpdateStyleLengths(); 466 UpdateStyleLengths();
458 467
459 // Clear style ranges as they might break new text graphemes and apply 468 // Clear style ranges as they might break new text graphemes and apply
460 // the first style to the whole text instead. 469 // the first style to the whole text instead.
461 colors_.SetValue(colors_.breaks().begin()->second); 470 colors_.SetValue(colors_.breaks().begin()->second);
462 baselines_.SetValue(baselines_.breaks().begin()->second); 471 baselines_.SetValue(baselines_.breaks().begin()->second);
472 weights_.SetValue(weights_.breaks().begin()->second);
463 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 473 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
464 styles_[style].SetValue(styles_[style].breaks().begin()->second); 474 styles_[style].SetValue(styles_[style].breaks().begin()->second);
465 cached_bounds_and_offset_valid_ = false; 475 cached_bounds_and_offset_valid_ = false;
466 476
467 // Reset selection model. SetText should always followed by SetSelectionModel 477 // Reset selection model. SetText should always followed by SetSelectionModel
468 // or SetCursorPosition in upper layer. 478 // or SetCursorPosition in upper layer.
469 SetSelectionModel(SelectionModel()); 479 SetSelectionModel(SelectionModel());
470 480
471 // Invalidate the cached text direction if it depends on the text contents. 481 // Invalidate the cached text direction if it depends on the text contents.
472 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) 482 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT)
(...skipping 15 matching lines...) Expand all
488 if (horizontal_alignment_ != alignment) { 498 if (horizontal_alignment_ != alignment) {
489 horizontal_alignment_ = alignment; 499 horizontal_alignment_ = alignment;
490 display_offset_ = Vector2d(); 500 display_offset_ = Vector2d();
491 cached_bounds_and_offset_valid_ = false; 501 cached_bounds_and_offset_valid_ = false;
492 } 502 }
493 } 503 }
494 504
495 void RenderText::SetFontList(const FontList& font_list) { 505 void RenderText::SetFontList(const FontList& font_list) {
496 font_list_ = font_list; 506 font_list_ = font_list;
497 const int font_style = font_list.GetFontStyle(); 507 const int font_style = font_list.GetFontStyle();
498 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); 508 weights_.SetValue(font_list.GetFontWeight());
499 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); 509 styles_[ITALIC].SetValue((font_style & Font::ITALIC) != 0);
500 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); 510 styles_[UNDERLINE].SetValue((font_style & Font::UNDERLINE) != 0);
501 baseline_ = kInvalidBaseline; 511 baseline_ = kInvalidBaseline;
502 cached_bounds_and_offset_valid_ = false; 512 cached_bounds_and_offset_valid_ = false;
503 OnLayoutTextAttributeChanged(false); 513 OnLayoutTextAttributeChanged(false);
504 } 514 }
505 515
506 void RenderText::SetCursorEnabled(bool cursor_enabled) { 516 void RenderText::SetCursorEnabled(bool cursor_enabled) {
507 cursor_enabled_ = cursor_enabled; 517 cursor_enabled_ = cursor_enabled;
508 cached_bounds_and_offset_valid_ = false; 518 cached_bounds_and_offset_valid_ = false;
509 } 519 }
510 520
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : 769 const size_t end = IsValidCursorIndex(range.end()) ? range.end() :
760 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); 770 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD);
761 styles_[style].ApplyValue(value, Range(start, end)); 771 styles_[style].ApplyValue(value, Range(start, end));
762 772
763 cached_bounds_and_offset_valid_ = false; 773 cached_bounds_and_offset_valid_ = false;
764 // TODO(oshima|msw): Not all style change requires layout changes. 774 // TODO(oshima|msw): Not all style change requires layout changes.
765 // Consider optimizing based on the type of change. 775 // Consider optimizing based on the type of change.
766 OnLayoutTextAttributeChanged(false); 776 OnLayoutTextAttributeChanged(false);
767 } 777 }
768 778
779 void RenderText::SetWeight(Font::Weight weight) {
780 weights_.SetValue(weight);
781
782 cached_bounds_and_offset_valid_ = false;
783 OnLayoutTextAttributeChanged(false);
784 }
785
786 void RenderText::ApplyWeight(Font::Weight weight, const Range& range) {
787 weights_.ApplyValue(weight, range);
788
789 cached_bounds_and_offset_valid_ = false;
790 OnLayoutTextAttributeChanged(false);
791 }
792
769 bool RenderText::GetStyle(TextStyle style) const { 793 bool RenderText::GetStyle(TextStyle style) const {
770 return (styles_[style].breaks().size() == 1) && 794 return (styles_[style].breaks().size() == 1) &&
771 styles_[style].breaks().front().second; 795 styles_[style].breaks().front().second;
772 } 796 }
773 797
774 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { 798 void RenderText::SetDirectionalityMode(DirectionalityMode mode) {
775 if (mode == directionality_mode_) 799 if (mode == directionality_mode_)
776 return; 800 return;
777 801
778 directionality_mode_ = mode; 802 directionality_mode_ = mode;
779 text_direction_ = base::i18n::UNKNOWN_DIRECTION; 803 text_direction_ = base::i18n::UNKNOWN_DIRECTION;
780 cached_bounds_and_offset_valid_ = false; 804 cached_bounds_and_offset_valid_ = false;
781 OnLayoutTextAttributeChanged(false); 805 OnLayoutTextAttributeChanged(false);
782 } 806 }
783 807
784 base::i18n::TextDirection RenderText::GetDisplayTextDirection() { 808 base::i18n::TextDirection RenderText::GetDisplayTextDirection() {
785 return GetTextDirection(GetDisplayText()); 809 return GetTextDirection(GetDisplayText());
786 } 810 }
787 811
788 VisualCursorDirection RenderText::GetVisualDirectionOfLogicalEnd() { 812 VisualCursorDirection RenderText::GetVisualDirectionOfLogicalEnd() {
789 return GetDisplayTextDirection() == base::i18n::LEFT_TO_RIGHT ? 813 return GetDisplayTextDirection() == base::i18n::LEFT_TO_RIGHT ?
790 CURSOR_RIGHT : CURSOR_LEFT; 814 CURSOR_RIGHT : CURSOR_LEFT;
791 } 815 }
792 816
793 SizeF RenderText::GetStringSizeF() { 817 SizeF RenderText::GetStringSizeF() {
794 return gfx::SizeF(GetStringSize()); 818 return SizeF(GetStringSize());
795 } 819 }
796 820
797 float RenderText::GetContentWidthF() { 821 float RenderText::GetContentWidthF() {
798 const float string_size = GetStringSizeF().width(); 822 const float string_size = GetStringSizeF().width();
799 // The cursor is drawn one pixel beyond the int-enclosed text bounds. 823 // The cursor is drawn one pixel beyond the int-enclosed text bounds.
800 return cursor_enabled_ ? std::ceil(string_size) + 1 : string_size; 824 return cursor_enabled_ ? std::ceil(string_size) + 1 : string_size;
801 } 825 }
802 826
803 int RenderText::GetContentWidth() { 827 int RenderText::GetContentWidth() {
804 return ToCeiledInt(GetContentWidthF()); 828 return ToCeiledInt(GetContentWidthF());
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 cursor_enabled_(true), 1014 cursor_enabled_(true),
991 cursor_visible_(false), 1015 cursor_visible_(false),
992 insert_mode_(true), 1016 insert_mode_(true),
993 cursor_color_(kDefaultColor), 1017 cursor_color_(kDefaultColor),
994 selection_color_(kDefaultColor), 1018 selection_color_(kDefaultColor),
995 selection_background_focused_color_(kDefaultSelectionBackgroundColor), 1019 selection_background_focused_color_(kDefaultSelectionBackgroundColor),
996 focused_(false), 1020 focused_(false),
997 composition_range_(Range::InvalidRange()), 1021 composition_range_(Range::InvalidRange()),
998 colors_(kDefaultColor), 1022 colors_(kDefaultColor),
999 baselines_(NORMAL_BASELINE), 1023 baselines_(NORMAL_BASELINE),
1024 weights_(Font::Weight::NORMAL),
1000 styles_(NUM_TEXT_STYLES), 1025 styles_(NUM_TEXT_STYLES),
1001 composition_and_selection_styles_applied_(false), 1026 composition_and_selection_styles_applied_(false),
1002 obscured_(false), 1027 obscured_(false),
1003 obscured_reveal_index_(-1), 1028 obscured_reveal_index_(-1),
1004 truncate_length_(0), 1029 truncate_length_(0),
1005 elide_behavior_(NO_ELIDE), 1030 elide_behavior_(NO_ELIDE),
1006 text_elided_(false), 1031 text_elided_(false),
1007 min_line_height_(0), 1032 min_line_height_(0),
1008 multiline_(false), 1033 multiline_(false),
1009 max_lines_(0), 1034 max_lines_(0),
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; 1326 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index;
1302 CHECK_GE(i, 0); 1327 CHECK_GE(i, 0);
1303 // Clamp indices to the length of the given layout or display text. 1328 // Clamp indices to the length of the given layout or display text.
1304 return std::min<size_t>(given_text.length(), i); 1329 return std::min<size_t>(given_text.length(), i);
1305 } 1330 }
1306 1331
1307 void RenderText::UpdateStyleLengths() { 1332 void RenderText::UpdateStyleLengths() {
1308 const size_t text_length = text_.length(); 1333 const size_t text_length = text_.length();
1309 colors_.SetMax(text_length); 1334 colors_.SetMax(text_length);
1310 baselines_.SetMax(text_length); 1335 baselines_.SetMax(text_length);
1336 weights_.SetMax(text_length);
1311 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 1337 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
1312 styles_[style].SetMax(text_length); 1338 styles_[style].SetMax(text_length);
1313 } 1339 }
1314 1340
1315 // static 1341 // static
1316 bool RenderText::RangeContainsCaret(const Range& range, 1342 bool RenderText::RangeContainsCaret(const Range& range,
1317 size_t caret_pos, 1343 size_t caret_pos,
1318 LogicalCursorDirection caret_affinity) { 1344 LogicalCursorDirection caret_affinity) {
1319 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). 1345 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9).
1320 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? 1346 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ?
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 new_text += base::i18n::kRightToLeftMark; 1479 new_text += base::i18n::kRightToLeftMark;
1454 } 1480 }
1455 render_text->SetText(new_text); 1481 render_text->SetText(new_text);
1456 } 1482 }
1457 1483
1458 // Restore styles and baselines without breaking multi-character graphemes. 1484 // Restore styles and baselines without breaking multi-character graphemes.
1459 render_text->styles_ = styles_; 1485 render_text->styles_ = styles_;
1460 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 1486 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
1461 RestoreBreakList(render_text.get(), &render_text->styles_[style]); 1487 RestoreBreakList(render_text.get(), &render_text->styles_[style]);
1462 RestoreBreakList(render_text.get(), &render_text->baselines_); 1488 RestoreBreakList(render_text.get(), &render_text->baselines_);
1489 render_text->weights_ = weights_;
1490 RestoreBreakList(render_text.get(), &render_text->weights_);
1463 1491
1464 // We check the width of the whole desired string at once to ensure we 1492 // We check the width of the whole desired string at once to ensure we
1465 // handle kerning/ligatures/etc. correctly. 1493 // handle kerning/ligatures/etc. correctly.
1466 const float guess_width = render_text->GetContentWidthF(); 1494 const float guess_width = render_text->GetContentWidthF();
1467 if (guess_width == available_width) 1495 if (guess_width == available_width)
1468 break; 1496 break;
1469 if (guess_width > available_width) { 1497 if (guess_width > available_width) {
1470 hi = guess - 1; 1498 hi = guess - 1;
1471 // Move back on the loop terminating condition when the guess is too wide. 1499 // Move back on the loop terminating condition when the guess is too wide.
1472 if (hi < lo) 1500 if (hi < lo)
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 1587
1560 SetDisplayOffset(display_offset_.x() + delta_x); 1588 SetDisplayOffset(display_offset_.x() + delta_x);
1561 } 1589 }
1562 1590
1563 void RenderText::DrawSelection(Canvas* canvas) { 1591 void RenderText::DrawSelection(Canvas* canvas) {
1564 for (const Rect& s : GetSubstringBounds(selection())) 1592 for (const Rect& s : GetSubstringBounds(selection()))
1565 canvas->FillRect(s, selection_background_focused_color_); 1593 canvas->FillRect(s, selection_background_focused_color_);
1566 } 1594 }
1567 1595
1568 } // namespace gfx 1596 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/render_text_harfbuzz.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698