OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/html/canvas/HitRegion.h" | |
7 | |
8 #include "core/accessibility/AXObject.h" | |
9 #include "core/accessibility/AXObjectCache.h" | |
10 | |
11 namespace WebCore { | |
12 | |
13 HitRegion::HitRegion(const HitRegionOptions& options) | |
14 : m_id(options.id) | |
15 , m_control(options.control) | |
16 , m_path(options.path) | |
17 { | |
18 } | |
19 | |
20 void HitRegion::updateAccessibility(Element* canvas) | |
21 { | |
22 if (!m_control || !canvas || !canvas->renderer() || !m_control->isDescendant Of(canvas)) | |
23 return; | |
24 | |
25 if (AXObjectCache* axObjectCache = m_control->document().existingAXObjectCac he()) { | |
26 if (AXObject* obj = axObjectCache->getOrCreate(m_control.get())) { | |
dmazzoni
2014/06/03 17:26:10
Let's move some of this logic to a new function on
zino
2014/06/08 08:39:49
Done.
| |
27 LayoutRect elementRect = LayoutRect(m_path.boundingRect()); | |
28 | |
29 IntRect canvasRect = canvas->renderer()->absoluteBoundingBoxRect(); | |
30 elementRect.moveBy(canvasRect.location()); | |
31 obj->setElementRect(elementRect); | |
32 | |
33 obj = obj->parentObject(); | |
34 while (obj && obj->node() != canvas) { | |
35 obj->setElementRect(elementRect); | |
fs
2014/06/03 11:47:01
This might be better answered by dmazzoni, but thi
dmazzoni
2014/06/03 17:26:10
Ideally it seems like we'd want container element
fs
2014/06/04 08:13:40
Computing on-demand SGTM.
zino
2014/06/08 08:39:49
Done.
| |
36 obj = obj->parentObject(); | |
37 } | |
38 } | |
39 } | |
40 } | |
41 | |
42 bool HitRegion::contains(const LayoutPoint& point) const | |
43 { | |
44 // FIXME: We should avoid following boundingRect test if fillRule is evenodd . | |
fs
2014/06/03 11:47:01
Why? AFAICT this broad-phase check is equally good
zino
2014/06/06 06:35:16
You're right.
Done.
| |
45 if (!m_path.boundingRect().contains(point)) | |
46 return false; | |
47 | |
48 return m_path.contains(point, RULE_NONZERO); | |
49 } | |
50 | |
51 void HitRegion::removePixels(const Path& clearArea) | |
52 { | |
53 m_path.subtractPath(clearArea); | |
54 } | |
55 | |
56 void HitRegionManager::addHitRegion(PassRefPtrWillBeRawPtr<HitRegion> passHitReg ion) | |
57 { | |
58 RefPtrWillBeRawPtr<HitRegion> hitRegion = passHitRegion; | |
59 | |
60 m_hitRegionList.add(hitRegion); | |
61 | |
62 if (!hitRegion->id().isEmpty()) | |
63 m_hitRegionIdMap.set(hitRegion->id(), hitRegion); | |
64 | |
65 if (hitRegion->control()) | |
66 m_hitRegionControlMap.set(hitRegion->control(), hitRegion); | |
67 } | |
68 | |
69 void HitRegionManager::removeHitRegion(HitRegion* hitRegion) | |
70 { | |
71 if (!hitRegion) | |
72 return; | |
73 | |
74 if (!hitRegion->id().isEmpty()) | |
75 m_hitRegionIdMap.remove(hitRegion->id()); | |
76 | |
77 if (hitRegion->control()) | |
78 m_hitRegionControlMap.remove(hitRegion->control()); | |
79 | |
80 m_hitRegionList.remove(hitRegion); | |
81 } | |
82 | |
83 void HitRegionManager::removeHitRegionById(const String& id) | |
84 { | |
85 if (!id.isEmpty()) | |
86 removeHitRegion(getHitRegionById(id)); | |
87 } | |
88 | |
89 void HitRegionManager::removeHitRegionByControl(const Element* control) | |
90 { | |
91 removeHitRegion(getHitRegionByControl(control)); | |
92 } | |
93 | |
94 void HitRegionManager::removeHitRegionsInRect(const FloatRect& rect, const Affin eTransform& ctm) | |
95 { | |
96 Path clearArea; | |
97 clearArea.addRect(rect); | |
98 clearArea.transform(ctm); | |
99 | |
100 HitRegionIterator itEnd = m_hitRegionList.rend(); | |
101 | |
102 for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) { | |
103 RefPtrWillBeRawPtr<HitRegion> hitRegion = *it; | |
104 hitRegion->removePixels(clearArea); | |
105 if (hitRegion->path().isEmpty()) | |
106 removeHitRegion(hitRegion.get()); | |
107 } | |
108 } | |
109 | |
110 void HitRegionManager::removeAllHitRegions() | |
111 { | |
112 m_hitRegionList.clear(); | |
113 m_hitRegionIdMap.clear(); | |
114 } | |
115 | |
116 HitRegion* HitRegionManager::getHitRegionById(const String& id) const | |
117 { | |
118 return m_hitRegionIdMap.get(id); | |
119 } | |
120 | |
121 HitRegion* HitRegionManager::getHitRegionByControl(const Element* control) const | |
122 { | |
123 if (control) | |
124 return m_hitRegionControlMap.get(control); | |
125 | |
126 return 0; | |
127 } | |
128 | |
129 HitRegion* HitRegionManager::getHitRegionAtPoint(const LayoutPoint& point) const | |
130 { | |
131 HitRegionIterator itEnd = m_hitRegionList.rend(); | |
132 | |
133 for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) { | |
134 RefPtrWillBeRawPtr<HitRegion> hitRegion = *it; | |
135 if (hitRegion->contains(point)) | |
136 return hitRegion.get(); | |
137 } | |
138 | |
139 return 0; | |
140 } | |
141 | |
142 unsigned HitRegionManager::getHitRegionsCount() const | |
143 { | |
144 return m_hitRegionList.size(); | |
145 } | |
146 | |
147 } // namespace WebCore | |
OLD | NEW |