summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/text/BidiResolver.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/text/BidiResolver.h')
-rw-r--r--Source/WebCore/platform/text/BidiResolver.h375
1 files changed, 198 insertions, 177 deletions
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();
}