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

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: Fixes for review issues. Created 4 years, 9 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
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 }
433
msw 2016/03/22 18:24:11 nit: remove blank line
Mikus 2016/03/23 17:53:22 Done.
428 #endif 434 #endif
429 435
430 void ApplyRenderParams(const FontRenderParams& params, 436 void ApplyRenderParams(const FontRenderParams& params,
431 bool subpixel_rendering_suppressed, 437 bool subpixel_rendering_suppressed,
432 SkPaint* paint) { 438 SkPaint* paint) {
433 paint->setAntiAlias(params.antialiasing); 439 paint->setAntiAlias(params.antialiasing);
434 paint->setLCDRenderText(!subpixel_rendering_suppressed && 440 paint->setLCDRenderText(!subpixel_rendering_suppressed &&
435 params.subpixel_rendering != FontRenderParams::SUBPIXEL_RENDERING_NONE); 441 params.subpixel_rendering != FontRenderParams::SUBPIXEL_RENDERING_NONE);
436 paint->setSubpixelText(params.subpixel_positioning); 442 paint->setSubpixelText(params.subpixel_positioning);
437 paint->setAutohinted(params.autohinter); 443 paint->setAutohinted(params.autohinter);
(...skipping 26 matching lines...) Expand all
464 DCHECK(!composition_range_.IsValid()); 470 DCHECK(!composition_range_.IsValid());
465 if (text_ == text) 471 if (text_ == text)
466 return; 472 return;
467 text_ = text; 473 text_ = text;
468 UpdateStyleLengths(); 474 UpdateStyleLengths();
469 475
470 // Clear style ranges as they might break new text graphemes and apply 476 // Clear style ranges as they might break new text graphemes and apply
471 // the first style to the whole text instead. 477 // the first style to the whole text instead.
472 colors_.SetValue(colors_.breaks().begin()->second); 478 colors_.SetValue(colors_.breaks().begin()->second);
473 baselines_.SetValue(baselines_.breaks().begin()->second); 479 baselines_.SetValue(baselines_.breaks().begin()->second);
480 weights_.SetValue(weights_.breaks().begin()->second);
474 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 481 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
475 styles_[style].SetValue(styles_[style].breaks().begin()->second); 482 styles_[style].SetValue(styles_[style].breaks().begin()->second);
476 cached_bounds_and_offset_valid_ = false; 483 cached_bounds_and_offset_valid_ = false;
477 484
478 // Reset selection model. SetText should always followed by SetSelectionModel 485 // Reset selection model. SetText should always followed by SetSelectionModel
479 // or SetCursorPosition in upper layer. 486 // or SetCursorPosition in upper layer.
480 SetSelectionModel(SelectionModel()); 487 SetSelectionModel(SelectionModel());
481 488
482 // Invalidate the cached text direction if it depends on the text contents. 489 // Invalidate the cached text direction if it depends on the text contents.
483 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT) 490 if (directionality_mode_ == DIRECTIONALITY_FROM_TEXT)
(...skipping 15 matching lines...) Expand all
499 if (horizontal_alignment_ != alignment) { 506 if (horizontal_alignment_ != alignment) {
500 horizontal_alignment_ = alignment; 507 horizontal_alignment_ = alignment;
501 display_offset_ = Vector2d(); 508 display_offset_ = Vector2d();
502 cached_bounds_and_offset_valid_ = false; 509 cached_bounds_and_offset_valid_ = false;
503 } 510 }
504 } 511 }
505 512
506 void RenderText::SetFontList(const FontList& font_list) { 513 void RenderText::SetFontList(const FontList& font_list) {
507 font_list_ = font_list; 514 font_list_ = font_list;
508 const int font_style = font_list.GetFontStyle(); 515 const int font_style = font_list.GetFontStyle();
509 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); 516 weights_.SetValue(font_list.GetFontWeight());
510 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); 517 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0);
msw 2016/03/22 18:24:11 Make these two SetStyle calls also assign directly
Mikus 2016/03/23 17:53:22 Done.
511 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); 518 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0);
512 baseline_ = kInvalidBaseline; 519 baseline_ = kInvalidBaseline;
513 cached_bounds_and_offset_valid_ = false; 520 cached_bounds_and_offset_valid_ = false;
514 OnLayoutTextAttributeChanged(false); 521 OnLayoutTextAttributeChanged(false);
515 } 522 }
516 523
517 void RenderText::SetCursorEnabled(bool cursor_enabled) { 524 void RenderText::SetCursorEnabled(bool cursor_enabled) {
518 cursor_enabled_ = cursor_enabled; 525 cursor_enabled_ = cursor_enabled;
519 cached_bounds_and_offset_valid_ = false; 526 cached_bounds_and_offset_valid_ = false;
520 } 527 }
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 const size_t end = IsValidCursorIndex(range.end()) ? range.end() : 768 const size_t end = IsValidCursorIndex(range.end()) ? range.end() :
762 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD); 769 IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD);
763 styles_[style].ApplyValue(value, Range(start, end)); 770 styles_[style].ApplyValue(value, Range(start, end));
764 771
765 cached_bounds_and_offset_valid_ = false; 772 cached_bounds_and_offset_valid_ = false;
766 // TODO(oshima|msw): Not all style change requires layout changes. 773 // TODO(oshima|msw): Not all style change requires layout changes.
767 // Consider optimizing based on the type of change. 774 // Consider optimizing based on the type of change.
768 OnLayoutTextAttributeChanged(false); 775 OnLayoutTextAttributeChanged(false);
769 } 776 }
770 777
778 void RenderText::SetWeight(gfx::Font::Weight weight) {
779 weights_.SetValue(weight);
780
781 cached_bounds_and_offset_valid_ = false;
782 OnLayoutTextAttributeChanged(false);
783 }
784
785 void RenderText::ApplyWeight(gfx::Font::Weight weight, const Range& range) {
786 weights_.ApplyValue(weight, range);
787
788 cached_bounds_and_offset_valid_ = false;
789 OnLayoutTextAttributeChanged(false);
790 }
791
771 bool RenderText::GetStyle(TextStyle style) const { 792 bool RenderText::GetStyle(TextStyle style) const {
772 return (styles_[style].breaks().size() == 1) && 793 return (styles_[style].breaks().size() == 1) &&
773 styles_[style].breaks().front().second; 794 styles_[style].breaks().front().second;
774 } 795 }
775 796
776 void RenderText::SetDirectionalityMode(DirectionalityMode mode) { 797 void RenderText::SetDirectionalityMode(DirectionalityMode mode) {
777 if (mode == directionality_mode_) 798 if (mode == directionality_mode_)
778 return; 799 return;
779 800
780 directionality_mode_ = mode; 801 directionality_mode_ = mode;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 cursor_enabled_(true), 1013 cursor_enabled_(true),
993 cursor_visible_(false), 1014 cursor_visible_(false),
994 insert_mode_(true), 1015 insert_mode_(true),
995 cursor_color_(kDefaultColor), 1016 cursor_color_(kDefaultColor),
996 selection_color_(kDefaultColor), 1017 selection_color_(kDefaultColor),
997 selection_background_focused_color_(kDefaultSelectionBackgroundColor), 1018 selection_background_focused_color_(kDefaultSelectionBackgroundColor),
998 focused_(false), 1019 focused_(false),
999 composition_range_(Range::InvalidRange()), 1020 composition_range_(Range::InvalidRange()),
1000 colors_(kDefaultColor), 1021 colors_(kDefaultColor),
1001 baselines_(NORMAL_BASELINE), 1022 baselines_(NORMAL_BASELINE),
1023 weights_(gfx::Font::Weight::NORMAL),
1002 styles_(NUM_TEXT_STYLES), 1024 styles_(NUM_TEXT_STYLES),
1003 composition_and_selection_styles_applied_(false), 1025 composition_and_selection_styles_applied_(false),
1004 obscured_(false), 1026 obscured_(false),
1005 obscured_reveal_index_(-1), 1027 obscured_reveal_index_(-1),
1006 truncate_length_(0), 1028 truncate_length_(0),
1007 elide_behavior_(NO_ELIDE), 1029 elide_behavior_(NO_ELIDE),
1008 text_elided_(false), 1030 text_elided_(false),
1009 min_line_height_(0), 1031 min_line_height_(0),
1010 multiline_(false), 1032 multiline_(false),
1011 word_wrap_behavior_(IGNORE_LONG_WORDS), 1033 word_wrap_behavior_(IGNORE_LONG_WORDS),
1012 replace_newline_chars_with_symbols_(true), 1034 replace_newline_chars_with_symbols_(true),
1013 subpixel_rendering_suppressed_(false), 1035 subpixel_rendering_suppressed_(false),
1014 clip_to_display_rect_(true), 1036 clip_to_display_rect_(true),
1015 baseline_(kInvalidBaseline), 1037 baseline_(kInvalidBaseline),
1016 cached_bounds_and_offset_valid_(false) { 1038 cached_bounds_and_offset_valid_(false) {}
1017 }
1018 1039
1019 SelectionModel RenderText::GetAdjacentSelectionModel( 1040 SelectionModel RenderText::GetAdjacentSelectionModel(
1020 const SelectionModel& current, 1041 const SelectionModel& current,
1021 BreakType break_type, 1042 BreakType break_type,
1022 VisualCursorDirection direction) { 1043 VisualCursorDirection direction) {
1023 EnsureLayout(); 1044 EnsureLayout();
1024 1045
1025 if (break_type == LINE_BREAK || text().empty()) 1046 if (break_type == LINE_BREAK || text().empty())
1026 return EdgeSelectionModel(direction); 1047 return EdgeSelectionModel(direction);
1027 if (break_type == CHARACTER_BREAK) 1048 if (break_type == CHARACTER_BREAK)
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; 1299 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index;
1279 CHECK_GE(i, 0); 1300 CHECK_GE(i, 0);
1280 // Clamp indices to the length of the given layout or display text. 1301 // Clamp indices to the length of the given layout or display text.
1281 return std::min<size_t>(given_text.length(), i); 1302 return std::min<size_t>(given_text.length(), i);
1282 } 1303 }
1283 1304
1284 void RenderText::UpdateStyleLengths() { 1305 void RenderText::UpdateStyleLengths() {
1285 const size_t text_length = text_.length(); 1306 const size_t text_length = text_.length();
1286 colors_.SetMax(text_length); 1307 colors_.SetMax(text_length);
1287 baselines_.SetMax(text_length); 1308 baselines_.SetMax(text_length);
1309 weights_.SetMax(text_length);
1288 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 1310 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
1289 styles_[style].SetMax(text_length); 1311 styles_[style].SetMax(text_length);
1290 } 1312 }
1291 1313
1292 // static 1314 // static
1293 bool RenderText::RangeContainsCaret(const Range& range, 1315 bool RenderText::RangeContainsCaret(const Range& range,
1294 size_t caret_pos, 1316 size_t caret_pos,
1295 LogicalCursorDirection caret_affinity) { 1317 LogicalCursorDirection caret_affinity) {
1296 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). 1318 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9).
1297 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? 1319 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ?
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 1403
1382 // Create a RenderText copy with attributes that affect the rendering width. 1404 // Create a RenderText copy with attributes that affect the rendering width.
1383 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); 1405 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType();
1384 render_text->SetFontList(font_list_); 1406 render_text->SetFontList(font_list_);
1385 render_text->SetDirectionalityMode(directionality_mode_); 1407 render_text->SetDirectionalityMode(directionality_mode_);
1386 render_text->SetCursorEnabled(cursor_enabled_); 1408 render_text->SetCursorEnabled(cursor_enabled_);
1387 render_text->set_truncate_length(truncate_length_); 1409 render_text->set_truncate_length(truncate_length_);
1388 render_text->styles_ = styles_; 1410 render_text->styles_ = styles_;
1389 render_text->baselines_ = baselines_; 1411 render_text->baselines_ = baselines_;
1390 render_text->colors_ = colors_; 1412 render_text->colors_ = colors_;
1413 render_text->weights_ = weights_;
1391 if (text_width == 0) { 1414 if (text_width == 0) {
1392 render_text->SetText(text); 1415 render_text->SetText(text);
1393 text_width = render_text->GetContentWidthF(); 1416 text_width = render_text->GetContentWidthF();
1394 } 1417 }
1395 if (text_width <= available_width) 1418 if (text_width <= available_width)
1396 return text; 1419 return text;
1397 1420
1398 const base::string16 ellipsis = base::string16(kEllipsisUTF16); 1421 const base::string16 ellipsis = base::string16(kEllipsisUTF16);
1399 const bool insert_ellipsis = (behavior != TRUNCATE); 1422 const bool insert_ellipsis = (behavior != TRUNCATE);
1400 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); 1423 const bool elide_in_middle = (behavior == ELIDE_MIDDLE);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 new_text += base::i18n::kRightToLeftMark; 1461 new_text += base::i18n::kRightToLeftMark;
1439 } 1462 }
1440 render_text->SetText(new_text); 1463 render_text->SetText(new_text);
1441 } 1464 }
1442 1465
1443 // Restore styles and baselines without breaking multi-character graphemes. 1466 // Restore styles and baselines without breaking multi-character graphemes.
1444 render_text->styles_ = styles_; 1467 render_text->styles_ = styles_;
1445 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 1468 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
1446 RestoreBreakList(render_text.get(), &render_text->styles_[style]); 1469 RestoreBreakList(render_text.get(), &render_text->styles_[style]);
1447 RestoreBreakList(render_text.get(), &render_text->baselines_); 1470 RestoreBreakList(render_text.get(), &render_text->baselines_);
1471 RestoreBreakList(render_text.get(), &render_text->weights_);
1448 1472
1449 // We check the width of the whole desired string at once to ensure we 1473 // We check the width of the whole desired string at once to ensure we
1450 // handle kerning/ligatures/etc. correctly. 1474 // handle kerning/ligatures/etc. correctly.
1451 const float guess_width = render_text->GetContentWidthF(); 1475 const float guess_width = render_text->GetContentWidthF();
1452 if (guess_width == available_width) 1476 if (guess_width == available_width)
1453 break; 1477 break;
1454 if (guess_width > available_width) { 1478 if (guess_width > available_width) {
1455 hi = guess - 1; 1479 hi = guess - 1;
1456 // Move back on the loop terminating condition when the guess is too wide. 1480 // Move back on the loop terminating condition when the guess is too wide.
1457 if (hi < lo) 1481 if (hi < lo)
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 1568
1545 SetDisplayOffset(display_offset_.x() + delta_x); 1569 SetDisplayOffset(display_offset_.x() + delta_x);
1546 } 1570 }
1547 1571
1548 void RenderText::DrawSelection(Canvas* canvas) { 1572 void RenderText::DrawSelection(Canvas* canvas) {
1549 for (const Rect& s : GetSubstringBounds(selection())) 1573 for (const Rect& s : GetSubstringBounds(selection()))
1550 canvas->FillRect(s, selection_background_focused_color_); 1574 canvas->FillRect(s, selection_background_focused_color_);
1551 } 1575 }
1552 1576
1553 } // namespace gfx 1577 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698