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#pragma once
27
28#include "AffineTransform.h"
29#include "Region.h"
30#include "TouchAction.h"
31#include <wtf/OptionSet.h>
32#include <wtf/Vector.h>
33
34namespace WebCore {
35
36class EventRegion;
37class RenderStyle;
38
39class EventRegionContext {
40public:
41 explicit EventRegionContext(EventRegion&);
42
43 void pushTransform(const AffineTransform&);
44 void popTransform();
45
46 void unite(const Region&, const RenderStyle&);
47 bool contains(const IntRect&) const;
48
49private:
50 EventRegion& m_eventRegion;
51 Vector<AffineTransform> m_transformStack;
52};
53
54class EventRegion {
55public:
56 WEBCORE_EXPORT EventRegion();
57
58 EventRegionContext makeContext() { return EventRegionContext(*this); }
59
60 bool isEmpty() const { return m_region.isEmpty(); }
61
62 WEBCORE_EXPORT bool operator==(const EventRegion&) const;
63
64 WEBCORE_EXPORT void unite(const Region&, const RenderStyle&);
65 WEBCORE_EXPORT void translate(const IntSize&);
66
67 bool contains(const IntPoint& point) const { return m_region.contains(point); }
68 bool contains(const IntRect& rect) const { return m_region.contains(rect); }
69
70#if ENABLE(POINTER_EVENTS)
71 bool hasTouchActions() const { return !m_touchActionRegions.isEmpty(); }
72 WEBCORE_EXPORT OptionSet<TouchAction> touchActionsForPoint(const IntPoint&) const;
73#endif
74
75 template<class Encoder> void encode(Encoder&) const;
76 template<class Decoder> static Optional<EventRegion> decode(Decoder&);
77 // FIXME: Remove legacy decode.
78 template<class Decoder> static bool decode(Decoder&, EventRegion&);
79
80private:
81#if ENABLE(POINTER_EVENTS)
82 void uniteTouchActions(const Region&, OptionSet<TouchAction>);
83#endif
84 friend TextStream& operator<<(TextStream&, const EventRegion&);
85
86 Region m_region;
87#if ENABLE(POINTER_EVENTS)
88 Vector<Region> m_touchActionRegions;
89#endif
90};
91
92TextStream& operator<<(TextStream&, const EventRegion&);
93
94template<class Encoder>
95void EventRegion::encode(Encoder& encoder) const
96{
97 encoder << m_region;
98#if ENABLE(POINTER_EVENTS)
99 encoder << m_touchActionRegions;
100#endif
101}
102
103template<class Decoder>
104Optional<EventRegion> EventRegion::decode(Decoder& decoder)
105{
106 Optional<Region> region;
107 decoder >> region;
108 if (!region)
109 return WTF::nullopt;
110
111 EventRegion eventRegion;
112 eventRegion.m_region = WTFMove(*region);
113
114#if ENABLE(POINTER_EVENTS)
115 Optional<Vector<Region>> touchActionRegions;
116 decoder >> touchActionRegions;
117 if (!touchActionRegions)
118 return WTF::nullopt;
119
120 eventRegion.m_touchActionRegions = WTFMove(*touchActionRegions);
121#endif
122
123 return eventRegion;
124}
125
126template<class Decoder>
127bool EventRegion::decode(Decoder& decoder, EventRegion& eventRegion)
128{
129 Optional<EventRegion> decodedEventRegion;
130 decoder >> decodedEventRegion;
131 if (!decodedEventRegion)
132 return false;
133 eventRegion = WTFMove(*decodedEventRegion);
134 return true;
135}
136
137}
138