Chromium Code Reviews| 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 |