| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <climits> | 8 #include <climits> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 | 360 |
| 361 canvas_->DrawLine(start_, end, paint_); | 361 canvas_->DrawLine(start_, end, paint_); |
| 362 | 362 |
| 363 if (clipped) | 363 if (clipped) |
| 364 canvas_->Restore(); | 364 canvas_->Restore(); |
| 365 | 365 |
| 366 x += pieces_[i].first; | 366 x += pieces_[i].first; |
| 367 } | 367 } |
| 368 } | 368 } |
| 369 | 369 |
| 370 StyleIterator::StyleIterator(const BreakList<SkColor>& colors, | 370 StyleIterator::StyleIterator(const BreakList<uint32_t>& font_sizes, |
| 371 const BreakList<SkColor>& colors, |
| 371 const BreakList<BaselineStyle>& baselines, | 372 const BreakList<BaselineStyle>& baselines, |
| 372 const std::vector<BreakList<bool>>& styles) | 373 const std::vector<BreakList<bool>>& styles) |
| 373 : colors_(colors), baselines_(baselines), styles_(styles) { | 374 : font_sizes_(font_sizes), |
| 375 colors_(colors), |
| 376 baselines_(baselines), |
| 377 styles_(styles) { |
| 378 font_size_ = font_sizes_.breaks().begin(); |
| 374 color_ = colors_.breaks().begin(); | 379 color_ = colors_.breaks().begin(); |
| 375 baseline_ = baselines_.breaks().begin(); | 380 baseline_ = baselines_.breaks().begin(); |
| 376 for (size_t i = 0; i < styles_.size(); ++i) | 381 for (size_t i = 0; i < styles_.size(); ++i) |
| 377 style_.push_back(styles_[i].breaks().begin()); | 382 style_.push_back(styles_[i].breaks().begin()); |
| 378 } | 383 } |
| 379 | 384 |
| 380 StyleIterator::~StyleIterator() {} | 385 StyleIterator::~StyleIterator() {} |
| 381 | 386 |
| 382 Range StyleIterator::GetRange() const { | 387 Range StyleIterator::GetRange() const { |
| 383 Range range(colors_.GetRange(color_)); | 388 Range range(colors_.GetRange(color_)); |
| 389 range = range.Intersect(font_sizes_.GetRange(font_size_)); |
| 384 range = range.Intersect(baselines_.GetRange(baseline_)); | 390 range = range.Intersect(baselines_.GetRange(baseline_)); |
| 385 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 391 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
| 386 range = range.Intersect(styles_[i].GetRange(style_[i])); | 392 range = range.Intersect(styles_[i].GetRange(style_[i])); |
| 387 return range; | 393 return range; |
| 388 } | 394 } |
| 389 | 395 |
| 390 void StyleIterator::UpdatePosition(size_t position) { | 396 void StyleIterator::UpdatePosition(size_t position) { |
| 397 font_size_ = font_sizes_.GetBreak(position); |
| 391 color_ = colors_.GetBreak(position); | 398 color_ = colors_.GetBreak(position); |
| 392 baseline_ = baselines_.GetBreak(position); | 399 baseline_ = baselines_.GetBreak(position); |
| 393 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 400 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
| 394 style_[i] = styles_[i].GetBreak(position); | 401 style_[i] = styles_[i].GetBreak(position); |
| 395 } | 402 } |
| 396 | 403 |
| 397 LineSegment::LineSegment() : width(0), run(0) {} | 404 LineSegment::LineSegment() : width(0), run(0) {} |
| 398 | 405 |
| 399 LineSegment::~LineSegment() {} | 406 LineSegment::~LineSegment() {} |
| 400 | 407 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 | 450 |
| 444 void RenderText::SetText(const base::string16& text) { | 451 void RenderText::SetText(const base::string16& text) { |
| 445 DCHECK(!composition_range_.IsValid()); | 452 DCHECK(!composition_range_.IsValid()); |
| 446 if (text_ == text) | 453 if (text_ == text) |
| 447 return; | 454 return; |
| 448 text_ = text; | 455 text_ = text; |
| 449 UpdateStyleLengths(); | 456 UpdateStyleLengths(); |
| 450 | 457 |
| 451 // Clear style ranges as they might break new text graphemes and apply | 458 // Clear style ranges as they might break new text graphemes and apply |
| 452 // the first style to the whole text instead. | 459 // the first style to the whole text instead. |
| 460 font_sizes_.SetValue(font_sizes_.breaks().begin()->second); |
| 453 colors_.SetValue(colors_.breaks().begin()->second); | 461 colors_.SetValue(colors_.breaks().begin()->second); |
| 454 baselines_.SetValue(baselines_.breaks().begin()->second); | 462 baselines_.SetValue(baselines_.breaks().begin()->second); |
| 455 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 463 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 456 styles_[style].SetValue(styles_[style].breaks().begin()->second); | 464 styles_[style].SetValue(styles_[style].breaks().begin()->second); |
| 457 cached_bounds_and_offset_valid_ = false; | 465 cached_bounds_and_offset_valid_ = false; |
| 458 | 466 |
| 459 // Reset selection model. SetText should always followed by SetSelectionModel | 467 // Reset selection model. SetText should always followed by SetSelectionModel |
| 460 // or SetCursorPosition in upper layer. | 468 // or SetCursorPosition in upper layer. |
| 461 SetSelectionModel(SelectionModel()); | 469 SetSelectionModel(SelectionModel()); |
| 462 | 470 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 477 } | 485 } |
| 478 | 486 |
| 479 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { | 487 void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { |
| 480 if (horizontal_alignment_ != alignment) { | 488 if (horizontal_alignment_ != alignment) { |
| 481 horizontal_alignment_ = alignment; | 489 horizontal_alignment_ = alignment; |
| 482 display_offset_ = Vector2d(); | 490 display_offset_ = Vector2d(); |
| 483 cached_bounds_and_offset_valid_ = false; | 491 cached_bounds_and_offset_valid_ = false; |
| 484 } | 492 } |
| 485 } | 493 } |
| 486 | 494 |
| 495 void RenderText::SetVerticalAlignment(VerticalAlignment alignment) { |
| 496 if (vertical_alignment_ != alignment) { |
| 497 vertical_alignment_ = alignment; |
| 498 display_offset_ = Vector2d(); |
| 499 cached_bounds_and_offset_valid_ = false; |
| 500 } |
| 501 } |
| 502 |
| 487 void RenderText::SetFontList(const FontList& font_list) { | 503 void RenderText::SetFontList(const FontList& font_list) { |
| 488 font_list_ = font_list; | 504 font_list_ = font_list; |
| 489 const int font_style = font_list.GetFontStyle(); | 505 const int font_style = font_list.GetFontStyle(); |
| 490 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); | 506 SetStyle(BOLD, (font_style & gfx::Font::BOLD) != 0); |
| 491 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); | 507 SetStyle(ITALIC, (font_style & gfx::Font::ITALIC) != 0); |
| 492 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); | 508 SetStyle(UNDERLINE, (font_style & gfx::Font::UNDERLINE) != 0); |
| 493 baseline_ = kInvalidBaseline; | 509 baseline_ = kInvalidBaseline; |
| 494 cached_bounds_and_offset_valid_ = false; | 510 cached_bounds_and_offset_valid_ = false; |
| 495 OnLayoutTextAttributeChanged(false); | 511 OnLayoutTextAttributeChanged(false); |
| 496 } | 512 } |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 Range(0, text_.length()).Contains(composition_range)); | 708 Range(0, text_.length()).Contains(composition_range)); |
| 693 composition_range_.set_end(composition_range.end()); | 709 composition_range_.set_end(composition_range.end()); |
| 694 composition_range_.set_start(composition_range.start()); | 710 composition_range_.set_start(composition_range.start()); |
| 695 // TODO(oshima|msw): Altering composition underlines shouldn't | 711 // TODO(oshima|msw): Altering composition underlines shouldn't |
| 696 // require layout changes. It's currently necessary because | 712 // require layout changes. It's currently necessary because |
| 697 // RenderTextHarfBuzz paints text decorations by run, and | 713 // RenderTextHarfBuzz paints text decorations by run, and |
| 698 // RenderTextMac applies all styles during layout. | 714 // RenderTextMac applies all styles during layout. |
| 699 OnLayoutTextAttributeChanged(false); | 715 OnLayoutTextAttributeChanged(false); |
| 700 } | 716 } |
| 701 | 717 |
| 718 void RenderText::SetFontSize(uint32_t value) { |
| 719 font_sizes_.SetValue(value); |
| 720 cached_bounds_and_offset_valid_ = false; |
| 721 OnLayoutTextAttributeChanged(false); |
| 722 } |
| 723 |
| 724 void RenderText::ApplyFontSize(uint32_t value, const Range& range) { |
| 725 font_sizes_.ApplyValue(value, range); |
| 726 cached_bounds_and_offset_valid_ = false; |
| 727 OnLayoutTextAttributeChanged(false); |
| 728 } |
| 729 |
| 702 void RenderText::SetColor(SkColor value) { | 730 void RenderText::SetColor(SkColor value) { |
| 703 colors_.SetValue(value); | 731 colors_.SetValue(value); |
| 704 } | 732 } |
| 705 | 733 |
| 706 void RenderText::ApplyColor(SkColor value, const Range& range) { | 734 void RenderText::ApplyColor(SkColor value, const Range& range) { |
| 707 colors_.ApplyValue(value, range); | 735 colors_.ApplyValue(value, range); |
| 708 } | 736 } |
| 709 | 737 |
| 710 void RenderText::SetBaselineStyle(BaselineStyle value) { | 738 void RenderText::SetBaselineStyle(BaselineStyle value) { |
| 711 baselines_.SetValue(value); | 739 baselines_.SetValue(value); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 if (!multiline()) | 976 if (!multiline()) |
| 949 offset.Add(GetUpdatedDisplayOffset()); | 977 offset.Add(GetUpdatedDisplayOffset()); |
| 950 else | 978 else |
| 951 offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); | 979 offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); |
| 952 offset.Add(GetAlignmentOffset(line_number)); | 980 offset.Add(GetAlignmentOffset(line_number)); |
| 953 return offset; | 981 return offset; |
| 954 } | 982 } |
| 955 | 983 |
| 956 RenderText::RenderText() | 984 RenderText::RenderText() |
| 957 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), | 985 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), |
| 986 vertical_alignment_(VALIGN_MIDDLE), |
| 958 directionality_mode_(DIRECTIONALITY_FROM_TEXT), | 987 directionality_mode_(DIRECTIONALITY_FROM_TEXT), |
| 959 text_direction_(base::i18n::UNKNOWN_DIRECTION), | 988 text_direction_(base::i18n::UNKNOWN_DIRECTION), |
| 960 cursor_enabled_(true), | 989 cursor_enabled_(true), |
| 961 cursor_visible_(false), | 990 cursor_visible_(false), |
| 962 insert_mode_(true), | 991 insert_mode_(true), |
| 963 cursor_color_(kDefaultColor), | 992 cursor_color_(kDefaultColor), |
| 964 selection_color_(kDefaultColor), | 993 selection_color_(kDefaultColor), |
| 965 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 994 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
| 966 focused_(false), | 995 focused_(false), |
| 967 composition_range_(Range::InvalidRange()), | 996 composition_range_(Range::InvalidRange()), |
| 997 font_sizes_(0), |
| 968 colors_(kDefaultColor), | 998 colors_(kDefaultColor), |
| 969 baselines_(NORMAL_BASELINE), | 999 baselines_(NORMAL_BASELINE), |
| 970 styles_(NUM_TEXT_STYLES), | 1000 styles_(NUM_TEXT_STYLES), |
| 971 composition_and_selection_styles_applied_(false), | 1001 composition_and_selection_styles_applied_(false), |
| 972 obscured_(false), | 1002 obscured_(false), |
| 973 obscured_reveal_index_(-1), | 1003 obscured_reveal_index_(-1), |
| 974 truncate_length_(0), | 1004 truncate_length_(0), |
| 975 elide_behavior_(NO_ELIDE), | 1005 elide_behavior_(NO_ELIDE), |
| 976 text_elided_(false), | 1006 text_elided_(false), |
| 977 min_line_height_(0), | 1007 min_line_height_(0), |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 const int width = multiline_ ? | 1178 const int width = multiline_ ? |
| 1149 std::ceil(lines_[line_number].size.width()) + | 1179 std::ceil(lines_[line_number].size.width()) + |
| 1150 (cursor_enabled_ ? 1 : 0) : | 1180 (cursor_enabled_ ? 1 : 0) : |
| 1151 GetContentWidth(); | 1181 GetContentWidth(); |
| 1152 offset.set_x(display_rect().width() - width); | 1182 offset.set_x(display_rect().width() - width); |
| 1153 // Put any extra margin pixel on the left to match legacy behavior. | 1183 // Put any extra margin pixel on the left to match legacy behavior. |
| 1154 if (horizontal_alignment == ALIGN_CENTER) | 1184 if (horizontal_alignment == ALIGN_CENTER) |
| 1155 offset.set_x((offset.x() + 1) / 2); | 1185 offset.set_x((offset.x() + 1) / 2); |
| 1156 } | 1186 } |
| 1157 | 1187 |
| 1158 // Vertically center the text. | 1188 // Vertically align the text. |
| 1159 if (multiline_) { | 1189 if (multiline_) { |
| 1160 const int text_height = lines_.back().preceding_heights + | 1190 const int text_height = |
| 1161 lines_.back().size.height(); | 1191 lines_.back().preceding_heights + lines_.back().size.height(); |
| 1162 offset.set_y((display_rect_.height() - text_height) / 2); | 1192 if (vertical_alignment_ == VALIGN_TOP) { |
| 1193 offset.set_y(lines_.back().preceding_heights); |
| 1194 } else if (vertical_alignment_ == VALIGN_BOTTOM) { |
| 1195 offset.set_y(display_rect_.height() - text_height); |
| 1196 } else { |
| 1197 // Vertically center the text. |
| 1198 offset.set_y((display_rect_.height() - text_height) / 2); |
| 1199 } |
| 1163 } else { | 1200 } else { |
| 1164 offset.set_y(GetBaseline() - GetDisplayTextBaseline()); | 1201 if (vertical_alignment_ == VALIGN_TOP) { |
| 1202 offset.set_y(0); |
| 1203 } else if (vertical_alignment_ == VALIGN_BOTTOM) { |
| 1204 offset.set_y(display_rect_.height() - font_list_.GetHeight()); |
| 1205 } else { |
| 1206 // Vertically center the text. |
| 1207 offset.set_y(GetBaseline() - GetDisplayTextBaseline()); |
| 1208 } |
| 1165 } | 1209 } |
| 1166 | |
| 1167 return offset; | 1210 return offset; |
| 1168 } | 1211 } |
| 1169 | 1212 |
| 1170 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { | 1213 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { |
| 1171 const int width = display_rect().width(); | 1214 const int width = display_rect().width(); |
| 1172 if (multiline() || elide_behavior_ != FADE_TAIL || GetContentWidth() <= width) | 1215 if (multiline() || elide_behavior_ != FADE_TAIL || GetContentWidth() <= width) |
| 1173 return; | 1216 return; |
| 1174 | 1217 |
| 1175 const int gradient_width = CalculateFadeGradientWidth(font_list(), width); | 1218 const int gradient_width = CalculateFadeGradientWidth(font_list(), width); |
| 1176 if (gradient_width == 0) | 1219 if (gradient_width == 0) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 DCHECK(given_text == layout_text() || given_text == display_text()); | 1282 DCHECK(given_text == layout_text() || given_text == display_text()); |
| 1240 DCHECK_LE(index, text().length()); | 1283 DCHECK_LE(index, text().length()); |
| 1241 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; | 1284 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; |
| 1242 CHECK_GE(i, 0); | 1285 CHECK_GE(i, 0); |
| 1243 // Clamp indices to the length of the given layout or display text. | 1286 // Clamp indices to the length of the given layout or display text. |
| 1244 return std::min<size_t>(given_text.length(), i); | 1287 return std::min<size_t>(given_text.length(), i); |
| 1245 } | 1288 } |
| 1246 | 1289 |
| 1247 void RenderText::UpdateStyleLengths() { | 1290 void RenderText::UpdateStyleLengths() { |
| 1248 const size_t text_length = text_.length(); | 1291 const size_t text_length = text_.length(); |
| 1292 font_sizes_.SetMax(text_length); |
| 1249 colors_.SetMax(text_length); | 1293 colors_.SetMax(text_length); |
| 1250 baselines_.SetMax(text_length); | 1294 baselines_.SetMax(text_length); |
| 1251 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1295 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 1252 styles_[style].SetMax(text_length); | 1296 styles_[style].SetMax(text_length); |
| 1253 } | 1297 } |
| 1254 | 1298 |
| 1255 // static | 1299 // static |
| 1256 bool RenderText::RangeContainsCaret(const Range& range, | 1300 bool RenderText::RangeContainsCaret(const Range& range, |
| 1257 size_t caret_pos, | 1301 size_t caret_pos, |
| 1258 LogicalCursorDirection caret_affinity) { | 1302 LogicalCursorDirection caret_affinity) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 | 1388 |
| 1345 // Create a RenderText copy with attributes that affect the rendering width. | 1389 // Create a RenderText copy with attributes that affect the rendering width. |
| 1346 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); | 1390 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); |
| 1347 render_text->SetFontList(font_list_); | 1391 render_text->SetFontList(font_list_); |
| 1348 render_text->SetDirectionalityMode(directionality_mode_); | 1392 render_text->SetDirectionalityMode(directionality_mode_); |
| 1349 render_text->SetCursorEnabled(cursor_enabled_); | 1393 render_text->SetCursorEnabled(cursor_enabled_); |
| 1350 render_text->set_truncate_length(truncate_length_); | 1394 render_text->set_truncate_length(truncate_length_); |
| 1351 render_text->styles_ = styles_; | 1395 render_text->styles_ = styles_; |
| 1352 render_text->baselines_ = baselines_; | 1396 render_text->baselines_ = baselines_; |
| 1353 render_text->colors_ = colors_; | 1397 render_text->colors_ = colors_; |
| 1398 render_text->font_sizes_ = font_sizes_; |
| 1354 if (text_width == 0) { | 1399 if (text_width == 0) { |
| 1355 render_text->SetText(text); | 1400 render_text->SetText(text); |
| 1356 text_width = render_text->GetContentWidthF(); | 1401 text_width = render_text->GetContentWidthF(); |
| 1357 } | 1402 } |
| 1358 if (text_width <= available_width) | 1403 if (text_width <= available_width) |
| 1359 return text; | 1404 return text; |
| 1360 | 1405 |
| 1361 const base::string16 ellipsis = base::string16(kEllipsisUTF16); | 1406 const base::string16 ellipsis = base::string16(kEllipsisUTF16); |
| 1362 const bool insert_ellipsis = (behavior != TRUNCATE); | 1407 const bool insert_ellipsis = (behavior != TRUNCATE); |
| 1363 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); | 1408 const bool elide_in_middle = (behavior == ELIDE_MIDDLE); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 new_text += base::i18n::kRightToLeftMark; | 1446 new_text += base::i18n::kRightToLeftMark; |
| 1402 } | 1447 } |
| 1403 render_text->SetText(new_text); | 1448 render_text->SetText(new_text); |
| 1404 } | 1449 } |
| 1405 | 1450 |
| 1406 // Restore styles and baselines without breaking multi-character graphemes. | 1451 // Restore styles and baselines without breaking multi-character graphemes. |
| 1407 render_text->styles_ = styles_; | 1452 render_text->styles_ = styles_; |
| 1408 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1453 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 1409 RestoreBreakList(render_text.get(), render_text->styles_[style]); | 1454 RestoreBreakList(render_text.get(), render_text->styles_[style]); |
| 1410 RestoreBreakList(render_text.get(), baselines_); | 1455 RestoreBreakList(render_text.get(), baselines_); |
| 1456 RestoreBreakList(render_text.get(), font_sizes_); |
| 1411 | 1457 |
| 1412 // We check the width of the whole desired string at once to ensure we | 1458 // We check the width of the whole desired string at once to ensure we |
| 1413 // handle kerning/ligatures/etc. correctly. | 1459 // handle kerning/ligatures/etc. correctly. |
| 1414 const float guess_width = render_text->GetContentWidthF(); | 1460 const float guess_width = render_text->GetContentWidthF(); |
| 1415 if (guess_width == available_width) | 1461 if (guess_width == available_width) |
| 1416 break; | 1462 break; |
| 1417 if (guess_width > available_width) { | 1463 if (guess_width > available_width) { |
| 1418 hi = guess - 1; | 1464 hi = guess - 1; |
| 1419 // Move back on the loop terminating condition when the guess is too wide. | 1465 // Move back on the loop terminating condition when the guess is too wide. |
| 1420 if (hi < lo) | 1466 if (hi < lo) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1507 | 1553 |
| 1508 SetDisplayOffset(display_offset_.x() + delta_x); | 1554 SetDisplayOffset(display_offset_.x() + delta_x); |
| 1509 } | 1555 } |
| 1510 | 1556 |
| 1511 void RenderText::DrawSelection(Canvas* canvas) { | 1557 void RenderText::DrawSelection(Canvas* canvas) { |
| 1512 for (const Rect& s : GetSubstringBounds(selection())) | 1558 for (const Rect& s : GetSubstringBounds(selection())) |
| 1513 canvas->FillRect(s, selection_background_focused_color_); | 1559 canvas->FillRect(s, selection_background_focused_color_); |
| 1514 } | 1560 } |
| 1515 | 1561 |
| 1516 } // namespace gfx | 1562 } // namespace gfx |
| OLD | NEW |