[chromium] Show search tickmarks on css-styled scrollbars
authorthakis@chromium.org <thakis@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jul 2012 02:19:13 +0000 (02:19 +0000)
committerthakis@chromium.org <thakis@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Jul 2012 02:19:13 +0000 (02:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91949

Reviewed by Adrienne Walker.

This is done by letting RenderScrollbarTheme::paintTickmarks()
delegate to the native ScrollbarTheme. To make this possible,
move paintTickmarks() from ScrollbarThemeComposite to the
superclass ScrollbarTheme.

For testing, add internals.addTextMatchMarker() and add a pixel test.

* platform/ScrollbarTheme.h:
(WebCore::ScrollbarTheme::paintTickmarks):
Moved paintTickmarks() from ScrollbarThemeComposite to here.
* platform/ScrollbarThemeComposite.h:
Remove paintTickmarks().
* platform/chromium/ScrollbarThemeChromium.cpp:
(WebCore::ScrollbarThemeChromium::paintTickmarks):
Switch to drawing tickmarks as vectors, so they can be arbitrarily wide.
* platform/chromium/ScrollbarThemeChromiumMac.h:
(ScrollbarThemeChromiumMac):
Implement paintTickmarks(), so that css-styled scrollbars get tickmarks on mac.
* platform/chromium/ScrollbarThemeChromiumMac.mm:
(WebCore::ScrollbarThemeChromiumMac::paint):
(WebCore::ScrollbarThemeChromiumMac::paintTickmarks):
Implement paintTickmarks(), so that css-styled scrollbars get tickmarks on mac.
* rendering/RenderScrollbarTheme.cpp:
(WebCore::RenderScrollbarTheme::paintTickmarks):
Delegate to the native ScrollbarTheme for tickmark drawing.
(WebCore):
* rendering/RenderScrollbarTheme.h:
(RenderScrollbarTheme):
Override paintTickmarks().

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

19 files changed:
LayoutTests/fast/scrolling/scrollbar-tickmarks-styled-expected.txt [new file with mode: 0644]
LayoutTests/fast/scrolling/scrollbar-tickmarks-styled.html [new file with mode: 0644]
LayoutTests/platform/chromium-mac/fast/scrolling/scrollbar-tickmarks-styled-expected.png [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/dom/DocumentMarkerController.cpp
Source/WebCore/dom/DocumentMarkerController.h
Source/WebCore/dom/Range.cpp
Source/WebCore/dom/Range.h
Source/WebCore/platform/ScrollbarTheme.h
Source/WebCore/platform/ScrollbarThemeComposite.h
Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp
Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h
Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
Source/WebCore/rendering/RenderScrollbarTheme.cpp
Source/WebCore/rendering/RenderScrollbarTheme.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

diff --git a/LayoutTests/fast/scrolling/scrollbar-tickmarks-styled-expected.txt b/LayoutTests/fast/scrolling/scrollbar-tickmarks-styled-expected.txt
new file mode 100644 (file)
index 0000000..cfaf22a
--- /dev/null
@@ -0,0 +1 @@
diff --git a/LayoutTests/fast/scrolling/scrollbar-tickmarks-styled.html b/LayoutTests/fast/scrolling/scrollbar-tickmarks-styled.html
new file mode 100644 (file)
index 0000000..74b3fe3
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<head>
+<style>
+html {
+    font: Ahem 10px;
+    -webkit-font-smoothing: none;
+}
+::-webkit-scrollbar {
+    width: 13px;
+    height: 13px;
+}
+::-webkit-scrollbar-track {
+    background-color:green;
+}
+::-webkit-scrollbar-thumb {
+    background-color:rgba(128, 128, 128, 0.8);  /* Let tickmark shine through */
+}
+</style>
+<script>
+function highlight()
+{
+    var range = document.createRange();
+    var elt = document.getElementById('elt');
+    range.selectNodeContents(elt);
+    if (window.internals) {
+        window.internals.addTextMatchMarker(range, true);
+    }
+    if (window.testRunner)
+        testRunner.dumpAsText(true);
+}
+</script>
+</head>
+<body onload="highlight();">
+
+<div style="height:600px"></div>
+<span id="elt" style="position:absolute; top:300px">&nbsp;</span>
+
+</body>
+</html>
diff --git a/LayoutTests/platform/chromium-mac/fast/scrolling/scrollbar-tickmarks-styled-expected.png b/LayoutTests/platform/chromium-mac/fast/scrolling/scrollbar-tickmarks-styled-expected.png
new file mode 100644 (file)
index 0000000..8bea2c0
Binary files /dev/null and b/LayoutTests/platform/chromium-mac/fast/scrolling/scrollbar-tickmarks-styled-expected.png differ
index 8d0e8c7..bc504a7 100644 (file)
@@ -3594,6 +3594,9 @@ BUGWK90743 : fast/events/display-none-on-focus-crash.html = PASS TEXT
 // Flaky
 BUGWK90746 : fast/multicol/column-span-parent-continuation-crash.html = PASS TIMEOUT
 
+// Needs image
+BUGTHAKIS WIN LINUX : fast/scrolling/scrollbar-tickmarks-styled.html = IMAGE
+
 // Flaky
 BUGWK90896 WIN DEBUG : fast/js/dfg-cross-global-object-inline-new-array-literal.html = PASS TEXT
 
index 81bf43a..86300b8 100644 (file)
@@ -1,3 +1,40 @@
+2012-07-23  Nico Weber  <thakis@chromium.org>
+
+        [chromium] Show search tickmarks on css-styled scrollbars
+        https://bugs.webkit.org/show_bug.cgi?id=91949
+
+        Reviewed by Adrienne Walker.
+
+        This is done by letting RenderScrollbarTheme::paintTickmarks()
+        delegate to the native ScrollbarTheme. To make this possible,
+        move paintTickmarks() from ScrollbarThemeComposite to the
+        superclass ScrollbarTheme.
+
+        For testing, add internals.addTextMatchMarker() and add a pixel test.
+
+        * platform/ScrollbarTheme.h:
+        (WebCore::ScrollbarTheme::paintTickmarks):
+        Moved paintTickmarks() from ScrollbarThemeComposite to here.
+        * platform/ScrollbarThemeComposite.h:
+        Remove paintTickmarks().
+        * platform/chromium/ScrollbarThemeChromium.cpp:
+        (WebCore::ScrollbarThemeChromium::paintTickmarks):
+        Switch to drawing tickmarks as vectors, so they can be arbitrarily wide.
+        * platform/chromium/ScrollbarThemeChromiumMac.h:
+        (ScrollbarThemeChromiumMac):
+        Implement paintTickmarks(), so that css-styled scrollbars get tickmarks on mac.
+        * platform/chromium/ScrollbarThemeChromiumMac.mm:
+        (WebCore::ScrollbarThemeChromiumMac::paint):
+        (WebCore::ScrollbarThemeChromiumMac::paintTickmarks):
+        Implement paintTickmarks(), so that css-styled scrollbars get tickmarks on mac.
+        * rendering/RenderScrollbarTheme.cpp:
+        (WebCore::RenderScrollbarTheme::paintTickmarks):
+        Delegate to the native ScrollbarTheme for tickmark drawing.
+        (WebCore):
+        * rendering/RenderScrollbarTheme.h:
+        (RenderScrollbarTheme):
+        Override paintTickmarks().
+
 2012-07-23  Brian Anderson  <brianderson@chromium.org>
 
         [chromium] Use shallow flushes that don't glFlush
index 0551077..a3ebc93 100644 (file)
@@ -92,7 +92,7 @@ void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset,
 }
 
 
-void DocumentMarkerController::addTextMatchMarker(Range* range, bool activeMatch)
+void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch)
 {
     // Use a TextIterator to visit the potentially multiple nodes the range covers.
     for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
index 6a37248..8dd2b04 100644 (file)
@@ -50,7 +50,7 @@ public:
     void addMarker(Range*, DocumentMarker::MarkerType, const String& description);
     void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType);
     void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType, PassRefPtr<DocumentMarkerDetails>);
-    void addTextMatchMarker(Range*, bool activeMatch);
+    void addTextMatchMarker(const Range*, bool activeMatch);
 
     void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta);
     bool hasMarkers(Range*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
index d736ce5..3a9fb48 100644 (file)
@@ -1582,7 +1582,7 @@ Node* Range::pastLastNode() const
     return m_end.container()->traverseNextSibling();
 }
 
-IntRect Range::boundingBox()
+IntRect Range::boundingBox() const
 {
     IntRect result;
     Vector<IntRect> rects;
@@ -1593,7 +1593,7 @@ IntRect Range::boundingBox()
     return result;
 }
 
-void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed)
+void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
 {
     Node* startContainer = m_start.container();
     Node* endContainer = m_end.container();
index 8f0e98b..048cd69 100644 (file)
@@ -112,7 +112,7 @@ public:
 
     ShadowRoot* shadowRoot() const;
 
-    IntRect boundingBox();
+    IntRect boundingBox() const;
     
     enum RangeInFixedPosition {
         NotFixedPosition,
@@ -121,7 +121,7 @@ public:
     };
     
     // Not transform-friendly
-    void textRects(Vector<IntRect>&, bool useSelectionHeight = false, RangeInFixedPosition* = 0);
+    void textRects(Vector<IntRect>&, bool useSelectionHeight = false, RangeInFixedPosition* = 0) const;
     // Transform-friendly
     void textQuads(Vector<FloatQuad>&, bool useSelectionHeight = false, RangeInFixedPosition* = 0) const;
     void getBorderAndTextQuads(Vector<FloatQuad>&) const;
index 5fe45b1..cccc2f9 100644 (file)
@@ -86,6 +86,7 @@ public:
     virtual void paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect) { defaultPaintScrollCorner(context, cornerRect); }
     static void defaultPaintScrollCorner(GraphicsContext* context, const IntRect& cornerRect) { context->fillRect(cornerRect, Color::white, ColorSpaceDeviceRGB); }
 
+    virtual void paintTickmarks(GraphicsContext*, ScrollbarThemeClient*, const IntRect&) { }
     virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect&, const IntRect&, const IntRect&) { }
 
 #if USE(ACCELERATED_COMPOSITING) && ENABLE(RUBBER_BANDING)
index 696db12..dfd15ed 100644 (file)
@@ -60,7 +60,6 @@ public:
     virtual void paintTrackPiece(GraphicsContext*, ScrollbarThemeClient*, const IntRect&, ScrollbarPart) { }
     virtual void paintButton(GraphicsContext*, ScrollbarThemeClient*, const IntRect&, ScrollbarPart) { }
     virtual void paintThumb(GraphicsContext*, ScrollbarThemeClient*, const IntRect&) { }
-    virtual void paintTickmarks(GraphicsContext*, ScrollbarThemeClient*, const IntRect&) { }
 
     virtual IntRect constrainTrackRectToTrackPieces(ScrollbarThemeClient*, const IntRect& rect) { return rect; }
 };
index 682d82d..4a4938a 100644 (file)
@@ -113,14 +113,8 @@ void ScrollbarThemeChromium::paintTickmarks(GraphicsContext* context, ScrollbarT
     if (!tickmarks.size())
         return;
 
-    // Get the image for the tickmarks.
-    DEFINE_STATIC_LOCAL(RefPtr<Image>, dash, (Image::loadPlatformResource("tickmarkDash")));
-    if (dash->isNull()) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-
-    context->save();
+    GraphicsContextStateSaver stateSaver(*context);
+    context->setShouldAntialias(false);
 
     for (Vector<IntRect>::const_iterator i = tickmarks.begin(); i != tickmarks.end(); ++i) {
         // Calculate how far down (in %) the tick-mark should appear.
@@ -129,11 +123,14 @@ void ScrollbarThemeChromium::paintTickmarks(GraphicsContext* context, ScrollbarT
         // Calculate how far down (in pixels) the tick-mark should appear.
         const int yPos = rect.y() + (rect.height() * percent);
 
-        IntPoint tick(scrollbar->x(), yPos);
-        context->drawImage(dash.get(), ColorSpaceDeviceRGB, tick);
-    }
+        context->setFillColor(Color(0xCC, 0xAA, 0x00, 0xFF), ColorSpaceDeviceRGB);
+        FloatRect tickRect(rect.x(), yPos, rect.width(), 3);
+        context->fillRect(tickRect);
 
-    context->restore();
+        context->setFillColor(Color(0xFF, 0xDD, 0x00, 0xFF), ColorSpaceDeviceRGB);
+        FloatRect tickStroke(rect.x(), yPos + 1, rect.width(), 1);
+        context->fillRect(tickStroke);
+    }
 }
 
 } // namespace WebCore
index 19346e7..efbdd09 100644 (file)
@@ -39,6 +39,7 @@ public:
     virtual bool paint(ScrollbarThemeClient*, GraphicsContext*, const IntRect& damageRect);
 
     virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
+    virtual void paintTickmarks(GraphicsContext*, ScrollbarThemeClient*, const IntRect&) OVERRIDE;
     
 private:
     void paintGivenTickmarks(GraphicsContext*, ScrollbarThemeClient*, const IntRect&, const Vector<IntRect>&);
index 75e4a29..73d79b0 100644 (file)
@@ -227,7 +227,7 @@ bool ScrollbarThemeChromiumMac::paint(ScrollbarThemeClient* scrollbar, GraphicsC
     }
     // The ends are rounded and the thumb doesn't go there.
     tickmarkTrackRect.inflateY(-tickmarkTrackRect.width());
-    // Inset by 2 on the left and 3 on the right.
+    // Inset a bit.
     tickmarkTrackRect.setX(tickmarkTrackRect.x() + 2);
     tickmarkTrackRect.setWidth(tickmarkTrackRect.width() - 5);
     paintGivenTickmarks(drawingContext, scrollbar, tickmarkTrackRect, tickmarks);
@@ -409,5 +409,25 @@ void ScrollbarThemeChromiumMac::paintOverhangAreas(ScrollView* view, GraphicsCon
     }
 }
 
+void ScrollbarThemeChromiumMac::paintTickmarks(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
+{
+    // Note: This is only used for css-styled scrollbars on mac.
+    if (scrollbar->orientation() != VerticalScrollbar)
+        return;
+
+    if (rect.height() <= 0 || rect.width() <= 0)
+        return;
+
+    Vector<IntRect> tickmarks;
+    scrollbar->getTickmarks(tickmarks);
+    if (!tickmarks.size())
+        return;
+
+    // Inset a bit.
+    IntRect tickmarkTrackRect = rect;
+    tickmarkTrackRect.setX(tickmarkTrackRect.x() + 1);
+    tickmarkTrackRect.setWidth(tickmarkTrackRect.width() - 2);
+    paintGivenTickmarks(context, scrollbar, tickmarkTrackRect, tickmarks);
+}
 
 }
index 44e2aa6..6d2e09b 100644 (file)
@@ -138,4 +138,9 @@ void RenderScrollbarTheme::paintThumb(GraphicsContext* context, ScrollbarThemeCl
     toRenderScrollbar(scrollbar)->paintPart(context, ThumbPart, rect);
 }
 
+void RenderScrollbarTheme::paintTickmarks(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
+{
+    ScrollbarTheme::theme()->paintTickmarks(context, scrollbar, rect);
+}
+
 }
index 9cef394..c14de3f 100644 (file)
@@ -73,6 +73,7 @@ protected:
     virtual void paintTrackPiece(GraphicsContext*, ScrollbarThemeClient*, const IntRect&, ScrollbarPart);
     virtual void paintButton(GraphicsContext*, ScrollbarThemeClient*, const IntRect&, ScrollbarPart);
     virtual void paintThumb(GraphicsContext*, ScrollbarThemeClient*, const IntRect&);
+    virtual void paintTickmarks(GraphicsContext*, ScrollbarThemeClient*, const IntRect&) OVERRIDE;
 
     virtual IntRect constrainTrackRectToTrackPieces(ScrollbarThemeClient*, const IntRect&);
 };
index 93416e1..4d0315e 100644 (file)
@@ -624,6 +624,12 @@ String Internals::markerDescriptionForNode(Node* node, const String& markerType,
     return marker->description();
 }
 
+void Internals::addTextMatchMarker(const Range* range, bool isActive)
+{
+    range->ownerDocument()->updateLayoutIgnorePendingStylesheets();
+    range->ownerDocument()->markers()->addTextMatchMarker(range, isActive);
+}
+
 void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionCode& ec)
 {
     if (!document || !document->view()) {
index 976649f..58fc869 100644 (file)
@@ -117,6 +117,7 @@ public:
     unsigned markerCountForNode(Node*, const String&, ExceptionCode&);
     PassRefPtr<Range> markerRangeForNode(Node*, const String& markerType, unsigned index, ExceptionCode&);
     String markerDescriptionForNode(Node*, const String& markerType, unsigned index, ExceptionCode&);
+    void addTextMatchMarker(const Range*, bool isActive);
 
     void setScrollViewPosition(Document*, long x, long y, ExceptionCode&);
     void setPagination(Document* document, const String& mode, int gap, ExceptionCode& ec) { setPagination(document, mode, gap, 0, ec); }
index ca440e0..d133599 100644 (file)
@@ -86,6 +86,7 @@ module window {
         unsigned long markerCountForNode(in Node node, in DOMString markerType) raises(DOMException);
         Range markerRangeForNode(in Node node, in DOMString markerType, in unsigned long index) raises(DOMException);
         DOMString markerDescriptionForNode(in Node node, in DOMString markerType, in unsigned long index) raises(DOMException);
+        void addTextMatchMarker(in Range range, in boolean isActive);
 
         void setScrollViewPosition(in Document document, in long x, in long y) raises(DOMException);