2008-11-04 Simon Fraser <simon.fraser@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Nov 2008 18:54:50 +0000 (18:54 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Nov 2008 18:54:50 +0000 (18:54 +0000)
        Reviewed by Dave Hyatt

        https://bugs.webkit.org/show_bug.cgi?id=21941

        Rename absolutePosition() to localToAbsolute(), and add the ability
        to optionally take transforms into account (which will eventually be the
        default behavior).

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

43 files changed:
WebCore/ChangeLog
WebCore/WebCore.base.exp
WebCore/dom/ContainerNode.cpp
WebCore/dom/ContainerNode.h
WebCore/dom/MouseRelatedEvent.cpp
WebCore/dom/Node.cpp
WebCore/editing/SelectionController.cpp
WebCore/editing/visible_units.cpp
WebCore/html/HTMLAnchorElement.cpp
WebCore/html/HTMLAreaElement.cpp
WebCore/html/HTMLImageElement.cpp
WebCore/html/HTMLInputElement.cpp
WebCore/html/HTMLInputElement.h
WebCore/page/AccessibilityRenderObject.cpp
WebCore/page/EventHandler.cpp
WebCore/platform/graphics/FloatPoint.h
WebCore/platform/graphics/IntSize.h
WebCore/rendering/LayoutState.cpp
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderBox.cpp
WebCore/rendering/RenderBox.h
WebCore/rendering/RenderContainer.cpp
WebCore/rendering/RenderFlow.cpp
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderLayer.h
WebCore/rendering/RenderListBox.cpp
WebCore/rendering/RenderListMarker.cpp
WebCore/rendering/RenderObject.cpp
WebCore/rendering/RenderObject.h
WebCore/rendering/RenderPart.cpp
WebCore/rendering/RenderReplaced.cpp
WebCore/rendering/RenderSVGInlineText.cpp
WebCore/rendering/RenderSVGText.cpp
WebCore/rendering/RenderTableCell.cpp
WebCore/rendering/RenderTableCell.h
WebCore/rendering/RenderText.cpp
WebCore/rendering/RenderVideo.cpp
WebCore/rendering/RenderView.cpp
WebCore/rendering/RenderView.h
WebCore/rendering/RenderWidget.cpp
WebCore/svg/SVGSVGElement.cpp
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebRenderNode.mm

index ca61e8d..708cb2b 100644 (file)
@@ -1,3 +1,118 @@
+2008-11-04  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Dave Hyatt
+
+        https://bugs.webkit.org/show_bug.cgi?id=21941
+
+        Rename absolutePosition() to localToAbsolute(), and add the ability
+        to optionally take transforms into account (which will eventually be the
+        default behavior).
+
+        * WebCore.base.exp:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::getUpperLeftCorner):
+        (WebCore::ContainerNode::getLowerRightCorner):
+        (WebCore::ContainerNode::getRect):
+        * dom/ContainerNode.h:
+        * dom/MouseRelatedEvent.cpp:
+        (WebCore::MouseRelatedEvent::receivedTarget):
+        * dom/Node.cpp:
+        (WebCore::Node::getRect):
+        * editing/SelectionController.cpp:
+        (WebCore::SelectionController::layout):
+        (WebCore::SelectionController::caretRect):
+        * editing/visible_units.cpp:
+        (WebCore::previousLinePosition):
+        (WebCore::nextLinePosition):
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::isKeyboardFocusable):
+        (WebCore::HTMLAnchorElement::defaultEventHandler):
+        * html/HTMLAreaElement.cpp:
+        (WebCore::HTMLAreaElement::getRect):
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::x):
+        (WebCore::HTMLImageElement::y):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::defaultEventHandler):
+        * html/HTMLInputElement.h:
+        * page/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::boundingBoxRect):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleDrag):
+        * platform/graphics/FloatPoint.h:
+        (WebCore::roundedIntPoint):
+        * platform/graphics/IntSize.h:
+        (WebCore::IntSize::expand):
+        * rendering/LayoutState.cpp:
+        (WebCore::LayoutState::LayoutState):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::layoutBlock):
+        (WebCore::RenderBlock::paintObject):
+        (WebCore::RenderBlock::selectionGapRects):
+        (WebCore::RenderBlock::fillBlockSelectionGaps):
+        (WebCore::RenderBlock::nodeAtPoint):
+        (WebCore::RenderBlock::positionForCoordinates):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::localToAbsolute):
+        (WebCore::RenderBox::computeAbsoluteRepaintRect):
+        (WebCore::RenderBox::caretRect):
+        * rendering/RenderBox.h:
+        (WebCore::RenderBox::relativePositionOffset):
+        * rendering/RenderContainer.cpp:
+        (WebCore::RenderContainer::addLineBoxRects):
+        * rendering/RenderFlow.cpp:
+        (WebCore::RenderFlow::absoluteClippedOverflowRect):
+        (WebCore::RenderFlow::caretRect):
+        (WebCore::RenderFlow::addFocusRingRects):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::updateLayerPosition):
+        (WebCore::RenderLayer::convertToLayerCoords):
+        (WebCore::RenderLayer::addScrolledContentOffset):
+        (WebCore::RenderLayer::subtractScrolledContentOffset):
+        (WebCore::RenderLayer::scrollRectToVisible):
+        * rendering/RenderLayer.h:
+        (WebCore::RenderLayer::scrolledContentOffset):
+        (WebCore::RenderLayer::relativePositionOffset):
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::panScroll):
+        (WebCore::RenderListBox::scrollToward):
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::selectionRect):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::absoluteBoundingBoxRect):
+        (WebCore::RenderObject::computeAbsoluteRepaintRect):
+        (WebCore::RenderObject::localToAbsolute):
+        (WebCore::RenderObject::addDashboardRegions):
+        (WebCore::RenderObject::absoluteContentBox):
+        (WebCore::RenderObject::absoluteOutlineBox):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::localToAbsoluteForContent):
+        * rendering/RenderPart.cpp:
+        (WebCore::RenderPart::updateWidgetPosition):
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::selectionRect):
+        * rendering/RenderSVGInlineText.cpp:
+        (WebCore::RenderSVGInlineText::computeAbsoluteRectForRange):
+        * rendering/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::absoluteRects):
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::localToAbsolute):
+        * rendering/RenderTableCell.h:
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::addLineBoxRects):
+        (WebCore::RenderText::caretRect):
+        (WebCore::RenderText::selectionRect):
+        * rendering/RenderVideo.cpp:
+        (WebCore::RenderVideo::updatePlayer):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::localToAbsolute):
+        * rendering/RenderView.h:
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::updateWidgetPosition):
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::getScreenCTM):
+
 2008-11-03  Yael Aharon  <yael.aharon@nokia.com>
 
         Reviewed by Simon Hausmann.
index 2119483..013c52a 100644 (file)
@@ -566,6 +566,7 @@ __ZN7WebCore8Document4bodyEv
 __ZN7WebCore8DragDataC1EP11objc_objectRKNS_8IntPointES5_NS_13DragOperationEPNS_16PasteboardHelperE
 __ZN7WebCore8FormDataD1Ev
 __ZN7WebCore8IntPointC1ERK8_NSPoint
+__ZNK7WebCore10FloatPointcv8_NSPointEv
 __ZN7WebCore8Settings14setJavaEnabledEb
 __ZN7WebCore8Settings16setUsesPageCacheEb
 __ZN7WebCore8Settings16setZoomsTextOnlyEb
index bcd54c1..0f46ae6 100644 (file)
@@ -29,6 +29,7 @@
 #include "Editor.h"
 #include "EventNames.h"
 #include "ExceptionCode.h"
+#include "FloatRect.h"
 #include "Frame.h"
 #include "FrameView.h"
 #include "InlineTextBox.h"
@@ -647,25 +648,26 @@ void ContainerNode::cloneChildNodes(ContainerNode *clone)
         document()->frame()->editor()->deleteButtonController()->enable();
 }
 
-bool ContainerNode::getUpperLeftCorner(int &xPos, int &yPos) const
+// FIXME: This doesn't work correctly with transforms.
+bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
 {
     if (!renderer())
         return false;
+    // What is this code really trying to do?
     RenderObject *o = renderer();
     RenderObject *p = o;
 
-    xPos = yPos = 0;
     if (!o->isInline() || o->isReplaced()) {
-        o->absolutePosition(xPos, yPos);
+        point = o->localToAbsolute();
         return true;
     }
 
     // find the next text/image child, to get a position
-    while(o) {
+    while (o) {
         p = o;
         if (o->firstChild())
             o = o->firstChild();
-        else if(o->nextSibling())
+        else if (o->nextSibling())
             o = o->nextSibling();
         else {
             RenderObject *next = 0;
@@ -680,70 +682,72 @@ bool ContainerNode::getUpperLeftCorner(int &xPos, int &yPos) const
         }
 
         if (!o->isInline() || o->isReplaced()) {
-            o->absolutePosition(xPos, yPos);
+            point = o->localToAbsolute();
             return true;
         }
 
         if (p->element() && p->element() == this && o->isText() && !o->isBR() && !static_cast<RenderText*>(o)->firstTextBox()) {
                 // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
         } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
-            o->container()->absolutePosition(xPos, yPos);
+            point = o->container()->localToAbsolute();
             if (o->isText() && static_cast<RenderText *>(o)->firstTextBox()) {
-                xPos += static_cast<RenderText *>(o)->minXPos();
-                yPos += static_cast<RenderText *>(o)->firstTextBox()->root()->topOverflow();
-            } else {
-                xPos += o->xPos();
-                yPos += o->yPos();
-            }
+                point.move(static_cast<RenderText *>(o)->minXPos(),
+                           static_cast<RenderText *>(o)->firstTextBox()->root()->topOverflow());
+            } else
+                point.move(o->xPos(), o->yPos());
             return true;
         }
     }
     
     // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
-    // at the end of the document.  Scroll to the bottom.
+    // at the end of the document.  Scroll to the bottom. FIXME: who said anything about scrolling?
     if (!o && document()->view()) {
-        yPos += document()->view()->contentsHeight();
+        point = FloatPoint(0, document()->view()->contentsHeight());
         return true;
     }
     return false;
 }
 
-bool ContainerNode::getLowerRightCorner(int &xPos, int &yPos) const
+// FIXME: This doesn't work correctly with transforms.
+bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
 {
     if (!renderer())
         return false;
 
     RenderObject *o = renderer();
-    xPos = yPos = 0;
     if (!o->isInline() || o->isReplaced())
     {
-        o->absolutePosition(xPos, yPos);
-        xPos += o->width();
-        yPos += o->height() + o->borderTopExtra() + o->borderBottomExtra();
+        point = o->localToAbsolute();
+        point.move(o->width(),
+                   o->height() + o->borderTopExtra() + o->borderBottomExtra());
         return true;
     }
+
     // find the last text/image child, to get a position
-    while(o) {
-        if(o->lastChild())
+    while (o) {
+        if (o->lastChild())
             o = o->lastChild();
-        else if(o->previousSibling())
+        else if (o->previousSibling())
             o = o->previousSibling();
         else {
             RenderObject *prev = 0;
             while(!prev) {
                 o = o->parent();
-                if(!o) return false;
+                if (!o)
+                    return false;
                 prev = o->previousSibling();
             }
             o = prev;
         }
         if (o->isText() || o->isReplaced()) {
-            o->container()->absolutePosition(xPos, yPos);
+            point = o->container()->localToAbsolute();
+            int xOffset;
             if (o->isText())
-                xPos += static_cast<RenderText *>(o)->minXPos() + o->width();
+                xOffset = static_cast<RenderText *>(o)->minXPos() + o->width();
             else
-                xPos += o->xPos()+o->width();
-            yPos += o->yPos()+o->height();
+                xOffset = o->xPos() + o->width();
+            
+            point.move(xOffset, o->yPos() + o->height());
             return true;
         }
     }
@@ -752,29 +756,24 @@ bool ContainerNode::getLowerRightCorner(int &xPos, int &yPos) const
 
 IntRect ContainerNode::getRect() const
 {
-    int xPos = 0, yPos = 0, xEnd = 0, yEnd = 0;
-    bool foundUpperLeft = getUpperLeftCorner(xPos,yPos);
-    bool foundLowerRight = getLowerRightCorner(xEnd,yEnd);
+    FloatPoint  upperLeft, lowerRight;
+    bool foundUpperLeft = getUpperLeftCorner(upperLeft);
+    bool foundLowerRight = getLowerRightCorner(lowerRight);
     
     // If we've found one corner, but not the other,
     // then we should just return a point at the corner that we did find.
     if (foundUpperLeft != foundLowerRight)
     {
-        if (foundUpperLeft) {
-            xEnd = xPos;
-            yEnd = yPos;
-        } else {
-            xPos = xEnd;
-            yPos = yEnd;
-        }
+        if (foundUpperLeft)
+            lowerRight = upperLeft;
+        else
+            upperLeft = lowerRight;
     } 
 
-    if (xEnd < xPos)
-        xEnd = xPos;
-    if (yEnd < yPos)
-        yEnd = yPos;
-        
-    return IntRect(xPos, yPos, xEnd - xPos, yEnd - yPos);
+    lowerRight.setX(max(upperLeft.x(), lowerRight.x()));
+    lowerRight.setY(max(upperLeft.y(), lowerRight.y()));
+    
+    return enclosingIntRect(FloatRect(upperLeft, lowerRight - upperLeft));
 }
 
 void ContainerNode::setFocus(bool received)
index c36c941..91ca49a 100644 (file)
@@ -25,6 +25,7 @@
 #define ContainerNode_h
 
 #include "EventTargetNode.h"
+#include "FloatPoint.h"
 
 namespace WebCore {
     
@@ -89,8 +90,8 @@ protected:
 private:
     static void dispatchPostAttachCallbacks();
     
-    bool getUpperLeftCorner(int& x, int& y) const;
-    bool getLowerRightCorner(int& x, int& y) const;
+    bool getUpperLeftCorner(FloatPoint&) const;
+    bool getLowerRightCorner(FloatPoint&) const;
 
     Node* m_firstChild;
     Node* m_lastChild;
index 5a6c1f7..117a8ea 100644 (file)
@@ -133,11 +133,11 @@ void MouseRelatedEvent::receivedTarget()
     // Adjust offsetX/Y to be relative to the target's position.
     if (!isSimulated()) {
         if (RenderObject* r = targ->renderer()) {
-            int rx, ry;
-            if (r->absolutePosition(rx, ry)) {
-                m_offsetX -= rx;
-                m_offsetY -= ry;
-            }
+            // FIXME: This doesn't work correctly with transforms. We need
+            // an absoluteToLocal() method.
+            FloatPoint absPos = r->localToAbsolute();
+            m_offsetX -= absPos.x();
+            m_offsetY -= absPos.y();
         }
     }
 
index 3e1c985..91475eb 100644 (file)
@@ -409,10 +409,12 @@ bool Node::shouldUseInputMethod() const
 
 IntRect Node::getRect() const
 {
-    int _x, _y;
-    if (renderer() && renderer()->absolutePosition(_x, _y))
-        return IntRect( _x, _y, renderer()->width(), renderer()->height() + renderer()->borderTopExtra() + renderer()->borderBottomExtra());
-
+    // FIXME: broken with transforms
+    if (renderer()) {
+        FloatPoint absPos = renderer()->localToAbsolute();
+        return IntRect(roundedIntPoint(absPos),
+                       IntSize(renderer()->width(), renderer()->height() + renderer()->borderTopExtra() + renderer()->borderBottomExtra()));
+    }
     return IntRect();
 }
 
index bf52be4..89daf33 100644 (file)
@@ -740,9 +740,9 @@ void SelectionController::layout()
             ASSERT(pos.deepEquivalent().node()->renderer());
             m_caretRect = pos.caretRect();
 
-            int x, y;
-            pos.deepEquivalent().node()->renderer()->absolutePositionForContent(x, y);
-            m_caretPositionOnLayout = IntPoint(x, y);
+            // FIXME: broken with transforms
+            FloatPoint absPos = pos.deepEquivalent().node()->renderer()->localToAbsoluteForContent(FloatPoint());
+            m_caretPositionOnLayout = roundedIntPoint(absPos);
         }
     }
 
@@ -757,9 +757,8 @@ IntRect SelectionController::caretRect() const
     IntRect caret = m_caretRect;
 
     if (m_sel.start().node() && m_sel.start().node()->renderer()) {
-        int x, y;
-        m_sel.start().node()->renderer()->absolutePositionForContent(x, y);
-        caret.move(IntPoint(x, y) - m_caretPositionOnLayout);
+        FloatPoint absPos = m_sel.start().node()->renderer()->localToAbsoluteForContent(FloatPoint());
+        caret.move(roundedIntPoint(absPos) - m_caretPositionOnLayout);
     }
 
     return caret;
index 33118f1..c27026f 100644 (file)
@@ -493,16 +493,15 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
     }
     
     if (root) {
-        // FIXME: Can be wrong for multi-column layout.
-        int absx, absy;
-        containingBlock->absolutePositionForContent(absx, absy);
+        // FIXME: Can be wrong for multi-column layout, and with transforms
+        FloatPoint absPos = containingBlock->localToAbsoluteForContent(FloatPoint());
         if (containingBlock->hasOverflowClip())
-            containingBlock->layer()->subtractScrollOffset(absx, absy);
-        RenderObject *renderer = root->closestLeafChildForXPos(x - absx, isEditablePosition(p))->object();
+            absPos -= containingBlock->layer()->scrolledContentOffset();
+        RenderObject *renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->object();
         Node* node = renderer->element();
         if (editingIgnoresContent(node))
             return Position(node->parent(), node->nodeIndex());
-        return renderer->positionForCoordinates(x - absx, root->topOverflow());
+        return renderer->positionForCoordinates(x - absPos.x(), root->topOverflow());
     }
     
     // Could not find a previous line. This means we must already be on the first line.
@@ -595,16 +594,15 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int x)
     }
     
     if (root) {
-        // FIXME: Can be wrong for multi-column layout.
-        int absx, absy;
-        containingBlock->absolutePositionForContent(absx, absy);
+        // FIXME: Can be wrong for multi-column layout and with transforms
+        FloatPoint absPos = containingBlock->localToAbsoluteForContent(FloatPoint());
         if (containingBlock->hasOverflowClip())
-            containingBlock->layer()->subtractScrollOffset(absx, absy);
-        RenderObject *renderer = root->closestLeafChildForXPos(x - absx, isEditablePosition(p))->object();
+            absPos -= containingBlock->layer()->scrolledContentOffset();
+        RenderObject *renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->object();
         Node* node = renderer->element();
         if (editingIgnoresContent(node))
             return Position(node->parent(), node->nodeIndex());
-        return renderer->positionForCoordinates(x - absx, root->topOverflow());
+        return renderer->positionForCoordinates(x - absPos.x(), root->topOverflow());
     }    
 
     // Could not find a next line. This means we must already be on the last line.
index 0e09b5d..168cb2c 100644 (file)
@@ -115,9 +115,8 @@ bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
             return true;
 
     Vector<IntRect> rects;
-    int x, y;
-    renderer()->absolutePosition(x, y);
-    renderer()->absoluteRects(rects, x, y);
+    FloatPoint absPos = renderer()->localToAbsolute();
+    renderer()->absoluteRects(rects, absPos.x(), absPos.y());
     size_t n = rects.size();
     for (size_t i = 0; i < n; ++i)
         if (!rects[i].isEmpty())
@@ -200,10 +199,10 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
             if (img && img->isServerMap()) {
                 RenderImage* r = static_cast<RenderImage*>(img->renderer());
                 if (r && e) {
-                    int absx, absy;
-                    r->absolutePosition(absx, absy);
-                    int x = e->pageX() - absx;
-                    int y = e->pageY() - absy;
+                    // FIXME: broken with transforms
+                    FloatPoint absPos = r->localToAbsolute();
+                    int x = e->pageX() - absPos.x();
+                    int y = e->pageY() - absPos.y();
                     url += "?";
                     url += String::number(x);
                     url += ",";
index a865122..faa9069 100644 (file)
@@ -86,10 +86,10 @@ bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestRe
 
 IntRect HTMLAreaElement::getRect(RenderObject* obj) const
 {
-    int dx, dy;
-    obj->absolutePosition(dx, dy);
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = obj->localToAbsolute();
     Path p = getRegion(m_lastSize);
-    p.translate(IntSize(dx, dy));
+    p.translate(absPos - FloatPoint());
     return enclosingIntRect(p.boundingRect());
 }
 
index ea05689..62d1341 100644 (file)
@@ -407,9 +407,10 @@ int HTMLImageElement::x() const
     RenderObject* r = renderer();
     if (!r)
         return 0;
-    int x, y;
-    r->absolutePosition(x, y);
-    return x;
+
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = r->localToAbsolute();
+    return absPos.x();
 }
 
 int HTMLImageElement::y() const
@@ -417,9 +418,10 @@ int HTMLImageElement::y() const
     RenderObject* r = renderer();
     if (!r)
         return 0;
-    int x, y;
-    r->absolutePosition(x, y);
-    return y;
+
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = r->localToAbsolute();
+    return absPos.y();
 }
 
 bool HTMLImageElement::complete() const
index 50b7b7f..da83710 100644 (file)
@@ -1183,11 +1183,10 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
             xPos = 0;
             yPos = 0;
         } else {
-            int offsetX, offsetY;
-            renderer()->absolutePosition(offsetX, offsetY);
-            xPos = me->pageX() - offsetX;
-            // FIXME: Why is yPos a short?
-            yPos = me->pageY() - offsetY;
+            // FIXME: This doesn't work correctly with transforms.
+            IntPoint absOffset = roundedIntPoint(renderer()->localToAbsolute());
+            xPos = me->pageX() - absOffset.x();
+            yPos = me->pageY() - absOffset.y();
         }
     }
 
index 7f090a8..5bd324d 100644 (file)
@@ -228,9 +228,9 @@ private:
     String m_value;
     String m_originalValue;
     int xPos;
+    int yPos;
     int m_maxLen;
-    short m_size;
-    short yPos;
+    int m_size;
 
     short m_maxResults;
 
index 144aab0..7f09e83 100644 (file)
@@ -920,9 +920,8 @@ IntRect AccessibilityRenderObject::boundingBoxRect() const
     
     // FIXME: This doesn't work correctly with transforms.
     Vector<IntRect> rects;
-    int x, y;
-    obj->absolutePosition(x, y);
-    obj->absoluteRects(rects, x, y);
+    FloatPoint absPos = obj->localToAbsolute();
+    obj->absoluteRects(rects, absPos.x(), absPos.y());
     const size_t n = rects.size();
     for (size_t i = 0; i < n; ++i) {
         IntRect r = rects[i];
index e4fb54e..70202bf 100644 (file)
@@ -2023,10 +2023,10 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
         // Check to see if the is a DOM based drag, if it is get the DOM specified drag 
         // image and offset
         if (dragState().m_dragSrcIsDHTML) {
-            int srcX, srcY;
             if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
-                renderer->absolutePosition(srcX, srcY);
-                IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
+                // FIXME: This doesn't work correctly with transforms.
+                FloatPoint absPos = renderer->localToAbsolute();
+                IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
                 dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
             } else {
                 // The renderer has disappeared, this can happen if the onStartDrag handler has hidden
index 6b3c769..815dcd3 100644 (file)
@@ -28,6 +28,7 @@
 #define FloatPoint_h
 
 #include "FloatSize.h"
+#include "IntPoint.h"
 #include <wtf/Platform.h>
 
 #if PLATFORM(CG)
@@ -146,6 +147,11 @@ inline bool operator!=(const FloatPoint& a, const FloatPoint& b)
     return a.x() != b.x() || a.y() != b.y();
 }
 
+inline IntPoint roundedIntPoint(const FloatPoint& p)
+{
+    return IntPoint(static_cast<int>(roundf(p.x())), static_cast<int>(roundf(p.y())));
+}
+
 }
 
 #endif
index 7245408..4d36545 100644 (file)
@@ -67,6 +67,12 @@ public:
 
     bool isEmpty() const { return m_width <= 0 || m_height <= 0; }
 
+    void expand(int width, int height)
+    {
+        m_width += width;
+        m_height += height;
+    }
+    
     IntSize expandedTo(const IntSize& other) const
     {
         return IntSize(m_width > other.m_width ? m_width : other.m_width,
index b473f99..872a640 100644 (file)
@@ -40,20 +40,15 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize&
 
     bool fixed = renderer->isPositioned() && renderer->style()->position() == FixedPosition;
     if (fixed) {
-        int fixedX = 0;
-        int fixedY = 0;
-        renderer->view()->absolutePosition(fixedX, fixedY, true);
-        m_offset = IntSize(fixedX, fixedY) + offset;
+        // FIXME: This doesn't work correctly with transforms.
+        FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), true);
+        m_offset = IntSize(fixedOffset.x(), fixedOffset.y()) + offset;
     } else
         m_offset = prev->m_offset + offset;
 
     if (renderer->isRelPositioned()) {
-        if (renderer->hasLayer()) {
-            int relX = 0;
-            int relY = 0;
-            renderer->layer()->relativePositionOffset(relX, relY);
-            m_offset += IntSize(relX, relY);
-        }
+        if (renderer->hasLayer())
+            m_offset += renderer->layer()->relativePositionOffset();
     } else if (renderer->isPositioned() && !fixed) {
         if (RenderObject* container = renderer->container())
             m_offset += renderer->offsetForPositionedInContainer(container);
@@ -74,7 +69,7 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize&
             m_clipRect = clipRect;
             m_clipped = true;
         }
-        layer->subtractScrollOffset(x, y);
+        layer->subtractScrolledContentOffset(x, y);
         m_offset = IntSize(x, y);
     }
     // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
@@ -84,10 +79,9 @@ LayoutState::LayoutState(RenderObject* root)
     : m_clipped(false)
 {
     RenderObject* container = root->container();
-    int x = 0;
-    int y = 0;
-    container->absolutePositionForContent(x, y);
-    m_offset = IntSize(x, y);
+    // FIXME: this is broken with transforms?
+    FloatPoint absContentPoint = container->localToAbsoluteForContent(FloatPoint());
+    m_offset = IntSize(absContentPoint.x(), absContentPoint.y());
     m_next = 0;
 }
 
index a608a3a..e466386 100644 (file)
@@ -751,7 +751,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
             // Adjust repaint rect for scroll offset
             int x = repaintRect.x();
             int y = repaintRect.y();
-            layer()->subtractScrollOffset(x, y);
+            layer()->subtractScrolledContentOffset(x, y);
             repaintRect.setX(x);
             repaintRect.setY(y);
 
@@ -1692,7 +1692,7 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
     int scrolledX = tx;
     int scrolledY = ty;
     if (hasOverflowClip())
-        m_layer->subtractScrollOffset(scrolledX, scrolledY);
+        m_layer->subtractScrolledContentOffset(scrolledX, scrolledY);
 
     // 2. paint contents
     if (paintPhase != PaintPhaseSelfOutline) {
@@ -1901,16 +1901,16 @@ GapRects RenderBlock::selectionGapRects()
     if (!shouldPaintSelectionGaps())
         return GapRects();
 
-    int tx, ty;
-    absolutePositionForContent(tx, ty);
+    // FIXME: this is broken with transforms
+    FloatPoint absContentPoint = localToAbsoluteForContent(FloatPoint());
     if (hasOverflowClip())
-        layer()->subtractScrollOffset(tx, ty);
+        absContentPoint -= layer()->scrolledContentOffset();
 
     int lastTop = -borderTopExtra();
     int lastLeft = leftSelectionOffset(this, lastTop);
     int lastRight = rightSelectionOffset(this, lastTop);
     
-    return fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight);
+    return fillSelectionGaps(this, absContentPoint.x(), absContentPoint.y(), absContentPoint.x(), absContentPoint.y(), lastTop, lastLeft, lastRight);
 }
 
 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
@@ -2055,10 +2055,8 @@ GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX,
         if (curr->isRelPositioned() && curr->hasLayer()) {
             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
             // Just disregard it completely.
-            int x = 0;
-            int y = 0;
-            curr->layer()->relativePositionOffset(x, y);
-            if (x || y)
+            IntSize relOffset = curr->layer()->relativePositionOffset();
+            if (relOffset.width() || relOffset.height())
                 continue;
         }
 
@@ -3140,7 +3138,7 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
         int scrolledX = tx;
         int scrolledY = ty;
         if (hasOverflowClip())
-            m_layer->subtractScrollOffset(scrolledX, scrolledY);
+            m_layer->subtractScrolledContentOffset(scrolledX, scrolledY);
 
         // Hit test contents if we don't have columns.
         if (!m_hasColumns && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
@@ -3295,7 +3293,7 @@ VisiblePosition RenderBlock::positionForCoordinates(int x, int y)
     int contentsX = x;
     int contentsY = y - borderTopExtra();
     if (hasOverflowClip())
-        m_layer->scrollOffset(contentsX, contentsY);
+        m_layer->addScrolledContentOffset(contentsX, contentsY);
     if (m_hasColumns) {
         IntPoint contentsPoint(contentsX, contentsY);
         adjustPointToColumnContents(contentsPoint);
index 4d15341..1ed2052 100644 (file)
@@ -991,15 +991,16 @@ IntSize RenderBox::offsetForPositionedInContainer(RenderObject* container) const
     return offset;
 }
 
-bool RenderBox::absolutePosition(int& xPos, int& yPos, bool fixed) const
+FloatPoint RenderBox::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
 {
     if (RenderView* v = view()) {
         if (LayoutState* layoutState = v->layoutState()) {
-            xPos = layoutState->m_offset.width() + m_x;
-            yPos = layoutState->m_offset.height() + m_y;
+            IntSize offset = layoutState->m_offset;
+            offset.expand(m_x, m_y);
+            localPoint += offset;
             if (style()->position() == RelativePosition && m_layer)
-                m_layer->relativePositionOffset(xPos, yPos);
-            return true;
+                localPoint += m_layer->relativePositionOffset();
+            return localPoint;
         }
     }
 
@@ -1007,15 +1008,14 @@ bool RenderBox::absolutePosition(int& xPos, int& yPos, bool fixed) const
         fixed = true;
 
     RenderObject* o = container();
-    if (o && o->absolutePositionForContent(xPos, yPos, fixed)) {
-        if (style()->position() == AbsolutePosition) {
-            IntSize offset = offsetForPositionedInContainer(o);
-            xPos += offset.width();
-            yPos += offset.height();
+    if (o) {
+        if (useTransforms && m_layer && m_layer->transform()) {
+            fixed = false;  // Elements with transforms act as a containing block for fixed position descendants
+            localPoint = m_layer->transform()->mapPoint(localPoint);
         }
 
-        if (o->hasOverflowClip())
-            o->layer()->subtractScrollOffset(xPos, yPos);
+        if (isRelPositioned())
+            localPoint += relativePositionOffset();
 
         if (!isInline() || isReplaced()) {
             RenderBlock* cb;
@@ -1023,25 +1023,21 @@ bool RenderBox::absolutePosition(int& xPos, int& yPos, bool fixed) const
                     && (cb = static_cast<RenderBlock*>(o))->hasColumns()) {
                 IntRect rect(m_x, m_y, 1, 1);
                 cb->adjustRectForColumns(rect);
-                xPos += rect.x();
-                yPos += rect.y();
-            } else {
-                xPos += m_x;
-                yPos += m_y;
-            }
+                localPoint.move(rect.x(), rect.y());
+            } else
+                localPoint.move(m_x, m_y);
         }
 
-        if (isRelPositioned()) {
-            xPos += relativePositionOffsetX();
-            yPos += relativePositionOffsetY();
-        }
+        if (o->hasOverflowClip())
+            localPoint -= o->layer()->scrolledContentOffset();
 
-        return true;
-    } else {
-        xPos = 0;
-        yPos = 0;
-        return false;
+        if (style()->position() == AbsolutePosition)
+            localPoint += offsetForPositionedInContainer(o);
+
+        return o->localToAbsoluteForContent(localPoint, fixed, useTransforms);
     }
+    
+    return FloatPoint();
 }
 
 void RenderBox::dirtyLineBoxes(bool fullLayout, bool /*isRootLineBox*/)
@@ -1124,12 +1120,9 @@ void RenderBox::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)
 {
     if (RenderView* v = view()) {
         if (LayoutState* layoutState = v->layoutState()) {
-            if (style()->position() == RelativePosition && m_layer) {
-                int relX = 0;
-                int relY = 0;
-                m_layer->relativePositionOffset(relX, relY);
-                rect.move(relX, relY);
-            }
+            if (style()->position() == RelativePosition && m_layer)
+                rect.move(m_layer->relativePositionOffset());
+
             rect.move(m_x, m_y);
             rect.move(layoutState->m_offset);
             if (layoutState->m_clipped)
@@ -1147,15 +1140,15 @@ void RenderBox::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)
         invalidatingReflection = false;
     }
 
-    int x = rect.x() + m_x;
-    int y = rect.y() + m_y;
+    IntPoint topLeft = rect.location();
+    topLeft.move(m_x, m_y);
 
     // Apply the relative position offset when invalidating a rectangle.  The layer
     // is translated, but the render box isn't, so we need to do this to get the
     // right dirty rect.  Since this is called from RenderObject::setStyle, the relative position
     // flag on the RenderObject has been cleared, so use the one on the style().
     if (style()->position() == RelativePosition && m_layer)
-        m_layer->relativePositionOffset(x, y);
+        topLeft += m_layer->relativePositionOffset();
 
     if (style()->position() == FixedPosition)
         fixed = true;
@@ -1165,27 +1158,23 @@ void RenderBox::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)
         if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
             RenderBlock* cb = static_cast<RenderBlock*>(o);
             if (cb->hasColumns()) {
-                IntRect repaintRect(x, y, rect.width(), rect.height());
+                IntRect repaintRect(topLeft, rect.size());
                 cb->adjustRectForColumns(repaintRect);
-                x = repaintRect.x();
-                y = repaintRect.y();
+                topLeft = repaintRect.location();
                 rect = repaintRect;
             }
         }
 
-        if (style()->position() == AbsolutePosition) {
-            IntSize offset = offsetForPositionedInContainer(o);
-            x += offset.width();
-            y += offset.height();
-        }
+        if (style()->position() == AbsolutePosition)
+            topLeft += offsetForPositionedInContainer(o);
         
         // We are now in our parent container's coordinate space.  Apply our transform to obtain a bounding box
         // in the parent's coordinate space that encloses us.
         if (m_layer && m_layer->transform()) {
             fixed = false;
             rect = m_layer->transform()->mapRect(rect);
-            x = rect.x() + m_x;
-            y = rect.y() + m_y;
+            topLeft = rect.location();
+            topLeft.move(m_x, m_y);
         }
 
         // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,
@@ -1195,15 +1184,15 @@ void RenderBox::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)
             // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint
             // anyway if its size does change.
             IntRect boxRect(0, 0, o->layer()->width(), o->layer()->height());
-            o->layer()->subtractScrollOffset(x, y); // For overflow:auto/scroll/hidden.
-            IntRect repaintRect(x, y, rect.width(), rect.height());
+            int x = 0, y = 0;
+            o->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
+            topLeft.move(x, y);
+            IntRect repaintRect(topLeft, rect.size());
             rect = intersection(repaintRect, boxRect);
             if (rect.isEmpty())
                 return;
-        } else {
-            rect.setX(x);
-            rect.setY(y);
-        }
+        } else
+            rect.setLocation(topLeft);
         
         o->computeAbsoluteRepaintRect(rect, fixed);
     }
@@ -2675,15 +2664,16 @@ IntRect RenderBox::caretRect(InlineBox* box, int caretOffset, int* extraWidthToE
         rect.setHeight(fontHeight);
 
     RenderObject* cb = containingBlock();
-    int cbx, cby;
-    if (!cb || !cb->absolutePosition(cbx, cby))
+    if (!cb)
         // No point returning a relative position.
         return IntRect();
 
+    FloatPoint absPos = cb->localToAbsolute();
+
     if (extraWidthToEndOfLine)
         *extraWidthToEndOfLine = xPos() + m_width - rect.right();
 
-    rect.move(cbx, cby);
+    rect.move(absPos.x(), absPos.y());
     return rect;
 }
 
index aa9bab7..8d5ec71 100644 (file)
@@ -49,7 +49,7 @@ public:
     virtual int overrideHeight() const;
     virtual void setOverrideSize(int);
 
-    virtual bool absolutePosition(int& x, int& y, bool fixed = false) const;
+    virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
 
     virtual int xPos() const { return m_x; }
     virtual int yPos() const { return m_y; }
@@ -135,7 +135,8 @@ public:
 
     int relativePositionOffsetX() const;
     int relativePositionOffsetY() const;
-
+    IntSize relativePositionOffset() const { return IntSize(relativePositionOffsetX(), relativePositionOffsetY()); }
+    
     virtual RenderLayer* layer() const { return m_layer; }
 
     virtual IntRect caretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
index 528c173..9825601 100644 (file)
@@ -662,9 +662,8 @@ VisiblePosition RenderContainer::positionForCoordinates(int x, int y)
 void RenderContainer::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigned end, bool)
 {
     if (!m_firstChild && (isInline() || isAnonymousBlock())) {
-        int x, y;
-        absolutePositionForContent(x, y);
-        absoluteRects(rects, x, y);
+        FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
+        absoluteRects(rects, absPos.x(), absPos.y());
         return;
     }
 
@@ -674,9 +673,8 @@ void RenderContainer::addLineBoxRects(Vector<IntRect>& rects, unsigned start, un
     unsigned offset = start;
     for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset) {
         if (child->isText() || child->isInline() || child->isAnonymousBlock()) {
-            int x, y;
-            child->absolutePositionForContent(x, y);
-            child->absoluteRects(rects, x, y);
+            FloatPoint absPos = child->localToAbsoluteForContent(FloatPoint());
+            child->absoluteRects(rects, absPos.x(), absPos.y());
         }
     }
 }
index eb689cf..ee6048c 100644 (file)
@@ -522,7 +522,7 @@ IntRect RenderFlow::absoluteClippedOverflowRect()
             int x = r.x();
             int y = r.y();
             IntRect boxRect(0, 0, cb->layer()->width(), cb->layer()->height());
-            cb->layer()->subtractScrollOffset(x, y); // For overflow:auto/scroll/hidden.
+            cb->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
             IntRect repaintRect(x, y, r.width(), r.height());
             r = intersection(repaintRect, boxRect);
         }
@@ -684,20 +684,19 @@ IntRect RenderFlow::caretRect(InlineBox* inlineBox, int caretOffset, int* extraW
             // So *extraWidthToEndOfLine will always be 0 here.
 
             int myRight = x + caretWidth;
-            int ignore;
-            absolutePositionForContent(myRight, ignore);
+            // FIXME: why call localToAbsoluteForContent() twice here, too?
+            FloatPoint absRightPoint = localToAbsoluteForContent(FloatPoint(myRight, 0));
 
             int containerRight = containingBlock()->xPos() + containingBlockWidth();
-            absolutePositionForContent(containerRight, ignore);
+            FloatPoint absContainerPoint = localToAbsoluteForContent(FloatPoint(containerRight, 0));
 
-            *extraWidthToEndOfLine = containerRight - myRight;
+            *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
         }
     }
 
-    int absx, absy;
-    absolutePositionForContent(absx, absy);
-    x += absx;
-    int y = absy + paddingTop() + borderTop();
+    FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
+    x += absPos.x();
+    int y = absPos.y() + paddingTop() + borderTop();
 
     return IntRect(x, y, caretWidth, height);
 }
@@ -723,15 +722,13 @@ void RenderFlow::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int
 
         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
             if (!curr->isText() && !curr->isListMarker()) {
-                int x = 0;
-                int y = 0;
+                FloatPoint pos;
+                // FIXME: This doesn't work correctly with transforms.
                 if (curr->layer()) 
-                    curr->absolutePosition(x, y);
-                else {
-                    x = tx + curr->xPos();
-                    y = ty + curr->yPos();
-                }
-                curr->addFocusRingRects(graphicsContext, x, y);
+                    pos = curr->localToAbsolute();
+                else
+                    pos = FloatPoint(tx + curr->xPos(), ty + curr->yPos());
+                curr->addFocusRingRects(graphicsContext, pos.x(), pos.y());
             }
     }
 
index 93efde1..06745e5 100644 (file)
@@ -409,7 +409,7 @@ void RenderLayer::updateLayerPosition()
         RenderLayer* positionedParent = enclosingPositionedAncestor();
 
         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
-        positionedParent->subtractScrollOffset(x, y);
+        positionedParent->subtractScrolledContentOffset(x, y);
         
         if (m_object->isPositioned()) {
             IntSize offset = static_cast<RenderBox*>(m_object)->offsetForPositionedInContainer(positionedParent->renderer());
@@ -417,7 +417,7 @@ void RenderLayer::updateLayerPosition()
             y += offset.height();
         }
     } else if (parent())
-        parent()->subtractScrollOffset(x, y);
+        parent()->subtractScrolledContentOffset(x, y);
     
     setPos(x,y);
 
@@ -687,11 +687,10 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int&
         
     if (m_object->style()->position() == FixedPosition) {
         // Add in the offset of the view.  We can obtain this by calling
-        // absolutePosition() on the RenderView.
-        int xOff, yOff;
-        m_object->absolutePosition(xOff, yOff, true);
-        x += xOff;
-        y += yOff;
+        // localToAbsolute() on the RenderView.
+        FloatPoint absPos = m_object->localToAbsolute(FloatPoint(), true);
+        x += absPos.x();
+        y += absPos.y();
         return;
     }
  
@@ -772,14 +771,14 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
 
 
 void
-RenderLayer::scrollOffset(int& x, int& y)
+RenderLayer::addScrolledContentOffset(int& x, int& y) const
 {
     x += scrollXOffset() + m_scrollLeftOverflow;
     y += scrollYOffset();
 }
 
 void
-RenderLayer::subtractScrollOffset(int& x, int& y)
+RenderLayer::subtractScrolledContentOffset(int& x, int& y) const
 {
     x -= scrollXOffset() + m_scrollLeftOverflow;
     y -= scrollYOffset();
@@ -865,17 +864,15 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
     if (m_object->hasOverflowClip() && !restrictedByLineClamp) {
         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
         // This will prevent us from revealing text hidden by the slider in Safari RSS.
-        int x, y;
-        m_object->absolutePosition(x, y);
-        x += m_object->borderLeft();
-        y += m_object->borderTop();
+        FloatPoint absPos = m_object->localToAbsolute();
+        absPos.move(m_object->borderLeft(), m_object->borderTop());
 
-        IntRect layerBounds = IntRect(x + scrollXOffset(), y + scrollYOffset(), m_object->clientWidth(), m_object->clientHeight());
+        IntRect layerBounds = IntRect(absPos.x() + scrollXOffset(), absPos.y() + scrollYOffset(), m_object->clientWidth(), m_object->clientHeight());
         IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
         IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
         
-        xOffset = r.x() - x;
-        yOffset = r.y() - y;
+        xOffset = r.x() - absPos.x();
+        yOffset = r.y() - absPos.y();
         // Adjust offsets if they're outside of the allowable range.
         xOffset = max(0, min(scrollWidth() - layerBounds.width(), xOffset));
         yOffset = max(0, min(scrollHeight() - layerBounds.height(), yOffset));
index f946b5f..68378a6 100644 (file)
@@ -208,10 +208,13 @@ public:
 
     // Scrolling methods for layers that can scroll their overflow.
     void scrollByRecursively(int xDelta, int yDelta);
-    void scrollOffset(int& x, int& y);
-    void subtractScrollOffset(int& x, int& y);
+    void addScrolledContentOffset(int& x, int& y) const;
+    void subtractScrolledContentOffset(int& x, int& y) const;
+    IntSize scrolledContentOffset() const { return IntSize(scrollXOffset() + m_scrollLeftOverflow, scrollYOffset()); }
+
     int scrollXOffset() const { return m_scrollX + m_scrollOriginX; }
     int scrollYOffset() const { return m_scrollY; }
+
     void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
     void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
     void scrollToYOffset(int y) { scrollToOffset(m_scrollX + m_scrollOriginX, y); }
@@ -254,7 +257,8 @@ public:
 
     void updateTransform();
 
-    void relativePositionOffset(int& relX, int& relY) { relX += m_relX; relY += m_relY; }
+    void relativePositionOffset(int& relX, int& relY) const { relX += m_relX; relY += m_relY; }
+    IntSize relativePositionOffset() const { return IntSize(m_relX, m_relY); }
 
     void clearClipRects();
     void clearClipRect();
@@ -400,8 +404,8 @@ protected:
     // Our scroll offsets if the view is scrolled.
     int m_scrollX;
     int m_scrollY;
-    int m_scrollOriginX;
-    int m_scrollLeftOverflow;
+    int m_scrollOriginX;        // only non-zero for rtl content
+    int m_scrollLeftOverflow;   // only non-zero for rtl content
 
     // The width/height of our scrolled area.
     int m_scrollWidth;
index c435ff4..667a0f1 100644 (file)
@@ -401,9 +401,8 @@ void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
     const int iconRadius = 7;
     const int speedReducer = 4;
 
-    int offsetX;
-    int offsetY;
-    absolutePosition(offsetX, offsetY);
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absOffset = localToAbsolute();
 
     IntPoint currentMousePosition = document()->frame()->eventHandler()->currentMousePosition();
     // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
@@ -423,7 +422,7 @@ void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
 
     if (yDelta > 0)
         //offsetY = view()->viewHeight();
-        offsetY += listHeight();
+        absOffset.move(0, listHeight());
    else if (yDelta < 0)
        yDelta--;
 
@@ -431,7 +430,7 @@ void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
     yDelta /= speedReducer;
 
     IntPoint scrollPoint(0,0);
-    scrollPoint.setY(offsetY + yDelta);
+    scrollPoint.setY(absOffset.y() + yDelta);
     int newOffset = scrollToward(scrollPoint);
     if (newOffset < 0) 
         return;
@@ -444,11 +443,10 @@ void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
 
 int RenderListBox::scrollToward(const IntPoint& destination)
 {
-    int rx = 0;
-    int ry = 0;
-    absolutePosition(rx, ry);
-    int offsetX = destination.x() - rx;
-    int offsetY = destination.y() - ry;
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = localToAbsolute();
+    int offsetX = destination.x() - absPos.x();
+    int offsetY = destination.y() - absPos.y();
 
     int rows = numVisibleItems();
     int offset = m_indexOffset;
index b2937b9..b2fb51c 100644 (file)
@@ -895,9 +895,8 @@ IntRect RenderListMarker::selectionRect(bool clipToVisibleContent)
     if (clipToVisibleContent)
         computeAbsoluteRepaintRect(rect);
     else {
-        int absx, absy;
-        absolutePosition(absx, absy);
-        rect.move(absx, absy);
+        FloatPoint absPos = localToAbsolute();
+        rect.move(absPos.x(), absPos.y());
     }
     
     return rect;
index e03fb66..b78c410 100644 (file)
@@ -1706,10 +1706,10 @@ void RenderObject::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool to
 
 IntRect RenderObject::absoluteBoundingBoxRect()
 {
-    int x, y;
-    absolutePosition(x, y);
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = localToAbsolute();
     Vector<IntRect> rects;
-    absoluteRects(rects, x, y);
+    absoluteRects(rects, absPos.x(), absPos.y());
 
     size_t n = rects.size();
     if (!n)
@@ -2007,7 +2007,7 @@ void RenderObject::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)
             IntRect boxRect(0, 0, o->layer()->width(), o->layer()->height());
             int x = rect.x();
             int y = rect.y();
-            o->layer()->subtractScrollOffset(x, y); // For overflow:auto/scroll/hidden.
+            o->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
             IntRect repaintRect(x, y, rect.width(), rect.height());
             rect = intersection(repaintRect, boxRect);
             if (rect.isEmpty())
@@ -2372,19 +2372,17 @@ IntRect RenderObject::viewRect() const
     return view()->viewRect();
 }
 
-bool RenderObject::absolutePosition(int& xPos, int& yPos, bool f) const
+FloatPoint RenderObject::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
 {
     RenderObject* o = parent();
     if (o) {
-        o->absolutePosition(xPos, yPos, f);
-        yPos += o->borderTopExtra();
+        localPoint.move(0.0f, static_cast<float>(o->borderTopExtra()));
         if (o->hasOverflowClip())
-            o->layer()->subtractScrollOffset(xPos, yPos);
-        return true;
-    } else {
-        xPos = yPos = 0;
-        return false;
+            localPoint -= o->layer()->scrolledContentOffset();
+        return o->localToAbsolute(localPoint, fixed, useTransforms);
     }
+
+    return FloatPoint();
 }
 
 IntRect RenderObject::caretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
@@ -2933,10 +2931,9 @@ void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions)
             region.clip.setWidth(0);
         }
 
-        int x, y;
-        absolutePosition(x, y);
-        region.bounds.setX(x + styleRegion.offset.left().value());
-        region.bounds.setY(y + styleRegion.offset.top().value());
+        FloatPoint absPos = localToAbsolute();
+        region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
+        region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
 
         if (document()->frame()) {
             float pageScaleFactor = document()->frame()->page()->chrome()->scaleFactor();
@@ -3055,9 +3052,8 @@ IntRect RenderObject::contentBox() const
 IntRect RenderObject::absoluteContentBox() const
 {
     IntRect rect = contentBox();
-    int x, y;
-    absolutePositionForContent(x, y);
-    rect.move(x, y);
+    FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
+    rect.move(absPos.x(), absPos.y());
     return rect;
 }
 
@@ -3089,9 +3085,8 @@ void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const
 IntRect RenderObject::absoluteOutlineBox() const
 {
     IntRect box = borderBox();
-    int x, y;
-    absolutePosition(x, y);
-    box.move(x, y);
+    FloatPoint absPos = localToAbsolute();
+    box.move(absPos.x(), absPos.y());
     box.move(view()->layoutDelta());
     adjustRectForOutlineAndShadow(box);
     return box;
index df56d96..828f4ae 100644 (file)
@@ -580,17 +580,17 @@ public:
     virtual int xPos() const { return 0; }
     virtual int yPos() const { return 0; }
 
-    // calculate client position of box
-    virtual bool absolutePosition(int& x, int& y, bool fixed = false) const;
+    // Convert the given local point to absolute coordinates
+    // FIXME: Temporary. If useTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware.
+    virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
 
     // This function is used to deal with the extra top space that can occur in table cells (called borderTopExtra).
     // The children of the cell do not factor this space in, so we have to add it in.  Any code that wants to
     // accurately deal with the contents of a cell must call this function instad of absolutePosition.
-    bool absolutePositionForContent(int& xPos, int& yPos, bool fixed = false) const
+    FloatPoint localToAbsoluteForContent(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const
     {
-        bool result = absolutePosition(xPos, yPos, fixed);
-        yPos += borderTopExtra();
-        return result;
+        localPoint.move(0.0f, static_cast<float>(borderTopExtra()));
+        return localToAbsolute(localPoint, fixed, useTransforms);
     }
 
     // width and height are without margins but include paddings and borders
index a9a821e..d840418 100644 (file)
@@ -88,13 +88,12 @@ void RenderPart::updateWidgetPosition()
     if (!m_widget)
         return;
     
-    int x, y, width, height;
-    absolutePosition(x, y);
-    x += borderLeft() + paddingLeft();
-    y += borderTop() + paddingTop();
+    int width, height;
+    FloatPoint absPos = localToAbsolute();
+    absPos.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
     width = m_width - borderLeft() - borderRight() - paddingLeft() - paddingRight();
     height = m_height - borderTop() - borderBottom() - paddingTop() - paddingBottom();
-    IntRect newBounds(x,y,width,height);
+    IntRect newBounds(absPos.x(), absPos.y(), width, height);
     bool boundsChanged = newBounds != m_widget->frameRect();
     if (boundsChanged) {
         // The widget changed positions.  Update the frame geometry.
index 52267d5..ead94b2 100644 (file)
@@ -258,9 +258,8 @@ IntRect RenderReplaced::selectionRect(bool clipToVisibleContent)
     if (clipToVisibleContent)
         computeAbsoluteRepaintRect(rect);
     else {
-        int absx, absy;
-        absolutePositionForContent(absx, absy);
-        rect.move(absx, absy);
+        FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
+        rect.move(absPos.x(), absPos.y());
     }
     
     return rect;
index 33a984c..4ba458d 100644 (file)
@@ -107,14 +107,14 @@ IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPo
         rect.unite(box->selectionRect(0, 0, startPos, endPos));
 
     // Mimic RenderBox::computeAbsoluteRepaintRect() functionality. But only the subset needed for SVG and respecting SVG transformations.
-    int x, y;
-    cb->container()->absolutePosition(x, y);
+    FloatPoint absPos = cb->container()->localToAbsolute();
 
     // Remove HTML parent translation offsets here! These need to be retrieved from the RenderSVGRoot object.
     // But do take the containingBlocks's container position into account, ie. SVG text in scrollable <div>.
     AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();
 
-    FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + x - xPos() - htmlParentCtm.e()), narrowPrecisionToFloat(rect.y() + y - yPos() - htmlParentCtm.f()), rect.width(), rect.height());
+    FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + absPos.x() - xPos() - htmlParentCtm.e()),
+                        narrowPrecisionToFloat(rect.y() + absPos.y() - yPos() - htmlParentCtm.f()), rect.width(), rect.height());
     return enclosingIntRect(absoluteTransform().mapRect(fixedRect));
 }
 
index 2f0e2d6..42b3427 100644 (file)
@@ -151,8 +151,7 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
     if (!root)
         return;
 
-    int x, y;
-    absolutePosition(x, y);
+    FloatPoint absPos = localToAbsolute();
 
     AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();
  
@@ -164,7 +163,7 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
         InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
         for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
             FloatRect boxRect(box->xPos(), box->yPos(), box->width(), box->height());
-            boxRect.move(narrowPrecisionToFloat(x - htmlParentCtm.e()), narrowPrecisionToFloat(y - htmlParentCtm.f()));
+            boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f()));
             rects.append(enclosingIntRect(absoluteTransform().mapRect(boxRect)));
         }
     }
index 9f44b65..08a1818 100644 (file)
@@ -196,13 +196,13 @@ void RenderTableCell::computeAbsoluteRepaintRect(IntRect& r, bool fixed)
     RenderBlock::computeAbsoluteRepaintRect(r, fixed);
 }
 
-bool RenderTableCell::absolutePosition(int& xPos, int& yPos, bool fixed) const
+FloatPoint RenderTableCell::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
 {
-    bool result = RenderBlock::absolutePosition(xPos, yPos, fixed);
+    FloatPoint result = RenderBlock::localToAbsolute(localPoint, fixed, useTransforms);
     RenderView* v = view();
     if ((!v || !v->layoutState()) && parent()) {
-        xPos -= parent()->xPos(); // Rows are in the same coordinate space, so don't add their offset in.
-        yPos -= parent()->yPos();
+        // Rows are in the same coordinate space, so don't add their offset in.
+        result.move(-parent()->xPos(), -parent()->yPos());
     }
     return result;
 }
index 25257bb..d22b362 100644 (file)
@@ -101,7 +101,7 @@ public:
 
     virtual IntRect absoluteClippedOverflowRect();
     virtual void computeAbsoluteRepaintRect(IntRect&, bool fixed = false);
-    virtual bool absolutePosition(int& x, int& y, bool fixed = false) const;
+    virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
 
     virtual int baselinePosition(bool firstLine = false, bool isRootLineBox = false) const;
 
index be8e337..0a99cf5 100644 (file)
@@ -214,27 +214,26 @@ void RenderText::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigne
     start = min(start, static_cast<unsigned>(INT_MAX));
     end = min(end, static_cast<unsigned>(INT_MAX));
     
-    int x, y;
-    absolutePositionForContent(x, y);
+    FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
 
     for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
         // Note: box->end() returns the index of the last character, not the index past it
         if (start <= box->start() && box->end() < end) {
-            IntRect r = IntRect(x + box->xPos(), y + box->yPos(), box->width(), box->height());
+            IntRect r = IntRect(absPos.x() + box->xPos(), absPos.y() + box->yPos(), box->width(), box->height());
             if (useSelectionHeight) {
-                IntRect selectionRect = box->selectionRect(x, y, start, end);
+                IntRect selectionRect = box->selectionRect(absPos.x(), absPos.y(), start, end);
                 r.setHeight(selectionRect.height());
                 r.setY(selectionRect.y());
             }
             rects.append(r);
         } else {
             unsigned realEnd = min(box->end() + 1, end);
-            IntRect r = box->selectionRect(x, y, start, realEnd);
+            IntRect r = box->selectionRect(absPos.x(), absPos.y(), start, realEnd);
             if (!r.isEmpty()) {
                 if (!useSelectionHeight) {
                     // change the height and y position because selectionRect uses selection-specific values
                     r.setHeight(box->height());
-                    r.setY(y + box->yPos());
+                    r.setY(absPos.y() + box->yPos());
                 }
                 rects.append(r);
             }
@@ -342,18 +341,18 @@ IntRect RenderText::caretRect(InlineBox* inlineBox, int caretOffset, int* extraW
     if (extraWidthToEndOfLine)
         *extraWidthToEndOfLine = (box->root()->width() + rootLeft) - (left + 1);
 
-    int absx, absy;
-    absolutePositionForContent(absx, absy);
-    left += absx;
-    top += absy;
+    // FIXME: broken with transforms
+    FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
+    left += absPos.x();
+    top += absPos.y();
 
     RenderBlock* cb = containingBlock();
     if (style()->autoWrap()) {
         int availableWidth = cb->lineWidth(top);
         if (box->direction() == LTR)
-            left = min(left, absx + rootLeft + availableWidth - 1);
+            left = min(left, static_cast<int>(absPos.x()) + rootLeft + availableWidth - 1);
         else
-            left = max(left, absx + rootLeft);
+            left = max(left, static_cast<int>(absPos.x()) + rootLeft);
     }
 
     return IntRect(left, top, 1, height);
@@ -1079,9 +1078,9 @@ IntRect RenderText::selectionRect(bool clipToVisibleContent)
     else {
         if (cb->hasColumns())
             cb->adjustRectForColumns(rect);
-        int absx, absy;
-        absolutePosition(absx, absy);
-        rect.move(absx, absy);
+        // FIXME: This doesn't work correctly with transforms.
+        FloatPoint absPos = localToAbsolute();
+        rect.move(absPos.x(), absPos.y());
     }
 
     return rect;
index d677725..a932356 100644 (file)
@@ -124,11 +124,11 @@ void RenderVideo::updatePlayer()
         mediaPlayer->setVisible(false);
         return;
     }
-    int x;
-    int y;
-    absolutePosition(x, y);
+    
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = localToAbsolute();
     IntRect videoBounds = videoBox(); 
-    videoBounds.move(x, y);
+    videoBounds.move(absPos.x(), absPos.y());
     mediaPlayer->setFrameView(document()->view());
     mediaPlayer->setRect(videoBounds);
     mediaPlayer->setVisible(true);
index 81157a8..5a496ef 100644 (file)
@@ -131,14 +131,12 @@ void RenderView::layout()
     setNeedsLayout(false);
 }
 
-bool RenderView::absolutePosition(int& xPos, int& yPos, bool fixed) const
+FloatPoint RenderView::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
 {
-    if (fixed && m_frameView) {
-        xPos = m_frameView->scrollX();
-        yPos = m_frameView->scrollY();
-    } else
-        xPos = yPos = 0;
-    return true;
+    if (fixed && m_frameView)
+        localPoint += m_frameView->scrollOffset();
+
+    return localPoint;
 }
 
 void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
index b437cd1..4c92cc8 100644 (file)
@@ -44,7 +44,7 @@ public:
     virtual void calcWidth();
     virtual void calcHeight();
     virtual void calcPrefWidths();
-    virtual bool absolutePosition(int& xPos, int& yPos, bool fixed = false) const;
+    virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
     
     int docHeight() const;
     int docWidth() const;
index 57b8722..e887d00 100644 (file)
@@ -218,16 +218,14 @@ void RenderWidget::updateWidgetPosition()
     if (!m_widget)
         return;
 
-    int x;
-    int y;
-    absolutePosition(x, y);
-    x += borderLeft() + paddingLeft();
-    y += borderTop() + paddingTop();
+    // FIXME: This doesn't work correctly with transforms.
+    FloatPoint absPos = localToAbsolute();
+    absPos.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
 
     int width = m_width - borderLeft() - borderRight() - paddingLeft() - paddingRight();
     int height = m_height - borderTop() - borderBottom() - paddingTop() - paddingBottom();
 
-    IntRect newBounds(x, y, width, height);
+    IntRect newBounds(absPos.x(), absPos.y(), width, height);
     IntRect oldBounds(m_widget->frameRect());
     if (newBounds != oldBounds) {
         // The widget changed positions.  Update the frame geometry.
index 23a1fd9..6875ab8 100644 (file)
@@ -397,25 +397,21 @@ AffineTransform SVGSVGElement::getCTM() const
 AffineTransform SVGSVGElement::getScreenCTM() const
 {
     document()->updateLayoutIgnorePendingStylesheets();
-    float rootX = 0.0f;
-    float rootY = 0.0f;
-    
+    FloatPoint rootLocation;    
+
     if (RenderObject* renderer = this->renderer()) {
         if (isOutermostSVG()) {
-            int tx = 0;
-            int ty = 0;
+            // FIXME: This doesn't work correctly with CSS transforms.
+            FloatPoint point;
             if (renderer->parent())
-                renderer->absolutePosition(tx, ty, true);
-            rootX += tx;
-            rootY += ty;
-        } else {
-            rootX += x().value(this);
-            rootY += y().value(this);
-        }
+                point = renderer->localToAbsolute(point, true);
+            rootLocation.move(point.x(), point.y());
+        } else
+            rootLocation.move(x().value(this), y().value(this));
     }
     
     AffineTransform mat = SVGStyledLocatableElement::getScreenCTM();
-    mat.translate(rootX, rootY);
+    mat.translate(rootLocation.x(), rootLocation.y());
 
     if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
         AffineTransform viewBox = viewBoxToViewTransform(width().value(this), height().value(this));
index 78db0ab..28c0554 100644 (file)
@@ -1,3 +1,16 @@
+2008-11-04  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Dave Hyatt
+
+        https://bugs.webkit.org/show_bug.cgi?id=21941
+
+        Rename absolutePosition() to localToAbsolute(), and add the ability
+        to optionally take transforms into account (which will eventually be the
+        default behavior).
+
+        * WebView/WebRenderNode.mm:
+        (copyRenderNode):
+
 2008-11-01  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin Adler.
index c34ac34..52d094e 100644 (file)
@@ -86,10 +86,10 @@ static WebRenderNode *copyRenderNode(RenderObject* node)
     Widget* widget = renderWidget ? renderWidget->widget() : 0;
     NSView *view = widget ? widget->platformWidget() : nil;
 
-    int nx, ny;
-    node->absolutePosition(nx, ny);
+    // FIXME: broken with transforms
+    FloatPoint absPos = node->localToAbsolute(FloatPoint());
     WebRenderNode *result = [[WebRenderNode alloc] initWithName:name
-        position:NSMakePoint(nx, ny) rect:NSMakeRect(node->xPos(), node->yPos(), node->width(), node->height())
+        position:absPos rect:NSMakeRect(node->xPos(), node->yPos(), node->width(), node->height())
         view:view children:children];
 
     [name release];