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 |