Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1366)

Unified Diff: Source/core/rendering/InlineIterator.h

Issue 26315003: Bidi-Isolate inlines break layout with collapsed whitespace (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/InlineIterator.h
diff --git a/Source/core/rendering/InlineIterator.h b/Source/core/rendering/InlineIterator.h
index 1885f8e521cc745ac587b5990ee6eba530d3d431..349d6ac83c4f950d750c6bda71b945287b22995e 100644
--- a/Source/core/rendering/InlineIterator.h
+++ b/Source/core/rendering/InlineIterator.h
@@ -474,6 +474,8 @@ static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv
// FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply
// ASSERT here that we didn't create multiple objects for the same inline.
resolver.isolatedRuns().append(isolatedRun);
+ LineMidpointState& lineMidpointState = resolver.midpointState();
+ resolver.setMidpointStateForIsolatedRun(isolatedRun, lineMidpointState);
}
class IsolateTracker {
@@ -498,26 +500,49 @@ public:
void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { }
void commitExplicitEmbedding() { }
- void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, InlineBidiResolver& resolver)
+ void adjustMidpointForIsolatedRun(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver)
leviw_travelin_and_unemployed 2013/10/07 21:58:42 This seems really similar to RenderBlock::appendRu
+ {
+ if (start > end)
+ return;
+
+ LineMidpointState& lineMidpointState = resolver.midpointState();
+ bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints);
+ InlineIterator nextMidpoint;
+ if (haveNextMidpoint)
+ nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint];
+ if (lineMidpointState.betweenMidpoints) {
+ if (!(haveNextMidpoint && nextMidpoint.m_obj == obj))
+ return;
+ lineMidpointState.betweenMidpoints = false;
+ lineMidpointState.currentMidpoint++;
+ if (start < end)
+ return adjustMidpointForIsolatedRun(obj, start, end, resolver);
+ } else {
+ if (!haveNextMidpoint || (obj != nextMidpoint.m_obj))
+ return;
+ if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) {
+ lineMidpointState.betweenMidpoints = true;
+ lineMidpointState.currentMidpoint++;
+ if (nextMidpoint.m_pos != UINT_MAX)
+ return adjustMidpointForIsolatedRun(obj, nextMidpoint.m_pos + 1, end, resolver);
+ }
+ }
+ }
+
+ void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, InlineBidiResolver& resolver)
{
// We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine.
// We'll be called for every span inside the isolated span so we just ignore subsequent calls.
// We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats.
- if (m_haveAddedFakeRunForRootIsolate || RenderBlock::shouldSkipCreatingRunsForObject(obj))
- return;
- m_haveAddedFakeRunForRootIsolate = true;
+ if (!(m_haveAddedFakeRunForRootIsolate || RenderBlock::shouldSkipCreatingRunsForObject(obj))) {
+ addPlaceholderRunForIsolatedInline(resolver, obj, pos);
+ m_haveAddedFakeRunForRootIsolate = true;
+ }
+ adjustMidpointForIsolatedRun(obj, pos, end, resolver);
+
// obj and pos together denote a single position in the inline, from which the parsing of the isolate will start.
// We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the
// isolate, when we call createBidiRunsForLine it will stop at whichever comes first.
- addPlaceholderRunForIsolatedInline(resolver, obj, pos);
- // FIXME: Inline isolates don't work properly with collapsing whitespace, see webkit.org/b/109624
- // For now, if we enter an isolate between midpoints, we increment our current midpoint or else
- // we'll leave the isolate and ignore the content that follows.
- MidpointState<InlineIterator>& midpointState = resolver.midpointState();
- if (midpointState.betweenMidpoints && midpointState.midpoints[midpointState.currentMidpoint].object() == obj) {
- midpointState.betweenMidpoints = false;
- ++midpointState.currentMidpoint;
- }
}
private:
@@ -537,7 +562,7 @@ inline void InlineBidiResolver::appendRun()
RenderObject* obj = m_sor.m_obj;
while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) {
if (isolateTracker.inIsolate())
- isolateTracker.addFakeRunIfNecessary(obj, start, *this);
+ isolateTracker.addFakeRunIfNecessary(obj, start, obj->length(), *this);
else
RenderBlock::appendRunsForObject(m_runs, start, obj->length(), obj, *this);
// FIXME: start/obj should be an InlineIterator instead of two separate variables.
@@ -553,7 +578,7 @@ inline void InlineBidiResolver::appendRun()
// It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
int end = obj->length() ? pos + 1 : 0;
if (isolateTracker.inIsolate())
- isolateTracker.addFakeRunIfNecessary(obj, start, *this);
+ isolateTracker.addFakeRunIfNecessary(obj, start, end, *this);
else
RenderBlock::appendRunsForObject(m_runs, start, end, obj, *this);
}

Powered by Google App Engine
This is Rietveld 408576698