summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h')
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h130
1 files changed, 97 insertions, 33 deletions
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h b/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
index c0c30d9ad8a..e0ecc103241 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
@@ -25,6 +25,7 @@
#include "core/rendering/BidiRun.h"
#include "core/rendering/RenderBlockFlow.h"
+#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderText.h"
#include "wtf/StdLibExtras.h"
@@ -43,16 +44,16 @@ public:
InlineIterator()
: m_root(0)
, m_obj(0)
- , m_pos(0)
, m_nextBreakablePosition(-1)
+ , m_pos(0)
{
}
InlineIterator(RenderObject* root, RenderObject* o, unsigned p)
: m_root(root)
, m_obj(o)
- , m_pos(p)
, m_nextBreakablePosition(-1)
+ , m_pos(p)
{
}
@@ -73,7 +74,11 @@ public:
RenderObject* object() const { return m_obj; }
void setObject(RenderObject* object) { m_obj = object; }
+ int nextBreakablePosition() const { return m_nextBreakablePosition; }
+ void setNextBreakablePosition(int position) { m_nextBreakablePosition = position; }
+
unsigned offset() const { return m_pos; }
+ void setOffset(unsigned position) { m_pos = position; }
RenderObject* root() const { return m_root; }
void fastIncrementInTextNode();
@@ -100,20 +105,18 @@ private:
RenderObject* m_root;
RenderObject* m_obj;
-// FIXME: These should be private.
-public:
- unsigned m_pos;
int m_nextBreakablePosition;
+ unsigned m_pos;
};
inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
{
- return it1.m_pos == it2.m_pos && it1.object() == it2.object();
+ return it1.offset() == it2.offset() && it1.object() == it2.object();
}
inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
{
- return it1.m_pos != it2.m_pos || it1.object() != it2.object();
+ return it1.offset() != it2.offset() || it1.object() != it2.object();
}
static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi)
@@ -187,7 +190,7 @@ static bool isEmptyInline(RenderObject* object)
if (!object->isRenderInline())
return false;
- for (RenderObject* curr = object->firstChild(); curr; curr = curr->nextSibling()) {
+ for (RenderObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) {
if (curr->isFloatingOrOutOfFlowPositioned())
continue;
if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace())
@@ -213,7 +216,7 @@ static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* cur
while (current) {
next = 0;
if (!oldEndOfInline && !isIteratorTarget(current)) {
- next = current->firstChild();
+ next = current->slowFirstChild();
notifyObserverEnteredObject(observer, next);
}
@@ -280,7 +283,7 @@ static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re
return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInlinePtr);
}
-static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, InlineBidiResolver* resolver = 0)
+static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, InlineBidiResolver* resolver = 0)
{
RenderObject* o = root->firstChild();
if (!o)
@@ -308,7 +311,7 @@ static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, In
}
// FIXME: This method needs to be renamed when bidiNext finds a good name.
-static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderObject* root)
+static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderBlock* root)
{
RenderObject* o = root->firstChild();
// If either there are no children to walk, or the first one is correct
@@ -332,7 +335,7 @@ inline void InlineIterator::fastIncrementInTextNode()
// it shouldn't use functions called bidiFirst and bidiNext.
class InlineWalker {
public:
- InlineWalker(RenderObject* root)
+ InlineWalker(RenderBlock* root)
: m_root(root)
, m_current(0)
, m_atEndOfInline(false)
@@ -341,7 +344,7 @@ public:
m_current = bidiFirstIncludingEmptyInlines(m_root);
}
- RenderObject* root() { return m_root; }
+ RenderBlock* root() { return m_root; }
RenderObject* current() { return m_current; }
bool atEndOfInline() { return m_atEndOfInline; }
@@ -354,7 +357,7 @@ public:
return m_current;
}
private:
- RenderObject* m_root;
+ RenderBlock* m_root;
RenderObject* m_current;
bool m_atEndOfInline;
};
@@ -442,13 +445,74 @@ inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end)
{
bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() && m_current.object() == end.object());
if (inIsolate() && inEndOfLine) {
- m_current.moveTo(m_current.object(), end.m_pos, m_current.m_nextBreakablePosition);
+ m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakablePosition());
m_last = m_current;
updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral);
}
return inEndOfLine;
}
+static inline bool isCollapsibleSpace(UChar character, RenderText* renderer)
+{
+ if (character == ' ' || character == '\t' || character == softHyphen)
+ return true;
+ if (character == '\n')
+ return !renderer->style()->preserveNewline();
+ return false;
+}
+
+template <typename CharacterType>
+static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterType* characters, int start, int stop)
+{
+ int firstSpace = stop;
+ while (firstSpace > start) {
+ UChar current = characters[firstSpace - 1];
+ if (!isCollapsibleSpace(current, lastText))
+ break;
+ firstSpace--;
+ }
+
+ return firstSpace;
+}
+
+template <>
+inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run)
+{
+ ASSERT(run);
+ RenderObject* lastObject = run->m_object;
+ if (!lastObject->isText())
+ return run->m_stop;
+
+ RenderText* lastText = toRenderText(lastObject);
+ int firstSpace;
+ if (lastText->is8Bit())
+ firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), run->start(), run->stop());
+ else
+ firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), run->start(), run->stop());
+ return firstSpace;
+}
+
+template <>
+inline BidiRun* InlineBidiResolver::addTrailingRun(int start, int stop, BidiRun* run, BidiContext* context, TextDirection direction)
+{
+ BidiRun* newTrailingRun = new BidiRun(start, stop, run->m_object, context, WTF::Unicode::OtherNeutral);
+ if (direction == LTR)
+ m_runs.addRun(newTrailingRun);
+ else
+ m_runs.prependRun(newTrailingRun);
+
+ return newTrailingRun;
+}
+
+template <>
+inline bool InlineBidiResolver::needsToApplyL1Rule()
+{
+ if (!m_runs.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()
+ || !m_runs.logicallyLastRun()->m_object->style()->autoWrap())
+ return false;
+ return true;
+}
+
static inline bool isIsolatedInline(RenderObject* object)
{
ASSERT(object);
@@ -569,18 +633,18 @@ static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns
return;
LineMidpointState& lineMidpointState = resolver.midpointState();
- bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints);
+ bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointState.numMidpoints());
InlineIterator nextMidpoint;
if (haveNextMidpoint)
- nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint];
- if (lineMidpointState.betweenMidpoints) {
+ nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMidpoint()];
+ if (lineMidpointState.betweenMidpoints()) {
if (!(haveNextMidpoint && nextMidpoint.object() == obj))
return;
// This is a new start point. Stop ignoring objects and
// adjust our start.
- lineMidpointState.betweenMidpoints = false;
- start = nextMidpoint.m_pos;
- lineMidpointState.currentMidpoint++;
+ lineMidpointState.setBetweenMidpoints(false);
+ start = nextMidpoint.offset();
+ lineMidpointState.incrementCurrentMidpoint();
if (start < end)
return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, behavior, tracker);
} else {
@@ -591,13 +655,13 @@ static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns
// An end midpoint has been encountered within our object. We
// need to go ahead and append a run with our endpoint.
- if (nextMidpoint.m_pos + 1 <= end) {
- lineMidpointState.betweenMidpoints = true;
- lineMidpointState.currentMidpoint++;
- if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it.
- if (nextMidpoint.m_pos + 1 > start)
- appendRunObjectIfNecessary(obj, start, nextMidpoint.m_pos + 1, resolver, behavior, tracker);
- return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.m_pos + 1, end, resolver, behavior, tracker);
+ if (nextMidpoint.offset() + 1 <= end) {
+ lineMidpointState.setBetweenMidpoints(true);
+ lineMidpointState.incrementCurrentMidpoint();
+ if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it.
+ if (nextMidpoint.offset() + 1 > start)
+ appendRunObjectIfNecessary(obj, start, nextMidpoint.offset() + 1, resolver, behavior, tracker);
+ return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.offset() + 1, end, resolver, behavior, tracker);
}
} else {
appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker);
@@ -619,7 +683,7 @@ inline void InlineBidiResolver::appendRun()
// Initialize our state depending on if we're starting in the middle of such an inline.
// FIXME: Could this initialize from this->inIsolate() instead of walking up the render tree?
IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor));
- int start = m_sor.m_pos;
+ int start = m_sor.offset();
RenderObject* obj = m_sor.object();
while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.object()) {
if (isolateTracker.inIsolate())
@@ -630,12 +694,12 @@ inline void InlineBidiResolver::appendRun()
start = 0;
obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracker);
}
- bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.m_pos;
+ bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset();
if (obj && !isEndOfLine) {
- unsigned pos = obj == m_eor.object() ? m_eor.m_pos : INT_MAX;
- if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.m_pos <= pos) {
+ unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX;
+ if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.offset() <= pos) {
m_reachedEndOfLine = true;
- pos = m_endOfRunAtEndOfLine.m_pos;
+ pos = m_endOfRunAtEndOfLine.offset();
}
// 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;