| Differences between
and this patch
- a/Source/WebCore/ChangeLog +81 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2016-04-06  Myles C. Maxfield  <mmaxfield@apple.com>
2
3
        Rename MidpointState to WhitespaceCollapsingState
4
        https://bugs.webkit.org/show_bug.cgi?id=156304
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        MidpointState has nothing to do with midpoints.
9
10
        An individual midpoint is now known as a "whitespace collapsing transition."
11
12
        No new tests because there is no behavior change.
13
14
        * platform/text/BidiResolver.h:
15
        (WebCore::WhitespaceCollapsingState::reset): (See addMidpoint() below.)
16
        Previously, we were using operator= to destroy old Iterators when their
17
        storage inside the Vector was reused. Now that we are elliminating
18
        m_numMidpoints, we can push destruction earlier to this reset() function.
19
        Because the same amount of destruction happens in both cases, this doesn't
20
        add additional work. (Vector can destroy its contents without shrinking
21
        its storage overcommitment.)
22
        (WebCore::WhitespaceCollapsingState::startIgnoringSpaces):
23
        (WebCore::WhitespaceCollapsingState::stopIgnoringSpaces):
24
        (WebCore::WhitespaceCollapsingState::ensureLineBoxInsideIgnoredSpaces):
25
        (WebCore::WhitespaceCollapsingState::decrementTransitionAt):
26
        (WebCore::WhitespaceCollapsingState::thresholds): Make the return value
27
        const. The only clients of this function which needed mutation were
28
        migrated to using decrementTransitionAt().
29
        (WebCore::WhitespaceCollapsingState::numTransitions):
30
        (WebCore::WhitespaceCollapsingState::currentTransition):
31
        (WebCore::WhitespaceCollapsingState::setCurrentTransition):
32
        (WebCore::WhitespaceCollapsingState::incrementCurrentTransition):
33
        (WebCore::WhitespaceCollapsingState::decrementNumTransitions):
34
        (WebCore::WhitespaceCollapsingState::betweenTransitions):
35
        (WebCore::BidiResolverBase::whitespaceCollapsingState):
36
        (WebCore::Subclass>::setWhitespaceCollapsingTransitionForIsolatedRun):
37
        (WebCore::Subclass>::whitespaceCollapsingTransitionForIsolatedRun):
38
        (WebCore::MidpointState::MidpointState): Deleted.
39
        (WebCore::MidpointState::reset): Deleted.
40
        (WebCore::MidpointState::startIgnoringSpaces): Deleted.
41
        (WebCore::MidpointState::stopIgnoringSpaces): Deleted.
42
        (WebCore::MidpointState::ensureLineBoxInsideIgnoredSpaces): Deleted.
43
        (WebCore::MidpointState::midpoints): Deleted.
44
        (WebCore::MidpointState::numMidpoints): Deleted.
45
        (WebCore::MidpointState::currentMidpoint): Deleted.
46
        (WebCore::MidpointState::setCurrentMidpoint): Deleted.
47
        (WebCore::MidpointState::incrementCurrentMidpoint): Deleted.
48
        (WebCore::MidpointState::decrementNumMidpoints): Deleted.
49
        (WebCore::MidpointState::betweenMidpoints): Deleted.
50
        (WebCore::MidpointState::addMidpoint): Deleted. This code has been around for 13
51
        years (since r3672) where it was using QMemArray. That class doesn't have an
52
        append() class, so it was implemented inside this function. Luckily, Vector
53
        already overcommits its allocation, so we can elliminate m_numMidpoints entirely.
54
        (WebCore::BidiResolverBase::midpointState): Deleted.
55
        (WebCore::Subclass>::setMidpointForIsolatedRun): Deleted.
56
        (WebCore::Subclass>::midpointForIsolatedRun): Deleted.
57
        * rendering/InlineIterator.h:
58
        (WebCore::addPlaceholderRunForIsolatedInline):
59
        * rendering/RenderBlockLineLayout.cpp:
60
        (WebCore::RenderBlockFlow::appendRunsForObject):
61
        (WebCore::setUpResolverToResumeInIsolate):
62
        (WebCore::constructBidiRunsForSegment):
63
        (WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange):
64
        * rendering/line/BreakingContext.h:
65
        (WebCore::BreakingContext::BreakingContext):
66
        (WebCore::BreakingContext::handleBR):
67
        (WebCore::BreakingContext::handleOutOfFlowPositioned):
68
        (WebCore::shouldSkipWhitespaceAfterStartObject):
69
        (WebCore::BreakingContext::handleEmptyInline):
70
        (WebCore::BreakingContext::handleReplaced):
71
        (WebCore::ensureCharacterGetsLineBox):
72
        (WebCore::BreakingContext::handleText):
73
        (WebCore::checkWhitespaceCollapsingTransitions):
74
        (WebCore::BreakingContext::handleEndOfLine):
75
        (WebCore::checkMidpoints): Deleted.
76
        * rendering/line/TrailingObjects.cpp:
77
        (WebCore::TrailingObjects::updateWhitespaceCollapsingTransitionsForTrailingBoxes):
78
        (WebCore::TrailingObjects::updateMidpointsForTrailingBoxes): Deleted.
79
        * rendering/line/TrailingObjects.h:
80
        (WebCore::TrailingObjects::appendBoxIfNeeded):
81
1
2016-04-05  Hunseop Jeong  <hs85.jeong@samsung.com>
82
2016-04-05  Hunseop Jeong  <hs85.jeong@samsung.com>
2
83
3
        [Curl][Soup] Fix the build after r199039
84
        [Curl][Soup] Fix the build after r199039
- a/Source/WebCore/platform/text/BidiResolver.h -50 / +37 lines
Lines 1-6 a/Source/WebCore/platform/text/BidiResolver.h_sec1
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 Apple Inc.  All right reserved.
3
 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2016 Apple Inc.  All right reserved.
4
 *
4
 *
5
 * This library is free software; you can redistribute it and/or
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Library General Public
6
 * modify it under the terms of the GNU Library General Public
Lines 34-96 namespace WebCore { a/Source/WebCore/platform/text/BidiResolver.h_sec2
34
34
35
class RenderObject;
35
class RenderObject;
36
36
37
template <class Iterator> class MidpointState {
37
template <class Iterator> class WhitespaceCollapsingState {
38
public:
38
public:
39
    MidpointState()
40
    {
41
        reset();
42
    }
43
    
44
    void reset()
39
    void reset()
45
    {
40
    {
46
        m_numMidpoints = 0;
41
        m_transitions.clear();
47
        m_currentMidpoint = 0;
42
        m_currentTransition = 0;
48
    }
43
    }
49
    
44
    
50
    void startIgnoringSpaces(const Iterator& midpoint)
45
    void startIgnoringSpaces(const Iterator& transition)
51
    {
46
    {
52
        ASSERT(!(m_numMidpoints % 2));
47
        ASSERT(!(m_transitions.size() % 2));
53
        addMidpoint(midpoint);
48
        m_transitions.append(transition);
54
    }
49
    }
55
50
56
    void stopIgnoringSpaces(const Iterator& midpoint)
51
    void stopIgnoringSpaces(const Iterator& transition)
57
    {
52
    {
58
        ASSERT(m_numMidpoints % 2);
53
        ASSERT(m_transitions.size() % 2);
59
        addMidpoint(midpoint);
54
        m_transitions.append(transition);
60
    }
55
    }
61
56
62
    // When ignoring spaces, this needs to be called for objects that need line boxes such as RenderInlines or
57
    // When ignoring spaces, this needs to be called for objects that need line boxes such as RenderInlines or
63
    // hard line breaks to ensure that they're not ignored.
58
    // hard line breaks to ensure that they're not ignored.
64
    void ensureLineBoxInsideIgnoredSpaces(RenderObject* renderer)
59
    void ensureLineBoxInsideIgnoredSpaces(RenderObject& renderer)
65
    {
60
    {
66
        Iterator midpoint(0, renderer, 0);
61
        Iterator transition(0, &renderer, 0);
67
        stopIgnoringSpaces(midpoint);
62
        stopIgnoringSpaces(transition);
68
        startIgnoringSpaces(midpoint);
63
        startIgnoringSpaces(transition);
69
    }
64
    }
70
65
71
    Vector<Iterator>& midpoints() { return m_midpoints; }
66
    void decrementTransitionAt(size_t index)
72
    unsigned numMidpoints() const { return m_numMidpoints; }
73
    unsigned currentMidpoint() const { return m_currentMidpoint; }
74
    void setCurrentMidpoint(unsigned currentMidpoint) { m_currentMidpoint = currentMidpoint; }
75
    void incrementCurrentMidpoint() { ++m_currentMidpoint; }
76
    void decrementNumMidpoints() { --m_numMidpoints; }
77
    bool betweenMidpoints() const { return m_currentMidpoint % 2; }
78
private:
79
    // The goal is to reuse the line state across multiple
80
    // lines so we just keep an array around for midpoints and never clear it across multiple
81
    // lines. We track the number of items and position using the two other variables.
82
    Vector<Iterator> m_midpoints;
83
    unsigned m_numMidpoints;
84
    unsigned m_currentMidpoint;
85
86
    void addMidpoint(const Iterator& midpoint)
87
    {
67
    {
88
        if (m_midpoints.size() <= m_numMidpoints)
68
        m_transitions[index].fastDecrement();
89
            m_midpoints.grow(m_numMidpoints + 10);
90
91
        Iterator* midpointsIterator = m_midpoints.data();
92
        midpointsIterator[m_numMidpoints++] = midpoint;
93
    }
69
    }
70
71
    const Vector<Iterator>& transitions() { return m_transitions; }
72
    size_t numTransitions() const { return m_transitions.size(); }
73
    size_t currentTransition() const { return m_currentTransition; }
74
    void setCurrentTransition(size_t currentTransition) { m_currentTransition = currentTransition; }
75
    void incrementCurrentTransition() { ++m_currentTransition; }
76
    void decrementNumTransitions() { m_transitions.shrink(m_transitions.size() - 1); }
77
    bool betweenTransitions() const { return m_currentTransition % 2; }
78
private:
79
    Vector<Iterator> m_transitions;
80
    size_t m_currentTransition { 0 };
94
};
81
};
95
82
96
// The BidiStatus at a given position (typically the end of a line) can
83
// The BidiStatus at a given position (typically the end of a line) can
Lines 247-253 public: a/Source/WebCore/platform/text/BidiResolver.h_sec3
247
    const BidiStatus& status() const { return m_status; }
234
    const BidiStatus& status() const { return m_status; }
248
    void setStatus(const BidiStatus s) { m_status = s; }
235
    void setStatus(const BidiStatus s) { m_status = s; }
249
236
250
    MidpointState<Iterator>& midpointState() { return m_midpointState; }
237
    WhitespaceCollapsingState<Iterator>& whitespaceCollapsingState() { return m_whitespaceCollapsingState; }
251
238
252
    // The current algorithm handles nested isolates one layer of nesting at a time.
239
    // The current algorithm handles nested isolates one layer of nesting at a time.
253
    // But when we layout each isolated span, we will walk into (and ignore) all
240
    // But when we layout each isolated span, we will walk into (and ignore) all
Lines 267-274 public: a/Source/WebCore/platform/text/BidiResolver.h_sec4
267
    // It's unclear if this is still needed.
254
    // It's unclear if this is still needed.
268
    void markCurrentRunEmpty() { m_emptyRun = true; }
255
    void markCurrentRunEmpty() { m_emptyRun = true; }
269
256
270
    void setMidpointForIsolatedRun(Run&, unsigned);
257
    void setWhitespaceCollapsingTransitionForIsolatedRun(Run&, size_t);
271
    unsigned midpointForIsolatedRun(Run&);
258
    unsigned whitespaceCollapsingTransitionForIsolatedRun(Run&);
272
259
273
protected:
260
protected:
274
    // FIXME: Instead of InlineBidiResolvers subclassing this method, we should
261
    // FIXME: Instead of InlineBidiResolvers subclassing this method, we should
Lines 292-301 protected: a/Source/WebCore/platform/text/BidiResolver.h_sec5
292
    // into createBidiRunsForLine by the caller.
279
    // into createBidiRunsForLine by the caller.
293
    BidiRunList<Run> m_runs;
280
    BidiRunList<Run> m_runs;
294
281
295
    MidpointState<Iterator> m_midpointState;
282
    WhitespaceCollapsingState<Iterator> m_whitespaceCollapsingState;
296
283
297
    unsigned m_nestedIsolateCount;
284
    unsigned m_nestedIsolateCount;
298
    HashMap<Run*, unsigned> m_midpointForIsolatedRun;
285
    HashMap<Run*, unsigned> m_whitespaceCollapsingTransitionForIsolatedRun;
299
286
300
private:
287
private:
301
    void raiseExplicitEmbeddingLevel(UCharDirection from, UCharDirection to);
288
    void raiseExplicitEmbeddingLevel(UCharDirection from, UCharDirection to);
Lines 982-997 void BidiResolverBase<Iterator, Run, Subclass>::createBidiRunsForLine(const Iter a/Source/WebCore/platform/text/BidiResolver.h_sec6
982
}
969
}
983
970
984
template <class Iterator, class Run, class Subclass>
971
template <class Iterator, class Run, class Subclass>
985
void BidiResolverBase<Iterator, Run, Subclass>::setMidpointForIsolatedRun(Run& run, unsigned midpoint)
972
void BidiResolverBase<Iterator, Run, Subclass>::setWhitespaceCollapsingTransitionForIsolatedRun(Run& run, size_t transition)
986
{
973
{
987
    ASSERT(!m_midpointForIsolatedRun.contains(&run));
974
    ASSERT(!m_whitespaceCollapsingTransitionForIsolatedRun.contains(&run));
988
    m_midpointForIsolatedRun.add(&run, midpoint);
975
    m_whitespaceCollapsingTransitionForIsolatedRun.add(&run, transition);
989
}
976
}
990
977
991
template<class Iterator, class Run, class Subclass>
978
template<class Iterator, class Run, class Subclass>
992
unsigned BidiResolverBase<Iterator, Run, Subclass>::midpointForIsolatedRun(Run& run)
979
unsigned BidiResolverBase<Iterator, Run, Subclass>::whitespaceCollapsingTransitionForIsolatedRun(Run& run)
993
{
980
{
994
    return m_midpointForIsolatedRun.take(&run);
981
    return m_whitespaceCollapsingTransitionForIsolatedRun.take(&run);
995
}
982
}
996
983
997
} // namespace WebCore
984
} // namespace WebCore
- a/Source/WebCore/rendering/InlineIterator.h -1 / +1 lines
Lines 495-501 static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv a/Source/WebCore/rendering/InlineIterator.h_sec1
495
    std::unique_ptr<BidiRun> isolatedRun = std::make_unique<BidiRun>(pos, 0, obj, resolver.context(), resolver.dir());
495
    std::unique_ptr<BidiRun> isolatedRun = std::make_unique<BidiRun>(pos, 0, obj, resolver.context(), resolver.dir());
496
    // FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply
496
    // FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply
497
    // ASSERT here that we didn't create multiple objects for the same inline.
497
    // ASSERT here that we didn't create multiple objects for the same inline.
498
    resolver.setMidpointForIsolatedRun(*isolatedRun, resolver.midpointState().currentMidpoint());
498
    resolver.setWhitespaceCollapsingTransitionForIsolatedRun(*isolatedRun, resolver.whitespaceCollapsingState().currentTransition());
499
    resolver.isolatedRuns().append(BidiIsolatedRun(obj, pos, root, *isolatedRun));
499
    resolver.isolatedRuns().append(BidiIsolatedRun(obj, pos, root, *isolatedRun));
500
    resolver.runs().appendRun(WTFMove(isolatedRun));
500
    resolver.runs().appendRun(WTFMove(isolatedRun));
501
}
501
}
- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp -24 / +24 lines
Lines 81-118 void RenderBlockFlow::appendRunsForObject(BidiRunList<BidiRun>* runs, int start, a/Source/WebCore/rendering/RenderBlockLineLayout.cpp_sec1
81
    if (start > end || shouldSkipCreatingRunsForObject(obj))
81
    if (start > end || shouldSkipCreatingRunsForObject(obj))
82
        return;
82
        return;
83
83
84
    LineMidpointState& lineMidpointState = resolver.midpointState();
84
    LineWhitespaceCollapsingState& lineWhitespaceCollapsingState = resolver.whitespaceCollapsingState();
85
    bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointState.numMidpoints());
85
    bool haveNextTransition = (lineWhitespaceCollapsingState.currentTransition() < lineWhitespaceCollapsingState.numTransitions());
86
    InlineIterator nextMidpoint;
86
    InlineIterator nextTransition;
87
    if (haveNextMidpoint)
87
    if (haveNextTransition)
88
        nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMidpoint()];
88
        nextTransition = lineWhitespaceCollapsingState.transitions()[lineWhitespaceCollapsingState.currentTransition()];
89
    if (lineMidpointState.betweenMidpoints()) {
89
    if (lineWhitespaceCollapsingState.betweenTransitions()) {
90
        if (!haveNextMidpoint || (&obj != nextMidpoint.renderer()))
90
        if (!haveNextTransition || (&obj != nextTransition.renderer()))
91
            return;
91
            return;
92
        // This is a new start point. Stop ignoring objects and
92
        // This is a new start point. Stop ignoring objects and
93
        // adjust our start.
93
        // adjust our start.
94
        start = nextMidpoint.offset();
94
        start = nextTransition.offset();
95
        lineMidpointState.incrementCurrentMidpoint();
95
        lineWhitespaceCollapsingState.incrementCurrentTransition();
96
        if (start < end) {
96
        if (start < end) {
97
            appendRunsForObject(runs, start, end, obj, resolver);
97
            appendRunsForObject(runs, start, end, obj, resolver);
98
            return;
98
            return;
99
        }
99
        }
100
    } else {
100
    } else {
101
        if (!haveNextMidpoint || (&obj != nextMidpoint.renderer())) {
101
        if (!haveNextTransition || (&obj != nextTransition.renderer())) {
102
            if (runs)
102
            if (runs)
103
                runs->appendRun(createRun(start, end, obj, resolver));
103
                runs->appendRun(createRun(start, end, obj, resolver));
104
            return;
104
            return;
105
        }
105
        }
106
106
107
        // An end midpoint has been encountered within our object. We need to append a run with our endpoint.
107
        // An end transition has been encountered within our object. We need to append a run with our endpoint.
108
        if (static_cast<int>(nextMidpoint.offset() + 1) <= end) {
108
        if (static_cast<int>(nextTransition.offset() + 1) <= end) {
109
            lineMidpointState.incrementCurrentMidpoint();
109
            lineWhitespaceCollapsingState.incrementCurrentTransition();
110
            // The end of the line is before the object we're inspecting. Skip everything and return
110
            // The end of the line is before the object we're inspecting. Skip everything and return
111
            if (nextMidpoint.refersToEndOfPreviousNode())
111
            if (nextTransition.refersToEndOfPreviousNode())
112
                return;
112
                return;
113
            if (static_cast<int>(nextMidpoint.offset() + 1) > start && runs)
113
            if (static_cast<int>(nextTransition.offset() + 1) > start && runs)
114
                runs->appendRun(createRun(start, nextMidpoint.offset() + 1, obj, resolver));
114
                runs->appendRun(createRun(start, nextTransition.offset() + 1, obj, resolver));
115
            appendRunsForObject(runs, nextMidpoint.offset() + 1, end, obj, resolver);
115
            appendRunsForObject(runs, nextTransition.offset() + 1, end, obj, resolver);
116
        } else if (runs)
116
        } else if (runs)
117
            runs->appendRun(createRun(start, end, obj, resolver));
117
            runs->appendRun(createRun(start, end, obj, resolver));
118
    }
118
    }
Lines 1076-1084 static inline void notifyResolverToResumeInIsolate(InlineBidiResolver& resolver, a/Source/WebCore/rendering/RenderBlockLineLayout.cpp_sec2
1076
1076
1077
static inline void setUpResolverToResumeInIsolate(InlineBidiResolver& resolver, InlineBidiResolver& topResolver, BidiRun& isolatedRun, RenderObject* root, RenderObject* startObject)
1077
static inline void setUpResolverToResumeInIsolate(InlineBidiResolver& resolver, InlineBidiResolver& topResolver, BidiRun& isolatedRun, RenderObject* root, RenderObject* startObject)
1078
{
1078
{
1079
    // Set up m_midpointState
1079
    // Set up m_whitespaceCollapsingState
1080
    resolver.midpointState() = topResolver.midpointState();
1080
    resolver.whitespaceCollapsingState() = topResolver.whitespaceCollapsingState();
1081
    resolver.midpointState().setCurrentMidpoint(topResolver.midpointForIsolatedRun(isolatedRun));
1081
    resolver.whitespaceCollapsingState().setCurrentTransition(topResolver.whitespaceCollapsingTransitionForIsolatedRun(isolatedRun));
1082
1082
1083
    // Set up m_nestedIsolateCount
1083
    // Set up m_nestedIsolateCount
1084
    notifyResolverToResumeInIsolate(resolver, root, startObject);
1084
    notifyResolverToResumeInIsolate(resolver, root, startObject);
Lines 1145-1151 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, a/Source/WebCore/rendering/RenderBlockLineLayout.cpp_sec3
1145
        while (!isolatedResolver.isolatedRuns().isEmpty()) {
1145
        while (!isolatedResolver.isolatedRuns().isEmpty()) {
1146
            auto runWithContext = WTFMove(isolatedResolver.isolatedRuns().last());
1146
            auto runWithContext = WTFMove(isolatedResolver.isolatedRuns().last());
1147
            isolatedResolver.isolatedRuns().removeLast();
1147
            isolatedResolver.isolatedRuns().removeLast();
1148
            topResolver.setMidpointForIsolatedRun(runWithContext.runToReplace, isolatedResolver.midpointForIsolatedRun(runWithContext.runToReplace));
1148
            topResolver.setWhitespaceCollapsingTransitionForIsolatedRun(runWithContext.runToReplace, isolatedResolver.whitespaceCollapsingTransitionForIsolatedRun(runWithContext.runToReplace));
1149
            topResolver.isolatedRuns().append(WTFMove(runWithContext));
1149
            topResolver.isolatedRuns().append(WTFMove(runWithContext));
1150
        }
1150
        }
1151
    }
1151
    }
Lines 1286-1292 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I a/Source/WebCore/rendering/RenderBlockLineLayout.cpp_sec4
1286
{
1286
{
1287
    const RenderStyle& styleToUse = style();
1287
    const RenderStyle& styleToUse = style();
1288
    bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1288
    bool paginated = view().layoutState() && view().layoutState()->isPaginated();
1289
    LineMidpointState& lineMidpointState = resolver.midpointState();
1289
    LineWhitespaceCollapsingState& lineWhitespaceCollapsingState = resolver.whitespaceCollapsingState();
1290
    InlineIterator end = resolver.position();
1290
    InlineIterator end = resolver.position();
1291
    bool checkForEndLineMatch = layoutState.endLine();
1291
    bool checkForEndLineMatch = layoutState.endLine();
1292
    RenderTextInfo renderTextInfo;
1292
    RenderTextInfo renderTextInfo;
Lines 1305-1311 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I a/Source/WebCore/rendering/RenderBlockLineLayout.cpp_sec5
1305
            }
1305
            }
1306
        }
1306
        }
1307
1307
1308
        lineMidpointState.reset();
1308
        lineWhitespaceCollapsingState.reset();
1309
1309
1310
        layoutState.lineInfo().setEmpty(true);
1310
        layoutState.lineInfo().setEmpty(true);
1311
        layoutState.lineInfo().resetRunsFromLeadingWhitespace();
1311
        layoutState.lineInfo().resetRunsFromLeadingWhitespace();
Lines 1455-1461 void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I a/Source/WebCore/rendering/RenderBlockLineLayout.cpp_sec6
1455
            layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : nullptr);
1455
            layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : nullptr);
1456
        }
1456
        }
1457
1457
1458
        lineMidpointState.reset();
1458
        lineWhitespaceCollapsingState.reset();
1459
        resolver.setPosition(end, numberOfIsolateAncestors(end));
1459
        resolver.setPosition(end, numberOfIsolateAncestors(end));
1460
    }
1460
    }
1461
1461
- a/Source/WebCore/rendering/line/BreakingContext.h -40 / +40 lines
Lines 129-135 public: a/Source/WebCore/rendering/line/BreakingContext.h_sec1
129
        , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTableCell() || !m_blockStyle.logicalWidth().isIntrinsicOrAuto())
129
        , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTableCell() || !m_blockStyle.logicalWidth().isIntrinsicOrAuto())
130
        , m_atEnd(false)
130
        , m_atEnd(false)
131
        , m_hadUncommittedWidthBeforeCurrent(false)
131
        , m_hadUncommittedWidthBeforeCurrent(false)
132
        , m_lineMidpointState(resolver.midpointState())
132
        , m_lineWhitespaceCollapsingState(resolver.whitespaceCollapsingState())
133
    {
133
    {
134
        m_lineInfo.setPreviousLineBrokeCleanly(false);
134
        m_lineInfo.setPreviousLineBrokeCleanly(false);
135
    }
135
    }
Lines 292-298 private: a/Source/WebCore/rendering/line/BreakingContext.h_sec2
292
    
292
    
293
    bool m_hangsAtEnd { false };
293
    bool m_hangsAtEnd { false };
294
294
295
    LineMidpointState& m_lineMidpointState;
295
    LineWhitespaceCollapsingState& m_lineWhitespaceCollapsingState;
296
296
297
    TrailingObjects m_trailingObjects;
297
    TrailingObjects m_trailingObjects;
298
};
298
};
Lines 334-342 inline void BreakingContext::increment() a/Source/WebCore/rendering/line/BreakingContext.h_sec3
334
inline void BreakingContext::handleBR(EClear& clear)
334
inline void BreakingContext::handleBR(EClear& clear)
335
{
335
{
336
    if (fitsOnLineOrHangsAtEnd()) {
336
    if (fitsOnLineOrHangsAtEnd()) {
337
        RenderObject* br = m_current.renderer();
337
        RenderObject& br = *m_current.renderer();
338
        m_lineBreakHistory.push([&](InlineIterator& modifyMe) {
338
        m_lineBreakHistory.push([&](InlineIterator& modifyMe) {
339
            modifyMe.moveToStartOf(br);
339
            modifyMe.moveToStartOf(&br);
340
            modifyMe.increment();
340
            modifyMe.increment();
341
        });
341
        });
342
342
Lines 354-365 inline void BreakingContext::handleBR(EClear& clear) a/Source/WebCore/rendering/line/BreakingContext.h_sec4
354
        // need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
354
        // need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
355
        // run for this object.
355
        // run for this object.
356
        if (m_ignoringSpaces && m_currentStyle->clear() != CNONE)
356
        if (m_ignoringSpaces && m_currentStyle->clear() != CNONE)
357
            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(br);
357
            m_lineWhitespaceCollapsingState.ensureLineBoxInsideIgnoredSpaces(br);
358
        // If we were preceded by collapsing space and are in a right-aligned container we need to ensure the space gets
358
        // If we were preceded by collapsing space and are in a right-aligned container we need to ensure the space gets
359
        // collapsed away so that it doesn't push the text out from the container's right-hand edge.
359
        // collapsed away so that it doesn't push the text out from the container's right-hand edge.
360
        // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
360
        // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
361
        else if (m_ignoringSpaces && (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT))
361
        else if (m_ignoringSpaces && (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT))
362
            m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
362
            m_lineWhitespaceCollapsingState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
363
363
364
        if (!m_lineInfo.isEmpty())
364
        if (!m_lineInfo.isEmpty())
365
            clear = m_currentStyle->clear();
365
            clear = m_currentStyle->clear();
Lines 438-445 inline void BreakingContext::handleOutOfFlowPositioned(Vector<RenderBox*>& posit a/Source/WebCore/rendering/line/BreakingContext.h_sec5
438
    // then start ignoring spaces again.
438
    // then start ignoring spaces again.
439
    if (isInlineType || box.container()->isRenderInline()) {
439
    if (isInlineType || box.container()->isRenderInline()) {
440
        if (m_ignoringSpaces)
440
        if (m_ignoringSpaces)
441
            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(&box);
441
            m_lineWhitespaceCollapsingState.ensureLineBoxInsideIgnoredSpaces(box);
442
        m_trailingObjects.appendBoxIfNeeded(&box);
442
        m_trailingObjects.appendBoxIfNeeded(box);
443
    } else
443
    } else
444
        positionedObjects.append(&box);
444
        positionedObjects.append(&box);
445
445
Lines 469-475 inline void BreakingContext::handleFloat() a/Source/WebCore/rendering/line/BreakingContext.h_sec6
469
469
470
// This is currently just used for list markers and inline flows that have line boxes. Neither should
470
// This is currently just used for list markers and inline flows that have line boxes. Neither should
471
// have an effect on whitespace at the start of the line.
471
// have an effect on whitespace at the start of the line.
472
inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow& block, RenderObject* o, LineMidpointState& lineMidpointState)
472
inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow& block, RenderObject* o, LineWhitespaceCollapsingState& lineWhitespaceCollapsingState)
473
{
473
{
474
    RenderObject* next = bidiNextSkippingEmptyInlines(block, o);
474
    RenderObject* next = bidiNextSkippingEmptyInlines(block, o);
475
    while (next && next->isFloatingOrOutOfFlowPositioned())
475
    while (next && next->isFloatingOrOutOfFlowPositioned())
Lines 479-485 inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow& block, RenderO a/Source/WebCore/rendering/line/BreakingContext.h_sec7
479
        RenderText& nextText = downcast<RenderText>(*next);
479
        RenderText& nextText = downcast<RenderText>(*next);
480
        UChar nextChar = nextText.characterAt(0);
480
        UChar nextChar = nextText.characterAt(0);
481
        if (nextText.style().isCollapsibleWhiteSpace(nextChar)) {
481
        if (nextText.style().isCollapsibleWhiteSpace(nextChar)) {
482
            lineMidpointState.startIgnoringSpaces(InlineIterator(nullptr, o, 0));
482
            lineWhitespaceCollapsingState.startIgnoringSpaces(InlineIterator(nullptr, o, 0));
483
            return true;
483
            return true;
484
        }
484
        }
485
    }
485
    }
Lines 506-521 inline void BreakingContext::handleEmptyInline() a/Source/WebCore/rendering/line/BreakingContext.h_sec8
506
            m_lineInfo.setEmpty(false, &m_block, &m_width);
506
            m_lineInfo.setEmpty(false, &m_block, &m_width);
507
        if (m_ignoringSpaces) {
507
        if (m_ignoringSpaces) {
508
            m_trailingObjects.clear();
508
            m_trailingObjects.clear();
509
            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_current.renderer());
509
            m_lineWhitespaceCollapsingState.ensureLineBoxInsideIgnoredSpaces(*m_current.renderer());
510
        } else if (m_blockStyle.collapseWhiteSpace() && m_resolver.position().renderer() == m_current.renderer()
510
        } else if (m_blockStyle.collapseWhiteSpace() && m_resolver.position().renderer() == m_current.renderer()
511
            && shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineMidpointState)) {
511
            && shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineWhitespaceCollapsingState)) {
512
            // Like with list markers, we start ignoring spaces to make sure that any
512
            // Like with list markers, we start ignoring spaces to make sure that any
513
            // additional spaces we see will be discarded.
513
            // additional spaces we see will be discarded.
514
            m_currentCharacterIsSpace = true;
514
            m_currentCharacterIsSpace = true;
515
            m_currentCharacterIsWS = true;
515
            m_currentCharacterIsWS = true;
516
            m_ignoringSpaces = true;
516
            m_ignoringSpaces = true;
517
        } else
517
        } else
518
            m_trailingObjects.appendBoxIfNeeded(&flowBox);
518
            m_trailingObjects.appendBoxIfNeeded(flowBox);
519
    }
519
    }
520
    
520
    
521
    float inlineWidth = inlineLogicalWidth(m_current.renderer()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox);
521
    float inlineWidth = inlineLogicalWidth(m_current.renderer()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox);
Lines 549-555 inline void BreakingContext::handleReplaced() a/Source/WebCore/rendering/line/BreakingContext.h_sec9
549
            m_lineLayoutState.prevFloatBottomFromAnonymousInlineBlock(), m_lineLayoutState.maxFloatBottomFromAnonymousInlineBlock());
549
            m_lineLayoutState.prevFloatBottomFromAnonymousInlineBlock(), m_lineLayoutState.maxFloatBottomFromAnonymousInlineBlock());
550
550
551
    if (m_ignoringSpaces)
551
    if (m_ignoringSpaces)
552
        m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), 0));
552
        m_lineWhitespaceCollapsingState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), 0));
553
553
554
    m_lineInfo.setEmpty(false, &m_block, &m_width);
554
    m_lineInfo.setEmpty(false, &m_block, &m_width);
555
    m_ignoringSpaces = false;
555
    m_ignoringSpaces = false;
Lines 561-567 inline void BreakingContext::handleReplaced() a/Source/WebCore/rendering/line/BreakingContext.h_sec10
561
    // item, then this is all moot.
561
    // item, then this is all moot.
562
    LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox) + m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedBox) + inlineLogicalWidth(m_current.renderer());
562
    LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox) + m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedBox) + inlineLogicalWidth(m_current.renderer());
563
    if (is<RenderListMarker>(*m_current.renderer())) {
563
    if (is<RenderListMarker>(*m_current.renderer())) {
564
        if (m_blockStyle.collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineMidpointState)) {
564
        if (m_blockStyle.collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineWhitespaceCollapsingState)) {
565
            // Like with inline flows, we start ignoring spaces to make sure that any
565
            // Like with inline flows, we start ignoring spaces to make sure that any
566
            // additional spaces we see will be discarded.
566
            // additional spaces we see will be discarded.
567
            m_currentCharacterIsSpace = true;
567
            m_currentCharacterIsSpace = true;
Lines 642-653 ALWAYS_INLINE float textWidth(RenderText& text, unsigned from, unsigned len, con a/Source/WebCore/rendering/line/BreakingContext.h_sec11
642
    return font.width(run, &fallbackFonts, &glyphOverflow);
642
    return font.width(run, &fallbackFonts, &glyphOverflow);
643
}
643
}
644
644
645
// Adding a pair of midpoints before a character will split it out into a new line box.
645
// Adding a pair of whitespace collapsing transitions before a character will split it out into a new line box.
646
inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointState, InlineIterator& textParagraphSeparator)
646
inline void ensureCharacterGetsLineBox(LineWhitespaceCollapsingState& lineWhitespaceCollapsingState, InlineIterator& textParagraphSeparator)
647
{
647
{
648
    InlineIterator midpoint(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset());
648
    InlineIterator transition(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset());
649
    lineMidpointState.startIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset() - 1));
649
    lineWhitespaceCollapsingState.startIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset() - 1));
650
    lineMidpointState.stopIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset()));
650
    lineWhitespaceCollapsingState.stopIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset()));
651
}
651
}
652
652
653
inline void tryHyphenating(RenderText& text, const FontCascade& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
653
inline void tryHyphenating(RenderText& text, const FontCascade& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
Lines 887-893 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec12
887
                    m_ignoringSpaces = false;
887
                    m_ignoringSpaces = false;
888
                    wordSpacingForWordMeasurement = 0;
888
                    wordSpacingForWordMeasurement = 0;
889
                    lastSpace = m_current.offset(); // e.g., "Foo    goo", don't add in any of the ignored spaces.
889
                    lastSpace = m_current.offset(); // e.g., "Foo    goo", don't add in any of the ignored spaces.
890
                    m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
890
                    m_lineWhitespaceCollapsingState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
891
                    stoppedIgnoringSpaces = true;
891
                    stoppedIgnoringSpaces = true;
892
                } else {
892
                } else {
893
                    // Just keep ignoring these spaces.
893
                    // Just keep ignoring these spaces.
Lines 948-954 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec13
948
                    }
948
                    }
949
                    if (m_lineBreakHistory.atTextParagraphSeparator()) {
949
                    if (m_lineBreakHistory.atTextParagraphSeparator()) {
950
                        if (!stoppedIgnoringSpaces && m_current.offset() > 0)
950
                        if (!stoppedIgnoringSpaces && m_current.offset() > 0)
951
                            ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
951
                            ensureCharacterGetsLineBox(m_lineWhitespaceCollapsingState, m_current);
952
                        m_lineBreakHistory.increment();
952
                        m_lineBreakHistory.increment();
953
                        m_lineInfo.setPreviousLineBrokeCleanly(true);
953
                        m_lineInfo.setPreviousLineBrokeCleanly(true);
954
                        wordMeasurement.endOffset = m_lineBreakHistory.offset();
954
                        wordMeasurement.endOffset = m_lineBreakHistory.offset();
Lines 1004-1010 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec14
1004
1004
1005
            if (c == '\n' && m_preservesNewline) {
1005
            if (c == '\n' && m_preservesNewline) {
1006
                if (!stoppedIgnoringSpaces && m_current.offset())
1006
                if (!stoppedIgnoringSpaces && m_current.offset())
1007
                    ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
1007
                    ensureCharacterGetsLineBox(m_lineWhitespaceCollapsingState, m_current);
1008
                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
1008
                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
1009
                m_lineBreakHistory.increment();
1009
                m_lineBreakHistory.increment();
1010
                m_lineInfo.setPreviousLineBrokeCleanly(true);
1010
                m_lineInfo.setPreviousLineBrokeCleanly(true);
Lines 1039-1048 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec15
1039
                    m_ignoringSpaces = true;
1039
                    m_ignoringSpaces = true;
1040
1040
1041
                    // We just entered a mode where we are ignoring
1041
                    // We just entered a mode where we are ignoring
1042
                    // spaces. Create a midpoint to terminate the run
1042
                    // spaces. Create a transition to terminate the run
1043
                    // before the second space.
1043
                    // before the second space.
1044
                    m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
1044
                    m_lineWhitespaceCollapsingState.startIgnoringSpaces(m_startOfIgnoredSpaces);
1045
                    m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
1045
                    m_trailingObjects.updateWhitespaceCollapsingTransitionsForTrailingBoxes(m_lineWhitespaceCollapsingState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
1046
                }
1046
                }
1047
            }
1047
            }
1048
        } else {
1048
        } else {
Lines 1052-1058 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec16
1052
                lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
1052
                lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
1053
                wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurements.last().width) ? wordSpacing : 0;
1053
                wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurements.last().width) ? wordSpacing : 0;
1054
                lastSpace = m_current.offset(); // e.g., "Foo    goo", don't add in any of the ignored spaces.
1054
                lastSpace = m_current.offset(); // e.g., "Foo    goo", don't add in any of the ignored spaces.
1055
                m_lineMidpointState.stopIgnoringSpaces(InlineIterator(nullptr, m_current.renderer(), m_current.offset()));
1055
                m_lineWhitespaceCollapsingState.stopIgnoringSpaces(InlineIterator(nullptr, m_current.renderer(), m_current.offset()));
1056
            }
1056
            }
1057
            if (m_hangsAtEnd && !renderText.isHangableStopOrComma(c))
1057
            if (m_hangsAtEnd && !renderText.isHangableStopOrComma(c))
1058
                m_hangsAtEnd = false;
1058
                m_hangsAtEnd = false;
Lines 1061-1067 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec17
1061
        if (isSVGText && m_current.offset()) {
1061
        if (isSVGText && m_current.offset()) {
1062
            // Force creation of new InlineBoxes for each absolute positioned character (those that start new text chunks).
1062
            // Force creation of new InlineBoxes for each absolute positioned character (those that start new text chunks).
1063
            if (downcast<RenderSVGInlineText>(renderText).characterStartsNewTextChunk(m_current.offset()))
1063
            if (downcast<RenderSVGInlineText>(renderText).characterStartsNewTextChunk(m_current.offset()))
1064
                ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
1064
                ensureCharacterGetsLineBox(m_lineWhitespaceCollapsingState, m_current);
1065
        }
1065
        }
1066
1066
1067
        if (m_currentCharacterIsSpace && !previousCharacterIsSpace) {
1067
        if (m_currentCharacterIsSpace && !previousCharacterIsSpace) {
Lines 1074-1080 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool a/Source/WebCore/rendering/line/BreakingContext.h_sec18
1074
                m_startOfIgnoredSpaces.setOffset(m_startOfIgnoredSpaces.offset() - 1);
1074
                m_startOfIgnoredSpaces.setOffset(m_startOfIgnoredSpaces.offset() - 1);
1075
                // If there's just a single trailing space start ignoring it now so it collapses away.
1075
                // If there's just a single trailing space start ignoring it now so it collapses away.
1076
                if (m_current.offset() == renderText.textLength() - 1)
1076
                if (m_current.offset() == renderText.textLength() - 1)
1077
                    m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
1077
                    m_lineWhitespaceCollapsingState.startIgnoringSpaces(m_startOfIgnoredSpaces);
1078
            }
1078
            }
1079
        }
1079
        }
1080
1080
Lines 1220-1242 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() a/Source/WebCore/rendering/line/BreakingContext.h_sec19
1220
    }
1220
    }
1221
}
1221
}
1222
1222
1223
inline TrailingObjects::CollapseFirstSpaceOrNot checkMidpoints(LineMidpointState& lineMidpointState, const InlineIterator& lBreak)
1223
inline TrailingObjects::CollapseFirstSpaceOrNot checkWhitespaceCollapsingTransitions(LineWhitespaceCollapsingState& lineWhitespaceCollapsingState, const InlineIterator& lBreak)
1224
{
1224
{
1225
    // Check to see if our last midpoint is a start point beyond the line break. If so,
1225
    // Check to see if our last transition is a start point beyond the line break. If so,
1226
    // shave it off the list, and shave off a trailing space if the previous end point doesn't
1226
    // shave it off the list, and shave off a trailing space if the previous end point doesn't
1227
    // preserve whitespace.
1227
    // preserve whitespace.
1228
    if (lBreak.renderer() && lineMidpointState.numMidpoints() && !(lineMidpointState.numMidpoints() % 2)) {
1228
    if (lBreak.renderer() && lineWhitespaceCollapsingState.numTransitions() && !(lineWhitespaceCollapsingState.numTransitions() % 2)) {
1229
        InlineIterator* midpoints = lineMidpointState.midpoints().data();
1229
        const InlineIterator* transitions = lineWhitespaceCollapsingState.transitions().data();
1230
        InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints() - 2];
1230
        const InlineIterator& endpoint = transitions[lineWhitespaceCollapsingState.numTransitions() - 2];
1231
        const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoints() - 1];
1231
        const InlineIterator& startpoint = transitions[lineWhitespaceCollapsingState.numTransitions() - 1];
1232
        InlineIterator currpoint = endpoint;
1232
        InlineIterator currpoint = endpoint;
1233
        while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak)
1233
        while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak)
1234
            currpoint.increment();
1234
            currpoint.increment();
1235
        if (currpoint == lBreak) {
1235
        if (currpoint == lBreak) {
1236
            // We hit the line break before the start point. Shave off the start point.
1236
            // We hit the line break before the start point. Shave off the start point.
1237
            lineMidpointState.decrementNumMidpoints();
1237
            lineWhitespaceCollapsingState.decrementNumTransitions();
1238
            if (endpoint.renderer()->style().collapseWhiteSpace() && endpoint.renderer()->isText()) {
1238
            if (endpoint.renderer()->style().collapseWhiteSpace() && endpoint.renderer()->isText()) {
1239
                endpoint.fastDecrement();
1239
                lineWhitespaceCollapsingState.decrementTransitionAt(lineWhitespaceCollapsingState.numTransitions() - 1);
1240
                return TrailingObjects::DoNotCollapseFirstSpace;
1240
                return TrailingObjects::DoNotCollapseFirstSpace;
1241
            }
1241
            }
1242
        }
1242
        }
Lines 1269-1278 inline InlineIterator BreakingContext::handleEndOfLine() a/Source/WebCore/rendering/line/BreakingContext.h_sec20
1269
        m_lineBreakHistory.increment();
1269
        m_lineBreakHistory.increment();
1270
    }
1270
    }
1271
1271
1272
    // Sanity check our midpoints.
1272
    // Sanity check our whitespace collapsing transitions.
1273
    TrailingObjects::CollapseFirstSpaceOrNot collapsed = checkMidpoints(m_lineMidpointState, m_lineBreakHistory.current());
1273
    TrailingObjects::CollapseFirstSpaceOrNot collapsed = checkWhitespaceCollapsingTransitions(m_lineWhitespaceCollapsingState, m_lineBreakHistory.current());
1274
1274
1275
    m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lineBreakHistory.current(), collapsed);
1275
    m_trailingObjects.updateWhitespaceCollapsingTransitionsForTrailingBoxes(m_lineWhitespaceCollapsingState, m_lineBreakHistory.current(), collapsed);
1276
1276
1277
    // We might have made lineBreak an iterator that points past the end
1277
    // We might have made lineBreak an iterator that points past the end
1278
    // of the object. Do this adjustment to make it point to the start
1278
    // of the object. Do this adjustment to make it point to the start
- a/Source/WebCore/rendering/line/TrailingObjects.cpp -19 / +19 lines
Lines 29-72 a/Source/WebCore/rendering/line/TrailingObjects.cpp_sec1
29
29
30
namespace WebCore {
30
namespace WebCore {
31
31
32
void TrailingObjects::updateMidpointsForTrailingBoxes(LineMidpointState& lineMidpointState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstSpace)
32
void TrailingObjects::updateWhitespaceCollapsingTransitionsForTrailingBoxes(LineWhitespaceCollapsingState& lineWhitespaceCollapsingState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstSpace)
33
{
33
{
34
    if (!m_whitespace)
34
    if (!m_whitespace)
35
        return;
35
        return;
36
36
37
    // This object is either going to be part of the last midpoint, or it is going to be the actual endpoint.
37
    // This object is either going to be part of the last transition, or it is going to be the actual endpoint.
38
    // In both cases we just decrease our pos by 1 level to exclude the space, allowing it to - in effect - collapse into the newline.
38
    // In both cases we just decrease our pos by 1 level to exclude the space, allowing it to - in effect - collapse into the newline.
39
    if (lineMidpointState.numMidpoints() % 2) {
39
    if (lineWhitespaceCollapsingState.numTransitions() % 2) {
40
        // Find the trailing space object's midpoint.
40
        // Find the trailing space object's transition.
41
        int trailingSpaceMidpoint = lineMidpointState.numMidpoints() - 1;
41
        int trailingSpaceTransition = lineWhitespaceCollapsingState.numTransitions() - 1;
42
        for ( ; trailingSpaceMidpoint > 0 && lineMidpointState.midpoints()[trailingSpaceMidpoint].renderer() != m_whitespace; --trailingSpaceMidpoint) { }
42
        for ( ; trailingSpaceTransition > 0 && lineWhitespaceCollapsingState.transitions()[trailingSpaceTransition].renderer() != m_whitespace; --trailingSpaceTransition) { }
43
        ASSERT(trailingSpaceMidpoint >= 0);
43
        ASSERT(trailingSpaceTransition >= 0);
44
        if (collapseFirstSpace == CollapseFirstSpace)
44
        if (collapseFirstSpace == CollapseFirstSpace)
45
            lineMidpointState.midpoints()[trailingSpaceMidpoint].fastDecrement();
45
            lineWhitespaceCollapsingState.decrementTransitionAt(trailingSpaceTransition);
46
46
47
        // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts
47
        // Now make sure every single trailingPositionedBox following the trailingSpaceTransition properly stops and starts
48
        // ignoring spaces.
48
        // ignoring spaces.
49
        size_t currentMidpoint = trailingSpaceMidpoint + 1;
49
        size_t currentTransition = trailingSpaceTransition + 1;
50
        for (size_t i = 0; i < m_boxes.size(); ++i) {
50
        for (size_t i = 0; i < m_boxes.size(); ++i) {
51
            if (currentMidpoint >= lineMidpointState.numMidpoints()) {
51
            if (currentTransition >= lineWhitespaceCollapsingState.numTransitions()) {
52
                // We don't have a midpoint for this box yet.
52
                // We don't have a transition for this box yet.
53
                lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_boxes[i]);
53
                lineWhitespaceCollapsingState.ensureLineBoxInsideIgnoredSpaces(m_boxes[i]);
54
            } else {
54
            } else {
55
                ASSERT(lineMidpointState.midpoints()[currentMidpoint].renderer() == m_boxes[i]);
55
                ASSERT(lineWhitespaceCollapsingState.transitions()[currentTransition].renderer() == &(m_boxes[i].get()));
56
                ASSERT(lineMidpointState.midpoints()[currentMidpoint + 1].renderer() == m_boxes[i]);
56
                ASSERT(lineWhitespaceCollapsingState.transitions()[currentTransition + 1].renderer() == &(m_boxes[i].get()));
57
            }
57
            }
58
            currentMidpoint += 2;
58
            currentTransition += 2;
59
        }
59
        }
60
    } else if (!lBreak.renderer()) {
60
    } else if (!lBreak.renderer()) {
61
        ASSERT(m_whitespace->isText());
61
        ASSERT(m_whitespace->isText());
62
        ASSERT(collapseFirstSpace == CollapseFirstSpace);
62
        ASSERT(collapseFirstSpace == CollapseFirstSpace);
63
        // Add a new end midpoint that stops right at the very end.
63
        // Add a new end transition that stops right at the very end.
64
        unsigned length = m_whitespace->textLength();
64
        unsigned length = m_whitespace->textLength();
65
        unsigned pos = length >= 2 ? length - 2 : UINT_MAX;
65
        unsigned pos = length >= 2 ? length - 2 : UINT_MAX;
66
        InlineIterator endMid(0, m_whitespace, pos);
66
        InlineIterator endMid(0, m_whitespace, pos);
67
        lineMidpointState.startIgnoringSpaces(endMid);
67
        lineWhitespaceCollapsingState.startIgnoringSpaces(endMid);
68
        for (size_t i = 0; i < m_boxes.size(); ++i)
68
        for (size_t i = 0; i < m_boxes.size(); ++i)
69
            lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_boxes[i]);
69
            lineWhitespaceCollapsingState.ensureLineBoxInsideIgnoredSpaces(m_boxes[i]);
70
    }
70
    }
71
}
71
}
72
72
- a/Source/WebCore/rendering/line/TrailingObjects.h -6 / +6 lines
Lines 1-6 a/Source/WebCore/rendering/line/TrailingObjects.h_sec1
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, 2011 Apple Inc. All right reserved.
3
 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2016 Apple Inc. All right reserved.
4
 * Copyright (C) 2010 Google Inc. All rights reserved.
4
 * Copyright (C) 2010 Google Inc. All rights reserved.
5
 * Copyright (C) 2013 ChangSeok Oh <shivamidow@gmail.com>
5
 * Copyright (C) 2013 ChangSeok Oh <shivamidow@gmail.com>
6
 * Copyright (C) 2013 Adobe Systems Inc. All right reserved.
6
 * Copyright (C) 2013 Adobe Systems Inc. All right reserved.
Lines 38-46 struct BidiIsolatedRun; a/Source/WebCore/rendering/line/TrailingObjects.h_sec2
38
38
39
template <class Iterator, class Run> class BidiResolver;
39
template <class Iterator, class Run> class BidiResolver;
40
template <class Iterator, class Run, class IsolateRun> class BidiResolverWithIsolate;
40
template <class Iterator, class Run, class IsolateRun> class BidiResolverWithIsolate;
41
template <class Iterator> class MidpointState;
41
template <class Iterator> class WhitespaceCollapsingState;
42
typedef BidiResolverWithIsolate<InlineIterator, BidiRun, BidiIsolatedRun> InlineBidiResolver;
42
typedef BidiResolverWithIsolate<InlineIterator, BidiRun, BidiIsolatedRun> InlineBidiResolver;
43
typedef MidpointState<InlineIterator> LineMidpointState;
43
typedef WhitespaceCollapsingState<InlineIterator> LineWhitespaceCollapsingState;
44
44
45
class TrailingObjects {
45
class TrailingObjects {
46
public:
46
public:
Lines 60-66 public: a/Source/WebCore/rendering/line/TrailingObjects.h_sec3
60
        m_boxes.shrink(0); // Use shrink(0) instead of clear() to retain our capacity.
60
        m_boxes.shrink(0); // Use shrink(0) instead of clear() to retain our capacity.
61
    }
61
    }
62
62
63
    void appendBoxIfNeeded(RenderBoxModelObject* box)
63
    void appendBoxIfNeeded(RenderBoxModelObject& box)
64
    {
64
    {
65
        if (m_whitespace)
65
        if (m_whitespace)
66
            m_boxes.append(box);
66
            m_boxes.append(box);
Lines 68-78 public: a/Source/WebCore/rendering/line/TrailingObjects.h_sec4
68
68
69
    enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace };
69
    enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace };
70
70
71
    void updateMidpointsForTrailingBoxes(LineMidpointState&, const InlineIterator& lBreak, CollapseFirstSpaceOrNot);
71
    void updateWhitespaceCollapsingTransitionsForTrailingBoxes(LineWhitespaceCollapsingState&, const InlineIterator& lBreak, CollapseFirstSpaceOrNot);
72
72
73
private:
73
private:
74
    RenderText* m_whitespace;
74
    RenderText* m_whitespace;
75
    Vector<RenderBoxModelObject*, 4> m_boxes;
75
    Vector<std::reference_wrapper<RenderBoxModelObject>, 4> m_boxes;
76
};
76
};
77
77
78
}
78
}

Return to Bug 156304