| 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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 Range(0, text_.length()).Contains(composition_range)); | 708 Range(0, text_.length()).Contains(composition_range)); |
| 701 composition_range_.set_end(composition_range.end()); | 709 composition_range_.set_end(composition_range.end()); |
| 702 composition_range_.set_start(composition_range.start()); | 710 composition_range_.set_start(composition_range.start()); |
| 703 // TODO(oshima|msw): Altering composition underlines shouldn't | 711 // TODO(oshima|msw): Altering composition underlines shouldn't |
| 704 // require layout changes. It's currently necessary because | 712 // require layout changes. It's currently necessary because |
| 705 // RenderTextHarfBuzz paints text decorations by run, and | 713 // RenderTextHarfBuzz paints text decorations by run, and |
| 706 // RenderTextMac applies all styles during layout. | 714 // RenderTextMac applies all styles during layout. |
| 707 OnLayoutTextAttributeChanged(false); | 715 OnLayoutTextAttributeChanged(false); |
| 708 } | 716 } |
| 709 | 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 |
| 710 void RenderText::SetColor(SkColor value) { | 730 void RenderText::SetColor(SkColor value) { |
| 711 colors_.SetValue(value); | 731 colors_.SetValue(value); |
| 712 } | 732 } |
| 713 | 733 |
| 714 void RenderText::ApplyColor(SkColor value, const Range& range) { | 734 void RenderText::ApplyColor(SkColor value, const Range& range) { |
| 715 colors_.ApplyValue(value, range); | 735 colors_.ApplyValue(value, range); |
| 716 } | 736 } |
| 717 | 737 |
| 718 void RenderText::SetBaselineStyle(BaselineStyle value) { | 738 void RenderText::SetBaselineStyle(BaselineStyle value) { |
| 719 baselines_.SetValue(value); | 739 baselines_.SetValue(value); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 directionality_mode_(DIRECTIONALITY_FROM_TEXT), | 987 directionality_mode_(DIRECTIONALITY_FROM_TEXT), |
| 968 text_direction_(base::i18n::UNKNOWN_DIRECTION), | 988 text_direction_(base::i18n::UNKNOWN_DIRECTION), |
| 969 cursor_enabled_(true), | 989 cursor_enabled_(true), |
| 970 cursor_visible_(false), | 990 cursor_visible_(false), |
| 971 insert_mode_(true), | 991 insert_mode_(true), |
| 972 cursor_color_(kDefaultColor), | 992 cursor_color_(kDefaultColor), |
| 973 selection_color_(kDefaultColor), | 993 selection_color_(kDefaultColor), |
| 974 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 994 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
| 975 focused_(false), | 995 focused_(false), |
| 976 composition_range_(Range::InvalidRange()), | 996 composition_range_(Range::InvalidRange()), |
| 997 font_sizes_(0), |
| 977 colors_(kDefaultColor), | 998 colors_(kDefaultColor), |
| 978 baselines_(NORMAL_BASELINE), | 999 baselines_(NORMAL_BASELINE), |
| 979 styles_(NUM_TEXT_STYLES), | 1000 styles_(NUM_TEXT_STYLES), |
| 980 composition_and_selection_styles_applied_(false), | 1001 composition_and_selection_styles_applied_(false), |
| 981 obscured_(false), | 1002 obscured_(false), |
| 982 obscured_reveal_index_(-1), | 1003 obscured_reveal_index_(-1), |
| 983 truncate_length_(0), | 1004 truncate_length_(0), |
| 984 elide_behavior_(NO_ELIDE), | 1005 elide_behavior_(NO_ELIDE), |
| 985 text_elided_(false), | 1006 text_elided_(false), |
| 986 min_line_height_(0), | 1007 min_line_height_(0), |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 DCHECK(given_text == layout_text() || given_text == display_text()); | 1282 DCHECK(given_text == layout_text() || given_text == display_text()); |
| 1262 DCHECK_LE(index, text().length()); | 1283 DCHECK_LE(index, text().length()); |
| 1263 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; | 1284 ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index; |
| 1264 CHECK_GE(i, 0); | 1285 CHECK_GE(i, 0); |
| 1265 // 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. |
| 1266 return std::min<size_t>(given_text.length(), i); | 1287 return std::min<size_t>(given_text.length(), i); |
| 1267 } | 1288 } |
| 1268 | 1289 |
| 1269 void RenderText::UpdateStyleLengths() { | 1290 void RenderText::UpdateStyleLengths() { |
| 1270 const size_t text_length = text_.length(); | 1291 const size_t text_length = text_.length(); |
| 1292 font_sizes_.SetMax(text_length); |
| 1271 colors_.SetMax(text_length); | 1293 colors_.SetMax(text_length); |
| 1272 baselines_.SetMax(text_length); | 1294 baselines_.SetMax(text_length); |
| 1273 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1295 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 1274 styles_[style].SetMax(text_length); | 1296 styles_[style].SetMax(text_length); |
| 1275 } | 1297 } |
| 1276 | 1298 |
| 1277 // static | 1299 // static |
| 1278 bool RenderText::RangeContainsCaret(const Range& range, | 1300 bool RenderText::RangeContainsCaret(const Range& range, |
| 1279 size_t caret_pos, | 1301 size_t caret_pos, |
| 1280 LogicalCursorDirection caret_affinity) { | 1302 LogicalCursorDirection caret_affinity) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 | 1388 |
| 1367 // Create a RenderText copy with attributes that affect the rendering width. | 1389 // Create a RenderText copy with attributes that affect the rendering width. |
| 1368 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); | 1390 scoped_ptr<RenderText> render_text = CreateInstanceOfSameType(); |
| 1369 render_text->SetFontList(font_list_); | 1391 render_text->SetFontList(font_list_); |
| 1370 render_text->SetDirectionalityMode(directionality_mode_); | 1392 render_text->SetDirectionalityMode(directionality_mode_); |
| 1371 render_text->SetCursorEnabled(cursor_enabled_); | 1393 render_text->SetCursorEnabled(cursor_enabled_); |
| 1372 render_text->set_truncate_length(truncate_length_); | 1394 render_text->set_truncate_length(truncate_length_); |
| 1373 render_text->styles_ = styles_; | 1395 render_text->styles_ = styles_; |
| 1374 render_text->baselines_ = baselines_; | 1396 render_text->baselines_ = baselines_; |
| 1375 render_text->colors_ = colors_; | 1397 render_text->colors_ = colors_; |
| 1398 render_text->font_sizes_ = font_sizes_; |
| 1376 if (text_width == 0) { | 1399 if (text_width == 0) { |
| 1377 render_text->SetText(text); | 1400 render_text->SetText(text); |
| 1378 text_width = render_text->GetContentWidthF(); | 1401 text_width = render_text->GetContentWidthF(); |
| 1379 } | 1402 } |
| 1380 if (text_width <= available_width) | 1403 if (text_width <= available_width) |
| 1381 return text; | 1404 return text; |
| 1382 | 1405 |
| 1383 const base::string16 ellipsis = base::string16(kEllipsisUTF16); | 1406 const base::string16 ellipsis = base::string16(kEllipsisUTF16); |
| 1384 const bool insert_ellipsis = (behavior != TRUNCATE); | 1407 const bool insert_ellipsis = (behavior != TRUNCATE); |
| 1385 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... |
| 1423 new_text += base::i18n::kRightToLeftMark; | 1446 new_text += base::i18n::kRightToLeftMark; |
| 1424 } | 1447 } |
| 1425 render_text->SetText(new_text); | 1448 render_text->SetText(new_text); |
| 1426 } | 1449 } |
| 1427 | 1450 |
| 1428 // Restore styles and baselines without breaking multi-character graphemes. | 1451 // Restore styles and baselines without breaking multi-character graphemes. |
| 1429 render_text->styles_ = styles_; | 1452 render_text->styles_ = styles_; |
| 1430 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1453 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 1431 RestoreBreakList(render_text.get(), render_text->styles_[style]); | 1454 RestoreBreakList(render_text.get(), render_text->styles_[style]); |
| 1432 RestoreBreakList(render_text.get(), render_text->baselines_); | 1455 RestoreBreakList(render_text.get(), render_text->baselines_); |
| 1456 RestoreBreakList(render_text.get(), render_text->font_sizes_); |
| 1433 | 1457 |
| 1434 // 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 |
| 1435 // handle kerning/ligatures/etc. correctly. | 1459 // handle kerning/ligatures/etc. correctly. |
| 1436 const float guess_width = render_text->GetContentWidthF(); | 1460 const float guess_width = render_text->GetContentWidthF(); |
| 1437 if (guess_width == available_width) | 1461 if (guess_width == available_width) |
| 1438 break; | 1462 break; |
| 1439 if (guess_width > available_width) { | 1463 if (guess_width > available_width) { |
| 1440 hi = guess - 1; | 1464 hi = guess - 1; |
| 1441 // 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. |
| 1442 if (hi < lo) | 1466 if (hi < lo) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 | 1553 |
| 1530 SetDisplayOffset(display_offset_.x() + delta_x); | 1554 SetDisplayOffset(display_offset_.x() + delta_x); |
| 1531 } | 1555 } |
| 1532 | 1556 |
| 1533 void RenderText::DrawSelection(Canvas* canvas) { | 1557 void RenderText::DrawSelection(Canvas* canvas) { |
| 1534 for (const Rect& s : GetSubstringBounds(selection())) | 1558 for (const Rect& s : GetSubstringBounds(selection())) |
| 1535 canvas->FillRect(s, selection_background_focused_color_); | 1559 canvas->FillRect(s, selection_background_focused_color_); |
| 1536 } | 1560 } |
| 1537 | 1561 |
| 1538 } // namespace gfx | 1562 } // namespace gfx |
| OLD | NEW |