Combine event and touch action regions into a single class
[WebKit-https.git] / Source / WebCore / rendering / EventRegion.cpp
1 /*
2  * Copyright (C) 2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "EventRegion.h"
28
29 #include "RenderStyle.h"
30
31 namespace WebCore {
32
33 EventRegion::EventRegion() = default;
34
35 bool EventRegion::operator==(const EventRegion& other) const
36 {
37 #if ENABLE(POINTER_EVENTS)
38     if (m_touchActionRegions != other.m_touchActionRegions)
39         return false;
40 #endif
41     return m_region == other.m_region;
42 }
43
44 void EventRegion::unite(const Region& region, const RenderStyle& style)
45 {
46     m_region.unite(region);
47
48 #if ENABLE(POINTER_EVENTS)
49     uniteTouchActions(region, style.effectiveTouchActions());
50 #else
51     UNUSED_PARAM(style);
52 #endif
53 }
54
55 void EventRegion::translate(const IntSize& offset)
56 {
57     m_region.translate(offset);
58
59 #if ENABLE(POINTER_EVENTS)
60     for (auto& touchActionRegion : m_touchActionRegions)
61         touchActionRegion.translate(offset);
62 #endif
63 }
64
65 #if ENABLE(POINTER_EVENTS)
66
67 constexpr unsigned toIndex(TouchAction touchAction)
68 {
69     switch (touchAction) {
70     case TouchAction::None:
71         return 0;
72     case TouchAction::Manipulation:
73         return 1;
74     case TouchAction::PanX:
75         return 2;
76     case TouchAction::PanY:
77         return 3;
78     case TouchAction::PinchZoom:
79         return 4;
80     case TouchAction::Auto:
81         break;
82     }
83     ASSERT_NOT_REACHED();
84     return 0;
85 }
86
87 constexpr TouchAction toTouchAction(unsigned index)
88 {
89     switch (index) {
90     case 0:
91         return TouchAction::None;
92     case 1:
93         return TouchAction::Manipulation;
94     case 2:
95         return TouchAction::PanX;
96     case 3:
97         return TouchAction::PanY;
98     case 4:
99         return TouchAction::PinchZoom;
100     default:
101         break;
102     }
103     ASSERT_NOT_REACHED();
104     return TouchAction::Auto;
105 }
106
107 void EventRegion::uniteTouchActions(const Region& touchRegion, OptionSet<TouchAction> touchActions)
108 {
109     for (auto touchAction : touchActions) {
110         if (touchAction == TouchAction::Auto)
111             break;
112         auto index = toIndex(touchAction);
113         if (m_touchActionRegions.size() < index + 1)
114             m_touchActionRegions.grow(index + 1);
115     }
116
117     for (unsigned i = 0; i < m_touchActionRegions.size(); ++i) {
118         auto regionTouchAction = toTouchAction(i);
119         if (touchActions.contains(regionTouchAction))
120             m_touchActionRegions[i].unite(touchRegion);
121         else
122             m_touchActionRegions[i].subtract(touchRegion);
123     }
124 }
125
126 OptionSet<TouchAction> EventRegion::touchActionsForPoint(const IntPoint& point) const
127 {
128     OptionSet<TouchAction> actions;
129
130     for (unsigned i = 0; i < m_touchActionRegions.size(); ++i) {
131         if (m_touchActionRegions[i].contains(point)) {
132             auto action = toTouchAction(i);
133             actions.add(action);
134             if (action == TouchAction::None || action == TouchAction::Manipulation)
135                 break;
136         }
137     }
138
139     return actions;
140 }
141
142 TextStream& operator<<(TextStream& ts, TouchAction touchAction)
143 {
144     switch (touchAction) {
145     case TouchAction::None:
146         return ts << "none";
147     case TouchAction::Manipulation:
148         return ts << "manipulation";
149     case TouchAction::PanX:
150         return ts << "pan-x";
151     case TouchAction::PanY:
152         return ts << "pan-y";
153     case TouchAction::PinchZoom:
154         return ts << "pinch-zoom";
155     case TouchAction::Auto:
156         return ts << "auto";
157     }
158     ASSERT_NOT_REACHED();
159     return ts;
160 }
161
162 #endif
163
164 TextStream& operator<<(TextStream& ts, const EventRegion& eventRegion)
165 {
166     ts << eventRegion.m_region;
167
168 #if ENABLE(POINTER_EVENTS)
169     if (!eventRegion.m_touchActionRegions.isEmpty()) {
170         TextStream::IndentScope indentScope(ts);
171         ts << indent << "(touch-action\n";
172         for (unsigned i = 0; i < eventRegion.m_touchActionRegions.size(); ++i) {
173             if (eventRegion.m_touchActionRegions[i].isEmpty())
174                 continue;
175             TextStream::IndentScope indentScope(ts);
176             ts << indent << "(" << toTouchAction(i);
177             ts << indent << eventRegion.m_touchActionRegions[i];
178             ts << indent << ")\n";
179         }
180         ts << indent << ")\n";
181     }
182 #endif
183
184     return ts;
185 }
186
187 }