1/*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Dominik Röttsches <dominik.roettsches@access-company.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "TextBoundaries.h"
29
30#include <unicode/ubrk.h>
31#include <wtf/text/StringImpl.h>
32#include <wtf/text/TextBreakIterator.h>
33
34namespace WebCore {
35
36unsigned endOfFirstWordBoundaryContext(StringView text)
37{
38 unsigned length = text.length();
39 for (unsigned i = 0; i < length; ) {
40 unsigned first = i;
41 UChar32 ch;
42 U16_NEXT(text, i, length, ch);
43 if (!requiresContextForWordBoundary(ch))
44 return first;
45 }
46 return length;
47}
48
49unsigned startOfLastWordBoundaryContext(StringView text)
50{
51 unsigned length = text.length();
52 for (unsigned i = length; i > 0; ) {
53 unsigned last = i;
54 UChar32 ch;
55 U16_PREV(text, 0, i, ch);
56 if (!requiresContextForWordBoundary(ch))
57 return last;
58 }
59 return 0;
60}
61
62#if !PLATFORM(COCOA)
63
64int findNextWordFromIndex(StringView text, int position, bool forward)
65{
66 UBreakIterator* it = wordBreakIterator(text);
67
68 if (forward) {
69 position = ubrk_following(it, position);
70 while (position != UBRK_DONE) {
71 // We stop searching when the character preceeding the break is alphanumeric.
72 if (static_cast<unsigned>(position) < text.length() && u_isalnum(text[position - 1]))
73 return position;
74
75 position = ubrk_following(it, position);
76 }
77
78 return text.length();
79 } else {
80 position = ubrk_preceding(it, position);
81 while (position != UBRK_DONE) {
82 // We stop searching when the character following the break is alphanumeric.
83 if (position && u_isalnum(text[position]))
84 return position;
85
86 position = ubrk_preceding(it, position);
87 }
88
89 return 0;
90 }
91}
92
93void findWordBoundary(StringView text, int position, int* start, int* end)
94{
95 UBreakIterator* it = wordBreakIterator(text);
96 *end = ubrk_following(it, position);
97 if (*end < 0)
98 *end = ubrk_last(it);
99 *start = ubrk_previous(it);
100}
101
102void findEndWordBoundary(StringView text, int position, int* end)
103{
104 UBreakIterator* it = wordBreakIterator(text);
105 *end = ubrk_following(it, position);
106 if (*end < 0)
107 *end = ubrk_last(it);
108}
109
110#endif // !PLATFORM(COCOA)
111
112} // namespace WebCore
113