Move test for contained caret offset to RenderTextLineBoxes
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Oct 2013 12:24:57 +0000 (12:24 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Oct 2013 12:24:57 +0000 (12:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=122887

Reviewed by Andreas Kling.

* dom/Position.cpp:
(WebCore::Position::renderedOffset):
(WebCore::Position::isCandidate):

    Remove isRenderedText, call RenderText::containsCaretOffset instead.

(WebCore::Position::isRenderedCharacter):
(WebCore::Position::rendersInDifferentPosition):
* dom/Position.h:
* dom/PositionIterator.cpp:
(WebCore::PositionIterator::isCandidate):
* rendering/InlineTextBox.cpp:
* rendering/InlineTextBox.h:
* rendering/RenderText.cpp:
(WebCore::RenderText::containsCharacterOffset):
(WebCore::RenderText::containsCaretOffset):
* rendering/RenderText.h:
* rendering/RenderTextLineBoxes.cpp:
(WebCore::RenderTextLineBoxes::containsOffset):

    Combined implementations of Position::isRenderedCharacter and Position::isRenderedText.

* rendering/RenderTextLineBoxes.h:

    Remove containsCaretOffset(), functionality is now in RenderTextLineBoxes::containsOffset.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@157514 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/Position.cpp
Source/WebCore/dom/Position.h
Source/WebCore/dom/PositionIterator.cpp
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/InlineTextBox.h
Source/WebCore/rendering/RenderText.cpp
Source/WebCore/rendering/RenderText.h
Source/WebCore/rendering/RenderTextLineBoxes.cpp
Source/WebCore/rendering/RenderTextLineBoxes.h

index a54719d..559cda5 100644 (file)
@@ -1,3 +1,36 @@
+2013-10-16  Antti Koivisto  <antti@apple.com>
+
+        Move test for contained caret offset to RenderTextLineBoxes
+        https://bugs.webkit.org/show_bug.cgi?id=122887
+
+        Reviewed by Andreas Kling.
+
+        * dom/Position.cpp:
+        (WebCore::Position::renderedOffset):
+        (WebCore::Position::isCandidate):
+        
+            Remove isRenderedText, call RenderText::containsCaretOffset instead.
+
+        (WebCore::Position::isRenderedCharacter):
+        (WebCore::Position::rendersInDifferentPosition):
+        * dom/Position.h:
+        * dom/PositionIterator.cpp:
+        (WebCore::PositionIterator::isCandidate):
+        * rendering/InlineTextBox.cpp:
+        * rendering/InlineTextBox.h:
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::containsCharacterOffset):
+        (WebCore::RenderText::containsCaretOffset):
+        * rendering/RenderText.h:
+        * rendering/RenderTextLineBoxes.cpp:
+        (WebCore::RenderTextLineBoxes::containsOffset):
+        
+            Combined implementations of Position::isRenderedCharacter and Position::isRenderedText.
+
+        * rendering/RenderTextLineBoxes.h:
+        
+            Remove containsCaretOffset(), functionality is now in RenderTextLineBoxes::containsOffset.
+
 2013-10-16  Andreas Kling  <akling@apple.com>
 
         RenderElement::isChildAllowed() should take const references.
index 1c4c0c6..33eb366 100644 (file)
@@ -488,7 +488,7 @@ int Position::renderedOffset() const
         return m_offset;
                     
     int result = 0;
-    RenderText* textRenderer = toRenderText(deprecatedNode()->renderer());
+    RenderText* textRenderer = toText(deprecatedNode())->renderer();
     for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
         int start = box->start();
         int end = box->start() + box->len();
@@ -945,7 +945,7 @@ bool Position::isCandidate() const
         return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
 
     if (renderer->isText())
-        return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
+        return !nodeIsUserSelectNone(deprecatedNode()) && toRenderText(renderer)->containsCaretOffset(m_offset);
 
     if (isTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
         return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
@@ -966,53 +966,16 @@ bool Position::isCandidate() const
     return false;
 }
 
-bool Position::inRenderedText() const
-{
-    if (isNull() || !deprecatedNode()->isTextNode())
-        return false;
-        
-    RenderObject* renderer = deprecatedNode()->renderer();
-    if (!renderer)
-        return false;
-    
-    RenderText *textRenderer = toRenderText(renderer);
-    for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
-        if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
-            // The offset we're looking for is before this node
-            // this means the offset must be in content that is
-            // not rendered. Return false.
-            return false;
-        }
-        if (box->containsCaretOffset(m_offset))
-            // Return false for offsets inside composed characters.
-            return m_offset == 0 || m_offset == textRenderer->nextOffset(textRenderer->previousOffset(m_offset));
-    }
-    
-    return false;
-}
-
 bool Position::isRenderedCharacter() const
 {
     if (isNull() || !deprecatedNode()->isTextNode())
         return false;
         
-    RenderObject* renderer = deprecatedNode()->renderer();
+    RenderText* renderer = toText(deprecatedNode())->renderer();
     if (!renderer)
         return false;
     
-    RenderText* textRenderer = toRenderText(renderer);
-    for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
-        if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
-            // The offset we're looking for is before this node
-            // this means the offset must be in content that is
-            // not rendered. Return false.
-            return false;
-        }
-        if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast<int>(box->start() + box->len()))
-            return true;
-    }
-    
-    return false;
+    return renderer->containsCharacterOffset(m_offset);
 }
 
 static bool inSameEnclosingBlockFlowElement(Node* a, Node* b)
@@ -1059,10 +1022,10 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
     if (!inSameEnclosingBlockFlowElement(deprecatedNode(), pos.deprecatedNode()))
         return true;
 
-    if (deprecatedNode()->isTextNode() && !inRenderedText())
+    if (renderer->isText() && !toRenderText(renderer)->containsCaretOffset(m_offset))
         return false;
 
-    if (pos.deprecatedNode()->isTextNode() && !pos.inRenderedText())
+    if (posRenderer->isText() && !toRenderText(posRenderer)->containsCaretOffset(pos.m_offset))
         return false;
 
     int thisRenderedOffset = renderedOffset();
index 9a931a6..072e1bc 100644 (file)
@@ -178,7 +178,6 @@ public:
     Position downstream(EditingBoundaryCrossingRule = CannotCrossEditingBoundary) const;
     
     bool isCandidate() const;
-    bool inRenderedText() const;
     bool isRenderedCharacter() const;
     bool rendersInDifferentPosition(const Position&) const;
 
index a9bc2d8..d9b5c20 100644 (file)
@@ -29,6 +29,7 @@
 #include "HTMLNames.h"
 #include "Node.h"
 #include "RenderBlock.h"
+#include "RenderText.h"
 #include "htmlediting.h"
 
 namespace WebCore {
@@ -154,7 +155,7 @@ bool PositionIterator::isCandidate() const
         return !m_offsetInAnchor && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
 
     if (renderer->isText())
-        return !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).inRenderedText();
+        return !Position::nodeIsUserSelectNone(m_anchorNode) && toRenderText(renderer)->containsCaretOffset(m_offsetInAnchor);
 
     if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
         return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
index 3f61fd4..29690fb 100644 (file)
@@ -1459,30 +1459,6 @@ float InlineTextBox::positionForOffset(int offset) const
     return font.selectionRectForText(constructTextRun(lineStyle, font), IntPoint(logicalLeft(), 0), 0, from, to).maxX();
 }
 
-bool InlineTextBox::containsCaretOffset(int offset) const
-{
-    // Offsets before the box are never "in".
-    if (offset < m_start)
-        return false;
-
-    int pastEnd = m_start + m_len;
-
-    // Offsets inside the box (not at either edge) are always "in".
-    if (offset < pastEnd)
-        return true;
-
-    // Offsets outside the box are always "out".
-    if (offset > pastEnd)
-        return false;
-
-    // Offsets at the end are "out" for line breaks (they are on the next line).
-    if (isLineBreak())
-        return false;
-
-    // Offsets at the end are "in" for normal boxes (but the caller has to check affinity).
-    return true;
-}
-
 TextRun InlineTextBox::constructTextRun(const RenderStyle& style, const Font& font, BufferForAppendingHyphen* charactersWithHyphen) const
 {
     ASSERT(renderer().text());
index cac4814..3440e13 100644 (file)
@@ -157,8 +157,6 @@ public:
     virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
     virtual float positionForOffset(int offset) const;
 
-    bool containsCaretOffset(int offset) const; // false for offset after line break
-
     // Needs to be public, so the static paintTextWithShadows() function can use it.
     static FloatSize applyShadowToGraphicsContext(GraphicsContext*, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal);
 
index 4d5eba6..0e75579 100644 (file)
@@ -1151,6 +1151,16 @@ int RenderText::caretMaxOffset() const
     return m_lineBoxes.caretMaxOffset(*this);
 }
 
+bool RenderText::containsCharacterOffset(unsigned offset) const
+{
+    return m_lineBoxes.containsOffset(*this, offset, RenderTextLineBoxes::CharacterOffset);
+}
+
+bool RenderText::containsCaretOffset(unsigned offset) const
+{
+    return m_lineBoxes.containsOffset(*this, offset, RenderTextLineBoxes::CaretOffset);
+}
+
 bool RenderText::hasRenderedText() const
 {
     return m_lineBoxes.hasRenderedText();
index f625bc9..41322f2 100644 (file)
@@ -120,6 +120,8 @@ public:
 
     virtual int caretMinOffset() const OVERRIDE;
     virtual int caretMaxOffset() const OVERRIDE;
+    bool containsCharacterOffset(unsigned) const;
+    bool containsCaretOffset(unsigned) const;
     bool hasRenderedText() const;
 
     virtual int previousOffset(int current) const OVERRIDE FINAL;
index eea8360..f2c73e9 100644 (file)
@@ -225,6 +225,24 @@ int RenderTextLineBoxes::caretMaxOffset(const RenderText& renderer) const
     return maxOffset;
 }
 
+bool RenderTextLineBoxes::containsOffset(const RenderText& renderer, unsigned offset, OffsetType type) const
+{
+    for (auto box = m_first; box; box = box->nextTextBox()) {
+        if (offset < box->start() && !renderer.containsReversedText())
+            return false;
+        unsigned boxEnd = box->start() + box->len();
+        if (offset >= box->start() && offset <= boxEnd) {
+            if (offset == boxEnd && (type == CharacterOffset || box->isLineBreak()))
+                continue;
+            if (type == CharacterOffset)
+                return true;
+            // Return false for offsets inside composed characters.
+            return !offset || offset == static_cast<unsigned>(renderer.nextOffset(renderer.previousOffset(offset)));
+        }
+    }
+    return false;
+}
+
 enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPositionIsNotAtStart };
 
 static bool lineDirectionPointFitsInBox(int pointLineDirection, const InlineTextBox& box, ShouldAffinityBeDownstream& shouldAffinityBeDownstream)
index 5ba801f..9584213 100644 (file)
@@ -52,11 +52,16 @@ public:
     void removeAllFromParent(RenderText&);
     void deleteAll(RenderText&);
 
+    void dirtyAll();
+    bool dirtyRange(RenderText&, unsigned start, unsigned end, int lengthDelta);
+
     InlineTextBox* findNext(int offset, int& position) const;
 
     bool hasRenderedText() const;
     int caretMinOffset() const;
     int caretMaxOffset(const RenderText&) const;
+    enum OffsetType { CaretOffset, CharacterOffset };
+    bool containsOffset(const RenderText&, unsigned, OffsetType) const;
 
     VisiblePosition positionForPoint(const RenderText&, const LayoutPoint&) const;
 
@@ -72,9 +77,6 @@ public:
     Vector<FloatQuad> absoluteQuads(const RenderText&, bool* wasFixed, ClippingOption) const;
     Vector<FloatQuad> absoluteQuadsForRange(const RenderText&, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const;
 
-    void dirtyAll();
-    bool dirtyRange(RenderText&, unsigned start, unsigned end, int lengthDelta);
-
 #if !ASSERT_DISABLED
     ~RenderTextLineBoxes();
 #endif