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