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 |