| 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, 2009, 2010 Apple Inc. All right r
eserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right r
eserved. |
| 4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 while (object && object != iter.root()) { | 415 while (object && object != iter.root()) { |
| 416 if (isIsolatedInline(object)) | 416 if (isIsolatedInline(object)) |
| 417 count++; | 417 count++; |
| 418 object = object->parent(); | 418 object = object->parent(); |
| 419 } | 419 } |
| 420 return count; | 420 return count; |
| 421 } | 421 } |
| 422 | 422 |
| 423 // FIXME: This belongs on InlineBidiResolver, except it's a template specializat
ion | 423 // FIXME: This belongs on InlineBidiResolver, except it's a template specializat
ion |
| 424 // of BidiResolver which knows nothing about RenderObjects. | 424 // of BidiResolver which knows nothing about RenderObjects. |
| 425 static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv
er, RenderObject* isolatedInline) | 425 static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv
er, RenderObject* obj, unsigned pos) |
| 426 { | 426 { |
| 427 ASSERT(isolatedInline); | 427 ASSERT(obj); |
| 428 BidiRun* isolatedRun = new (isolatedInline->renderArena()) BidiRun(0, 0, iso
latedInline, resolver.context(), resolver.dir()); | 428 BidiRun* isolatedRun = new (obj->renderArena()) BidiRun(pos, 0, obj, resolve
r.context(), resolver.dir()); |
| 429 resolver.runs().addRun(isolatedRun); | 429 resolver.runs().addRun(isolatedRun); |
| 430 // FIXME: isolatedRuns() could be a hash of object->run and then we could ch
eaply | 430 // FIXME: isolatedRuns() could be a hash of object->run and then we could ch
eaply |
| 431 // ASSERT here that we didn't create multiple objects for the same inline. | 431 // ASSERT here that we didn't create multiple objects for the same inline. |
| 432 resolver.isolatedRuns().append(isolatedRun); | 432 resolver.isolatedRuns().append(isolatedRun); |
| 433 } | 433 } |
| 434 | 434 |
| 435 class IsolateTracker { | 435 class IsolateTracker { |
| 436 public: | 436 public: |
| 437 explicit IsolateTracker(unsigned nestedIsolateCount) | 437 explicit IsolateTracker(unsigned nestedIsolateCount) |
| 438 : m_nestedIsolateCount(nestedIsolateCount) | 438 : m_nestedIsolateCount(nestedIsolateCount) |
| 439 , m_haveAddedFakeRunForRootIsolate(false) | 439 , m_haveAddedFakeRunForRootIsolate(false) |
| 440 { | 440 { |
| 441 } | 441 } |
| 442 | 442 |
| 443 void enterIsolate() { m_nestedIsolateCount++; } | 443 void enterIsolate() { m_nestedIsolateCount++; } |
| 444 void exitIsolate() | 444 void exitIsolate() |
| 445 { | 445 { |
| 446 ASSERT(m_nestedIsolateCount >= 1); | 446 ASSERT(m_nestedIsolateCount >= 1); |
| 447 m_nestedIsolateCount--; | 447 m_nestedIsolateCount--; |
| 448 if (!inIsolate()) | 448 if (!inIsolate()) |
| 449 m_haveAddedFakeRunForRootIsolate = false; | 449 m_haveAddedFakeRunForRootIsolate = false; |
| 450 } | 450 } |
| 451 bool inIsolate() const { return m_nestedIsolateCount; } | 451 bool inIsolate() const { return m_nestedIsolateCount; } |
| 452 | 452 |
| 453 // We don't care if we encounter bidi directional overrides. | 453 // We don't care if we encounter bidi directional overrides. |
| 454 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } | 454 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } |
| 455 | 455 |
| 456 void addFakeRunIfNecessary(RenderObject* obj, InlineBidiResolver& resolver) | 456 void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, InlineBidiResolv
er& resolver) |
| 457 { | 457 { |
| 458 // We only need to lookup the root isolated span and add a fake run | 458 // We only need to add a fake run for a given isolated span once during
each call to createBidiRunsForLine. |
| 459 // for it once, but we'll be called for every span inside the isolated s
pan | 459 // We'll be called for every span inside the isolated span so we just ig
nore subsequent calls. |
| 460 // so we just ignore the call. | |
| 461 if (m_haveAddedFakeRunForRootIsolate) | 460 if (m_haveAddedFakeRunForRootIsolate) |
| 462 return; | 461 return; |
| 463 m_haveAddedFakeRunForRootIsolate = true; | 462 m_haveAddedFakeRunForRootIsolate = true; |
| 464 | 463 // obj and pos together denote a single position in the inline, from whi
ch the parsing of the isolate will start. |
| 465 // FIXME: position() could be outside the run and may be the wrong call
here. | 464 // We don't need to mark the end of the run because this is implicit: it
is either endOfLine or the end of the |
| 466 // If we were passed an InlineIterator instead that would have the right
root(). | 465 // isolate, when we call createBidiRunsForLine it will stop at whichever
comes first. |
| 467 RenderObject* isolatedInline = containingIsolate(obj, resolver.position(
).root()); | 466 addPlaceholderRunForIsolatedInline(resolver, obj, pos); |
| 468 // FIXME: Because enterIsolate is not passed a RenderObject, we have to
crawl up the | |
| 469 // tree to see which parent inline is the isolate. We could change enter
Isolate | |
| 470 // to take a RenderObject and do this logic there, but that would be a l
ayering | |
| 471 // violation for BidiResolver (which knows nothing about RenderObject). | |
| 472 addPlaceholderRunForIsolatedInline(resolver, isolatedInline); | |
| 473 } | 467 } |
| 474 | 468 |
| 475 private: | 469 private: |
| 476 unsigned m_nestedIsolateCount; | 470 unsigned m_nestedIsolateCount; |
| 477 bool m_haveAddedFakeRunForRootIsolate; | 471 bool m_haveAddedFakeRunForRootIsolate; |
| 478 }; | 472 }; |
| 479 | 473 |
| 480 template <> | 474 template <> |
| 481 inline void InlineBidiResolver::appendRun() | 475 inline void InlineBidiResolver::appendRun() |
| 482 { | 476 { |
| 483 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { | 477 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { |
| 484 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. | 478 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. |
| 485 // Initialize our state depending on if we're starting in the middle of
such an inline. | 479 // Initialize our state depending on if we're starting in the middle of
such an inline. |
| 486 // FIXME: Could this initialize from this->inIsolate() instead of walkin
g up the render tree? | 480 // FIXME: Could this initialize from this->inIsolate() instead of walkin
g up the render tree? |
| 487 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); | 481 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); |
| 488 int start = m_sor.m_pos; | 482 int start = m_sor.m_pos; |
| 489 RenderObject* obj = m_sor.m_obj; | 483 RenderObject* obj = m_sor.m_obj; |
| 490 while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) { | 484 while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) { |
| 491 if (isolateTracker.inIsolate()) | 485 if (isolateTracker.inIsolate()) |
| 492 isolateTracker.addFakeRunIfNecessary(obj, *this); | 486 isolateTracker.addFakeRunIfNecessary(obj, start, *this); |
| 493 else | 487 else |
| 494 RenderBlock::appendRunsForObject(m_runs, start, obj->length(), o
bj, *this); | 488 RenderBlock::appendRunsForObject(m_runs, start, obj->length(), o
bj, *this); |
| 495 // FIXME: start/obj should be an InlineIterator instead of two separ
ate variables. | 489 // FIXME: start/obj should be an InlineIterator instead of two separ
ate variables. |
| 496 start = 0; | 490 start = 0; |
| 497 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke
r); | 491 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke
r); |
| 498 } | 492 } |
| 499 if (obj) { | 493 if (obj) { |
| 500 unsigned pos = obj == m_eor.m_obj ? m_eor.m_pos : UINT_MAX; | 494 unsigned pos = obj == m_eor.m_obj ? m_eor.m_pos : UINT_MAX; |
| 501 if (obj == endOfLine.m_obj && endOfLine.m_pos <= pos) { | 495 if (obj == endOfLine.m_obj && endOfLine.m_pos <= pos) { |
| 502 m_reachedEndOfLine = true; | 496 m_reachedEndOfLine = true; |
| 503 pos = endOfLine.m_pos; | 497 pos = endOfLine.m_pos; |
| 504 } | 498 } |
| 505 // It's OK to add runs for zero-length RenderObjects, just don't mak
e the run larger than it should be | 499 // It's OK to add runs for zero-length RenderObjects, just don't mak
e the run larger than it should be |
| 506 int end = obj->length() ? pos + 1 : 0; | 500 int end = obj->length() ? pos + 1 : 0; |
| 507 if (isolateTracker.inIsolate()) | 501 if (isolateTracker.inIsolate()) |
| 508 isolateTracker.addFakeRunIfNecessary(obj, *this); | 502 isolateTracker.addFakeRunIfNecessary(obj, start, *this); |
| 509 else | 503 else |
| 510 RenderBlock::appendRunsForObject(m_runs, start, end, obj, *this)
; | 504 RenderBlock::appendRunsForObject(m_runs, start, end, obj, *this)
; |
| 511 } | 505 } |
| 512 | 506 |
| 513 m_eor.increment(); | 507 m_eor.increment(); |
| 514 m_sor = m_eor; | 508 m_sor = m_eor; |
| 515 } | 509 } |
| 516 | 510 |
| 517 m_direction = WTF::Unicode::OtherNeutral; | 511 m_direction = WTF::Unicode::OtherNeutral; |
| 518 m_status.eor = WTF::Unicode::OtherNeutral; | 512 m_status.eor = WTF::Unicode::OtherNeutral; |
| 519 } | 513 } |
| 520 | 514 |
| 521 } | 515 } |
| 522 | 516 |
| 523 #endif // InlineIterator_h | 517 #endif // InlineIterator_h |
| OLD | NEW |