summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/text
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/text')
-rw-r--r--Source/WebCore/platform/text/BidiResolver.h238
-rw-r--r--Source/WebCore/platform/text/BidiRunList.h209
-rw-r--r--Source/WebCore/platform/text/LocalizedNumberICU.cpp1
-rw-r--r--Source/WebCore/platform/text/StringWithDirection.h79
-rw-r--r--Source/WebCore/platform/text/TextCheckerClient.h15
-rw-r--r--Source/WebCore/platform/text/TextChecking.h12
-rw-r--r--Source/WebCore/platform/text/UnicodeBidi.h40
7 files changed, 392 insertions, 202 deletions
diff --git a/Source/WebCore/platform/text/BidiResolver.h b/Source/WebCore/platform/text/BidiResolver.h
index 5b92ee2..c6efdd8 100644
--- a/Source/WebCore/platform/text/BidiResolver.h
+++ b/Source/WebCore/platform/text/BidiResolver.h
@@ -23,6 +23,7 @@
#define BidiResolver_h
#include "BidiContext.h"
+#include "BidiRunList.h"
#include <wtf/Noncopyable.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
@@ -147,17 +148,15 @@ enum VisualDirectionOverride {
VisualRightToLeftOverride
};
+// BidiResolver is WebKit's implementation of the Unicode Bidi Algorithm
+// http://unicode.org/reports/tr9
template <class Iterator, class Run> class BidiResolver {
WTF_MAKE_NONCOPYABLE(BidiResolver);
public:
BidiResolver()
: m_direction(WTF::Unicode::OtherNeutral)
, m_reachedEndOfLine(false)
- , emptyRun(true)
- , m_firstRun(0)
- , m_lastRun(0)
- , m_logicallyLastRun(0)
- , m_runCount(0)
+ , m_emptyRun(true)
{
}
@@ -186,22 +185,16 @@ public:
void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = NoVisualOverride, bool hardLineBreak = false);
- Run* firstRun() const { return m_firstRun; }
- Run* lastRun() const { return m_lastRun; }
- Run* logicallyLastRun() const { return m_logicallyLastRun; }
- unsigned runCount() const { return m_runCount; }
+ BidiRunList<Run>& runs() { return m_runs; }
- void addRun(Run*);
- void prependRun(Run*);
-
- void moveRunToEnd(Run*);
- void moveRunToBeginning(Run*);
-
- void deleteRuns();
+ // FIXME: This used to be part of deleteRuns() but was a layering violation.
+ // It's unclear if this is still needed.
+ void markCurrentRunEmpty() { m_emptyRun = true; }
protected:
+ // FIXME: Instead of InlineBidiResolvers subclassing this method, we should
+ // pass in some sort of Traits object which knows how to create runs for appending.
void appendRun();
- void reverseRuns(unsigned start, unsigned end);
Iterator m_current;
// sor and eor are "start of run" and "end of run" respectively and correpond
@@ -213,13 +206,13 @@ protected:
WTF::Unicode::Direction m_direction;
Iterator endOfLine;
bool m_reachedEndOfLine;
- Iterator lastBeforeET;
- bool emptyRun;
+ Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator
+ bool m_emptyRun;
+
+ // FIXME: This should not belong to the resolver, but rather be passed
+ // into createBidiRunsForLine by the caller.
+ BidiRunList<Run> m_runs;
- Run* m_firstRun;
- Run* m_lastRun;
- Run* m_logicallyLastRun;
- unsigned m_runCount;
MidpointState<Iterator> m_midpointState;
private:
@@ -234,79 +227,9 @@ private:
};
template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::addRun(Run* run)
-{
- if (!m_firstRun)
- m_firstRun = run;
- else
- m_lastRun->m_next = run;
- m_lastRun = run;
- m_runCount++;
-}
-
-template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::prependRun(Run* run)
-{
- ASSERT(!run->m_next);
-
- if (!m_lastRun)
- m_lastRun = run;
- else
- run->m_next = m_firstRun;
- m_firstRun = run;
- m_runCount++;
-}
-
-template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::moveRunToEnd(Run* run)
-{
- ASSERT(m_firstRun);
- ASSERT(m_lastRun);
- ASSERT(run->m_next);
-
- Run* current = 0;
- Run* next = m_firstRun;
- while (next != run) {
- current = next;
- next = current->next();
- }
-
- if (!current)
- m_firstRun = run->next();
- else
- current->m_next = run->m_next;
-
- run->m_next = 0;
- m_lastRun->m_next = run;
- m_lastRun = run;
-}
-
-template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::moveRunToBeginning(Run* run)
-{
- ASSERT(m_firstRun);
- ASSERT(m_lastRun);
- ASSERT(run != m_firstRun);
-
- Run* current = m_firstRun;
- Run* next = current->next();
- while (next != run) {
- current = next;
- next = current->next();
- }
-
- current->m_next = run->m_next;
- if (run == m_lastRun)
- m_lastRun = current;
-
- run->m_next = m_firstRun;
- m_firstRun = run;
-}
-
-template <class Iterator, class Run>
void BidiResolver<Iterator, Run>::appendRun()
{
- if (!emptyRun && !m_eor.atEnd()) {
+ if (!m_emptyRun && !m_eor.atEnd()) {
unsigned startOffset = m_sor.offset();
unsigned endOffset = m_eor.offset();
@@ -316,7 +239,7 @@ void BidiResolver<Iterator, Run>::appendRun()
}
if (endOffset >= startOffset)
- addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
+ m_runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
m_eor.increment();
m_sor = m_eor;
@@ -357,7 +280,7 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire
{
using namespace WTF::Unicode;
- if (!emptyRun && m_eor != m_last) {
+ if (!m_emptyRun && m_eor != m_last) {
checkDirectionInLowerRaiseEmbeddingLevel();
// bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
if (from == LeftToRight) {
@@ -380,8 +303,10 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire
}
m_eor = m_last;
}
+
appendRun();
- emptyRun = true;
+ m_emptyRun = true;
+
// sor for the new run is determined by the higher level (rule X10)
setLastDir(from);
setLastStrongDir(from);
@@ -393,7 +318,7 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
{
using namespace WTF::Unicode;
- if (!emptyRun && m_eor != m_last) {
+ if (!m_emptyRun && m_eor != m_last) {
checkDirectionInLowerRaiseEmbeddingLevel();
// bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
if (to == LeftToRight) {
@@ -418,8 +343,10 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
}
m_eor = m_last;
}
+
appendRun();
- emptyRun = true;
+ m_emptyRun = true;
+
setLastDir(to);
setLastStrongDir(to);
m_eor = Iterator();
@@ -466,75 +393,6 @@ bool BidiResolver<Iterator, Run>::commitExplicitEmbedding()
}
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::deleteRuns()
-{
- emptyRun = true;
- if (!m_firstRun)
- return;
-
- Run* curr = m_firstRun;
- while (curr) {
- Run* s = curr->next();
- curr->destroy();
- curr = s;
- }
-
- m_firstRun = 0;
- m_lastRun = 0;
- m_runCount = 0;
-}
-
-template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::reverseRuns(unsigned start, unsigned end)
-{
- if (start >= end)
- return;
-
- ASSERT(end < m_runCount);
-
- // Get the item before the start of the runs to reverse and put it in
- // |beforeStart|. |curr| should point to the first run to reverse.
- Run* curr = m_firstRun;
- Run* beforeStart = 0;
- unsigned i = 0;
- while (i < start) {
- i++;
- beforeStart = curr;
- curr = curr->next();
- }
-
- Run* startRun = curr;
- while (i < end) {
- i++;
- curr = curr->next();
- }
- Run* endRun = curr;
- Run* afterEnd = curr->next();
-
- i = start;
- curr = startRun;
- Run* newNext = afterEnd;
- while (i <= end) {
- // Do the reversal.
- Run* next = curr->next();
- curr->m_next = newNext;
- newNext = curr;
- curr = next;
- i++;
- }
-
- // Now hook up beforeStart and afterEnd to the startRun and endRun.
- if (beforeStart)
- beforeStart->m_next = endRun;
- else
- m_firstRun = endRun;
-
- startRun->m_next = afterEnd;
- if (!afterEnd)
- m_lastRun = startRun;
-}
-
-template <class Iterator, class Run>
inline void BidiResolver<Iterator, Run>::updateStatusLastFromCurrentDirection(WTF::Unicode::Direction dirCurrent)
{
using namespace WTF::Unicode;
@@ -581,7 +439,7 @@ inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
{
unsigned char levelLow = 128;
unsigned char levelHigh = 0;
- for (Run* run = firstRun(); run; run = run->next()) {
+ for (Run* run = m_runs.firstRun(); run; run = run->next()) {
levelHigh = std::max(run->level(), levelHigh);
levelLow = std::min(run->level(), levelLow);
}
@@ -595,11 +453,11 @@ inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
if (!(levelLow % 2))
levelLow++;
- unsigned count = runCount() - 1;
+ unsigned count = m_runs.runCount() - 1;
while (levelHigh >= levelLow) {
unsigned i = 0;
- Run* run = firstRun();
+ Run* run = m_runs.firstRun();
while (i < count) {
for (;i < count && run && run->level() < levelHigh; i++)
run = run->next();
@@ -607,7 +465,7 @@ inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
for (;i <= count && run && run->level() >= levelHigh; i++)
run = run->next();
unsigned end = i - 1;
- reverseRuns(start, end);
+ m_runs.reverseRuns(start, end);
}
levelHigh--;
}
@@ -621,7 +479,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
ASSERT(m_direction == OtherNeutral);
if (override != NoVisualOverride) {
- emptyRun = false;
+ m_emptyRun = false;
m_sor = m_current;
m_eor = Iterator();
while (m_current != end && !m_current.atEnd()) {
@@ -630,13 +488,13 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
m_direction = override == VisualLeftToRightOverride ? LeftToRight : RightToLeft;
appendRun();
- m_logicallyLastRun = m_lastRun;
+ m_runs.setLogicallyLastRun(m_runs.lastRun());
if (override == VisualRightToLeftOverride)
- reverseRuns(0, runCount() - 1);
+ m_runs.reverseRuns(0, m_runs.runCount() - 1);
return;
}
- emptyRun = true;
+ m_emptyRun = true;
m_eor = Iterator();
@@ -818,7 +676,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
// Terminate the EN run.
appendRun();
// Make an R run.
- m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -829,7 +687,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
appendRun();
if (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft) {
// Make an R run.
- m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -837,7 +695,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
} else if (m_status.lastStrong == RightToLeft) {
// Extend the R run to include the neutrals.
- m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -905,7 +763,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_eor = m_current;
m_status.eor = dirCurrent;
} else if (m_status.last != EuropeanNumberTerminator)
- lastBeforeET = emptyRun ? m_eor : m_last;
+ m_lastBeforeET = m_emptyRun ? m_eor : m_last;
break;
// boundary neutrals should be ignored
@@ -951,8 +809,8 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_eor = stateAtEnd.m_eor;
m_last = stateAtEnd.m_last;
m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine;
- lastBeforeET = stateAtEnd.lastBeforeET;
- emptyRun = stateAtEnd.emptyRun;
+ m_lastBeforeET = stateAtEnd.m_lastBeforeET;
+ m_emptyRun = stateAtEnd.m_emptyRun;
m_direction = OtherNeutral;
break;
}
@@ -960,9 +818,9 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
updateStatusLastFromCurrentDirection(dirCurrent);
m_last = m_current;
- if (emptyRun) {
+ if (m_emptyRun) {
m_sor = m_current;
- emptyRun = false;
+ m_emptyRun = false;
}
increment();
@@ -975,29 +833,29 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_eor = stateAtEnd.m_eor;
m_last = stateAtEnd.m_last;
m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine;
- lastBeforeET = stateAtEnd.lastBeforeET;
- emptyRun = stateAtEnd.emptyRun;
+ m_lastBeforeET = stateAtEnd.m_lastBeforeET;
+ m_emptyRun = stateAtEnd.m_emptyRun;
m_direction = OtherNeutral;
break;
}
}
if (!pastEnd && (m_current == end || m_current.atEnd())) {
- if (emptyRun)
+ if (m_emptyRun)
break;
stateAtEnd.m_status = m_status;
stateAtEnd.m_sor = m_sor;
stateAtEnd.m_eor = m_eor;
stateAtEnd.m_last = m_last;
stateAtEnd.m_reachedEndOfLine = m_reachedEndOfLine;
- stateAtEnd.lastBeforeET = lastBeforeET;
- stateAtEnd.emptyRun = emptyRun;
+ stateAtEnd.m_lastBeforeET = m_lastBeforeET;
+ stateAtEnd.m_emptyRun = m_emptyRun;
endOfLine = m_last;
pastEnd = true;
}
}
- m_logicallyLastRun = m_lastRun;
+ m_runs.setLogicallyLastRun(m_runs.lastRun());
reorderRunsFromLevels();
endOfLine = Iterator();
}
diff --git a/Source/WebCore/platform/text/BidiRunList.h b/Source/WebCore/platform/text/BidiRunList.h
new file mode 100644
index 0000000..a4aa3c2
--- /dev/null
+++ b/Source/WebCore/platform/text/BidiRunList.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved.
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BidiRunList_h
+#define BidiRunList_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+template <class Run>
+class BidiRunList {
+ WTF_MAKE_NONCOPYABLE(BidiRunList);
+public:
+ BidiRunList()
+ : m_firstRun(0)
+ , m_lastRun(0)
+ , m_logicallyLastRun(0)
+ , m_runCount(0)
+ {
+ }
+
+ // FIXME: Once BidiResolver no longer owns the BidiRunList,
+ // then ~BidiRunList should call deleteRuns() automatically.
+
+ Run* firstRun() const { return m_firstRun; }
+ Run* lastRun() const { return m_lastRun; }
+ Run* logicallyLastRun() const { return m_logicallyLastRun; }
+ unsigned runCount() const { return m_runCount; }
+
+ void addRun(Run*);
+ void prependRun(Run*);
+
+ void moveRunToEnd(Run*);
+ void moveRunToBeginning(Run*);
+
+ void deleteRuns();
+ void reverseRuns(unsigned start, unsigned end);
+ void reorderRunsFromLevels();
+
+ void setLogicallyLastRun(Run* run) { m_logicallyLastRun = run; }
+
+private:
+ Run* m_firstRun;
+ Run* m_lastRun;
+ Run* m_logicallyLastRun;
+ unsigned m_runCount;
+};
+
+template <class Run>
+inline void BidiRunList<Run>::addRun(Run* run)
+{
+ if (!m_firstRun)
+ m_firstRun = run;
+ else
+ m_lastRun->m_next = run;
+ m_lastRun = run;
+ m_runCount++;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::prependRun(Run* run)
+{
+ ASSERT(!run->m_next);
+
+ if (!m_lastRun)
+ m_lastRun = run;
+ else
+ run->m_next = m_firstRun;
+ m_firstRun = run;
+ m_runCount++;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::moveRunToEnd(Run* run)
+{
+ ASSERT(m_firstRun);
+ ASSERT(m_lastRun);
+ ASSERT(run->m_next);
+
+ Run* current = 0;
+ Run* next = m_firstRun;
+ while (next != run) {
+ current = next;
+ next = current->next();
+ }
+
+ if (!current)
+ m_firstRun = run->next();
+ else
+ current->m_next = run->m_next;
+
+ run->m_next = 0;
+ m_lastRun->m_next = run;
+ m_lastRun = run;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::moveRunToBeginning(Run* run)
+{
+ ASSERT(m_firstRun);
+ ASSERT(m_lastRun);
+ ASSERT(run != m_firstRun);
+
+ Run* current = m_firstRun;
+ Run* next = current->next();
+ while (next != run) {
+ current = next;
+ next = current->next();
+ }
+
+ current->m_next = run->m_next;
+ if (run == m_lastRun)
+ m_lastRun = current;
+
+ run->m_next = m_firstRun;
+ m_firstRun = run;
+}
+
+template <class Run>
+void BidiRunList<Run>::deleteRuns()
+{
+ if (!m_firstRun)
+ return;
+
+ Run* curr = m_firstRun;
+ while (curr) {
+ Run* s = curr->next();
+ curr->destroy();
+ curr = s;
+ }
+
+ m_firstRun = 0;
+ m_lastRun = 0;
+ m_runCount = 0;
+}
+
+template <class Run>
+void BidiRunList<Run>::reverseRuns(unsigned start, unsigned end)
+{
+ if (start >= end)
+ return;
+
+ ASSERT(end < m_runCount);
+
+ // Get the item before the start of the runs to reverse and put it in
+ // |beforeStart|. |curr| should point to the first run to reverse.
+ Run* curr = m_firstRun;
+ Run* beforeStart = 0;
+ unsigned i = 0;
+ while (i < start) {
+ i++;
+ beforeStart = curr;
+ curr = curr->next();
+ }
+
+ Run* startRun = curr;
+ while (i < end) {
+ i++;
+ curr = curr->next();
+ }
+ Run* endRun = curr;
+ Run* afterEnd = curr->next();
+
+ i = start;
+ curr = startRun;
+ Run* newNext = afterEnd;
+ while (i <= end) {
+ // Do the reversal.
+ Run* next = curr->next();
+ curr->m_next = newNext;
+ newNext = curr;
+ curr = next;
+ i++;
+ }
+
+ // Now hook up beforeStart and afterEnd to the startRun and endRun.
+ if (beforeStart)
+ beforeStart->m_next = endRun;
+ else
+ m_firstRun = endRun;
+
+ startRun->m_next = afterEnd;
+ if (!afterEnd)
+ m_lastRun = startRun;
+}
+
+} // namespace WebCore
+
+#endif // BidiRunList
diff --git a/Source/WebCore/platform/text/LocalizedNumberICU.cpp b/Source/WebCore/platform/text/LocalizedNumberICU.cpp
index 7c4b1cb..da16262 100644
--- a/Source/WebCore/platform/text/LocalizedNumberICU.cpp
+++ b/Source/WebCore/platform/text/LocalizedNumberICU.cpp
@@ -37,6 +37,7 @@
#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
+using namespace icu;
using namespace std;
namespace WebCore {
diff --git a/Source/WebCore/platform/text/StringWithDirection.h b/Source/WebCore/platform/text/StringWithDirection.h
new file mode 100644
index 0000000..3302f81
--- /dev/null
+++ b/Source/WebCore/platform/text/StringWithDirection.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StringWithDirection_h
+#define StringWithDirection_h
+
+#include "PlatformString.h"
+#include "TextDirection.h"
+
+namespace WebCore {
+
+// In some circumstances we want to store a String along with the TextDirection
+// of the String as learned from the context of the String. For example,
+// consider storing the title derived from <title dir='rtl'>some title</title>
+// in the history.
+//
+// Note that is explicitly *not* the direction of the string as learned
+// from the characters of the string; it's extra metadata we have external
+// to the string.
+class StringWithDirection {
+public:
+ StringWithDirection()
+ : m_direction(LTR)
+ {
+ }
+
+ StringWithDirection(const String& string, TextDirection dir)
+ : m_string(string)
+ , m_direction(dir)
+ {
+ }
+
+ const String& string() const { return m_string; }
+ TextDirection direction() const { return m_direction; }
+
+ bool isEmpty() const { return m_string.isEmpty(); }
+ bool isNull() const { return m_string.isNull(); }
+
+ bool operator==(const StringWithDirection& other) const
+ {
+ return other.m_string == m_string && other.m_direction == m_direction;
+ }
+ bool operator!=(const StringWithDirection& other) const { return !((*this) == other); }
+
+private:
+ String m_string;
+ TextDirection m_direction;
+};
+
+}
+
+#endif // StringWithDirection_h
diff --git a/Source/WebCore/platform/text/TextCheckerClient.h b/Source/WebCore/platform/text/TextCheckerClient.h
index 8abbed4..d16ade1 100644
--- a/Source/WebCore/platform/text/TextCheckerClient.h
+++ b/Source/WebCore/platform/text/TextCheckerClient.h
@@ -45,16 +45,6 @@ struct GrammarDetail {
String userDescription;
};
-enum TextCheckingType {
- TextCheckingTypeSpelling = 1 << 1,
- TextCheckingTypeGrammar = 1 << 2,
- TextCheckingTypeLink = 1 << 5,
- TextCheckingTypeQuote = 1 << 6,
- TextCheckingTypeDash = 1 << 7,
- TextCheckingTypeReplacement = 1 << 8,
- TextCheckingTypeCorrection = 1 << 9
-};
-
struct TextCheckingResult {
TextCheckingType type;
int location;
@@ -72,15 +62,16 @@ public:
virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0;
virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) = 0;
virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0;
+
#if USE(UNIFIED_TEXT_CHECKING)
- virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) = 0;
+ virtual void checkTextOfParagraph(const UChar* text, int length, TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results) = 0;
#endif
// For spellcheckers that support multiple languages, it's often important to be able to identify the language in order to
// provide more accurate correction suggestions. Caller can pass in more text in "context" to aid such spellcheckers on language
// identification. Noramlly it's the text surrounding the "word" for which we are getting correction suggestions.
virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) = 0;
- virtual void requestCheckingOfString(SpellChecker*, int, const String&) = 0;
+ virtual void requestCheckingOfString(SpellChecker*, int, TextCheckingTypeMask, const String&) = 0;
};
}
diff --git a/Source/WebCore/platform/text/TextChecking.h b/Source/WebCore/platform/text/TextChecking.h
index 022fb82..d2040d5 100644
--- a/Source/WebCore/platform/text/TextChecking.h
+++ b/Source/WebCore/platform/text/TextChecking.h
@@ -42,6 +42,18 @@ namespace WebCore {
#define WTF_USE_AUTOMATIC_TEXT_REPLACEMENT 1
#endif
+enum TextCheckingType {
+ TextCheckingTypeSpelling = 1 << 1,
+ TextCheckingTypeGrammar = 1 << 2,
+ TextCheckingTypeLink = 1 << 5,
+ TextCheckingTypeQuote = 1 << 6,
+ TextCheckingTypeDash = 1 << 7,
+ TextCheckingTypeReplacement = 1 << 8,
+ TextCheckingTypeCorrection = 1 << 9
+};
+
+typedef unsigned TextCheckingTypeMask;
+
}
#endif // TextChecking_h
diff --git a/Source/WebCore/platform/text/UnicodeBidi.h b/Source/WebCore/platform/text/UnicodeBidi.h
new file mode 100644
index 0000000..8e0d86e
--- /dev/null
+++ b/Source/WebCore/platform/text/UnicodeBidi.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UnicodeBidi_h
+#define UnicodeBidi_h
+
+namespace WebCore {
+
+enum EUnicodeBidi {
+ UBNormal,
+ Embed,
+ Override,
+ Isolate
+};
+
+}
+
+#endif