[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

simon.fraser at apple.com simon.fraser at apple.com
Wed Apr 7 23:54:36 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 0365603a6c7e45bd507ecdeb7411c2a13816aecb
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 23 23:30:31 2009 +0000

    2009-11-23  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            DocumentMarkers need to be educated about transforms
            https://bugs.webkit.org/show_bug.cgi?id=31751
    
            Find highlight is incorrect with transforms
            <rdar://problem/6358394>
    
            Allow callers to specify that Frame::selectionTextRects() takes transforms into account
            when computing the set of rects that encompass a selection. For transformed elemenets, the
            selection rect will be the bounding box of the selected content.
    
            Fix DocumentMarkers to cache rects in absolute coordinates, rather than painting coordinates.
    
            Test: editing/selection/transformed-selection-rects.html
    
            * WebCore.base.exp:
            Frame::selectionTextRects() has a new parameter.
    
            * dom/Document.cpp:
            (WebCore::Document::setRenderedRectForMarker):
            * dom/Document.h:
            Pass the marker as a const reference.
    
            * dom/Range.h:
            * dom/Range.cpp:
            (WebCore::Range::textQuads):
            Add a new method, textQuads(), which returns a list of quads, respecting transforms.
    
            * page/Frame.h:
            * page/Frame.cpp:
            (WebCore::Frame::selectionTextRects):
            Add a new parameter, respectTransforms, and when that is RespectTransforms, use the quad
            method to get quads for ranges, and then take their bounding boxes.
    
            * rendering/InlineTextBox.h:
            * rendering/InlineTextBox.cpp:
            (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
            (WebCore::InlineTextBox::paintTextMatchMarker):
            (WebCore::InlineTextBox::computeRectForReplacementMarker):
            (WebCore::InlineTextBox::paintDocumentMarkers):
            (WebCore::InlineTextBox::textPos):
            (WebCore::InlineTextBox::offsetForPosition):
    
            Pass DocumentMarkers as a const references.
            Convert the argument to setRenderedRectForMarker() into absolute coordinates.
    
            * rendering/RenderView.cpp:
            (WebCore::RenderView::selectionBounds):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51324 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index fe81f82..7d583a9 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,21 @@
+2009-11-23  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        DocumentMarkers need to be educated about transforms
+        https://bugs.webkit.org/show_bug.cgi?id=31751
+        
+        Find highlight is incorrect with transforms
+        <rdar://problem/6358394>
+        
+        Add test to show the selection rect for selection in a transformed element.
+
+        * editing/editing.js:
+        * editing/selection/transformed-selection-rects.html: Added.
+        * platform/mac/editing/selection/transformed-selection-rects-expected.checksum: Added.
+        * platform/mac/editing/selection/transformed-selection-rects-expected.png: Added.
+        * platform/mac/editing/selection/transformed-selection-rects-expected.txt: Added.
+
 2009-11-23  Csaba Osztrogonác  <ossy at webkit.org>
 
         Unreviewed. Skip new tests.
diff --git a/LayoutTests/editing/editing.js b/LayoutTests/editing/editing.js
index 477a4e5..94833aa 100644
--- a/LayoutTests/editing/editing.js
+++ b/LayoutTests/editing/editing.js
@@ -12,6 +12,8 @@ var selection = window.getSelection();
 function execSetSelectionCommand(sn, so, en, eo) {
     window.getSelection().setBaseAndExtent(sn, so, en, eo);
 }
+
+// Args are startNode, startOffset, endNode, endOffset
 function setSelectionCommand(sn, so, en, eo) {
     if (commandDelay > 0) {
         window.setTimeout(execSetSelectionCommand, commandCount * commandDelay, sn, so, en, eo);
diff --git a/LayoutTests/editing/selection/transformed-selection-rects.html b/LayoutTests/editing/selection/transformed-selection-rects.html
new file mode 100644
index 0000000..630735f
--- /dev/null
+++ b/LayoutTests/editing/selection/transformed-selection-rects.html
@@ -0,0 +1,39 @@
+<html>
+<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  <style type="text/css" media="screen">
+    .transformed {
+      width: 600px;
+      margin: 20px;
+      padding: 10px;
+      font-size: 18pt;
+      -webkit-transform-origin: top left;
+      -webkit-transform: rotate(10deg);
+      border: 1px solid black;
+    }
+    #test {
+      font-weight: bold;
+    }
+  </style>
+<script src="../editing.js" language="JavaScript" type="text/JavaScript" ></script>
+<script>
+function editingTest() {
+    if (window.layoutTestController)
+        window.layoutTestController.dumpSelectionRect();
+        
+    var testNode = document.getElementById('test');
+    setSelectionCommand(testNode, 0, testNode, 0);
+    extendSelectionForwardByWordCommand();
+}
+</script>
+</head>
+<body>
+
+  <p>Tests that selection rects take transforms into account. The red box should be the bounds of the transformed selection.</p>
+  <div class="transformed">
+    <p>Lorem ipsum <span id="test">dolor sit amet, consectetur adipisicing</span> elit.</p>
+  </div>
+
+<script>runEditingTest()</script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.checksum b/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.checksum
new file mode 100644
index 0000000..56c5067
--- /dev/null
+++ b/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.checksum
@@ -0,0 +1 @@
+0b71625c6462e6a0348e132aa71dba00
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.png b/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.png
new file mode 100644
index 0000000..f0f14d6
Binary files /dev/null and b/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.png differ
diff --git a/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt b/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt
new file mode 100644
index 0000000..b2344aa
--- /dev/null
+++ b/LayoutTests/platform/mac/editing/selection/transformed-selection-rects-expected.txt
@@ -0,0 +1,22 @@
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x572
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 738x18
+          text run at (0,0) width 738: "Tests that selection rects take transforms into account. The red box should be the bounds of the transformed selection."
+layer at (28,46) size 622x98
+  RenderBlock {DIV} at (20,38) size 622x98 [border: (1px solid #000000)]
+    RenderBlock {P} at (11,35) size 600x28
+      RenderText {#text} at (0,0) size 136x28
+        text run at (0,0) width 136: "Lorem ipsum "
+      RenderInline {SPAN} at (0,0) size 389x28
+        RenderText {#text} at (136,0) size 389x28
+          text run at (136,0) width 389: "dolor sit amet, consectetur adipisicing"
+      RenderText {#text} at (525,0) size 44x28
+        text run at (525,0) width 44: " elit."
+selection start: position 0 of child 0 {#text} of child 1 {SPAN} of child 1 {P} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
+selection end:   position 5 of child 0 {#text} of child 1 {SPAN} of child 1 {P} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 812e36b..ceaae74 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,55 @@
+2009-11-23  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        DocumentMarkers need to be educated about transforms
+        https://bugs.webkit.org/show_bug.cgi?id=31751
+        
+        Find highlight is incorrect with transforms
+        <rdar://problem/6358394>
+
+        Allow callers to specify that Frame::selectionTextRects() takes transforms into account
+        when computing the set of rects that encompass a selection. For transformed elemenets, the
+        selection rect will be the bounding box of the selected content.
+        
+        Fix DocumentMarkers to cache rects in absolute coordinates, rather than painting coordinates.
+        
+        Test: editing/selection/transformed-selection-rects.html
+        
+        * WebCore.base.exp:
+        Frame::selectionTextRects() has a new parameter.
+        
+        * dom/Document.cpp:
+        (WebCore::Document::setRenderedRectForMarker):
+        * dom/Document.h:
+        Pass the marker as a const reference.
+        
+        * dom/Range.h:
+        * dom/Range.cpp:
+        (WebCore::Range::textQuads):
+        Add a new method, textQuads(), which returns a list of quads, respecting transforms.
+        
+        * page/Frame.h:
+        * page/Frame.cpp:
+        (WebCore::Frame::selectionTextRects):
+        Add a new parameter, respectTransforms, and when that is RespectTransforms, use the quad
+        method to get quads for ranges, and then take their bounding boxes.
+
+        * rendering/InlineTextBox.h:
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+        (WebCore::InlineTextBox::paintTextMatchMarker):
+        (WebCore::InlineTextBox::computeRectForReplacementMarker):
+        (WebCore::InlineTextBox::paintDocumentMarkers):
+        (WebCore::InlineTextBox::textPos):
+        (WebCore::InlineTextBox::offsetForPosition):
+        
+        Pass DocumentMarkers as a const references.
+        Convert the argument to setRenderedRectForMarker() into absolute coordinates.
+        
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::selectionBounds):
+
 2009-11-23  Dirk Schulze  <krit at webkit.org>
 
         Reviewed by Oliver Hunt.
diff --git a/WebCore/WebCore.base.exp b/WebCore/WebCore.base.exp
index 3aeaf07..79f665a 100644
--- a/WebCore/WebCore.base.exp
+++ b/WebCore/WebCore.base.exp
@@ -896,7 +896,7 @@ __ZNK7WebCore5Frame15selectionBoundsEb
 __ZNK7WebCore5Frame16inViewSourceModeEv
 __ZNK7WebCore5Frame17firstRectForRangeEPNS_5RangeE
 __ZNK7WebCore5Frame18documentTypeStringEv
-__ZNK7WebCore5Frame18selectionTextRectsERN3WTF6VectorINS_9FloatRectELm0EEEb
+__ZNK7WebCore5Frame18selectionTextRectsERN3WTF6VectorINS_9FloatRectELm0EEENS0_30SelectionRectRespectTransformsEb
 __ZNK7WebCore5Frame20selectionGranularityEv
 __ZNK7WebCore5Frame30applyEditingStyleToBodyElementEv
 __ZNK7WebCore5Frame31fontAttributesForSelectionStartEv
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 6b18603..da60887 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -3735,7 +3735,7 @@ void Document::repaintMarkers(DocumentMarker::MarkerType markerType)
     }
 }
 
-void Document::setRenderedRectForMarker(Node* node, DocumentMarker marker, const IntRect& r)
+void Document::setRenderedRectForMarker(Node* node, const DocumentMarker& marker, const IntRect& r)
 {
     MarkerMapVectorPair* vectorPair = m_markers.get(node);
     if (!vectorPair) {
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 3295577..e5b984c 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -730,7 +730,7 @@ public:
     void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
     void removeMarkers(Node*);
     void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
-    void setRenderedRectForMarker(Node*, DocumentMarker, const IntRect&);
+    void setRenderedRectForMarker(Node*, const DocumentMarker&, const IntRect&);
     void invalidateRenderedRectsForMarkersInRect(const IntRect&);
     void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
     void setMarkersActive(Range*, bool);
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index 122130d..84a46c2 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -1595,12 +1595,32 @@ IntRect Range::boundingBox()
 
 void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight)
 {
-    if (!m_start.container() || !m_end.container())
+    Node* startContainer = m_start.container();
+    Node* endContainer = m_end.container();
+
+    if (!startContainer || !endContainer)
         return;
 
+    Node* stopNode = pastLastNode();
+    for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
+        RenderObject* r = node->renderer();
+        if (!r || !r->isText())
+            continue;
+        RenderText* renderText = toRenderText(r);
+        int startOffset = node == startContainer ? m_start.offset() : 0;
+        int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+        renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
+    }
+}
+
+void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight)
+{
     Node* startContainer = m_start.container();
     Node* endContainer = m_end.container();
 
+    if (!startContainer || !endContainer)
+        return;
+
     Node* stopNode = pastLastNode();
     for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
         RenderObject* r = node->renderer();
@@ -1608,8 +1628,8 @@ void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight)
             continue;
         RenderText* renderText = toRenderText(r);
         int startOffset = node == startContainer ? m_start.offset() : 0;
-        int endOffset = node == endContainer ? m_end.offset() : INT_MAX;
-        renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
+        int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+        renderText->absoluteQuadsForRange(quads, startOffset, endOffset, useSelectionHeight);
     }
 }
 
diff --git a/WebCore/dom/Range.h b/WebCore/dom/Range.h
index e2e282b..583f9f0 100644
--- a/WebCore/dom/Range.h
+++ b/WebCore/dom/Range.h
@@ -105,7 +105,10 @@ public:
     Node* shadowTreeRootNode() const;
 
     IntRect boundingBox();
+    // Not transform-friendly
     void textRects(Vector<IntRect>&, bool useSelectionHeight = false);
+    // Transform-friendly
+    void textQuads(Vector<FloatQuad>&, bool useSelectionHeight = false);
 
     void nodeChildrenChanged(ContainerNode*);
     void nodeWillBeRemoved(Node*);
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index d73b56f..a2b0a50 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -1266,7 +1266,7 @@ FloatRect Frame::selectionBounds(bool clipToVisibleContent) const
     return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
 }
 
-void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const
+void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const
 {
     RenderView* root = contentRenderer();
     if (!root)
@@ -1274,18 +1274,35 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
 
     RefPtr<Range> selectedRange = selection()->toNormalizedRange();
 
-    Vector<IntRect> intRects;
-    selectedRange->textRects(intRects, true);
-
-    unsigned size = intRects.size();
     FloatRect visibleContentRect = m_view->visibleContentRect();
-    for (unsigned i = 0; i < size; ++i)
-        if (clipToVisibleContent)
-            rects.append(intersection(intRects[i], visibleContentRect));
-        else
-            rects.append(intRects[i]);
-}
+    
+    // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect.
+    // We may not want to do that.
+    if (respectTransforms) {
+        Vector<FloatQuad> quads;
+        selectedRange->textQuads(quads, true);
+
+        unsigned size = quads.size();
+        for (unsigned i = 0; i < size; ++i) {
+            IntRect currRect = quads[i].enclosingBoundingBox();
+            if (clipToVisibleContent)
+                rects.append(intersection(currRect, visibleContentRect));
+            else
+                rects.append(currRect);
+        }
+    } else {
+        Vector<IntRect> intRects;
+        selectedRange->textRects(intRects, true);
 
+        unsigned size = intRects.size();
+        for (unsigned i = 0; i < size; ++i) {
+            if (clipToVisibleContent)
+                rects.append(intersection(intRects[i], visibleContentRect));
+            else
+                rects.append(intRects[i]);
+        }
+    }
+}
 
 // Scans logically forward from "start", including any child frames
 static HTMLFormElement *scanForForm(Node *start)
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index fc52af9..ca9a6d4 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -274,7 +274,8 @@ namespace WebCore {
         void clearTypingStyle();
 
         FloatRect selectionBounds(bool clipToVisibleContent = true) const;
-        void selectionTextRects(Vector<FloatRect>&, bool clipToVisibleContent = true) const;
+        enum SelectionRectRespectTransforms { RespectTransforms = true, IgnoreTransforms = false };
+        void selectionTextRects(Vector<FloatRect>&, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent = true) const;
 
         HTMLFormElement* currentForm() const;
 
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index 292f247..31e6967 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -700,7 +700,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
         context->clearShadow();
 }
 
-void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font, bool grammar)
+void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
 {
     // Never print spelling/grammar markers (5327887)
     if (textRenderer()->document()->printing())
@@ -739,8 +739,11 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
         
         // Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to
         // display a toolTip. We don't do this for misspelling markers.
-        if (grammar)
+        if (grammar) {
+            markerRect.move(-tx, -ty);
+            markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
             renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
+        }
     }
     
     // IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to
@@ -763,7 +766,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
     pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar);
 }
 
-void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font)
+void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, const DocumentMarker& marker, RenderStyle* style, const Font& font)
 {
     // Use same y positioning and height as for selection, so that when the selection and this highlight are on
     // the same word there are no pieces sticking out.
@@ -773,10 +776,10 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
     int sPos = max(marker.startOffset - m_start, (unsigned)0);
     int ePos = min(marker.endOffset - m_start, (unsigned)m_len);    
     TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
-    IntPoint startPoint = IntPoint(m_x + tx, y + ty);
     
-    // Always compute and store the rect associated with this marker
-    IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
+    // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
+    IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, y), h, sPos, ePos));
+    markerRect = root()->block()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
     renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
      
     // Optionally highlight the text
@@ -787,12 +790,12 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
         pt->save();
         updateGraphicsContext(pt, color, color, 0, style->colorSpace());  // Don't draw text at all!
         pt->clip(IntRect(tx + m_x, ty + y, m_width, h));
-        pt->drawHighlightForText(font, run, startPoint, h, color, style->colorSpace(), sPos, ePos);
+        pt->drawHighlightForText(font, run, IntPoint(m_x + tx, y + ty), h, color, style->colorSpace(), sPos, ePos);
         pt->restore();
     }
 }
 
-void InlineTextBox::computeRectForReplacementMarker(int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font)
+void InlineTextBox::computeRectForReplacementMarker(int /*tx*/, int /*ty*/, const DocumentMarker& marker, RenderStyle* style, const Font& font)
 {
     // Replacement markers are not actually drawn, but their rects need to be computed for hit testing.
     int y = selectionTop();
@@ -801,10 +804,11 @@ void InlineTextBox::computeRectForReplacementMarker(int tx, int ty, DocumentMark
     int sPos = max(marker.startOffset - m_start, (unsigned)0);
     int ePos = min(marker.endOffset - m_start, (unsigned)m_len);    
     TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
-    IntPoint startPoint = IntPoint(m_x + tx, y + ty);
+    IntPoint startPoint = IntPoint(m_x, y);
     
     // Compute and store the rect associated with this marker.
     IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
+    markerRect = root()->block()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
     renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
 }
     
@@ -819,7 +823,7 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, Re
     // Give any document markers that touch this run a chance to draw before the text has been drawn.
     // Note end() points at the last char, not one past it like endOffset and ranges do.
     for ( ; markerIt != markers.end(); markerIt++) {
-        DocumentMarker marker = *markerIt;
+        const DocumentMarker& marker = *markerIt;
         
         // Paint either the background markers or the foreground markers, but not both
         switch (marker.type) {
@@ -938,7 +942,7 @@ int InlineTextBox::textPos() const
     if (x() == 0)
         return 0;
         
-    RenderBlock *blockElement = renderer()->containingBlock();
+    RenderBlock* blockElement = renderer()->containingBlock();
     return direction() == RTL ? x() - blockElement->borderRight() - blockElement->paddingRight()
                       : x() - blockElement->borderLeft() - blockElement->paddingLeft();
 }
@@ -949,7 +953,7 @@ int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const
         return 0;
 
     RenderText* text = toRenderText(renderer());
-    RenderStyle *style = text->style(m_firstLine);
+    RenderStyle* style = text->style(m_firstLine);
     const Font* f = &style->font();
     return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()),
                                 _x - m_x, includePartialGlyphs);
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index d6658df..80af2e3 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -131,9 +131,9 @@ protected:
 private:
     void paintDecoration(GraphicsContext*, int tx, int ty, int decoration, ShadowData*);
     void paintSelection(GraphicsContext*, int tx, int ty, RenderStyle*, const Font&);
-    void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&, bool grammar);
-    void paintTextMatchMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&);
-    void computeRectForReplacementMarker(int tx, int ty, DocumentMarker, RenderStyle*, const Font&);
+    void paintSpellingOrGrammarMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
+    void paintTextMatchMarker(GraphicsContext*, int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
+    void computeRectForReplacementMarker(int tx, int ty, const DocumentMarker&, RenderStyle*, const Font&);
 };
 
 inline RenderText* InlineTextBox::textRenderer() const
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 02a45d3..77fa3f1 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -326,7 +326,13 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
     SelectionMap::iterator end = selectedObjects.end();
     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
         RenderSelectionInfo* info = i->second;
-        selRect.unite(info->rect());
+        // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
+        IntRect currRect = info->rect();
+        if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) {
+            FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
+            currRect = absQuad.enclosingBoundingBox(); 
+        }
+        selRect.unite(currRect);
         delete info;
     }
     return selRect;
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index 3992281..54ff0d1 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,23 @@
+2009-11-23  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        DocumentMarkers need to be educated about transforms
+        https://bugs.webkit.org/show_bug.cgi?id=31751
+        
+        Find highlight is incorrect with transforms
+        <rdar://problem/6358394>
+        
+        Allow callers to specify that Frame::selectionTextRects() takes transforms into account
+        when computing the set of rects that encompass a selection. For transformed elemenets, the
+        selection rect will be the bounding box of the selected content.
+        
+        Fix DocumentMarkers to cache rects in absolute coordinates, rather than painting coordinates.
+        
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView selectionTextRects]):
+        Pass RespectTransforms to get a list of rects with transforms taken into account.
+
 2009-11-23  Kevin Decker  <kdecker at apple.com>
 
         Reviewed by Adam Roben.
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index 7c8c4db..aa1932d 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -5911,7 +5911,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
     
     Vector<FloatRect> list;
     if (Frame* coreFrame = core([self _frame]))
-        coreFrame->selectionTextRects(list);
+        coreFrame->selectionTextRects(list, Frame::RespectTransforms);
 
     unsigned size = list.size();
     NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:size] autorelease];

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list