Tap highlighting: Support better outlines for multiline inlines https://bugs.webkit...
authorkenneth@webkit.org <kenneth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 Jan 2012 14:28:13 +0000 (14:28 +0000)
committerkenneth@webkit.org <kenneth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 Jan 2012 14:28:13 +0000 (14:28 +0000)
Reviewed by Simon Hausmann.

.:

Update the test to use a transform.

* ManualTests/qt/tap-highlighting-inlines.html:

Source/WebCore:

Covered by manual tests.

Do not use the linesBoundingBox anymore but draw a custom path
with rounded corners. Inlines are drawn as max 3 rects, first
line rect, joined middle rect and the rect for the last line.

* page/GestureTapHighlighter.cpp:
* platform/graphics/Path.h: Make addBeziersForRoundedRect public.

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

ChangeLog
ManualTests/qt/tap-highlighting-inlines.html
Source/WebCore/ChangeLog
Source/WebCore/page/GestureTapHighlighter.cpp
Source/WebCore/platform/graphics/Path.h

index 6919734..ef34659 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-01-31  Kenneth Rohde Christiansen  <kenneth@webkit.org>
+
+        Tap highlighting: Support better outlines for multiline inlines
+        https://bugs.webkit.org/show_bug.cgi?id=77428
+
+        Reviewed by Simon Hausmann.
+
+        Update the test to use a transform.
+
+        * ManualTests/qt/tap-highlighting-inlines.html:
+
 2012-01-31  Nayan Kumar K  <nayankk@motorola.com>
 
         [GTK] Remove V8 compilation option.
index c483952..6bb44df 100644 (file)
@@ -1,5 +1,5 @@
 <body>
-    <p style="width: 10em; background-color: gray">
+    <p style="position:absolute; left:100px; top:20px; width: 10em; -webkit-transform: rotate(30deg)">
     <a href="">some link</a><br><br>
     <a href="">some link breaking lines</a><br><br>
     hola mundo! <a href="">a split up link</a><br><br>
index d2a84cb..e0ee870 100644 (file)
@@ -1,3 +1,19 @@
+2012-01-31  Kenneth Rohde Christiansen  <kenneth@webkit.org>
+
+        Tap highlighting: Support better outlines for multiline inlines
+        https://bugs.webkit.org/show_bug.cgi?id=77428
+
+        Reviewed by Simon Hausmann.
+
+        Covered by manual tests.
+
+        Do not use the linesBoundingBox anymore but draw a custom path
+        with rounded corners. Inlines are drawn as max 3 rects, first
+        line rect, joined middle rect and the rect for the last line.
+
+        * page/GestureTapHighlighter.cpp:
+        * platform/graphics/Path.h: Make addBeziersForRoundedRect public.
+
 2012-01-31  Alexei Filippov  <alexeif@chromium.org>
 
         Web Inspector: show sizes in bytes instead of KB, MB in heap profiler.
index 03c66c0..7548abe 100644 (file)
@@ -46,17 +46,17 @@ namespace WebCore {
 
 namespace {
 
-inline LayoutSize ownerFrameToMainFrameOffset(const RenderObject* o)
+inline LayoutPoint ownerFrameToMainFrameOffset(const RenderObject* o)
 {
     ASSERT(o->node());
     Frame* containingFrame = o->frame();
     if (!containingFrame)
-        return LayoutSize();
+        return LayoutPoint();
 
     Frame* mainFrame = containingFrame->page()->mainFrame();
 
     LayoutPoint mainFramePoint = mainFrame->view()->rootViewToContents(containingFrame->view()->contentsToRootView(LayoutPoint()));
-    return toLayoutSize(mainFramePoint);
+    return mainFramePoint;
 }
 
 AffineTransform localToAbsoluteTransform(const RenderObject* o)
@@ -84,6 +84,7 @@ AffineTransform localToAbsoluteTransform(const RenderObject* o)
 Path pathForRenderBox(RenderBox* o)
 {
     ASSERT(o);
+    const int rounding = 4;
 
     LayoutRect contentBox;
     LayoutRect paddingBox;
@@ -102,28 +103,86 @@ Path pathForRenderBox(RenderBox* o)
             paddingBox.height() + o->borderTop() + o->borderBottom());
 
     FloatRect rect(borderBox);
-    rect.inflate(5);
+    rect.inflate(rounding);
 
-    rect.move(ownerFrameToMainFrameOffset(o));
+    rect.move(toLayoutSize(ownerFrameToMainFrameOffset(o)));
 
     Path path;
-    path.addRoundedRect(rect, FloatSize(10, 10));
+    FloatSize rounded(rounding * 1.8, rounding * 1.8);
+    path.addRoundedRect(rect, rounded);
 
     return path;
 }
 
-Path pathForRenderInline(RenderInline* o)
+void addRectWithRoundedCorners(Path& path, const LayoutRect& rect, bool topLeft, bool topRight, bool bottomLeft, bool bottomRight)
 {
-    // FIXME: Adapt this to not just use the bounding box.
-    LayoutRect borderBox = o->linesBoundingBox();
+    const int rounding = 4;
 
-    FloatRect rect(borderBox);
-    rect.inflate(5);
+    FloatRect copy(rect);
+    copy.inflateX(rounding);
+    copy.inflateY(rounding / 2);
 
-    rect.move(ownerFrameToMainFrameOffset(o));
+    FloatSize rounded(rounding * 1.8, rounding * 1.8);
+    FloatSize squared(0, 0);
 
+    path.addBeziersForRoundedRect(copy,
+            topLeft ? rounded : squared, topRight ? rounded : squared,
+            bottomLeft ? rounded : squared, bottomRight ? rounded : squared);
+}
+
+inline bool contains(LayoutRect rect, int x)
+{
+    return !rect.isEmpty() && x >= rect.x() && x <= rect.maxX();
+}
+
+Path pathForRenderInline(RenderInline* o)
+{
+    ASSERT(o);
     Path path;
-    path.addRoundedRect(rect, FloatSize(10, 10));
+
+    Vector<LayoutRect> rects;
+    o->absoluteRects(rects, /* acc. offset */ ownerFrameToMainFrameOffset(o));
+
+    LayoutRect first = rects.size() ? rects.first() : LayoutRect();
+    LayoutRect last = rects.size() > 1 ? rects.last() : LayoutRect();
+    LayoutRect middle;
+    for (int i = 1; i < rects.size() - 1; ++i)
+        middle.uniteIfNonZero(rects.at(i));
+
+    if (!middle.isEmpty()) {
+        int leftSide = middle.x();
+        int rightSide = middle.maxX();
+
+        if (!first.isEmpty()) {
+            leftSide = std::min(leftSide, first.x());
+            rightSide = std::max(rightSide, first.maxX());
+        }
+        if (!last.isEmpty()) {
+            leftSide = std::min(leftSide, last.x());
+            rightSide = std::max(rightSide, last.maxX());
+        }
+
+        middle.setX(leftSide);
+        middle.setWidth(rightSide - leftSide);
+    }
+
+    if (!first.isEmpty()) {
+        bool roundBottomLeft = !contains(middle, first.x()) && !contains(last, first.x());
+        bool roundBottomRight = !contains(middle, first.maxX()) && !contains(last, first.maxX());
+        addRectWithRoundedCorners(path, first, /* roundTopLeft */ true, /* roundTopRight */ true, roundBottomLeft, roundBottomRight);
+    }
+
+    if (!middle.isEmpty()) {
+        bool roundTopLeft = !contains(first, middle.x());
+        bool roundBottomRight = !contains(last, middle.maxX());
+        addRectWithRoundedCorners(path, middle, roundTopLeft, /* roundTopRight */ false, /* roundBottomLeft */ false, roundBottomRight);
+    }
+
+    if (!last.isEmpty()) {
+        bool roundTopLeft = !contains(middle, last.x()) && !contains(first, last.x());
+        bool roundTopRight = !contains(middle, last.maxX()) && !contains(first, last.maxX());
+        addRectWithRoundedCorners(path, last, roundTopLeft, roundTopRight, /* roundBottomLeft */ true, /* roundBottomRight */ true);
+    }
 
     return path;
 }
index d14d908..69ba93e 100644 (file)
@@ -146,9 +146,9 @@ namespace WebCore {
         void apply(void* info, PathApplierFunction) const;
         void transform(const AffineTransform&);
 
-    private:
         void addBeziersForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
 
+    private:
         PlatformPathPtr m_path;
     };