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/BidiContext.cpp50
-rw-r--r--Source/WebCore/platform/text/BidiContext.h25
-rw-r--r--Source/WebCore/platform/text/BidiResolver.h375
-rw-r--r--Source/WebCore/platform/text/LocalizedNumber.h4
-rw-r--r--Source/WebCore/platform/text/LocalizedNumberICU.cpp4
-rw-r--r--Source/WebCore/platform/text/LocalizedNumberNone.cpp2
-rw-r--r--Source/WebCore/platform/text/TextCheckerClient.h4
-rw-r--r--Source/WebCore/platform/text/TextChecking.h47
-rw-r--r--Source/WebCore/platform/text/TextCodec.h2
-rw-r--r--Source/WebCore/platform/text/TextCodecICU.cpp7
-rw-r--r--Source/WebCore/platform/text/TextEncodingRegistry.cpp2
-rw-r--r--Source/WebCore/platform/text/TextOrientation.h35
-rw-r--r--Source/WebCore/platform/text/mac/LocalizedNumberMac.mm6
-rw-r--r--Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp3
14 files changed, 360 insertions, 206 deletions
diff --git a/Source/WebCore/platform/text/BidiContext.cpp b/Source/WebCore/platform/text/BidiContext.cpp
index fb6b8cf..f507514 100644
--- a/Source/WebCore/platform/text/BidiContext.cpp
+++ b/Source/WebCore/platform/text/BidiContext.cpp
@@ -21,48 +21,80 @@
#include "config.h"
#include "BidiContext.h"
+#include <wtf/Vector.h>
namespace WebCore {
using namespace WTF::Unicode;
-inline PassRefPtr<BidiContext> BidiContext::createUncached(unsigned char level, Direction direction, bool override, BidiContext* parent)
+inline PassRefPtr<BidiContext> BidiContext::createUncached(unsigned char level, Direction direction, bool override, BidiEmbeddingSource source, BidiContext* parent)
{
- return adoptRef(new BidiContext(level, direction, override, parent));
+ return adoptRef(new BidiContext(level, direction, override, source, parent));
}
-PassRefPtr<BidiContext> BidiContext::create(unsigned char level, Direction direction, bool override, BidiContext* parent)
+PassRefPtr<BidiContext> BidiContext::create(unsigned char level, Direction direction, bool override, BidiEmbeddingSource source, BidiContext* parent)
{
ASSERT(direction == (level % 2 ? RightToLeft : LeftToRight));
if (parent)
- return createUncached(level, direction, override, parent);
+ return createUncached(level, direction, override, source, parent);
ASSERT(level <= 1);
if (!level) {
if (!override) {
- static BidiContext* ltrContext = createUncached(0, LeftToRight, false, 0).releaseRef();
+ static BidiContext* ltrContext = createUncached(0, LeftToRight, false, FromStyleOrDOM, 0).releaseRef();
return ltrContext;
}
- static BidiContext* ltrOverrideContext = createUncached(0, LeftToRight, true, 0).releaseRef();
+ static BidiContext* ltrOverrideContext = createUncached(0, LeftToRight, true, FromStyleOrDOM, 0).releaseRef();
return ltrOverrideContext;
}
if (!override) {
- static BidiContext* rtlContext = createUncached(1, RightToLeft, false, 0).releaseRef();
+ static BidiContext* rtlContext = createUncached(1, RightToLeft, false, FromStyleOrDOM, 0).releaseRef();
return rtlContext;
}
- static BidiContext* rtlOverrideContext = createUncached(1, RightToLeft, true, 0).releaseRef();
+ static BidiContext* rtlOverrideContext = createUncached(1, RightToLeft, true, FromStyleOrDOM, 0).releaseRef();
return rtlOverrideContext;
}
+static inline PassRefPtr<BidiContext> copyContextAndRebaselineLevel(BidiContext* context, BidiContext* parent)
+{
+ ASSERT(context);
+ unsigned char newLevel = parent ? parent->level() : 0;
+ if (context->dir() == RightToLeft)
+ newLevel = nextGreaterOddLevel(newLevel);
+ else if (parent)
+ newLevel = nextGreaterEvenLevel(newLevel);
+
+ return BidiContext::create(newLevel, context->dir(), context->override(), context->source(), parent);
+}
+
+// The BidiContext stack must be immutable -- they're re-used for re-layout after
+// DOM modification/editing -- so we copy all the non-unicode contexts, and
+// recalculate their levels.
+PassRefPtr<BidiContext> BidiContext::copyStackRemovingUnicodeEmbeddingContexts()
+{
+ Vector<BidiContext*, 64> contexts;
+ for (BidiContext* iter = this; iter; iter = iter->parent()) {
+ if (iter->source() != FromUnicode)
+ contexts.append(iter);
+ }
+ ASSERT(contexts.size());
+
+ RefPtr<BidiContext> topContext = copyContextAndRebaselineLevel(contexts.last(), 0);
+ for (int i = contexts.size() - 1; i > 0; --i)
+ topContext = copyContextAndRebaselineLevel(contexts[i - 1], topContext.get());
+
+ return topContext.release();
+}
+
bool operator==(const BidiContext& c1, const BidiContext& c2)
{
if (&c1 == &c2)
return true;
- if (c1.level() != c2.level() || c1.override() != c2.override() || c1.dir() != c2.dir())
+ if (c1.level() != c2.level() || c1.override() != c2.override() || c1.dir() != c2.dir() || c1.source() != c2.source())
return false;
if (!c1.parent())
return !c2.parent();
diff --git a/Source/WebCore/platform/text/BidiContext.h b/Source/WebCore/platform/text/BidiContext.h
index b52815f..9f45d65 100644
--- a/Source/WebCore/platform/text/BidiContext.h
+++ b/Source/WebCore/platform/text/BidiContext.h
@@ -30,33 +30,52 @@
namespace WebCore {
+enum BidiEmbeddingSource {
+ FromStyleOrDOM,
+ FromUnicode
+};
+
// Used to keep track of explicit embeddings.
class BidiContext : public RefCounted<BidiContext> {
public:
- static PassRefPtr<BidiContext> create(unsigned char level, WTF::Unicode::Direction direction, bool override = false, BidiContext* parent = 0);
+ static PassRefPtr<BidiContext> create(unsigned char level, WTF::Unicode::Direction, bool override = false, BidiEmbeddingSource = FromStyleOrDOM, BidiContext* parent = 0);
BidiContext* parent() const { return m_parent.get(); }
unsigned char level() const { return m_level; }
WTF::Unicode::Direction dir() const { return static_cast<WTF::Unicode::Direction>(m_direction); }
bool override() const { return m_override; }
+ BidiEmbeddingSource source() const { return static_cast<BidiEmbeddingSource>(m_source); }
+ PassRefPtr<BidiContext> copyStackRemovingUnicodeEmbeddingContexts();
private:
- BidiContext(unsigned char level, WTF::Unicode::Direction direction, bool override, BidiContext* parent)
+ BidiContext(unsigned char level, WTF::Unicode::Direction direction, bool override, BidiEmbeddingSource source, BidiContext* parent)
: m_level(level)
, m_direction(direction)
, m_override(override)
+ , m_source(source)
, m_parent(parent)
{
}
- static PassRefPtr<BidiContext> createUncached(unsigned char level, WTF::Unicode::Direction, bool override, BidiContext* parent);
+ static PassRefPtr<BidiContext> createUncached(unsigned char level, WTF::Unicode::Direction, bool override, BidiEmbeddingSource, BidiContext* parent);
unsigned char m_level;
unsigned m_direction : 5; // Direction
bool m_override : 1;
+ unsigned m_source : 1; // BidiEmbeddingSource
RefPtr<BidiContext> m_parent;
};
+inline unsigned char nextGreaterOddLevel(unsigned char level)
+{
+ return (level + 1) | 1;
+}
+
+inline unsigned char nextGreaterEvenLevel(unsigned char level)
+{
+ return (level + 2) & ~1;
+}
+
bool operator==(const BidiContext&, const BidiContext&);
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/BidiResolver.h b/Source/WebCore/platform/text/BidiResolver.h
index 07e9274..5b92ee2 100644
--- a/Source/WebCore/platform/text/BidiResolver.h
+++ b/Source/WebCore/platform/text/BidiResolver.h
@@ -75,6 +75,21 @@ struct BidiStatus {
RefPtr<BidiContext> context;
};
+class BidiEmbedding {
+public:
+ BidiEmbedding(WTF::Unicode::Direction direction, BidiEmbeddingSource source)
+ : m_direction(direction)
+ , m_source(source)
+ {
+ }
+
+ WTF::Unicode::Direction direction() const { return m_direction; }
+ BidiEmbeddingSource source() const { return m_source; }
+private:
+ WTF::Unicode::Direction m_direction;
+ BidiEmbeddingSource m_source;
+};
+
inline bool operator==(const BidiStatus& status1, const BidiStatus& status2)
{
return status1.eor == status2.eor && status1.last == status2.last && status1.lastStrong == status2.lastStrong && *(status1.context) == *(status2.context);
@@ -134,10 +149,10 @@ enum VisualDirectionOverride {
template <class Iterator, class Run> class BidiResolver {
WTF_MAKE_NONCOPYABLE(BidiResolver);
-public :
+public:
BidiResolver()
: m_direction(WTF::Unicode::OtherNeutral)
- , reachedEndOfLine(false)
+ , m_reachedEndOfLine(false)
, emptyRun(true)
, m_firstRun(0)
, m_lastRun(0)
@@ -146,10 +161,10 @@ public :
{
}
- const Iterator& position() const { return current; }
- void setPosition(const Iterator& position) { current = position; }
+ const Iterator& position() const { return m_current; }
+ void setPosition(const Iterator& position) { m_current = position; }
- void increment() { current.increment(); }
+ void increment() { m_current.increment(); }
BidiContext* context() const { return m_status.context.get(); }
void setContext(PassRefPtr<BidiContext> c) { m_status.context = c; }
@@ -166,7 +181,7 @@ public :
MidpointState<Iterator>& midpointState() { return m_midpointState; }
- void embed(WTF::Unicode::Direction);
+ void embed(WTF::Unicode::Direction, BidiEmbeddingSource);
bool commitExplicitEmbedding();
void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = NoVisualOverride, bool hardLineBreak = false);
@@ -188,14 +203,16 @@ protected:
void appendRun();
void reverseRuns(unsigned start, unsigned end);
- Iterator current;
- Iterator sor;
- Iterator eor;
- Iterator last;
+ Iterator m_current;
+ // sor and eor are "start of run" and "end of run" respectively and correpond
+ // to abreviations used in UBA spec: http://unicode.org/reports/tr9/#BD7
+ Iterator m_sor;
+ Iterator m_eor;
+ Iterator m_last;
BidiStatus m_status;
WTF::Unicode::Direction m_direction;
Iterator endOfLine;
- bool reachedEndOfLine;
+ bool m_reachedEndOfLine;
Iterator lastBeforeET;
bool emptyRun;
@@ -210,7 +227,10 @@ private:
void lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from);
void checkDirectionInLowerRaiseEmbeddingLevel();
- Vector<WTF::Unicode::Direction, 8> m_currentExplicitEmbeddingSequence;
+ void updateStatusLastFromCurrentDirection(WTF::Unicode::Direction);
+ void reorderRunsFromLevels();
+
+ Vector<BidiEmbedding, 8> m_currentExplicitEmbeddingSequence;
};
template <class Iterator, class Run>
@@ -286,20 +306,20 @@ inline void BidiResolver<Iterator, Run>::moveRunToBeginning(Run* run)
template <class Iterator, class Run>
void BidiResolver<Iterator, Run>::appendRun()
{
- if (!emptyRun && !eor.atEnd()) {
- unsigned startOffset = sor.offset();
- unsigned endOffset = eor.offset();
+ if (!emptyRun && !m_eor.atEnd()) {
+ unsigned startOffset = m_sor.offset();
+ unsigned endOffset = m_eor.offset();
if (!endOfLine.atEnd() && endOffset >= endOfLine.offset()) {
- reachedEndOfLine = true;
+ m_reachedEndOfLine = true;
endOffset = endOfLine.offset();
}
if (endOffset >= startOffset)
addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
- eor.increment();
- sor = eor;
+ m_eor.increment();
+ m_sor = m_eor;
}
m_direction = WTF::Unicode::OtherNeutral;
@@ -307,12 +327,12 @@ void BidiResolver<Iterator, Run>::appendRun()
}
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::embed(WTF::Unicode::Direction d)
+void BidiResolver<Iterator, Run>::embed(WTF::Unicode::Direction dir, BidiEmbeddingSource source)
{
using namespace WTF::Unicode;
- ASSERT(d == PopDirectionalFormat || d == LeftToRightEmbedding || d == LeftToRightOverride || d == RightToLeftEmbedding || d == RightToLeftOverride);
- m_currentExplicitEmbeddingSequence.append(d);
+ ASSERT(dir == PopDirectionalFormat || dir == LeftToRightEmbedding || dir == LeftToRightOverride || dir == RightToLeftEmbedding || dir == RightToLeftOverride);
+ m_currentExplicitEmbeddingSequence.append(BidiEmbedding(dir, source));
}
template <class Iterator, class Run>
@@ -320,7 +340,7 @@ void BidiResolver<Iterator, Run>::checkDirectionInLowerRaiseEmbeddingLevel()
{
using namespace WTF::Unicode;
- ASSERT(m_status.eor != OtherNeutral || eor.atEnd());
+ ASSERT(m_status.eor != OtherNeutral || m_eor.atEnd());
ASSERT(m_status.last != NonSpacingMark
&& m_status.last != BoundaryNeutral
&& m_status.last != RightToLeftEmbedding
@@ -337,7 +357,7 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire
{
using namespace WTF::Unicode;
- if (!emptyRun && eor != last) {
+ if (!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) {
@@ -358,14 +378,14 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire
appendRun();
m_direction = RightToLeft;
}
- eor = last;
+ m_eor = m_last;
}
appendRun();
emptyRun = true;
// sor for the new run is determined by the higher level (rule X10)
setLastDir(from);
setLastStrongDir(from);
- eor = Iterator();
+ m_eor = Iterator();
}
template <class Iterator, class Run>
@@ -373,7 +393,7 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
{
using namespace WTF::Unicode;
- if (!emptyRun && eor != last) {
+ if (!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) {
@@ -396,13 +416,13 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
appendRun();
m_direction = RightToLeft;
}
- eor = last;
+ m_eor = m_last;
}
appendRun();
emptyRun = true;
setLastDir(to);
setLastStrongDir(to);
- eor = Iterator();
+ m_eor = Iterator();
}
template <class Iterator, class Run>
@@ -414,25 +434,20 @@ bool BidiResolver<Iterator, Run>::commitExplicitEmbedding()
RefPtr<BidiContext> toContext = context();
for (size_t i = 0; i < m_currentExplicitEmbeddingSequence.size(); ++i) {
- Direction embedding = m_currentExplicitEmbeddingSequence[i];
- if (embedding == PopDirectionalFormat) {
+ BidiEmbedding embedding = m_currentExplicitEmbeddingSequence[i];
+ if (embedding.direction() == PopDirectionalFormat) {
if (BidiContext* parentContext = toContext->parent())
toContext = parentContext;
} else {
- Direction direction = (embedding == RightToLeftEmbedding || embedding == RightToLeftOverride) ? RightToLeft : LeftToRight;
- bool override = embedding == LeftToRightOverride || embedding == RightToLeftOverride;
+ Direction direction = (embedding.direction() == RightToLeftEmbedding || embedding.direction() == RightToLeftOverride) ? RightToLeft : LeftToRight;
+ bool override = embedding.direction() == LeftToRightOverride || embedding.direction() == RightToLeftOverride;
unsigned char level = toContext->level();
- if (direction == RightToLeft) {
- // Go to the least greater odd integer
- level += 1;
- level |= 1;
- } else {
- // Go to the least greater even integer
- level += 2;
- level &= ~1;
- }
+ if (direction == RightToLeft)
+ level = nextGreaterOddLevel(level);
+ else
+ level = nextGreaterEvenLevel(level);
if (level < 61)
- toContext = BidiContext::create(level, direction, override, toContext.get());
+ toContext = BidiContext::create(level, direction, override, embedding.source(), toContext.get());
}
}
@@ -520,6 +535,85 @@ void BidiResolver<Iterator, Run>::reverseRuns(unsigned start, unsigned end)
}
template <class Iterator, class Run>
+inline void BidiResolver<Iterator, Run>::updateStatusLastFromCurrentDirection(WTF::Unicode::Direction dirCurrent)
+{
+ using namespace WTF::Unicode;
+ switch (dirCurrent) {
+ case EuropeanNumberTerminator:
+ if (m_status.last != EuropeanNumber)
+ m_status.last = EuropeanNumberTerminator;
+ break;
+ case EuropeanNumberSeparator:
+ case CommonNumberSeparator:
+ case SegmentSeparator:
+ case WhiteSpaceNeutral:
+ case OtherNeutral:
+ switch (m_status.last) {
+ case LeftToRight:
+ case RightToLeft:
+ case RightToLeftArabic:
+ case EuropeanNumber:
+ case ArabicNumber:
+ m_status.last = dirCurrent;
+ break;
+ default:
+ m_status.last = OtherNeutral;
+ }
+ break;
+ case NonSpacingMark:
+ case BoundaryNeutral:
+ case RightToLeftEmbedding:
+ case LeftToRightEmbedding:
+ case RightToLeftOverride:
+ case LeftToRightOverride:
+ case PopDirectionalFormat:
+ // ignore these
+ break;
+ case EuropeanNumber:
+ // fall through
+ default:
+ m_status.last = dirCurrent;
+ }
+}
+
+template <class Iterator, class Run>
+inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
+{
+ unsigned char levelLow = 128;
+ unsigned char levelHigh = 0;
+ for (Run* run = firstRun(); run; run = run->next()) {
+ levelHigh = std::max(run->level(), levelHigh);
+ levelLow = std::min(run->level(), levelLow);
+ }
+
+ // This implements reordering of the line (L2 according to Bidi spec):
+ // http://unicode.org/reports/tr9/#L2
+ // L2. From the highest level found in the text to the lowest odd level on each line,
+ // reverse any contiguous sequence of characters that are at that level or higher.
+
+ // Reversing is only done up to the lowest odd level.
+ if (!(levelLow % 2))
+ levelLow++;
+
+ unsigned count = runCount() - 1;
+
+ while (levelHigh >= levelLow) {
+ unsigned i = 0;
+ Run* run = firstRun();
+ while (i < count) {
+ for (;i < count && run && run->level() < levelHigh; i++)
+ run = run->next();
+ unsigned start = i;
+ for (;i <= count && run && run->level() >= levelHigh; i++)
+ run = run->next();
+ unsigned end = i - 1;
+ reverseRuns(start, end);
+ }
+ levelHigh--;
+ }
+}
+
+template <class Iterator, class Run>
void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, VisualDirectionOverride override, bool hardLineBreak)
{
using namespace WTF::Unicode;
@@ -528,10 +622,10 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
if (override != NoVisualOverride) {
emptyRun = false;
- sor = current;
- eor = Iterator();
- while (current != end && !current.atEnd()) {
- eor = current;
+ m_sor = m_current;
+ m_eor = Iterator();
+ while (m_current != end && !m_current.atEnd()) {
+ m_eor = m_current;
increment();
}
m_direction = override == VisualLeftToRightOverride ? LeftToRight : RightToLeft;
@@ -544,29 +638,34 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
emptyRun = true;
- eor = Iterator();
+ m_eor = Iterator();
- last = current;
+ m_last = m_current;
bool pastEnd = false;
BidiResolver<Iterator, Run> stateAtEnd;
while (true) {
Direction dirCurrent;
- if (pastEnd && (hardLineBreak || current.atEnd())) {
+ if (pastEnd && (hardLineBreak || m_current.atEnd())) {
BidiContext* c = context();
- while (c->parent())
- c = c->parent();
- dirCurrent = c->dir();
if (hardLineBreak) {
// A deviation from the Unicode Bidi Algorithm in order to match
- // Mac OS X text and WinIE: a hard line break resets bidi state.
- stateAtEnd.setContext(c);
+ // WinIE and user expectations: hard line breaks reset bidi state
+ // coming from unicode bidi control characters, but not those from
+ // DOM nodes with specified directionality
+ stateAtEnd.setContext(c->copyStackRemovingUnicodeEmbeddingContexts());
+
+ dirCurrent = stateAtEnd.context()->dir();
stateAtEnd.setEorDir(dirCurrent);
stateAtEnd.setLastDir(dirCurrent);
stateAtEnd.setLastStrongDir(dirCurrent);
+ } else {
+ while (c->parent())
+ c = c->parent();
+ dirCurrent = c->dir();
}
} else {
- dirCurrent = current.direction();
+ dirCurrent = m_current.direction();
if (context()->override()
&& dirCurrent != RightToLeftEmbedding
&& dirCurrent != LeftToRightEmbedding
@@ -578,7 +677,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
dirCurrent = m_status.last;
}
- ASSERT(m_status.eor != OtherNeutral || eor.atEnd());
+ ASSERT(m_status.eor != OtherNeutral || m_eor.atEnd());
switch (dirCurrent) {
// embedding and overrides (X1-X9 in the Bidi specs)
@@ -587,7 +686,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
case RightToLeftOverride:
case LeftToRightOverride:
case PopDirectionalFormat:
- embed(dirCurrent);
+ embed(dirCurrent, FromUnicode);
commitExplicitEmbedding();
break;
@@ -618,7 +717,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
appendRun();
if (context()->dir() != LeftToRight) {
// the neutrals take the embedding direction, which is R
- eor = last;
+ m_eor = m_last;
m_direction = RightToLeft;
appendRun();
}
@@ -629,14 +728,14 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
appendRun();
if (context()->dir() != LeftToRight) {
// the neutrals take the embedding direction, which is R
- eor = last;
+ m_eor = m_last;
m_direction = RightToLeft;
appendRun();
}
} else if (m_status.lastStrong != LeftToRight) {
//last stuff takes embedding dir
if (context()->dir() == RightToLeft) {
- eor = last;
+ m_eor = m_last;
m_direction = RightToLeft;
}
appendRun();
@@ -644,7 +743,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
default:
break;
}
- eor = current;
+ m_eor = m_current;
m_status.eor = LeftToRight;
m_status.lastStrong = LeftToRight;
m_direction = LeftToRight;
@@ -669,19 +768,19 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
case OtherNeutral:
if (m_status.eor == EuropeanNumber) {
if (m_status.lastStrong == LeftToRight && context()->dir() == LeftToRight)
- eor = last;
+ m_eor = m_last;
appendRun();
} else if (m_status.eor == ArabicNumber)
appendRun();
else if (m_status.lastStrong == LeftToRight) {
if (context()->dir() == LeftToRight)
- eor = last;
+ m_eor = m_last;
appendRun();
}
default:
break;
}
- eor = current;
+ m_eor = m_current;
m_status.eor = RightToLeft;
m_status.lastStrong = dirCurrent;
m_direction = RightToLeft;
@@ -699,7 +798,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
case RightToLeft:
case RightToLeftArabic:
case ArabicNumber:
- eor = last;
+ m_eor = m_last;
appendRun();
m_direction = EuropeanNumber;
break;
@@ -719,7 +818,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
// Terminate the EN run.
appendRun();
// Make an R run.
- eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -730,7 +829,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
appendRun();
if (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft) {
// Make an R run.
- eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -738,7 +837,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
} else if (m_status.lastStrong == RightToLeft) {
// Extend the R run to include the neutrals.
- eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -747,7 +846,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
default:
break;
}
- eor = current;
+ m_eor = m_current;
m_status.eor = EuropeanNumber;
if (m_direction == OtherNeutral)
m_direction = LeftToRight;
@@ -765,7 +864,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
case RightToLeft:
case RightToLeftArabic:
case EuropeanNumber:
- eor = last;
+ m_eor = m_last;
appendRun();
break;
case CommonNumberSeparator:
@@ -787,12 +886,12 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_direction = RightToLeft;
} else if (m_direction == OtherNeutral)
m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;
- eor = last;
+ m_eor = m_last;
appendRun();
default:
break;
}
- eor = current;
+ m_eor = m_current;
m_status.eor = ArabicNumber;
if (m_direction == OtherNeutral)
m_direction = ArabicNumber;
@@ -803,16 +902,16 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
case EuropeanNumberTerminator:
if (m_status.last == EuropeanNumber) {
dirCurrent = EuropeanNumber;
- eor = current;
+ m_eor = m_current;
m_status.eor = dirCurrent;
} else if (m_status.last != EuropeanNumberTerminator)
- lastBeforeET = emptyRun ? eor : last;
+ lastBeforeET = emptyRun ? m_eor : m_last;
break;
// boundary neutrals should be ignored
case BoundaryNeutral:
- if (eor == last)
- eor = current;
+ if (m_eor == m_last)
+ m_eor = m_current;
break;
// neutrals
case BlockSeparator:
@@ -829,9 +928,9 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
break;
}
- if (pastEnd && eor == current) {
- if (!reachedEndOfLine) {
- eor = endOfLine;
+ if (pastEnd && m_eor == m_current) {
+ if (!m_reachedEndOfLine) {
+ m_eor = endOfLine;
switch (m_status.eor) {
case LeftToRight:
case RightToLeft:
@@ -846,60 +945,23 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
appendRun();
}
- current = end;
+ m_current = end;
m_status = stateAtEnd.m_status;
- sor = stateAtEnd.sor;
- eor = stateAtEnd.eor;
- last = stateAtEnd.last;
- reachedEndOfLine = stateAtEnd.reachedEndOfLine;
+ m_sor = stateAtEnd.m_sor;
+ m_eor = stateAtEnd.m_eor;
+ m_last = stateAtEnd.m_last;
+ m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine;
lastBeforeET = stateAtEnd.lastBeforeET;
emptyRun = stateAtEnd.emptyRun;
m_direction = OtherNeutral;
break;
}
- // set m_status.last as needed.
- switch (dirCurrent) {
- case EuropeanNumberTerminator:
- if (m_status.last != EuropeanNumber)
- m_status.last = EuropeanNumberTerminator;
- break;
- case EuropeanNumberSeparator:
- case CommonNumberSeparator:
- case SegmentSeparator:
- case WhiteSpaceNeutral:
- case OtherNeutral:
- switch(m_status.last) {
- case LeftToRight:
- case RightToLeft:
- case RightToLeftArabic:
- case EuropeanNumber:
- case ArabicNumber:
- m_status.last = dirCurrent;
- break;
- default:
- m_status.last = OtherNeutral;
- }
- break;
- case NonSpacingMark:
- case BoundaryNeutral:
- case RightToLeftEmbedding:
- case LeftToRightEmbedding:
- case RightToLeftOverride:
- case LeftToRightOverride:
- case PopDirectionalFormat:
- // ignore these
- break;
- case EuropeanNumber:
- // fall through
- default:
- m_status.last = dirCurrent;
- }
-
- last = current;
+ updateStatusLastFromCurrentDirection(dirCurrent);
+ m_last = m_current;
if (emptyRun) {
- sor = current;
+ m_sor = m_current;
emptyRun = false;
}
@@ -907,12 +969,12 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
if (!m_currentExplicitEmbeddingSequence.isEmpty()) {
bool committed = commitExplicitEmbedding();
if (committed && pastEnd) {
- current = end;
+ m_current = end;
m_status = stateAtEnd.m_status;
- sor = stateAtEnd.sor;
- eor = stateAtEnd.eor;
- last = stateAtEnd.last;
- reachedEndOfLine = stateAtEnd.reachedEndOfLine;
+ m_sor = stateAtEnd.m_sor;
+ m_eor = stateAtEnd.m_eor;
+ m_last = stateAtEnd.m_last;
+ m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine;
lastBeforeET = stateAtEnd.lastBeforeET;
emptyRun = stateAtEnd.emptyRun;
m_direction = OtherNeutral;
@@ -920,64 +982,23 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
}
- if (!pastEnd && (current == end || current.atEnd())) {
+ if (!pastEnd && (m_current == end || m_current.atEnd())) {
if (emptyRun)
break;
stateAtEnd.m_status = m_status;
- stateAtEnd.sor = sor;
- stateAtEnd.eor = eor;
- stateAtEnd.last = last;
- stateAtEnd.reachedEndOfLine = reachedEndOfLine;
+ 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;
- endOfLine = last;
+ endOfLine = m_last;
pastEnd = true;
}
}
m_logicallyLastRun = m_lastRun;
-
- // reorder line according to run structure...
- // first find highest and lowest levels
- unsigned char levelLow = 128;
- unsigned char levelHigh = 0;
- Run* r = firstRun();
- while (r) {
- if (r->m_level > levelHigh)
- levelHigh = r->m_level;
- if (r->m_level < levelLow)
- levelLow = r->m_level;
- r = r->next();
- }
-
- // implements reordering of the line (L2 according to Bidi spec):
- // L2. From the highest level found in the text to the lowest odd level on each line,
- // reverse any contiguous sequence of characters that are at that level or higher.
-
- // reversing is only done up to the lowest odd level
- if (!(levelLow % 2))
- levelLow++;
-
- unsigned count = runCount() - 1;
-
- while (levelHigh >= levelLow) {
- unsigned i = 0;
- Run* currRun = firstRun();
- while (i < count) {
- while (i < count && currRun && currRun->m_level < levelHigh) {
- i++;
- currRun = currRun->next();
- }
- unsigned start = i;
- while (i <= count && currRun && currRun->m_level >= levelHigh) {
- i++;
- currRun = currRun->next();
- }
- unsigned end = i - 1;
- reverseRuns(start, end);
- }
- levelHigh--;
- }
+ reorderRunsFromLevels();
endOfLine = Iterator();
}
diff --git a/Source/WebCore/platform/text/LocalizedNumber.h b/Source/WebCore/platform/text/LocalizedNumber.h
index d70541f..01d2553 100644
--- a/Source/WebCore/platform/text/LocalizedNumber.h
+++ b/Source/WebCore/platform/text/LocalizedNumber.h
@@ -47,7 +47,9 @@ double parseLocalizedNumber(const String&);
// current locale. If an implementation doesn't support localized
// numbers or the input value is NaN or Infinitiy, the function should
// return an empty string.
-String formatLocalizedNumber(double);
+// fractionDigits is the maximum length of the fractional parts of the
+// resultant string.
+String formatLocalizedNumber(double, unsigned fractionDigits);
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/LocalizedNumberICU.cpp b/Source/WebCore/platform/text/LocalizedNumberICU.cpp
index 189151e..7c4b1cb 100644
--- a/Source/WebCore/platform/text/LocalizedNumberICU.cpp
+++ b/Source/WebCore/platform/text/LocalizedNumberICU.cpp
@@ -34,6 +34,7 @@
#include <limits>
#include <unicode/numfmt.h>
#include <unicode/parsepos.h>
+#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
using namespace std;
@@ -73,12 +74,13 @@ double parseLocalizedNumber(const String& numberString)
return U_SUCCESS(status) ? numericResult : numeric_limits<double>::quiet_NaN();
}
-String formatLocalizedNumber(double number)
+String formatLocalizedNumber(double number, unsigned fractionDigits)
{
NumberFormat* formatter = numberFormatter();
if (!formatter)
return String();
UnicodeString result;
+ formatter->setMaximumFractionDigits(clampToInteger(fractionDigits));
formatter->format(number, result);
return String(result.getBuffer(), result.length());
}
diff --git a/Source/WebCore/platform/text/LocalizedNumberNone.cpp b/Source/WebCore/platform/text/LocalizedNumberNone.cpp
index 729f2f1..c7a8ed2 100644
--- a/Source/WebCore/platform/text/LocalizedNumberNone.cpp
+++ b/Source/WebCore/platform/text/LocalizedNumberNone.cpp
@@ -42,7 +42,7 @@ double parseLocalizedNumber(const String&)
return numeric_limits<double>::quiet_NaN();
}
-String formatLocalizedNumber(double)
+String formatLocalizedNumber(double, unsigned)
{
return String();
}
diff --git a/Source/WebCore/platform/text/TextCheckerClient.h b/Source/WebCore/platform/text/TextCheckerClient.h
index acaa02c..8abbed4 100644
--- a/Source/WebCore/platform/text/TextCheckerClient.h
+++ b/Source/WebCore/platform/text/TextCheckerClient.h
@@ -28,6 +28,8 @@
#ifndef TextCheckerClient_h
#define TextCheckerClient_h
+#include "TextChecking.h"
+
#include <wtf/Forward.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
@@ -70,7 +72,7 @@ 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 PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#if USE(UNIFIED_TEXT_CHECKING)
virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) = 0;
#endif
diff --git a/Source/WebCore/platform/text/TextChecking.h b/Source/WebCore/platform/text/TextChecking.h
new file mode 100644
index 0000000..022fb82
--- /dev/null
+++ b/Source/WebCore/platform/text/TextChecking.h
@@ -0,0 +1,47 @@
+/*
+ * 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 TextChecking_h
+#define TextChecking_h
+
+namespace WebCore {
+
+#if !defined(BUILDING_ON_TIGER)
+#define WTF_USE_GRAMMAR_CHECKING 1
+#endif
+
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#define WTF_USE_UNIFIED_TEXT_CHECKING 1
+#define WTF_USE_AUTOMATIC_TEXT_REPLACEMENT 1
+#endif
+
+}
+
+#endif // TextChecking_h
diff --git a/Source/WebCore/platform/text/TextCodec.h b/Source/WebCore/platform/text/TextCodec.h
index 35229a3..0c2a38a 100644
--- a/Source/WebCore/platform/text/TextCodec.h
+++ b/Source/WebCore/platform/text/TextCodec.h
@@ -52,7 +52,7 @@ namespace WebCore {
// Encodes the character as en entity as above, but escaped
// non-alphanumeric characters. This is used in URLs.
// For example, U+6DE would be "%26%231758%3B".
- URLEncodedEntitiesForUnencodables,
+ URLEncodedEntitiesForUnencodables
};
typedef char UnencodableReplacementArray[32];
diff --git a/Source/WebCore/platform/text/TextCodecICU.cpp b/Source/WebCore/platform/text/TextCodecICU.cpp
index d07b50e..0d99196 100644
--- a/Source/WebCore/platform/text/TextCodecICU.cpp
+++ b/Source/WebCore/platform/text/TextCodecICU.cpp
@@ -149,13 +149,6 @@ void TextCodecICU::registerEncodingNames(EncodingNameRegistrar registrar)
registrar("x-windows-949", "windows-949");
registrar("x-uhc", "windows-949");
registrar("shift-jis", "Shift_JIS");
-#if !USE(BUILTIN_UTF8_CODEC)
- registrar("unicode11utf8", "UTF-8");
- registrar("unicode20utf8", "UTF-8");
- registrar("x-unicode20utf8", "UTF-8");
- registrar("utf8", "UTF-8");
- registrar("UTF-8", "UTF-8");
-#endif
// These aliases are present in modern versions of ICU, but use different codecs, and have no standard names.
// They are not present in ICU 3.2.
diff --git a/Source/WebCore/platform/text/TextEncodingRegistry.cpp b/Source/WebCore/platform/text/TextEncodingRegistry.cpp
index f604227..d6450b1 100644
--- a/Source/WebCore/platform/text/TextEncodingRegistry.cpp
+++ b/Source/WebCore/platform/text/TextEncodingRegistry.cpp
@@ -223,10 +223,8 @@ static void buildBaseTextCodecMaps()
TextCodecLatin1::registerEncodingNames(addToTextEncodingNameMap);
TextCodecLatin1::registerCodecs(addToTextCodecMap);
-#if USE(BUILTIN_UTF8_CODEC)
TextCodecUTF8::registerEncodingNames(addToTextEncodingNameMap);
TextCodecUTF8::registerCodecs(addToTextCodecMap);
-#endif
TextCodecUTF16::registerEncodingNames(addToTextEncodingNameMap);
TextCodecUTF16::registerCodecs(addToTextCodecMap);
diff --git a/Source/WebCore/platform/text/TextOrientation.h b/Source/WebCore/platform/text/TextOrientation.h
new file mode 100644
index 0000000..e229f1e
--- /dev/null
+++ b/Source/WebCore/platform/text/TextOrientation.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 Apple Computer, 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 TextOrientation_h
+#define TextOrientation_h
+
+namespace WebCore {
+
+enum TextOrientation { TextOrientationVerticalRight, TextOrientationUpright };
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm b/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm
index 8cfe200..826f707 100644
--- a/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm
+++ b/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm
@@ -65,10 +65,12 @@ double parseLocalizedNumber(const String& numberString)
return [number doubleValue];
}
-String formatLocalizedNumber(double inputNumber)
+String formatLocalizedNumber(double inputNumber, unsigned fractionDigits)
{
RetainPtr<NSNumber> number(AdoptNS, [[NSNumber alloc] initWithDouble:inputNumber]);
- return String([numberFormatter() stringFromNumber:number.get()]);
+ RetainPtr<NSNumberFormatter> formatter = numberFormatter();
+ [formatter.get() setMaximumFractionDigits:fractionDigits];
+ return String([formatter.get() stringFromNumber:number.get()]);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
index 3fae657..1fe400c 100644
--- a/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
+++ b/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
@@ -22,6 +22,7 @@
#include "TextBreakIterator.h"
#include <QtCore/qtextboundaryfinder.h>
+#include <algorithm>
#include <qdebug.h>
// #define DEBUG_TEXT_ITERATORS
@@ -89,7 +90,7 @@ const char* currentTextBreakLocaleID()
TextBreakIterator* lineBreakIterator = 0;
if (staticLineBreakIterator) {
setUpIterator(*staticLineBreakIterator, QTextBoundaryFinder::Line, string, length);
- swap(staticLineBreakIterator, lineBreakIterator);
+ std::swap(staticLineBreakIterator, lineBreakIterator);
}
if (!lineBreakIterator && string && length)