1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/spellchecker/word_trimmer.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/i18n/break_iterator.h"
11
TrimWords(size_t * start,size_t end,const base::string16 & text,size_t keep)12 base::string16 TrimWords(size_t* start,
13 size_t end,
14 const base::string16& text,
15 size_t keep) {
16 if (*start > text.length() || *start > end)
17 return text;
18 base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD);
19 if (!iter.Init())
20 return text;
21 // A circular buffer of the last |keep + 1| words seen before position |start|
22 // in |text|.
23 std::vector<size_t> word_offset(keep + 1, 0);
24 size_t first = std::string::npos;
25 size_t last = std::string::npos;
26 while (iter.Advance()) {
27 if (iter.IsWord()) {
28 word_offset[keep] = iter.prev();
29 if ((*start >= iter.prev() && *start < iter.pos()) ||
30 (end > iter.prev() && end <= iter.pos())) {
31 if (first == std::string::npos)
32 first = word_offset[0];
33 last = iter.pos();
34 }
35 if (first == std::string::npos) {
36 std::rotate(word_offset.begin(),
37 word_offset.begin() + 1,
38 word_offset.end());
39 }
40 if (iter.prev() > end && keep) {
41 last = iter.pos();
42 keep--;
43 }
44 }
45 }
46 if (first == std::string::npos)
47 return text;
48 *start -= first;
49 return text.substr(first, last - first);
50 }
51