| 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 * |
| 11 * This library is distributed in the hope that it will be useful, | 11 * This library is distributed in the hope that it will be useful, |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 * Library General Public License for more details. | 14 * Library General Public License for more details. |
| 15 * | 15 * |
| 16 * You should have received a copy of the GNU Library General Public License | 16 * You should have received a copy of the GNU Library General Public License |
| 17 * along with this library; see the file COPYING.LIB. If not, write to | 17 * along with this library; see the file COPYING.LIB. If not, write to |
| 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 19 * Boston, MA 02110-1301, USA. | 19 * Boston, MA 02110-1301, USA. |
| 20 * | 20 * |
| 21 */ | 21 */ |
| 22 | 22 |
| 23 #ifndef SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_ | 23 #ifndef SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_ |
| 24 #define SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_ | 24 #define SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_ |
| 25 | 25 |
| 26 #include "sky/engine/core/rendering/BidiRun.h" | 26 #include "sky/engine/core/rendering/BidiRun.h" |
| 27 #include "sky/engine/core/rendering/RenderBlockFlow.h" | |
| 28 #include "sky/engine/core/rendering/RenderInline.h" | 27 #include "sky/engine/core/rendering/RenderInline.h" |
| 28 #include "sky/engine/core/rendering/RenderParagraph.h" |
| 29 #include "sky/engine/core/rendering/RenderText.h" | 29 #include "sky/engine/core/rendering/RenderText.h" |
| 30 #include "sky/engine/core/rendering/line/TrailingObjects.h" |
| 30 #include "sky/engine/wtf/StdLibExtras.h" | 31 #include "sky/engine/wtf/StdLibExtras.h" |
| 31 | 32 |
| 32 namespace blink { | 33 namespace blink { |
| 33 | 34 |
| 34 // This class is used to RenderInline subtrees, stepping by character within the | 35 // This class is used to RenderInline subtrees, stepping by character within the |
| 35 // text children. InlineIterator will use bidiNext to find the next RenderText | 36 // text children. InlineIterator will use bidiNext to find the next RenderText |
| 36 // optionally notifying a BidiResolver every time it steps into/out of a RenderI
nline. | 37 // optionally notifying a BidiResolver every time it steps into/out of a RenderI
nline. |
| 37 class InlineIterator { | 38 class InlineIterator { |
| 38 public: | 39 public: |
| 39 enum IncrementRule { | 40 enum IncrementRule { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 InlineBidiResolver* observer = 0; | 277 InlineBidiResolver* observer = 0; |
| 277 return bidiNextSkippingEmptyInlines(root, current, observer); | 278 return bidiNextSkippingEmptyInlines(root, current, observer); |
| 278 } | 279 } |
| 279 | 280 |
| 280 static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re
nderObject* current, bool* endOfInlinePtr = 0) | 281 static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re
nderObject* current, bool* endOfInlinePtr = 0) |
| 281 { | 282 { |
| 282 InlineBidiResolver* observer = 0; // Callers who include empty inlines, neve
r use an observer. | 283 InlineBidiResolver* observer = 0; // Callers who include empty inlines, neve
r use an observer. |
| 283 return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInl
inePtr); | 284 return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInl
inePtr); |
| 284 } | 285 } |
| 285 | 286 |
| 286 static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root,
BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0) | 287 static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderParagraph* root,
BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0) |
| 287 { | 288 { |
| 288 RenderObject* o = root->firstChild(); | 289 RenderObject* o = root->firstChild(); |
| 289 if (!o) | 290 if (!o) |
| 290 return 0; | 291 return 0; |
| 291 | 292 |
| 292 if (o->isRenderInline()) { | 293 if (o->isRenderInline()) { |
| 293 notifyObserverEnteredObject(resolver, o); | 294 notifyObserverEnteredObject(resolver, o); |
| 294 if (!isEmptyInline(o)) | 295 if (!isEmptyInline(o)) |
| 295 o = bidiNextSkippingEmptyInlines(root, o, resolver); | 296 o = bidiNextSkippingEmptyInlines(root, o, resolver); |
| 296 else { | 297 else { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 324 | 325 |
| 325 inline void InlineIterator::fastIncrementInTextNode() | 326 inline void InlineIterator::fastIncrementInTextNode() |
| 326 { | 327 { |
| 327 ASSERT(m_obj); | 328 ASSERT(m_obj); |
| 328 ASSERT(m_obj->isText()); | 329 ASSERT(m_obj->isText()); |
| 329 ASSERT(m_pos <= toRenderText(m_obj)->textLength()); | 330 ASSERT(m_pos <= toRenderText(m_obj)->textLength()); |
| 330 if (m_pos < INT_MAX) | 331 if (m_pos < INT_MAX) |
| 331 m_pos++; | 332 m_pos++; |
| 332 } | 333 } |
| 333 | 334 |
| 334 // FIXME: This is used by RenderBlockFlow for simplified layout, and has nothing
to do with bidi | 335 // FIXME: This is used by RenderParagraph for simplified layout, and has nothing
to do with bidi |
| 335 // it shouldn't use functions called bidiFirst and bidiNext. | 336 // it shouldn't use functions called bidiFirst and bidiNext. |
| 336 class InlineWalker { | 337 class InlineWalker { |
| 337 public: | 338 public: |
| 338 InlineWalker(RenderBlock* root) | 339 InlineWalker(RenderBlock* root) |
| 339 : m_root(root) | 340 : m_root(root) |
| 340 , m_current(0) | 341 , m_current(0) |
| 341 , m_atEndOfInline(false) | 342 , m_atEndOfInline(false) |
| 342 { | 343 { |
| 343 // FIXME: This class should be taught how to do the SkipEmptyInlines cod
epath as well. | 344 // FIXME: This class should be taught how to do the SkipEmptyInlines cod
epath as well. |
| 344 m_current = bidiFirstIncludingEmptyInlines(m_root); | 345 m_current = bidiFirstIncludingEmptyInlines(m_root); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 // We don't care if we encounter bidi directional overrides. | 594 // We don't care if we encounter bidi directional overrides. |
| 594 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } | 595 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } |
| 595 void commitExplicitEmbedding(BidiRunList<BidiRun>&) { } | 596 void commitExplicitEmbedding(BidiRunList<BidiRun>&) { } |
| 596 BidiRunList<BidiRun>& runs() { return m_runs; } | 597 BidiRunList<BidiRun>& runs() { return m_runs; } |
| 597 | 598 |
| 598 void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, In
lineBidiResolver& resolver) | 599 void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, In
lineBidiResolver& resolver) |
| 599 { | 600 { |
| 600 // We only need to add a fake run for a given isolated span once during
each call to createBidiRunsForLine. | 601 // We only need to add a fake run for a given isolated span once during
each call to createBidiRunsForLine. |
| 601 // We'll be called for every span inside the isolated span so we just ig
nore subsequent calls. | 602 // We'll be called for every span inside the isolated span so we just ig
nore subsequent calls. |
| 602 // We also avoid creating a fake run until we hit a child that warrants
one, e.g. we skip floats. | 603 // We also avoid creating a fake run until we hit a child that warrants
one, e.g. we skip floats. |
| 603 if (RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) | 604 if (RenderParagraph::shouldSkipCreatingRunsForObject(obj)) |
| 604 return; | 605 return; |
| 605 if (!m_haveAddedFakeRunForRootIsolate) { | 606 if (!m_haveAddedFakeRunForRootIsolate) { |
| 606 BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos
); | 607 BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos
); |
| 607 resolver.setMidpointStateForIsolatedRun(run, m_midpointStateForRootI
solate); | 608 resolver.setMidpointStateForIsolatedRun(run, m_midpointStateForRootI
solate); |
| 608 m_haveAddedFakeRunForRootIsolate = true; | 609 m_haveAddedFakeRunForRootIsolate = true; |
| 609 } | 610 } |
| 610 // obj and pos together denote a single position in the inline, from whi
ch the parsing of the isolate will start. | 611 // obj and pos together denote a single position in the inline, from whi
ch the parsing of the isolate will start. |
| 611 // We don't need to mark the end of the run because this is implicit: it
is either endOfLine or the end of the | 612 // We don't need to mark the end of the run because this is implicit: it
is either endOfLine or the end of the |
| 612 // isolate, when we call createBidiRunsForLine it will stop at whichever
comes first. | 613 // isolate, when we call createBidiRunsForLine it will stop at whichever
comes first. |
| 613 } | 614 } |
| 614 | 615 |
| 615 private: | 616 private: |
| 616 unsigned m_nestedIsolateCount; | 617 unsigned m_nestedIsolateCount; |
| 617 bool m_haveAddedFakeRunForRootIsolate; | 618 bool m_haveAddedFakeRunForRootIsolate; |
| 618 LineMidpointState m_midpointStateForRootIsolate; | 619 LineMidpointState m_midpointStateForRootIsolate; |
| 619 BidiRunList<BidiRun>& m_runs; | 620 BidiRunList<BidiRun>& m_runs; |
| 620 }; | 621 }; |
| 621 | 622 |
| 622 static void inline appendRunObjectIfNecessary(RenderObject* obj, unsigned start,
unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, Isolate
Tracker& tracker) | 623 static void inline appendRunObjectIfNecessary(RenderObject* obj, unsigned start,
unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, Isolate
Tracker& tracker) |
| 623 { | 624 { |
| 624 if (behavior == AppendingFakeRun) | 625 if (behavior == AppendingFakeRun) |
| 625 tracker.addFakeRunIfNecessary(obj, start, end, resolver); | 626 tracker.addFakeRunIfNecessary(obj, start, end, resolver); |
| 626 else | 627 else |
| 627 resolver.runs().addRun(createRun(start, end, obj, resolver)); | 628 resolver.runs().addRun(createRun(start, end, obj, resolver)); |
| 628 } | 629 } |
| 629 | 630 |
| 630 static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns
igned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behav
ior, IsolateTracker& tracker) | 631 static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns
igned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behav
ior, IsolateTracker& tracker) |
| 631 { | 632 { |
| 632 if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) | 633 if (start > end || RenderParagraph::shouldSkipCreatingRunsForObject(obj)) |
| 633 return; | 634 return; |
| 634 | 635 |
| 635 LineMidpointState& lineMidpointState = resolver.midpointState(); | 636 LineMidpointState& lineMidpointState = resolver.midpointState(); |
| 636 bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointS
tate.numMidpoints()); | 637 bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointS
tate.numMidpoints()); |
| 637 InlineIterator nextMidpoint; | 638 InlineIterator nextMidpoint; |
| 638 if (haveNextMidpoint) | 639 if (haveNextMidpoint) |
| 639 nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMi
dpoint()]; | 640 nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMi
dpoint()]; |
| 640 if (lineMidpointState.betweenMidpoints()) { | 641 if (lineMidpointState.betweenMidpoints()) { |
| 641 if (!(haveNextMidpoint && nextMidpoint.object() == obj)) | 642 if (!(haveNextMidpoint && nextMidpoint.object() == obj)) |
| 642 return; | 643 return; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 m_sor = m_eor; | 720 m_sor = m_eor; |
| 720 } | 721 } |
| 721 | 722 |
| 722 m_direction = WTF::Unicode::OtherNeutral; | 723 m_direction = WTF::Unicode::OtherNeutral; |
| 723 m_status.eor = WTF::Unicode::OtherNeutral; | 724 m_status.eor = WTF::Unicode::OtherNeutral; |
| 724 } | 725 } |
| 725 | 726 |
| 726 } | 727 } |
| 727 | 728 |
| 728 #endif // SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_ | 729 #endif // SKY_ENGINE_CORE_RENDERING_INLINEITERATOR_H_ |
| OLD | NEW |