| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 { | 171 { |
| 172 return !(status1 == status2); | 172 return !(status1 == status2); |
| 173 } | 173 } |
| 174 | 174 |
| 175 enum VisualDirectionOverride { | 175 enum VisualDirectionOverride { |
| 176 NoVisualOverride, | 176 NoVisualOverride, |
| 177 VisualLeftToRightOverride, | 177 VisualLeftToRightOverride, |
| 178 VisualRightToLeftOverride | 178 VisualRightToLeftOverride |
| 179 }; | 179 }; |
| 180 | 180 |
| 181 class NoIsolatedRun { |
| 182 }; |
| 183 |
| 181 // BidiResolver is WebKit's implementation of the Unicode Bidi Algorithm | 184 // BidiResolver is WebKit's implementation of the Unicode Bidi Algorithm |
| 182 // http://unicode.org/reports/tr9 | 185 // http://unicode.org/reports/tr9 |
| 183 template <class Iterator, class Run> class BidiResolver { | 186 template <class Iterator, class Run, class IsolatedRun = NoIsolatedRun> class Bi
diResolver { |
| 184 WTF_MAKE_NONCOPYABLE(BidiResolver); | 187 WTF_MAKE_NONCOPYABLE(BidiResolver); |
| 185 public: | 188 public: |
| 186 BidiResolver() | 189 BidiResolver() |
| 187 : m_direction(WTF::Unicode::OtherNeutral) | 190 : m_direction(WTF::Unicode::OtherNeutral) |
| 188 , m_reachedEndOfLine(false) | 191 , m_reachedEndOfLine(false) |
| 189 , m_emptyRun(true) | 192 , m_emptyRun(true) |
| 190 , m_nestedIsolateCount(0) | 193 , m_nestedIsolateCount(0) |
| 191 , m_trailingSpaceRun(0) | 194 , m_trailingSpaceRun(0) |
| 192 { | 195 { |
| 193 } | 196 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 bool commitExplicitEmbedding(BidiRunList<Run>&); | 239 bool commitExplicitEmbedding(BidiRunList<Run>&); |
| 237 | 240 |
| 238 void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = No
VisualOverride, bool hardLineBreak = false, bool reorderRuns = true); | 241 void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = No
VisualOverride, bool hardLineBreak = false, bool reorderRuns = true); |
| 239 | 242 |
| 240 BidiRunList<Run>& runs() { return m_runs; } | 243 BidiRunList<Run>& runs() { return m_runs; } |
| 241 | 244 |
| 242 // FIXME: This used to be part of deleteRuns() but was a layering violation. | 245 // FIXME: This used to be part of deleteRuns() but was a layering violation. |
| 243 // It's unclear if this is still needed. | 246 // It's unclear if this is still needed. |
| 244 void markCurrentRunEmpty() { m_emptyRun = true; } | 247 void markCurrentRunEmpty() { m_emptyRun = true; } |
| 245 | 248 |
| 246 Vector<Run*>& isolatedRuns() { return m_isolatedRuns; } | 249 Vector<IsolatedRun>& isolatedRuns() { return m_isolatedRuns; } |
| 247 | 250 |
| 248 bool isEndOfLine(const Iterator& end) { return m_current == end || m_current
.atEnd(); } | 251 bool isEndOfLine(const Iterator& end) { return m_current == end || m_current
.atEnd(); } |
| 249 | 252 |
| 250 TextDirection determineParagraphDirectionality(bool* hasStrongDirectionality
= 0) | 253 TextDirection determineParagraphDirectionality(bool* hasStrongDirectionality
= 0) |
| 251 { | 254 { |
| 252 bool breakOnParagraph = true; | 255 bool breakOnParagraph = true; |
| 253 return determineDirectionalityInternal(breakOnParagraph, hasStrongDirect
ionality); | 256 return determineDirectionalityInternal(breakOnParagraph, hasStrongDirect
ionality); |
| 254 } | 257 } |
| 255 TextDirection determineDirectionality(bool* hasStrongDirectionality = 0) | 258 TextDirection determineDirectionality(bool* hasStrongDirectionality = 0) |
| 256 { | 259 { |
| 257 bool breakOnParagraph = false; | 260 bool breakOnParagraph = false; |
| 258 return determineDirectionalityInternal(breakOnParagraph, hasStrongDirect
ionality); | 261 return determineDirectionalityInternal(breakOnParagraph, hasStrongDirect
ionality); |
| 259 } | 262 } |
| 260 | 263 |
| 261 void setMidpointStateForIsolatedRun(Run*, const MidpointState<Iterator>&); | 264 void setMidpointStateForIsolatedRun(Run&, const MidpointState<Iterator>&); |
| 262 MidpointState<Iterator> midpointStateForIsolatedRun(Run*); | 265 MidpointState<Iterator> midpointStateForIsolatedRun(Run&); |
| 263 | 266 |
| 264 Iterator endOfLine() const { return m_endOfLine; } | 267 Iterator endOfLine() const { return m_endOfLine; } |
| 265 | 268 |
| 266 Run* trailingSpaceRun() const { return m_trailingSpaceRun; } | 269 Run* trailingSpaceRun() const { return m_trailingSpaceRun; } |
| 267 | 270 |
| 268 protected: | 271 protected: |
| 269 void increment() { m_current.increment(); } | 272 void increment() { m_current.increment(); } |
| 270 // FIXME: Instead of InlineBidiResolvers subclassing this method, we should | 273 // FIXME: Instead of InlineBidiResolvers subclassing this method, we should |
| 271 // pass in some sort of Traits object which knows how to create runs for app
ending. | 274 // pass in some sort of Traits object which knows how to create runs for app
ending. |
| 272 void appendRun(BidiRunList<Run>&); | 275 void appendRun(BidiRunList<Run>&); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 287 Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator | 290 Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator |
| 288 bool m_emptyRun; | 291 bool m_emptyRun; |
| 289 | 292 |
| 290 // FIXME: This should not belong to the resolver, but rather be passed | 293 // FIXME: This should not belong to the resolver, but rather be passed |
| 291 // into createBidiRunsForLine by the caller. | 294 // into createBidiRunsForLine by the caller. |
| 292 BidiRunList<Run> m_runs; | 295 BidiRunList<Run> m_runs; |
| 293 | 296 |
| 294 MidpointState<Iterator> m_midpointState; | 297 MidpointState<Iterator> m_midpointState; |
| 295 | 298 |
| 296 unsigned m_nestedIsolateCount; | 299 unsigned m_nestedIsolateCount; |
| 297 Vector<Run*> m_isolatedRuns; | 300 Vector<IsolatedRun> m_isolatedRuns; |
| 298 Run* m_trailingSpaceRun; | 301 Run* m_trailingSpaceRun; |
| 299 TextDirection m_paragraphDirectionality; | 302 TextDirection m_paragraphDirectionality; |
| 300 | 303 |
| 301 private: | 304 private: |
| 302 void raiseExplicitEmbeddingLevel(BidiRunList<Run>&, WTF::Unicode::Direction
from, WTF::Unicode::Direction to); | 305 void raiseExplicitEmbeddingLevel(BidiRunList<Run>&, WTF::Unicode::Direction
from, WTF::Unicode::Direction to); |
| 303 void lowerExplicitEmbeddingLevel(BidiRunList<Run>&, WTF::Unicode::Direction
from); | 306 void lowerExplicitEmbeddingLevel(BidiRunList<Run>&, WTF::Unicode::Direction
from); |
| 304 void checkDirectionInLowerRaiseEmbeddingLevel(); | 307 void checkDirectionInLowerRaiseEmbeddingLevel(); |
| 305 | 308 |
| 306 void updateStatusLastFromCurrentDirection(WTF::Unicode::Direction); | 309 void updateStatusLastFromCurrentDirection(WTF::Unicode::Direction); |
| 307 void reorderRunsFromLevels(BidiRunList<Run>&) const; | 310 void reorderRunsFromLevels(BidiRunList<Run>&) const; |
| 308 | 311 |
| 309 bool needsToApplyL1Rule(BidiRunList<Run>&) { return false; } | 312 bool needsToApplyL1Rule(BidiRunList<Run>&) { return false; } |
| 310 int findFirstTrailingSpaceAtRun(Run*) { return 0; } | 313 int findFirstTrailingSpaceAtRun(Run*) { return 0; } |
| 311 // http://www.unicode.org/reports/tr9/#L1 | 314 // http://www.unicode.org/reports/tr9/#L1 |
| 312 void applyL1Rule(BidiRunList<Run>&); | 315 void applyL1Rule(BidiRunList<Run>&); |
| 313 | 316 |
| 314 TextDirection determineDirectionalityInternal(bool breakOnParagraph, bool* h
asStrongDirectionality); | 317 TextDirection determineDirectionalityInternal(bool breakOnParagraph, bool* h
asStrongDirectionality); |
| 315 | 318 |
| 316 Vector<BidiEmbedding, 8> m_currentExplicitEmbeddingSequence; | 319 Vector<BidiEmbedding, 8> m_currentExplicitEmbeddingSequence; |
| 317 HashMap<Run *, MidpointState<Iterator>> m_midpointStateForIsolatedRun; | 320 HashMap<Run *, MidpointState<Iterator>> m_midpointStateForIsolatedRun; |
| 318 }; | 321 }; |
| 319 | 322 |
| 320 #if ENABLE(ASSERT) | 323 #if ENABLE(ASSERT) |
| 321 template <class Iterator, class Run> | 324 template <class Iterator, class Run, class IsolatedRun> |
| 322 BidiResolver<Iterator, Run>::~BidiResolver() | 325 BidiResolver<Iterator, Run, IsolatedRun>::~BidiResolver() |
| 323 { | 326 { |
| 324 // The owner of this resolver should have handled the isolated runs. | 327 // The owner of this resolver should have handled the isolated runs. |
| 325 ASSERT(m_isolatedRuns.isEmpty()); | 328 ASSERT(m_isolatedRuns.isEmpty()); |
| 326 } | 329 } |
| 327 #endif | 330 #endif |
| 328 | 331 |
| 329 template <class Iterator, class Run> | 332 template <class Iterator, class Run, class IsolatedRun> |
| 330 void BidiResolver<Iterator, Run>::appendRun(BidiRunList<Run>& runs) | 333 void BidiResolver<Iterator, Run, IsolatedRun>::appendRun(BidiRunList<Run>& runs) |
| 331 { | 334 { |
| 332 if (!m_emptyRun && !m_eor.atEnd()) { | 335 if (!m_emptyRun && !m_eor.atEnd()) { |
| 333 unsigned startOffset = m_sor.offset(); | 336 unsigned startOffset = m_sor.offset(); |
| 334 unsigned endOffset = m_eor.offset(); | 337 unsigned endOffset = m_eor.offset(); |
| 335 | 338 |
| 336 if (!m_endOfRunAtEndOfLine.atEnd() && endOffset >= m_endOfRunAtEndOfLine
.offset()) { | 339 if (!m_endOfRunAtEndOfLine.atEnd() && endOffset >= m_endOfRunAtEndOfLine
.offset()) { |
| 337 m_reachedEndOfLine = true; | 340 m_reachedEndOfLine = true; |
| 338 endOffset = m_endOfRunAtEndOfLine.offset(); | 341 endOffset = m_endOfRunAtEndOfLine.offset(); |
| 339 } | 342 } |
| 340 | 343 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 354 } | 357 } |
| 355 | 358 |
| 356 m_eor.increment(); | 359 m_eor.increment(); |
| 357 m_sor = m_eor; | 360 m_sor = m_eor; |
| 358 } | 361 } |
| 359 | 362 |
| 360 m_direction = WTF::Unicode::OtherNeutral; | 363 m_direction = WTF::Unicode::OtherNeutral; |
| 361 m_status.eor = WTF::Unicode::OtherNeutral; | 364 m_status.eor = WTF::Unicode::OtherNeutral; |
| 362 } | 365 } |
| 363 | 366 |
| 364 template <class Iterator, class Run> | 367 template <class Iterator, class Run, class IsolatedRun> |
| 365 void BidiResolver<Iterator, Run>::embed(WTF::Unicode::Direction dir, BidiEmbeddi
ngSource source) | 368 void BidiResolver<Iterator, Run, IsolatedRun>::embed(WTF::Unicode::Direction dir
, BidiEmbeddingSource source) |
| 366 { | 369 { |
| 367 // Isolated spans compute base directionality during their own UBA run. | 370 // Isolated spans compute base directionality during their own UBA run. |
| 368 // Do not insert fake embed characters once we enter an isolated span. | 371 // Do not insert fake embed characters once we enter an isolated span. |
| 369 ASSERT(!inIsolate()); | 372 ASSERT(!inIsolate()); |
| 370 using namespace WTF::Unicode; | 373 using namespace WTF::Unicode; |
| 371 | 374 |
| 372 ASSERT(dir == PopDirectionalFormat || dir == LeftToRightEmbedding || dir ==
LeftToRightOverride || dir == RightToLeftEmbedding || dir == RightToLeftOverride
); | 375 ASSERT(dir == PopDirectionalFormat || dir == LeftToRightEmbedding || dir ==
LeftToRightOverride || dir == RightToLeftEmbedding || dir == RightToLeftOverride
); |
| 373 m_currentExplicitEmbeddingSequence.append(BidiEmbedding(dir, source)); | 376 m_currentExplicitEmbeddingSequence.append(BidiEmbedding(dir, source)); |
| 374 } | 377 } |
| 375 | 378 |
| 376 template <class Iterator, class Run> | 379 template <class Iterator, class Run, class IsolatedRun> |
| 377 void BidiResolver<Iterator, Run>::checkDirectionInLowerRaiseEmbeddingLevel() | 380 void BidiResolver<Iterator, Run, IsolatedRun>::checkDirectionInLowerRaiseEmbeddi
ngLevel() |
| 378 { | 381 { |
| 379 using namespace WTF::Unicode; | 382 using namespace WTF::Unicode; |
| 380 | 383 |
| 381 ASSERT(m_status.eor != OtherNeutral || m_eor.atEnd()); | 384 ASSERT(m_status.eor != OtherNeutral || m_eor.atEnd()); |
| 382 ASSERT(m_status.last != NonSpacingMark | 385 ASSERT(m_status.last != NonSpacingMark |
| 383 && m_status.last != BoundaryNeutral | 386 && m_status.last != BoundaryNeutral |
| 384 && m_status.last != RightToLeftEmbedding | 387 && m_status.last != RightToLeftEmbedding |
| 385 && m_status.last != LeftToRightEmbedding | 388 && m_status.last != LeftToRightEmbedding |
| 386 && m_status.last != RightToLeftOverride | 389 && m_status.last != RightToLeftOverride |
| 387 && m_status.last != LeftToRightOverride | 390 && m_status.last != LeftToRightOverride |
| 388 && m_status.last != PopDirectionalFormat); | 391 && m_status.last != PopDirectionalFormat); |
| 389 if (m_direction == OtherNeutral) | 392 if (m_direction == OtherNeutral) |
| 390 m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightTo
Left; | 393 m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightTo
Left; |
| 391 } | 394 } |
| 392 | 395 |
| 393 template <class Iterator, class Run> | 396 template <class Iterator, class Run, class IsolatedRun> |
| 394 void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(BidiRunList<Run>&
runs, WTF::Unicode::Direction from) | 397 void BidiResolver<Iterator, Run, IsolatedRun>::lowerExplicitEmbeddingLevel(BidiR
unList<Run>& runs, WTF::Unicode::Direction from) |
| 395 { | 398 { |
| 396 using namespace WTF::Unicode; | 399 using namespace WTF::Unicode; |
| 397 | 400 |
| 398 if (!m_emptyRun && m_eor != m_last) { | 401 if (!m_emptyRun && m_eor != m_last) { |
| 399 checkDirectionInLowerRaiseEmbeddingLevel(); | 402 checkDirectionInLowerRaiseEmbeddingLevel(); |
| 400 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-
bidi.eor run or extend it through bidi.last | 403 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-
bidi.eor run or extend it through bidi.last |
| 401 if (from == LeftToRight) { | 404 if (from == LeftToRight) { |
| 402 // bidi.sor ... bidi.eor ... bidi.last L | 405 // bidi.sor ... bidi.eor ... bidi.last L |
| 403 if (m_status.eor == EuropeanNumber) { | 406 if (m_status.eor == EuropeanNumber) { |
| 404 if (m_status.lastStrong != LeftToRight) { | 407 if (m_status.lastStrong != LeftToRight) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 421 | 424 |
| 422 appendRun(runs); | 425 appendRun(runs); |
| 423 m_emptyRun = true; | 426 m_emptyRun = true; |
| 424 | 427 |
| 425 // sor for the new run is determined by the higher level (rule X10) | 428 // sor for the new run is determined by the higher level (rule X10) |
| 426 setLastDir(from); | 429 setLastDir(from); |
| 427 setLastStrongDir(from); | 430 setLastStrongDir(from); |
| 428 m_eor = Iterator(); | 431 m_eor = Iterator(); |
| 429 } | 432 } |
| 430 | 433 |
| 431 template <class Iterator, class Run> | 434 template <class Iterator, class Run, class IsolatedRun> |
| 432 void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(BidiRunList<Run>&
runs, WTF::Unicode::Direction from, WTF::Unicode::Direction to) | 435 void BidiResolver<Iterator, Run, IsolatedRun>::raiseExplicitEmbeddingLevel(BidiR
unList<Run>& runs, WTF::Unicode::Direction from, WTF::Unicode::Direction to) |
| 433 { | 436 { |
| 434 using namespace WTF::Unicode; | 437 using namespace WTF::Unicode; |
| 435 | 438 |
| 436 if (!m_emptyRun && m_eor != m_last) { | 439 if (!m_emptyRun && m_eor != m_last) { |
| 437 checkDirectionInLowerRaiseEmbeddingLevel(); | 440 checkDirectionInLowerRaiseEmbeddingLevel(); |
| 438 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-
bidi.eor run or extend it through bidi.last | 441 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-
bidi.eor run or extend it through bidi.last |
| 439 if (to == LeftToRight) { | 442 if (to == LeftToRight) { |
| 440 // bidi.sor ... bidi.eor ... bidi.last L | 443 // bidi.sor ... bidi.eor ... bidi.last L |
| 441 if (m_status.eor == EuropeanNumber) { | 444 if (m_status.eor == EuropeanNumber) { |
| 442 if (m_status.lastStrong != LeftToRight) { | 445 if (m_status.lastStrong != LeftToRight) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 460 } | 463 } |
| 461 | 464 |
| 462 appendRun(runs); | 465 appendRun(runs); |
| 463 m_emptyRun = true; | 466 m_emptyRun = true; |
| 464 | 467 |
| 465 setLastDir(to); | 468 setLastDir(to); |
| 466 setLastStrongDir(to); | 469 setLastStrongDir(to); |
| 467 m_eor = Iterator(); | 470 m_eor = Iterator(); |
| 468 } | 471 } |
| 469 | 472 |
| 470 template <class Iterator, class Run> | 473 template <class Iterator, class Run, class IsolatedRun> |
| 471 void BidiResolver<Iterator, Run>::applyL1Rule(BidiRunList<Run>& runs) | 474 void BidiResolver<Iterator, Run, IsolatedRun>::applyL1Rule(BidiRunList<Run>& run
s) |
| 472 { | 475 { |
| 473 ASSERT(runs.runCount()); | 476 ASSERT(runs.runCount()); |
| 474 if (!needsToApplyL1Rule(runs)) | 477 if (!needsToApplyL1Rule(runs)) |
| 475 return; | 478 return; |
| 476 | 479 |
| 477 Run* trailingSpaceRun = runs.logicallyLastRun(); | 480 Run* trailingSpaceRun = runs.logicallyLastRun(); |
| 478 | 481 |
| 479 int firstSpace = findFirstTrailingSpaceAtRun(trailingSpaceRun); | 482 int firstSpace = findFirstTrailingSpaceAtRun(trailingSpaceRun); |
| 480 if (firstSpace == trailingSpaceRun->stop()) | 483 if (firstSpace == trailingSpaceRun->stop()) |
| 481 return; | 484 return; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 499 if (m_paragraphDirectionality == LTR) { | 502 if (m_paragraphDirectionality == LTR) { |
| 500 runs.moveRunToEnd(trailingSpaceRun); | 503 runs.moveRunToEnd(trailingSpaceRun); |
| 501 trailingSpaceRun->m_level = 0; | 504 trailingSpaceRun->m_level = 0; |
| 502 } else { | 505 } else { |
| 503 runs.moveRunToBeginning(trailingSpaceRun); | 506 runs.moveRunToBeginning(trailingSpaceRun); |
| 504 trailingSpaceRun->m_level = 1; | 507 trailingSpaceRun->m_level = 1; |
| 505 } | 508 } |
| 506 m_trailingSpaceRun = trailingSpaceRun; | 509 m_trailingSpaceRun = trailingSpaceRun; |
| 507 } | 510 } |
| 508 | 511 |
| 509 template <class Iterator, class Run> | 512 template <class Iterator, class Run, class IsolatedRun> |
| 510 bool BidiResolver<Iterator, Run>::commitExplicitEmbedding(BidiRunList<Run>& runs
) | 513 bool BidiResolver<Iterator, Run, IsolatedRun>::commitExplicitEmbedding(BidiRunLi
st<Run>& runs) |
| 511 { | 514 { |
| 512 // When we're "inIsolate()" we're resolving the parent context which | 515 // When we're "inIsolate()" we're resolving the parent context which |
| 513 // ignores (skips over) the isolated content, including embedding levels. | 516 // ignores (skips over) the isolated content, including embedding levels. |
| 514 // We should never accrue embedding levels while skipping over isolated cont
ent. | 517 // We should never accrue embedding levels while skipping over isolated cont
ent. |
| 515 ASSERT(!inIsolate() || m_currentExplicitEmbeddingSequence.isEmpty()); | 518 ASSERT(!inIsolate() || m_currentExplicitEmbeddingSequence.isEmpty()); |
| 516 | 519 |
| 517 using namespace WTF::Unicode; | 520 using namespace WTF::Unicode; |
| 518 | 521 |
| 519 unsigned char fromLevel = context()->level(); | 522 unsigned char fromLevel = context()->level(); |
| 520 RefPtr<BidiContext> toContext = context(); | 523 RefPtr<BidiContext> toContext = context(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 544 else if (toLevel < fromLevel) | 547 else if (toLevel < fromLevel) |
| 545 lowerExplicitEmbeddingLevel(runs, fromLevel % 2 ? RightToLeft : LeftToRi
ght); | 548 lowerExplicitEmbeddingLevel(runs, fromLevel % 2 ? RightToLeft : LeftToRi
ght); |
| 546 | 549 |
| 547 setContext(toContext); | 550 setContext(toContext); |
| 548 | 551 |
| 549 m_currentExplicitEmbeddingSequence.clear(); | 552 m_currentExplicitEmbeddingSequence.clear(); |
| 550 | 553 |
| 551 return fromLevel != toLevel; | 554 return fromLevel != toLevel; |
| 552 } | 555 } |
| 553 | 556 |
| 554 template <class Iterator, class Run> | 557 template <class Iterator, class Run, class IsolatedRun> |
| 555 inline void BidiResolver<Iterator, Run>::updateStatusLastFromCurrentDirection(WT
F::Unicode::Direction dirCurrent) | 558 inline void BidiResolver<Iterator, Run, IsolatedRun>::updateStatusLastFromCurren
tDirection(WTF::Unicode::Direction dirCurrent) |
| 556 { | 559 { |
| 557 using namespace WTF::Unicode; | 560 using namespace WTF::Unicode; |
| 558 switch (dirCurrent) { | 561 switch (dirCurrent) { |
| 559 case EuropeanNumberTerminator: | 562 case EuropeanNumberTerminator: |
| 560 if (m_status.last != EuropeanNumber) | 563 if (m_status.last != EuropeanNumber) |
| 561 m_status.last = EuropeanNumberTerminator; | 564 m_status.last = EuropeanNumberTerminator; |
| 562 break; | 565 break; |
| 563 case EuropeanNumberSeparator: | 566 case EuropeanNumberSeparator: |
| 564 case CommonNumberSeparator: | 567 case CommonNumberSeparator: |
| 565 case SegmentSeparator: | 568 case SegmentSeparator: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 586 case PopDirectionalFormat: | 589 case PopDirectionalFormat: |
| 587 // ignore these | 590 // ignore these |
| 588 break; | 591 break; |
| 589 case EuropeanNumber: | 592 case EuropeanNumber: |
| 590 // fall through | 593 // fall through |
| 591 default: | 594 default: |
| 592 m_status.last = dirCurrent; | 595 m_status.last = dirCurrent; |
| 593 } | 596 } |
| 594 } | 597 } |
| 595 | 598 |
| 596 template <class Iterator, class Run> | 599 template <class Iterator, class Run, class IsolatedRun> |
| 597 inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels(BidiRunList<Run>&
runs) const | 600 inline void BidiResolver<Iterator, Run, IsolatedRun>::reorderRunsFromLevels(Bidi
RunList<Run>& runs) const |
| 598 { | 601 { |
| 599 unsigned char levelLow = BidiContext::kMaxLevel; | 602 unsigned char levelLow = BidiContext::kMaxLevel; |
| 600 unsigned char levelHigh = 0; | 603 unsigned char levelHigh = 0; |
| 601 for (Run* run = runs.firstRun(); run; run = run->next()) { | 604 for (Run* run = runs.firstRun(); run; run = run->next()) { |
| 602 levelHigh = std::max(run->level(), levelHigh); | 605 levelHigh = std::max(run->level(), levelHigh); |
| 603 levelLow = std::min(run->level(), levelLow); | 606 levelLow = std::min(run->level(), levelLow); |
| 604 } | 607 } |
| 605 | 608 |
| 606 // This implements reordering of the line (L2 according to Bidi spec): | 609 // This implements reordering of the line (L2 according to Bidi spec): |
| 607 // http://unicode.org/reports/tr9/#L2 | 610 // http://unicode.org/reports/tr9/#L2 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 623 unsigned start = i; | 626 unsigned start = i; |
| 624 for (;i <= count && run && run->level() >= levelHigh; i++) | 627 for (;i <= count && run && run->level() >= levelHigh; i++) |
| 625 run = run->next(); | 628 run = run->next(); |
| 626 unsigned end = i - 1; | 629 unsigned end = i - 1; |
| 627 runs.reverseRuns(start, end); | 630 runs.reverseRuns(start, end); |
| 628 } | 631 } |
| 629 levelHigh--; | 632 levelHigh--; |
| 630 } | 633 } |
| 631 } | 634 } |
| 632 | 635 |
| 633 template <class Iterator, class Run> | 636 template <class Iterator, class Run, class IsolatedRun> |
| 634 TextDirection BidiResolver<Iterator, Run>::determineDirectionalityInternal( | 637 TextDirection BidiResolver<Iterator, Run, IsolatedRun>::determineDirectionalityI
nternal( |
| 635 bool breakOnParagraph, bool* hasStrongDirectionality) | 638 bool breakOnParagraph, bool* hasStrongDirectionality) |
| 636 { | 639 { |
| 637 while (!m_current.atEnd()) { | 640 while (!m_current.atEnd()) { |
| 638 if (inIsolate()) { | 641 if (inIsolate()) { |
| 639 increment(); | 642 increment(); |
| 640 continue; | 643 continue; |
| 641 } | 644 } |
| 642 if (breakOnParagraph && m_current.atParagraphSeparator()) | 645 if (breakOnParagraph && m_current.atParagraphSeparator()) |
| 643 break; | 646 break; |
| 644 UChar32 current = m_current.current(); | 647 UChar32 current = m_current.current(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 675 } | 678 } |
| 676 | 679 |
| 677 inline TextDirection directionForCharacter(UChar32 character) | 680 inline TextDirection directionForCharacter(UChar32 character) |
| 678 { | 681 { |
| 679 WTF::Unicode::Direction charDirection = WTF::Unicode::direction(character); | 682 WTF::Unicode::Direction charDirection = WTF::Unicode::direction(character); |
| 680 if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unic
ode::RightToLeftArabic) | 683 if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unic
ode::RightToLeftArabic) |
| 681 return RTL; | 684 return RTL; |
| 682 return LTR; | 685 return LTR; |
| 683 } | 686 } |
| 684 | 687 |
| 685 template <class Iterator, class Run> | 688 template <class Iterator, class Run, class IsolatedRun> |
| 686 void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
ualDirectionOverride override, bool hardLineBreak, bool reorderRuns) | 689 void BidiResolver<Iterator, Run, IsolatedRun>::createBidiRunsForLine(const Itera
tor& end, VisualDirectionOverride override, bool hardLineBreak, bool reorderRuns
) |
| 687 { | 690 { |
| 688 using namespace WTF::Unicode; | 691 using namespace WTF::Unicode; |
| 689 | 692 |
| 690 ASSERT(m_direction == OtherNeutral); | 693 ASSERT(m_direction == OtherNeutral); |
| 691 m_trailingSpaceRun = 0; | 694 m_trailingSpaceRun = 0; |
| 692 | 695 |
| 693 m_endOfLine = end; | 696 m_endOfLine = end; |
| 694 | 697 |
| 695 if (override != NoVisualOverride) { | 698 if (override != NoVisualOverride) { |
| 696 m_emptyRun = false; | 699 m_emptyRun = false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 707 m_runs.reverseRuns(0, m_runs.runCount() - 1); | 710 m_runs.reverseRuns(0, m_runs.runCount() - 1); |
| 708 return; | 711 return; |
| 709 } | 712 } |
| 710 | 713 |
| 711 m_emptyRun = true; | 714 m_emptyRun = true; |
| 712 | 715 |
| 713 m_eor = Iterator(); | 716 m_eor = Iterator(); |
| 714 | 717 |
| 715 m_last = m_current; | 718 m_last = m_current; |
| 716 bool lastLineEnded = false; | 719 bool lastLineEnded = false; |
| 717 BidiResolver<Iterator, Run> stateAtEnd; | 720 BidiResolver<Iterator, Run, IsolatedRun> stateAtEnd; |
| 718 | 721 |
| 719 while (true) { | 722 while (true) { |
| 720 if (inIsolate() && m_emptyRun) { | 723 if (inIsolate() && m_emptyRun) { |
| 721 m_sor = m_current; | 724 m_sor = m_current; |
| 722 m_emptyRun = false; | 725 m_emptyRun = false; |
| 723 } | 726 } |
| 724 | 727 |
| 725 if (!lastLineEnded && isEndOfLine(end)) { | 728 if (!lastLineEnded && isEndOfLine(end)) { |
| 726 if (m_emptyRun) | 729 if (m_emptyRun) |
| 727 break; | 730 break; |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1084 m_runs.setLogicallyLastRun(m_runs.lastRun()); | 1087 m_runs.setLogicallyLastRun(m_runs.lastRun()); |
| 1085 if (reorderRuns) | 1088 if (reorderRuns) |
| 1086 reorderRunsFromLevels(m_runs); | 1089 reorderRunsFromLevels(m_runs); |
| 1087 m_endOfRunAtEndOfLine = Iterator(); | 1090 m_endOfRunAtEndOfLine = Iterator(); |
| 1088 m_endOfLine = Iterator(); | 1091 m_endOfLine = Iterator(); |
| 1089 | 1092 |
| 1090 if (!hardLineBreak && m_runs.runCount()) | 1093 if (!hardLineBreak && m_runs.runCount()) |
| 1091 applyL1Rule(m_runs); | 1094 applyL1Rule(m_runs); |
| 1092 } | 1095 } |
| 1093 | 1096 |
| 1094 template <class Iterator, class Run> | 1097 template <class Iterator, class Run, class IsolatedRun> |
| 1095 void BidiResolver<Iterator, Run>::setMidpointStateForIsolatedRun(Run* run, const
MidpointState<Iterator>& midpoint) | 1098 void BidiResolver<Iterator, Run, IsolatedRun>::setMidpointStateForIsolatedRun(Ru
n& run, const MidpointState<Iterator>& midpoint) |
| 1096 { | 1099 { |
| 1097 ASSERT(!m_midpointStateForIsolatedRun.contains(run)); | 1100 ASSERT(!m_midpointStateForIsolatedRun.contains(&run)); |
| 1098 m_midpointStateForIsolatedRun.add(run, midpoint); | 1101 m_midpointStateForIsolatedRun.add(&run, midpoint); |
| 1099 } | 1102 } |
| 1100 | 1103 |
| 1101 template<class Iterator, class Run> | 1104 template<class Iterator, class Run, class IsolatedRun> |
| 1102 MidpointState<Iterator> BidiResolver<Iterator, Run>::midpointStateForIsolatedRun
(Run* run) | 1105 MidpointState<Iterator> BidiResolver<Iterator, Run, IsolatedRun>::midpointStateF
orIsolatedRun(Run& run) |
| 1103 { | 1106 { |
| 1104 return m_midpointStateForIsolatedRun.take(run); | 1107 return m_midpointStateForIsolatedRun.take(&run); |
| 1105 } | 1108 } |
| 1106 | 1109 |
| 1107 | |
| 1108 } // namespace blink | 1110 } // namespace blink |
| 1109 | 1111 |
| 1110 #endif // BidiResolver_h | 1112 #endif // BidiResolver_h |
| OLD | NEW |