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

Side by Side Diff: app/text_elider.cc

Issue 5964007: Last part of change for bug 49747.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years 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 | Annotate | Revision Log
« no previous file with comments | « app/text_elider.h ('k') | app/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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 <vector> 5 #include <vector>
6 6
7 #include "app/text_elider.h" 7 #include "app/text_elider.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "base/i18n/break_iterator.h"
10 #include "base/i18n/char_iterator.h"
9 #include "base/i18n/rtl.h" 11 #include "base/i18n/rtl.h"
10 #include "base/string_split.h" 12 #include "base/string_split.h"
11 #include "base/string_util.h" 13 #include "base/string_util.h"
12 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
13 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
14 #include "gfx/font.h" 16 #include "gfx/font.h"
15 #include "googleurl/src/gurl.h" 17 #include "googleurl/src/gurl.h"
16 #include "net/base/escape.h" 18 #include "net/base/escape.h"
17 #include "net/base/net_util.h" 19 #include "net/base/net_util.h"
18 #include "net/base/registry_controlled_domain.h" 20 #include "net/base/registry_controlled_domain.h"
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 output->assign(input.substr(0, lstr_len) + L"..." + 493 output->assign(input.substr(0, lstr_len) + L"..." +
492 input.substr(input.length() - rstr_len)); 494 input.substr(input.length() - rstr_len));
493 break; 495 break;
494 } 496 }
495 } 497 }
496 498
497 return true; 499 return true;
498 } 500 }
499 501
500 } // namespace gfx 502 } // namespace gfx
503
504 namespace {
505
506 // Internal class used to track progress of a rectangular string elide
507 // operation. Exists so the top-level ElideRectangleString() function
508 // can be broken into smaller methods sharing this state.
509 class RectangleString {
510 public:
511 RectangleString(size_t max_rows, size_t max_cols, string16 *output)
512 : max_rows_(max_rows),
513 max_cols_(max_cols),
514 current_row_(0),
515 current_col_(0),
516 suppressed_(false),
517 output_(output) {}
518
519 // Perform deferred initializions following creation. Must be called
520 // before any input can be added via AddString().
521 void Init() { output_->clear(); }
522
523 // Add an input string, reformatting to fit the desired dimensions.
524 // AddString() may be called multiple times to concatenate together
525 // multiple strings into the region (the current caller doesn't do
526 // this, however).
527 void AddString(const string16& input);
528
529 // Perform any deferred output processing. Must be called after the
530 // last AddString() call has occured.
531 bool Finalize();
532
533 private:
534 // Add a line to the rectangular region at the current position,
535 // either by itself or by breaking it into words.
536 void AddLine(const string16& line);
537
538 // Add a word to the rectangluar region at the current position,
539 // either by itelf or by breaking it into characters.
540 void AddWord(const string16& word);
541
542 // Add text to the output string if the rectangular boundaries
543 // have not been exceeded, advancing the current position.
544 void Append(const string16& string);
545
546 // Add a newline to the output string if the rectangular boundaries
547 // have not been exceeded, resetting the current position to the
548 // beginning of the next line.
549 void NewLine();
550
551 // Maximum number of rows allowed in the output string.
552 size_t max_rows_;
553
554 // Maximum number of characters allowed in the output string.
555 size_t max_cols_;
556
557 // Current row position, always incremented and may exceed max_rows_
558 // when the input can not fit in the region. We stop appending to
559 // the output string, however, when this condition occurs. In the
560 // future, we may want to expose this value to allow the caller to
561 // determine how many rows would actually be required to hold the
562 // formatted string.
563 size_t current_row_;
564
565 // Current character position, should never exceed max_cols_.
566 size_t current_col_;
567
568 // True when some of the input has been truncated.
569 bool suppressed_;
570
571 // String onto which the output is accumulated.
572 string16 *output_;
573 };
574
575 void RectangleString::AddString(const string16& input) {
576 base::BreakIterator lines(&input, base::BreakIterator::BREAK_NEWLINE);
577 if (lines.Init()) {
578 while (lines.Advance())
579 AddLine(lines.GetString());
580 } else {
581 NOTREACHED() << "BreakIterator (lines) init failed";
582 }
583 }
584
585 bool RectangleString::Finalize() {
586 if (suppressed_) {
587 output_->append(ASCIIToUTF16("..."));
588 return true;
589 }
590 return false;
591 }
592
593 void RectangleString::AddLine(const string16& line) {
594 if (line.length() < max_cols_) {
595 Append(line);
596 } else {
597 base::BreakIterator words(&line, base::BreakIterator::BREAK_SPACE);
598 if (words.Init()) {
599 while (words.Advance())
600 AddWord(words.GetString());
601 } else {
602 NOTREACHED() << "BreakIterator (words) init failed";
603 }
604 }
605 // Account for naturally-occuring newlines.
606 ++current_row_;
607 current_col_ = 0;
608 }
609
610 void RectangleString::AddWord(const string16& word) {
611 if (word.length() < max_cols_) {
612 // Word can be made to fit, no need to fragment it.
613 if (current_col_ + word.length() >= max_cols_)
614 NewLine();
615 Append(word);
616 } else {
617 // Word is so big that it must be fragmented.
618 int array_start = 0;
619 int char_start = 0;
620 base::UTF16CharIterator chars(&word);
621 while (!chars.end()) {
622 // When boundary is hit, add as much as will fit on this line.
623 if (current_col_ + (chars.char_pos() - char_start) >= max_cols_) {
624 Append(word.substr(array_start, chars.array_pos() - array_start));
625 NewLine();
626 array_start = chars.array_pos();
627 char_start = chars.char_pos();
628 }
629 chars.Advance();
630 }
631 // add last remaining fragment, if any.
632 if (array_start != chars.array_pos())
633 Append(word.substr(array_start, chars.array_pos() - array_start));
634 }
635 }
636
637 void RectangleString::Append(const string16& string) {
638 if (current_row_ < max_rows_)
639 output_->append(string);
640 else
641 suppressed_ = true;
642 current_col_ += string.length();
643 }
644
645 void RectangleString::NewLine() {
646 if (current_row_ < max_rows_)
647 output_->append(ASCIIToUTF16("\n"));
648 else
649 suppressed_ = true;
650 ++current_row_;
651 current_col_ = 0;
652 }
653
654 } // namespace
655
656 namespace gfx {
657
658 bool ElideRectangleString(const string16& input, size_t max_rows,
659 size_t max_cols, string16* output) {
660 RectangleString rect(max_rows, max_cols, output);
661 rect.Init();
662 rect.AddString(input);
663 return rect.Finalize();
664 }
665
666 } // namespace gfx
667
OLDNEW
« no previous file with comments | « app/text_elider.h ('k') | app/text_elider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698