#include "wtf/PassRefPtr.h"
#include "wtf/Vector.h"
-namespace WebCore {
+namespace blink {
class RenderObject;
{
}
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
~BidiResolver();
#endif
bool inIsolate() const { return m_nestedIsolateCount; }
void embed(WTF::Unicode::Direction, BidiEmbeddingSource);
- bool commitExplicitEmbedding();
+ bool commitExplicitEmbedding(BidiRunList<Run>&);
void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = NoVisualOverride, bool hardLineBreak = false, bool reorderRuns = true);
void increment() { m_current.increment(); }
// 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 appendRun(BidiRunList<Run>&);
- Run* addTrailingRun(int, int, Run*, BidiContext*, TextDirection) { return 0; }
+ Run* addTrailingRun(BidiRunList<Run>&, int, int, Run*, BidiContext*, TextDirection) const { return 0; }
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
TextDirection m_paragraphDirectionality;
private:
- void raiseExplicitEmbeddingLevel(WTF::Unicode::Direction from, WTF::Unicode::Direction to);
- void lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from);
+ void raiseExplicitEmbeddingLevel(BidiRunList<Run>&, WTF::Unicode::Direction from, WTF::Unicode::Direction to);
+ void lowerExplicitEmbeddingLevel(BidiRunList<Run>&, WTF::Unicode::Direction from);
void checkDirectionInLowerRaiseEmbeddingLevel();
void updateStatusLastFromCurrentDirection(WTF::Unicode::Direction);
- void reorderRunsFromLevels();
+ void reorderRunsFromLevels(BidiRunList<Run>&) const;
- bool needsToApplyL1Rule() { return false; }
+ bool needsToApplyL1Rule(BidiRunList<Run>&) { return false; }
int findFirstTrailingSpaceAtRun(Run*) { return 0; }
// http://www.unicode.org/reports/tr9/#L1
- void applyL1Rule();
+ void applyL1Rule(BidiRunList<Run>&);
Vector<BidiEmbedding, 8> m_currentExplicitEmbeddingSequence;
HashMap<Run *, MidpointState<Iterator> > m_midpointStateForIsolatedRun;
};
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
template <class Iterator, class Run>
BidiResolver<Iterator, Run>::~BidiResolver()
{
#endif
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::appendRun()
+void BidiResolver<Iterator, Run>::appendRun(BidiRunList<Run>& runs)
{
if (!m_emptyRun && !m_eor.atEnd()) {
unsigned startOffset = m_sor.offset();
}
if (endOffset >= startOffset)
- m_runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
+ runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
m_eor.increment();
m_sor = m_eor;
}
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from)
+void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(BidiRunList<Run>& runs, WTF::Unicode::Direction from)
{
using namespace WTF::Unicode;
if (m_status.eor == EuropeanNumber) {
if (m_status.lastStrong != LeftToRight) {
m_direction = EuropeanNumber;
- appendRun();
+ appendRun(runs);
}
} else if (m_status.eor == ArabicNumber) {
m_direction = ArabicNumber;
- appendRun();
+ appendRun(runs);
} else if (m_status.lastStrong != LeftToRight) {
- appendRun();
+ appendRun(runs);
m_direction = LeftToRight;
}
} else if (m_status.eor == EuropeanNumber || m_status.eor == ArabicNumber || m_status.lastStrong == LeftToRight) {
- appendRun();
+ appendRun(runs);
m_direction = RightToLeft;
}
m_eor = m_last;
}
- appendRun();
+ appendRun(runs);
m_emptyRun = true;
// sor for the new run is determined by the higher level (rule X10)
}
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Direction from, WTF::Unicode::Direction to)
+void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(BidiRunList<Run>& runs, WTF::Unicode::Direction from, WTF::Unicode::Direction to)
{
using namespace WTF::Unicode;
if (m_status.eor == EuropeanNumber) {
if (m_status.lastStrong != LeftToRight) {
m_direction = EuropeanNumber;
- appendRun();
+ appendRun(runs);
}
} else if (m_status.eor == ArabicNumber) {
m_direction = ArabicNumber;
- appendRun();
+ appendRun(runs);
} else if (m_status.lastStrong != LeftToRight && from == LeftToRight) {
- appendRun();
+ appendRun(runs);
m_direction = LeftToRight;
}
} else if (m_status.eor == ArabicNumber
|| (m_status.eor == EuropeanNumber && (m_status.lastStrong != LeftToRight || from == RightToLeft))
|| (m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && from == RightToLeft)) {
- appendRun();
+ appendRun(runs);
m_direction = RightToLeft;
}
m_eor = m_last;
}
- appendRun();
+ appendRun(runs);
m_emptyRun = true;
setLastDir(to);
}
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::applyL1Rule()
+void BidiResolver<Iterator, Run>::applyL1Rule(BidiRunList<Run>& runs)
{
- ASSERT(m_runs.runCount());
- if (!needsToApplyL1Rule())
+ ASSERT(runs.runCount());
+ if (!needsToApplyL1Rule(runs))
return;
- Run* trailingSpaceRun = m_runs.logicallyLastRun();
+ Run* trailingSpaceRun = runs.logicallyLastRun();
int firstSpace = findFirstTrailingSpaceAtRun(trailingSpaceRun);
if (firstSpace == trailingSpaceRun->stop())
return;
- bool shouldReorder = trailingSpaceRun != (m_paragraphDirectionality == LTR ? m_runs.lastRun() : m_runs.firstRun());
+ bool shouldReorder = trailingSpaceRun != (m_paragraphDirectionality == LTR ? runs.lastRun() : runs.firstRun());
if (firstSpace != trailingSpaceRun->start()) {
BidiContext* baseContext = context();
while (BidiContext* parent = baseContext->parent())
baseContext = parent;
- m_trailingSpaceRun = addTrailingRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun, baseContext, m_paragraphDirectionality);
+ m_trailingSpaceRun = addTrailingRun(runs, firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun, baseContext, m_paragraphDirectionality);
ASSERT(m_trailingSpaceRun);
trailingSpaceRun->m_stop = firstSpace;
return;
}
if (m_paragraphDirectionality == LTR) {
- m_runs.moveRunToEnd(trailingSpaceRun);
+ runs.moveRunToEnd(trailingSpaceRun);
trailingSpaceRun->m_level = 0;
} else {
- m_runs.moveRunToBeginning(trailingSpaceRun);
+ runs.moveRunToBeginning(trailingSpaceRun);
trailingSpaceRun->m_level = 1;
}
m_trailingSpaceRun = trailingSpaceRun;
}
template <class Iterator, class Run>
-bool BidiResolver<Iterator, Run>::commitExplicitEmbedding()
+bool BidiResolver<Iterator, Run>::commitExplicitEmbedding(BidiRunList<Run>& runs)
{
// When we're "inIsolate()" we're resolving the parent context which
// ignores (skips over) the isolated content, including embedding levels.
unsigned char toLevel = toContext->level();
if (toLevel > fromLevel)
- raiseExplicitEmbeddingLevel(fromLevel % 2 ? RightToLeft : LeftToRight, toLevel % 2 ? RightToLeft : LeftToRight);
+ raiseExplicitEmbeddingLevel(runs, fromLevel % 2 ? RightToLeft : LeftToRight, toLevel % 2 ? RightToLeft : LeftToRight);
else if (toLevel < fromLevel)
- lowerExplicitEmbeddingLevel(fromLevel % 2 ? RightToLeft : LeftToRight);
+ lowerExplicitEmbeddingLevel(runs, fromLevel % 2 ? RightToLeft : LeftToRight);
setContext(toContext);
}
template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
+inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels(BidiRunList<Run>& runs) const
{
unsigned char levelLow = BidiContext::kMaxLevel;
unsigned char levelHigh = 0;
- for (Run* run = m_runs.firstRun(); run; run = run->next()) {
+ for (Run* run = runs.firstRun(); run; run = run->next()) {
levelHigh = std::max(run->level(), levelHigh);
levelLow = std::min(run->level(), levelLow);
}
if (!(levelLow % 2))
levelLow++;
- unsigned count = m_runs.runCount() - 1;
+ unsigned count = runs.runCount() - 1;
while (levelHigh >= levelLow) {
unsigned i = 0;
- Run* run = m_runs.firstRun();
+ Run* run = runs.firstRun();
while (i < count) {
for (;i < count && run && run->level() < levelHigh; i++)
run = run->next();
for (;i <= count && run && run->level() >= levelHigh; i++)
run = run->next();
unsigned end = i - 1;
- m_runs.reverseRuns(start, end);
+ runs.reverseRuns(start, end);
}
levelHigh--;
}
increment();
}
m_direction = override == VisualLeftToRightOverride ? LeftToRight : RightToLeft;
- appendRun();
+ appendRun(m_runs);
m_runs.setLogicallyLastRun(m_runs.lastRun());
if (override == VisualRightToLeftOverride && m_runs.runCount())
m_runs.reverseRuns(0, m_runs.runCount() - 1);
case LeftToRightOverride:
case PopDirectionalFormat:
embed(dirCurrent, FromUnicode);
- commitExplicitEmbedding();
+ commitExplicitEmbedding(m_runs);
break;
// strong types
case EuropeanNumber:
case ArabicNumber:
if (m_status.last != EuropeanNumber || m_status.lastStrong != LeftToRight)
- appendRun();
+ appendRun(m_runs);
break;
case LeftToRight:
break;
if (m_status.lastStrong != LeftToRight) {
// the numbers need to be on a higher embedding level, so let's close that run
m_direction = EuropeanNumber;
- appendRun();
+ appendRun(m_runs);
if (context()->dir() != LeftToRight) {
// the neutrals take the embedding direction, which is R
m_eor = m_last;
m_direction = RightToLeft;
- appendRun();
+ appendRun(m_runs);
}
}
} else if (m_status.eor == ArabicNumber) {
// Arabic numbers are always on a higher embedding level, so let's close that run
m_direction = ArabicNumber;
- appendRun();
+ appendRun(m_runs);
if (context()->dir() != LeftToRight) {
// the neutrals take the embedding direction, which is R
m_eor = m_last;
m_direction = RightToLeft;
- appendRun();
+ appendRun(m_runs);
}
} else if (m_status.lastStrong != LeftToRight) {
// last stuff takes embedding dir
m_eor = m_last;
m_direction = RightToLeft;
}
- appendRun();
+ appendRun(m_runs);
}
default:
break;
case LeftToRight:
case EuropeanNumber:
case ArabicNumber:
- appendRun();
+ appendRun(m_runs);
case RightToLeft:
case RightToLeftArabic:
break;
if (m_status.eor == EuropeanNumber) {
if (m_status.lastStrong == LeftToRight && context()->dir() == LeftToRight)
m_eor = m_last;
- appendRun();
+ appendRun(m_runs);
} else if (m_status.eor == ArabicNumber) {
- appendRun();
+ appendRun(m_runs);
} else if (m_status.lastStrong == LeftToRight) {
if (context()->dir() == LeftToRight)
m_eor = m_last;
- appendRun();
+ appendRun(m_runs);
}
default:
break;
case RightToLeftArabic:
case ArabicNumber:
m_eor = m_last;
- appendRun();
+ appendRun(m_runs);
m_direction = EuropeanNumber;
break;
case EuropeanNumberSeparator:
if (m_status.lastStrong == RightToLeft) {
// ENs on both sides behave like Rs, so the neutrals should be R.
// Terminate the EN run.
- appendRun();
+ appendRun(m_runs);
// Make an R run.
m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
- appendRun();
+ appendRun(m_runs);
// Begin a new EN run.
m_direction = EuropeanNumber;
}
} else if (m_status.eor == ArabicNumber) {
// Terminate the AN run.
- appendRun();
+ appendRun(m_runs);
if (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft) {
// Make an R run.
m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
- appendRun();
+ appendRun(m_runs);
// Begin a new EN run.
m_direction = EuropeanNumber;
}
// Extend the R run to include the neutrals.
m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
- appendRun();
+ appendRun(m_runs);
// Begin a new EN run.
m_direction = EuropeanNumber;
}
switch (m_status.last) {
case LeftToRight:
if (context()->dir() == LeftToRight)
- appendRun();
+ appendRun(m_runs);
break;
case ArabicNumber:
break;
case RightToLeftArabic:
case EuropeanNumber:
m_eor = m_last;
- appendRun();
+ appendRun(m_runs);
break;
case CommonNumberSeparator:
if (m_status.eor == ArabicNumber)
|| (m_status.eor == EuropeanNumber && (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft))
|| (m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && context()->dir() == RightToLeft)) {
// Terminate the run before the neutrals.
- appendRun();
+ appendRun(m_runs);
// Begin an R run for the neutrals.
m_direction = RightToLeft;
} else if (m_direction == OtherNeutral) {
m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;
}
m_eor = m_last;
- appendRun();
+ appendRun(m_runs);
default:
break;
}
default:
ASSERT_NOT_REACHED();
}
- appendRun();
+ appendRun(m_runs);
}
m_current = end;
m_status = stateAtEnd.m_status;
increment();
if (!m_currentExplicitEmbeddingSequence.isEmpty()) {
- bool committed = commitExplicitEmbedding();
+ bool committed = commitExplicitEmbedding(m_runs);
if (committed && lastLineEnded) {
m_current = end;
m_status = stateAtEnd.m_status;
m_runs.setLogicallyLastRun(m_runs.lastRun());
if (reorderRuns)
- reorderRunsFromLevels();
+ reorderRunsFromLevels(m_runs);
m_endOfRunAtEndOfLine = Iterator();
m_endOfLine = Iterator();
if (!hardLineBreak && m_runs.runCount())
- applyL1Rule();
+ applyL1Rule(m_runs);
}
template <class Iterator, class Run>
}
-} // namespace WebCore
+} // namespace blink
#endif // BidiResolver_h