03c66c08fcda24bde9b62590747af217503e99c5
[WebKit-https.git] / Source / WebCore / page / GestureTapHighlighter.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "GestureTapHighlighter.h"
32
33 #include "Element.h"
34 #include "Frame.h"
35 #include "FrameView.h"
36 #include "GraphicsContext.h"
37 #include "GraphicsTypes.h"
38 #include "Node.h"
39 #include "Page.h"
40 #include "RenderBoxModelObject.h"
41 #include "RenderInline.h"
42 #include "RenderLayer.h"
43 #include "RenderObject.h"
44
45 namespace WebCore {
46
47 namespace {
48
49 inline LayoutSize ownerFrameToMainFrameOffset(const RenderObject* o)
50 {
51     ASSERT(o->node());
52     Frame* containingFrame = o->frame();
53     if (!containingFrame)
54         return LayoutSize();
55
56     Frame* mainFrame = containingFrame->page()->mainFrame();
57
58     LayoutPoint mainFramePoint = mainFrame->view()->rootViewToContents(containingFrame->view()->contentsToRootView(LayoutPoint()));
59     return toLayoutSize(mainFramePoint);
60 }
61
62 AffineTransform localToAbsoluteTransform(const RenderObject* o)
63 {
64     AffineTransform transform;
65     LayoutPoint referencePoint;
66
67     while (o) {
68         RenderObject* nextContainer = o->container();
69         if (!nextContainer)
70             break;
71
72         LayoutSize containerOffset = o->offsetFromContainer(nextContainer, referencePoint);
73         TransformationMatrix t;
74         o->getTransformFromContainer(nextContainer, containerOffset, t);
75
76         transform = t.toAffineTransform() * transform;
77         referencePoint.move(containerOffset);
78         o = nextContainer;
79     }
80
81     return transform;
82 }
83
84 Path pathForRenderBox(RenderBox* o)
85 {
86     ASSERT(o);
87
88     LayoutRect contentBox;
89     LayoutRect paddingBox;
90     LayoutRect borderBox;
91
92     contentBox = o->contentBoxRect();
93     paddingBox = LayoutRect(
94             contentBox.x() - o->paddingLeft(),
95             contentBox.y() - o->paddingTop(),
96             contentBox.width() + o->paddingLeft() + o->paddingRight(),
97             contentBox.height() + o->paddingTop() + o->paddingBottom());
98     borderBox = LayoutRect(
99             paddingBox.x() - o->borderLeft(),
100             paddingBox.y() - o->borderTop(),
101             paddingBox.width() + o->borderLeft() + o->borderRight(),
102             paddingBox.height() + o->borderTop() + o->borderBottom());
103
104     FloatRect rect(borderBox);
105     rect.inflate(5);
106
107     rect.move(ownerFrameToMainFrameOffset(o));
108
109     Path path;
110     path.addRoundedRect(rect, FloatSize(10, 10));
111
112     return path;
113 }
114
115 Path pathForRenderInline(RenderInline* o)
116 {
117     // FIXME: Adapt this to not just use the bounding box.
118     LayoutRect borderBox = o->linesBoundingBox();
119
120     FloatRect rect(borderBox);
121     rect.inflate(5);
122
123     rect.move(ownerFrameToMainFrameOffset(o));
124
125     Path path;
126     path.addRoundedRect(rect, FloatSize(10, 10));
127
128     return path;
129 }
130
131 } // anonymous namespace
132
133 namespace GestureTapHighlighter {
134
135 Path pathForNodeHighlight(const Node* node)
136 {
137     RenderObject* renderer = node->renderer();
138
139     Path path;
140     if (!renderer || (!renderer->isBox() && !renderer->isRenderInline()))
141         return path;
142
143     if (renderer->isBox())
144         path = pathForRenderBox(toRenderBox(renderer));
145     else
146         path = pathForRenderInline(toRenderInline(renderer));
147
148     path.transform(localToAbsoluteTransform(renderer));
149     return path;
150 }
151
152 } // namespace GestureTapHighlighter
153
154 } // namespace WebCore