Chromium Code Reviews| 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 // FIXME: This belongs on InlineBidiResolver, except it's a template specializat ion | 467 // FIXME: This belongs on InlineBidiResolver, except it's a template specializat ion |
| 468 // of BidiResolver which knows nothing about RenderObjects. | 468 // of BidiResolver which knows nothing about RenderObjects. |
| 469 static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv er, RenderObject* obj, unsigned pos) | 469 static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv er, RenderObject* obj, unsigned pos) |
| 470 { | 470 { |
| 471 ASSERT(obj); | 471 ASSERT(obj); |
| 472 BidiRun* isolatedRun = new BidiRun(pos, 0, obj, resolver.context(), resolver .dir()); | 472 BidiRun* isolatedRun = new BidiRun(pos, 0, obj, resolver.context(), resolver .dir()); |
| 473 resolver.runs().addRun(isolatedRun); | 473 resolver.runs().addRun(isolatedRun); |
| 474 // FIXME: isolatedRuns() could be a hash of object->run and then we could ch eaply | 474 // FIXME: isolatedRuns() could be a hash of object->run and then we could ch eaply |
| 475 // ASSERT here that we didn't create multiple objects for the same inline. | 475 // ASSERT here that we didn't create multiple objects for the same inline. |
| 476 resolver.isolatedRuns().append(isolatedRun); | 476 resolver.isolatedRuns().append(isolatedRun); |
| 477 LineMidpointState& lineMidpointState = resolver.midpointState(); | |
| 478 resolver.setMidpointStateForIsolatedRun(isolatedRun, lineMidpointState); | |
| 479 } | |
| 480 | |
| 481 static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBi diResolver& resolver) | |
| 482 { | |
| 483 return new BidiRun(start, end, obj, resolver.context(), resolver.dir()); | |
| 484 } | |
| 485 | |
| 486 static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns igned start, unsigned end, InlineBidiResolver& resolver, bool isAppendingFakeRun In = true, BidiRunList<BidiRun>* runs = 0) | |
|
leviw_travelin_and_unemployed
2013/10/07 23:52:55
I'd like to avoid boolean parameters here if possi
| |
| 487 { | |
| 488 if (start > end || RenderBlock::shouldSkipCreatingRunsForObject(obj)) | |
| 489 return; | |
| 490 | |
| 491 LineMidpointState& lineMidpointState = resolver.midpointState(); | |
| 492 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta te.numMidpoints); | |
| 493 InlineIterator nextMidpoint; | |
| 494 if (haveNextMidpoint) | |
| 495 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp oint]; | |
| 496 if (lineMidpointState.betweenMidpoints) { | |
| 497 if (!(haveNextMidpoint && nextMidpoint.m_obj == obj)) | |
| 498 return; | |
| 499 // This is a new start point. Stop ignoring objects and | |
| 500 // adjust our start. | |
| 501 lineMidpointState.betweenMidpoints = false; | |
| 502 start = nextMidpoint.m_pos; | |
| 503 lineMidpointState.currentMidpoint++; | |
| 504 if (start < end) | |
| 505 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end , resolver, isAppendingFakeRunIn, runs); | |
| 506 } else { | |
| 507 if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) { | |
| 508 if (isAppendingFakeRunIn) | |
| 509 return; | |
| 510 runs->addRun(createRun(start, end, obj, resolver)); | |
| 511 return; | |
| 512 } | |
| 513 | |
| 514 // An end midpoint has been encountered within our object. We | |
| 515 // need to go ahead and append a run with our endpoint. | |
| 516 if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) { | |
| 517 lineMidpointState.betweenMidpoints = true; | |
| 518 lineMidpointState.currentMidpoint++; | |
| 519 if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it. | |
| 520 if (static_cast<int>(nextMidpoint.m_pos + 1) > start && !isAppen dingFakeRunIn) | |
| 521 runs->addRun(createRun(start, nextMidpoint.m_pos + 1, obj, r esolver)); | |
| 522 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMi dpoint.m_pos + 1, end, resolver, isAppendingFakeRunIn, runs); | |
| 523 } | |
| 524 } else if (!isAppendingFakeRunIn) { | |
| 525 runs->addRun(createRun(start, end, obj, resolver)); | |
| 526 } | |
| 527 } | |
| 477 } | 528 } |
| 478 | 529 |
| 479 class IsolateTracker { | 530 class IsolateTracker { |
| 480 public: | 531 public: |
| 481 explicit IsolateTracker(unsigned nestedIsolateCount) | 532 explicit IsolateTracker(unsigned nestedIsolateCount) |
| 482 : m_nestedIsolateCount(nestedIsolateCount) | 533 : m_nestedIsolateCount(nestedIsolateCount) |
| 483 , m_haveAddedFakeRunForRootIsolate(false) | 534 , m_haveAddedFakeRunForRootIsolate(false) |
| 484 { | 535 { |
| 485 } | 536 } |
| 486 | 537 |
| 487 void enterIsolate() { m_nestedIsolateCount++; } | 538 void enterIsolate() { m_nestedIsolateCount++; } |
| 488 void exitIsolate() | 539 void exitIsolate() |
| 489 { | 540 { |
| 490 ASSERT(m_nestedIsolateCount >= 1); | 541 ASSERT(m_nestedIsolateCount >= 1); |
| 491 m_nestedIsolateCount--; | 542 m_nestedIsolateCount--; |
| 492 if (!inIsolate()) | 543 if (!inIsolate()) |
| 493 m_haveAddedFakeRunForRootIsolate = false; | 544 m_haveAddedFakeRunForRootIsolate = false; |
| 494 } | 545 } |
| 495 bool inIsolate() const { return m_nestedIsolateCount; } | 546 bool inIsolate() const { return m_nestedIsolateCount; } |
| 496 | 547 |
| 497 // We don't care if we encounter bidi directional overrides. | 548 // We don't care if we encounter bidi directional overrides. |
| 498 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } | 549 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } |
| 499 void commitExplicitEmbedding() { } | 550 void commitExplicitEmbedding() { } |
| 500 | 551 |
| 501 void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, InlineBidiResolv er& resolver) | 552 |
| 553 void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, In lineBidiResolver& resolver) | |
| 502 { | 554 { |
| 503 // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine. | 555 // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine. |
| 504 // We'll be called for every span inside the isolated span so we just ig nore subsequent calls. | 556 // We'll be called for every span inside the isolated span so we just ig nore subsequent calls. |
| 505 // We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats. | 557 // We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats. |
| 506 if (m_haveAddedFakeRunForRootIsolate || RenderBlock::shouldSkipCreatingR unsForObject(obj)) | 558 if (!(m_haveAddedFakeRunForRootIsolate || RenderBlock::shouldSkipCreatin gRunsForObject(obj))) { |
| 507 return; | 559 addPlaceholderRunForIsolatedInline(resolver, obj, pos); |
| 508 m_haveAddedFakeRunForRootIsolate = true; | 560 m_haveAddedFakeRunForRootIsolate = true; |
| 561 } | |
| 562 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, pos, end, resolver); | |
| 563 | |
| 509 // obj and pos together denote a single position in the inline, from whi ch the parsing of the isolate will start. | 564 // obj and pos together denote a single position in the inline, from whi ch the parsing of the isolate will start. |
| 510 // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the | 565 // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the |
| 511 // isolate, when we call createBidiRunsForLine it will stop at whichever comes first. | 566 // isolate, when we call createBidiRunsForLine it will stop at whichever comes first. |
| 512 addPlaceholderRunForIsolatedInline(resolver, obj, pos); | |
| 513 // FIXME: Inline isolates don't work properly with collapsing whitespace , see webkit.org/b/109624 | |
| 514 // For now, if we enter an isolate between midpoints, we increment our c urrent midpoint or else | |
| 515 // we'll leave the isolate and ignore the content that follows. | |
| 516 MidpointState<InlineIterator>& midpointState = resolver.midpointState(); | |
| 517 if (midpointState.betweenMidpoints && midpointState.midpoints[midpointSt ate.currentMidpoint].object() == obj) { | |
| 518 midpointState.betweenMidpoints = false; | |
| 519 ++midpointState.currentMidpoint; | |
| 520 } | |
| 521 } | 567 } |
| 522 | 568 |
| 523 private: | 569 private: |
| 524 unsigned m_nestedIsolateCount; | 570 unsigned m_nestedIsolateCount; |
| 525 bool m_haveAddedFakeRunForRootIsolate; | 571 bool m_haveAddedFakeRunForRootIsolate; |
| 526 }; | 572 }; |
| 527 | 573 |
| 528 template <> | 574 template <> |
| 529 inline void InlineBidiResolver::appendRun() | 575 inline void InlineBidiResolver::appendRun() |
| 530 { | 576 { |
| 531 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { | 577 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { |
| 532 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. | 578 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. |
| 533 // Initialize our state depending on if we're starting in the middle of such an inline. | 579 // Initialize our state depending on if we're starting in the middle of such an inline. |
| 534 // FIXME: Could this initialize from this->inIsolate() instead of walkin g up the render tree? | 580 // FIXME: Could this initialize from this->inIsolate() instead of walkin g up the render tree? |
| 535 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); | 581 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); |
| 536 int start = m_sor.m_pos; | 582 int start = m_sor.m_pos; |
| 537 RenderObject* obj = m_sor.m_obj; | 583 RenderObject* obj = m_sor.m_obj; |
| 538 while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) { | 584 while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) { |
| 539 if (isolateTracker.inIsolate()) | 585 if (isolateTracker.inIsolate()) |
| 540 isolateTracker.addFakeRunIfNecessary(obj, start, *this); | 586 isolateTracker.addFakeRunIfNecessary(obj, start, obj->length(), *this); |
| 541 else | 587 else |
| 542 RenderBlock::appendRunsForObject(m_runs, start, obj->length(), o bj, *this); | 588 RenderBlock::appendRunsForObject(m_runs, start, obj->length(), o bj, *this); |
| 543 // FIXME: start/obj should be an InlineIterator instead of two separ ate variables. | 589 // FIXME: start/obj should be an InlineIterator instead of two separ ate variables. |
| 544 start = 0; | 590 start = 0; |
| 545 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke r); | 591 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke r); |
| 546 } | 592 } |
| 547 if (obj) { | 593 if (obj) { |
| 548 unsigned pos = obj == m_eor.m_obj ? m_eor.m_pos : INT_MAX; | 594 unsigned pos = obj == m_eor.m_obj ? m_eor.m_pos : INT_MAX; |
| 549 if (obj == endOfLine.m_obj && endOfLine.m_pos <= pos) { | 595 if (obj == endOfLine.m_obj && endOfLine.m_pos <= pos) { |
| 550 m_reachedEndOfLine = true; | 596 m_reachedEndOfLine = true; |
| 551 pos = endOfLine.m_pos; | 597 pos = endOfLine.m_pos; |
| 552 } | 598 } |
| 553 // It's OK to add runs for zero-length RenderObjects, just don't mak e the run larger than it should be | 599 // It's OK to add runs for zero-length RenderObjects, just don't mak e the run larger than it should be |
| 554 int end = obj->length() ? pos + 1 : 0; | 600 int end = obj->length() ? pos + 1 : 0; |
| 555 if (isolateTracker.inIsolate()) | 601 if (isolateTracker.inIsolate()) |
| 556 isolateTracker.addFakeRunIfNecessary(obj, start, *this); | 602 isolateTracker.addFakeRunIfNecessary(obj, start, end, *this); |
| 557 else | 603 else |
| 558 RenderBlock::appendRunsForObject(m_runs, start, end, obj, *this) ; | 604 RenderBlock::appendRunsForObject(m_runs, start, end, obj, *this) ; |
| 559 } | 605 } |
| 560 | 606 |
| 561 m_eor.increment(); | 607 m_eor.increment(); |
| 562 m_sor = m_eor; | 608 m_sor = m_eor; |
| 563 } | 609 } |
| 564 | 610 |
| 565 m_direction = WTF::Unicode::OtherNeutral; | 611 m_direction = WTF::Unicode::OtherNeutral; |
| 566 m_status.eor = WTF::Unicode::OtherNeutral; | 612 m_status.eor = WTF::Unicode::OtherNeutral; |
| 567 } | 613 } |
| 568 | 614 |
| 569 } | 615 } |
| 570 | 616 |
| 571 #endif // InlineIterator_h | 617 #endif // InlineIterator_h |
| OLD | NEW |