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.
6 #include "core/html/canvas/HitRegion.h"
8 #include "core/accessibility/AXObjectCache.h"
9 #include "core/rendering/RenderBoxModelObject.h"
13 HitRegion::HitRegion(const HitRegionOptions& options)
15 , m_control(options.control)
16 , m_path(options.path)
17 , m_fillRule(options.fillRule)
21 void HitRegion::updateAccessibility(Element* canvas)
23 if (!m_control || !canvas || !canvas->renderer() || !m_control->isDescendantOf(canvas))
26 AXObjectCache* axObjectCache = m_control->document().existingAXObjectCache();
30 FloatRect boundingRect = m_path.boundingRect();
32 // Offset by the canvas rect, taking border and padding into account.
33 RenderBoxModelObject* rbmo = canvas->renderBoxModelObject();
34 IntRect canvasRect = canvas->renderer()->absoluteBoundingBoxRect();
35 canvasRect.move(rbmo->borderLeft() + rbmo->paddingLeft(),
36 rbmo->borderTop() + rbmo->paddingTop());
37 LayoutRect elementRect = enclosingLayoutRect(boundingRect);
38 elementRect.moveBy(canvasRect.location());
40 axObjectCache->setCanvasObjectBounds(m_control.get(), elementRect);
43 bool HitRegion::contains(const LayoutPoint& point) const
45 return m_path.contains(point, m_fillRule);
48 void HitRegion::removePixels(const Path& clearArea)
50 m_path.subtractPath(clearArea);
53 void HitRegion::trace(Visitor* visitor)
55 visitor->trace(m_control);
58 void HitRegionManager::addHitRegion(PassRefPtrWillBeRawPtr<HitRegion> passHitRegion)
60 RefPtrWillBeRawPtr<HitRegion> hitRegion = passHitRegion;
62 m_hitRegionList.add(hitRegion);
64 if (!hitRegion->id().isEmpty())
65 m_hitRegionIdMap.set(hitRegion->id(), hitRegion);
67 if (hitRegion->control())
68 m_hitRegionControlMap.set(hitRegion->control(), hitRegion);
71 void HitRegionManager::removeHitRegion(HitRegion* hitRegion)
76 if (!hitRegion->id().isEmpty())
77 m_hitRegionIdMap.remove(hitRegion->id());
79 if (hitRegion->control())
80 m_hitRegionControlMap.remove(hitRegion->control());
82 m_hitRegionList.remove(hitRegion);
85 void HitRegionManager::removeHitRegionById(const String& id)
88 removeHitRegion(getHitRegionById(id));
91 void HitRegionManager::removeHitRegionByControl(Element* control)
93 removeHitRegion(getHitRegionByControl(control));
96 void HitRegionManager::removeHitRegionsInRect(const FloatRect& rect, const AffineTransform& ctm)
99 clearArea.addRect(rect);
100 clearArea.transform(ctm);
102 HitRegionIterator itEnd = m_hitRegionList.rend();
103 HitRegionList toBeRemoved;
105 for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) {
106 RefPtrWillBeRawPtr<HitRegion> hitRegion = *it;
107 hitRegion->removePixels(clearArea);
108 if (hitRegion->path().isEmpty())
109 toBeRemoved.add(hitRegion);
112 itEnd = toBeRemoved.rend();
113 for (HitRegionIterator it = toBeRemoved.rbegin(); it != itEnd; ++it)
114 removeHitRegion(it->get());
117 void HitRegionManager::removeAllHitRegions()
119 m_hitRegionList.clear();
120 m_hitRegionIdMap.clear();
121 m_hitRegionControlMap.clear();
124 HitRegion* HitRegionManager::getHitRegionById(const String& id) const
126 return m_hitRegionIdMap.get(id);
129 HitRegion* HitRegionManager::getHitRegionByControl(Element* control) const
132 return m_hitRegionControlMap.get(control);
137 HitRegion* HitRegionManager::getHitRegionAtPoint(const LayoutPoint& point) const
139 HitRegionIterator itEnd = m_hitRegionList.rend();
141 for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) {
142 RefPtrWillBeRawPtr<HitRegion> hitRegion = *it;
143 if (hitRegion->contains(point))
144 return hitRegion.get();
150 unsigned HitRegionManager::getHitRegionsCount() const
152 return m_hitRegionList.size();
155 void HitRegionManager::trace(Visitor* visitor)
158 visitor->trace(m_hitRegionList);
159 visitor->trace(m_hitRegionIdMap);
160 visitor->trace(m_hitRegionControlMap);
164 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(HitRegionManager)