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

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

Issue 614103007: Error in popup on Link (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: For testing Created 6 years, 2 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 | « no previous file | ui/gfx/text_elider_unittest.cc » ('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 // This file implements utility functions for eliding and formatting UI text. 5 // This file implements utility functions for eliding and formatting UI text.
6 // 6 //
7 // Note that several of the functions declared in text_elider.h are implemented 7 // Note that several of the functions declared in text_elider.h are implemented
8 // in this file using helper classes in an unnamed namespace. 8 // in this file using helper classes in an unnamed namespace.
9 9
10 #include "ui/gfx/text_elider.h" 10 #include "ui/gfx/text_elider.h"
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 RectangleText(const FontList& font_list, 470 RectangleText(const FontList& font_list,
471 float available_pixel_width, 471 float available_pixel_width,
472 int available_pixel_height, 472 int available_pixel_height,
473 WordWrapBehavior wrap_behavior, 473 WordWrapBehavior wrap_behavior,
474 std::vector<base::string16>* lines) 474 std::vector<base::string16>* lines)
475 : font_list_(font_list), 475 : font_list_(font_list),
476 line_height_(font_list.GetHeight()), 476 line_height_(font_list.GetHeight()),
477 available_pixel_width_(available_pixel_width), 477 available_pixel_width_(available_pixel_width),
478 available_pixel_height_(available_pixel_height), 478 available_pixel_height_(available_pixel_height),
479 wrap_behavior_(wrap_behavior), 479 wrap_behavior_(wrap_behavior),
480 current_width_(0),
481 current_height_(0), 480 current_height_(0),
482 last_line_ended_in_lf_(false), 481 last_line_ended_in_lf_(false),
483 lines_(lines), 482 lines_(lines),
484 insufficient_width_(false), 483 insufficient_width_(false),
485 insufficient_height_(false) {} 484 insufficient_height_(false) {}
486 485
487 // Perform deferred initializions following creation. Must be called 486 // Perform deferred initializions following creation. Must be called
488 // before any input can be added via AddString(). 487 // before any input can be added via AddString().
489 void Init() { lines_->clear(); } 488 void Init() { lines_->clear(); }
490 489
(...skipping 16 matching lines...) Expand all
507 506
508 // Wrap the specified word across multiple lines. 507 // Wrap the specified word across multiple lines.
509 int WrapWord(const base::string16& word); 508 int WrapWord(const base::string16& word);
510 509
511 // Add a long word - wrapping, eliding or truncating per the wrap behavior. 510 // Add a long word - wrapping, eliding or truncating per the wrap behavior.
512 int AddWordOverflow(const base::string16& word); 511 int AddWordOverflow(const base::string16& word);
513 512
514 // Add a word to the rectangluar region at the current position. 513 // Add a word to the rectangluar region at the current position.
515 int AddWord(const base::string16& word); 514 int AddWord(const base::string16& word);
516 515
517 // Append the specified |text| to the current output line, incrementing the
518 // running width by the specified amount. This is an optimization over
519 // |AddToCurrentLine()| when |text_width| is already known.
520 void AddToCurrentLineWithWidth(const base::string16& text, float text_width);
521
522 // Append the specified |text| to the current output line. 516 // Append the specified |text| to the current output line.
523 void AddToCurrentLine(const base::string16& text); 517 void AddToCurrentLine(const base::string16& text);
524 518
525 // Set the current position to the beginning of the next line. 519 // Set the current position to the beginning of the next line.
526 bool NewLine(); 520 bool NewLine();
527 521
528 // The font list used for measuring text width. 522 // The font list used for measuring text width.
529 const FontList& font_list_; 523 const FontList& font_list_;
530 524
531 // The height of each line of text. 525 // The height of each line of text.
532 const int line_height_; 526 const int line_height_;
533 527
534 // The number of pixels of available width in the rectangle. 528 // The number of pixels of available width in the rectangle.
535 const float available_pixel_width_; 529 const float available_pixel_width_;
536 530
537 // The number of pixels of available height in the rectangle. 531 // The number of pixels of available height in the rectangle.
538 const int available_pixel_height_; 532 const int available_pixel_height_;
539 533
540 // The wrap behavior for words that are too long to fit on a single line. 534 // The wrap behavior for words that are too long to fit on a single line.
541 const WordWrapBehavior wrap_behavior_; 535 const WordWrapBehavior wrap_behavior_;
542 536
543 // The current running width.
544 float current_width_;
545
546 // The current running height. 537 // The current running height.
547 int current_height_; 538 int current_height_;
548 539
549 // The current line of text. 540 // The current line of text.
550 base::string16 current_line_; 541 base::string16 current_line_;
551 542
552 // Indicates whether the last line ended with \n. 543 // Indicates whether the last line ended with \n.
553 bool last_line_ended_in_lf_; 544 bool last_line_ended_in_lf_;
554 545
555 // The output vector of lines. 546 // The output vector of lines.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 } 585 }
595 if (last_line_ended_in_lf_) 586 if (last_line_ended_in_lf_)
596 lines_->push_back(base::string16()); 587 lines_->push_back(base::string16());
597 return (insufficient_width_ ? INSUFFICIENT_SPACE_HORIZONTAL : 0) | 588 return (insufficient_width_ ? INSUFFICIENT_SPACE_HORIZONTAL : 0) |
598 (insufficient_height_ ? INSUFFICIENT_SPACE_VERTICAL : 0); 589 (insufficient_height_ ? INSUFFICIENT_SPACE_VERTICAL : 0);
599 } 590 }
600 591
601 void RectangleText::AddLine(const base::string16& line) { 592 void RectangleText::AddLine(const base::string16& line) {
602 const float line_width = GetStringWidthF(line, font_list_); 593 const float line_width = GetStringWidthF(line, font_list_);
603 if (line_width <= available_pixel_width_) { 594 if (line_width <= available_pixel_width_) {
604 AddToCurrentLineWithWidth(line, line_width); 595 AddToCurrentLine(line);
605 } else { 596 } else {
606 // Iterate over positions that are valid to break the line at. In general, 597 // Iterate over positions that are valid to break the line at. In general,
607 // these are word boundaries but after any punctuation following the word. 598 // these are word boundaries but after any punctuation following the word.
608 base::i18n::BreakIterator words(line, 599 base::i18n::BreakIterator words(line,
609 base::i18n::BreakIterator::BREAK_LINE); 600 base::i18n::BreakIterator::BREAK_LINE);
610 if (words.Init()) { 601 if (words.Init()) {
611 while (words.Advance()) { 602 while (words.Advance()) {
612 const bool truncate = !current_line_.empty(); 603 const bool truncate = !current_line_.empty();
613 const base::string16& word = words.GetString(); 604 const base::string16& word = words.GetString();
614 const int lines_added = AddWord(word); 605 const int lines_added = AddWord(word);
615 if (lines_added) { 606 if (lines_added) {
616 if (truncate) { 607 if (truncate) {
617 // Trim trailing whitespace from the line that was added. 608 // Trim trailing whitespace from the line that was added.
618 const int line = lines_->size() - lines_added; 609 const int line = lines_->size() - lines_added;
619 base::TrimWhitespace(lines_->at(line), base::TRIM_TRAILING, 610 base::TrimWhitespace(lines_->at(line), base::TRIM_TRAILING,
620 &lines_->at(line)); 611 &lines_->at(line));
621 } 612 }
622 if (base::ContainsOnlyChars(word, base::kWhitespaceUTF16)) { 613 if (base::ContainsOnlyChars(word, base::kWhitespaceUTF16)) {
623 // Skip the first space if the previous line was carried over. 614 // Skip the first space if the previous line was carried over.
624 current_width_ = 0;
625 current_line_.clear(); 615 current_line_.clear();
626 } 616 }
627 } 617 }
628 } 618 }
629 } else { 619 } else {
630 NOTREACHED() << "BreakIterator (words) init failed"; 620 NOTREACHED() << "BreakIterator (words) init failed";
631 } 621 }
632 } 622 }
633 // Account for naturally-occuring newlines. 623 // Account for naturally-occuring newlines.
634 NewLine(); 624 NewLine();
(...skipping 25 matching lines...) Expand all
660 650
661 // Unless this is the very first word, put it on a new line. 651 // Unless this is the very first word, put it on a new line.
662 if (!current_line_.empty()) { 652 if (!current_line_.empty()) {
663 if (!NewLine()) 653 if (!NewLine())
664 return 0; 654 return 0;
665 lines_added++; 655 lines_added++;
666 } 656 }
667 657
668 if (wrap_behavior_ == IGNORE_LONG_WORDS) { 658 if (wrap_behavior_ == IGNORE_LONG_WORDS) {
669 current_line_ = word; 659 current_line_ = word;
670 current_width_ = available_pixel_width_;
671 } else if (wrap_behavior_ == WRAP_LONG_WORDS) { 660 } else if (wrap_behavior_ == WRAP_LONG_WORDS) {
672 lines_added += WrapWord(word); 661 lines_added += WrapWord(word);
673 } else { 662 } else {
674 const ElideBehavior elide_behavior = 663 const ElideBehavior elide_behavior =
675 (wrap_behavior_ == ELIDE_LONG_WORDS ? ELIDE_TAIL : TRUNCATE); 664 (wrap_behavior_ == ELIDE_LONG_WORDS ? ELIDE_TAIL : TRUNCATE);
676 const base::string16 elided_word = 665 const base::string16 elided_word =
677 ElideText(word, font_list_, available_pixel_width_, elide_behavior); 666 ElideText(word, font_list_, available_pixel_width_, elide_behavior);
678 AddToCurrentLine(elided_word); 667 AddToCurrentLine(elided_word);
679 insufficient_width_ = true; 668 insufficient_width_ = true;
680 } 669 }
681 670
682 return lines_added; 671 return lines_added;
683 } 672 }
684 673
685 int RectangleText::AddWord(const base::string16& word) { 674 int RectangleText::AddWord(const base::string16& word) {
686 int lines_added = 0; 675 int lines_added = 0;
687 base::string16 trimmed; 676 base::string16 trimmed;
688 base::TrimWhitespace(word, base::TRIM_TRAILING, &trimmed); 677 base::TrimWhitespace(word, base::TRIM_TRAILING, &trimmed);
689 const float trimmed_width = GetStringWidthF(trimmed, font_list_); 678 const float trimmed_width = GetStringWidthF(trimmed, font_list_);
690 if (trimmed_width <= available_pixel_width_) { 679 if (trimmed_width <= available_pixel_width_) {
691 // Word can be made to fit, no need to fragment it. 680 // Word can be made to fit, no need to fragment it.
692 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) 681 base::string16 line_with_new_word(current_line_);
682 line_with_new_word.append(trimmed);
683 float new_width = GetStringWidthF(line_with_new_word, font_list_);
684 // We can't just add trimmed_width to current_width and compare it to
685 // available_pixel_width. Sometimes sum of widths of two strings is not
686 // equal to width of concatenation of these strings (see crbug.com/415213).
687 if ((new_width > available_pixel_width_) && NewLine())
693 lines_added++; 688 lines_added++;
694 // Append the non-trimmed word, in case more words are added after. 689 // Append the non-trimmed word, in case more words are added after.
695 AddToCurrentLine(word); 690 AddToCurrentLine(word);
696 } else { 691 } else {
697 lines_added = AddWordOverflow(wrap_behavior_ == IGNORE_LONG_WORDS ? 692 lines_added = AddWordOverflow(wrap_behavior_ == IGNORE_LONG_WORDS ?
698 trimmed : word); 693 trimmed : word);
699 } 694 }
700 return lines_added; 695 return lines_added;
701 } 696 }
702 697
703 void RectangleText::AddToCurrentLine(const base::string16& text) { 698 void RectangleText::AddToCurrentLine(const base::string16& text) {
704 AddToCurrentLineWithWidth(text, GetStringWidthF(text, font_list_));
705 }
706
707 void RectangleText::AddToCurrentLineWithWidth(const base::string16& text,
708 float text_width) {
709 if (current_height_ >= available_pixel_height_) { 699 if (current_height_ >= available_pixel_height_) {
710 insufficient_height_ = true; 700 insufficient_height_ = true;
711 return; 701 return;
712 } 702 }
713 current_line_.append(text); 703 current_line_.append(text);
714 current_width_ += text_width;
715 } 704 }
716 705
717 bool RectangleText::NewLine() { 706 bool RectangleText::NewLine() {
718 bool line_added = false; 707 bool line_added = false;
719 if (current_height_ < available_pixel_height_) { 708 if (current_height_ < available_pixel_height_) {
720 lines_->push_back(current_line_); 709 lines_->push_back(current_line_);
721 current_line_.clear(); 710 current_line_.clear();
722 line_added = true; 711 line_added = true;
723 } else { 712 } else {
724 insufficient_height_ = true; 713 insufficient_height_ = true;
725 } 714 }
726 current_height_ += line_height_; 715 current_height_ += line_height_;
727 current_width_ = 0;
728 return line_added; 716 return line_added;
729 } 717 }
730 718
731 } // namespace 719 } // namespace
732 720
733 bool ElideRectangleString(const base::string16& input, size_t max_rows, 721 bool ElideRectangleString(const base::string16& input, size_t max_rows,
734 size_t max_cols, bool strict, 722 size_t max_cols, bool strict,
735 base::string16* output) { 723 base::string16* output) {
736 RectangleString rect(max_rows, max_cols, strict, output); 724 RectangleString rect(max_rows, max_cols, strict, output);
737 rect.Init(); 725 rect.Init();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 index = char_iterator.getIndex(); 803 index = char_iterator.getIndex();
816 } else { 804 } else {
817 // String has leading whitespace, return the elide string. 805 // String has leading whitespace, return the elide string.
818 return kElideString; 806 return kElideString;
819 } 807 }
820 808
821 return string.substr(0, index) + kElideString; 809 return string.substr(0, index) + kElideString;
822 } 810 }
823 811
824 } // namespace gfx 812 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/text_elider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698