| Index: Source/core/html/canvas/HitRegion.cpp
|
| diff --git a/Source/core/html/canvas/HitRegion.cpp b/Source/core/html/canvas/HitRegion.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c6a1608d300f761773ab0e44f6fccc7f94a308ba
|
| --- /dev/null
|
| +++ b/Source/core/html/canvas/HitRegion.cpp
|
| @@ -0,0 +1,162 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "config.h"
|
| +#include "core/html/canvas/HitRegion.h"
|
| +
|
| +#include "core/accessibility/AXObjectCache.h"
|
| +#include "core/rendering/RenderBoxModelObject.h"
|
| +
|
| +namespace WebCore {
|
| +
|
| +HitRegion::HitRegion(const HitRegionOptions& options)
|
| + : m_id(options.id)
|
| + , m_control(options.control)
|
| + , m_path(options.path)
|
| +{
|
| +}
|
| +
|
| +void HitRegion::updateAccessibility(Element* canvas)
|
| +{
|
| + if (!m_control || !canvas || !canvas->renderer() || !m_control->isDescendantOf(canvas))
|
| + return;
|
| +
|
| + AXObjectCache* axObjectCache = m_control->document().existingAXObjectCache();
|
| + if (!axObjectCache)
|
| + return;
|
| +
|
| + FloatRect boundingRect = m_path.boundingRect();
|
| +
|
| + // Offset by the canvas rect, taking border and padding into account.
|
| + RenderBoxModelObject* rbmo = canvas->renderBoxModelObject();
|
| + IntRect canvasRect = canvas->renderer()->absoluteBoundingBoxRect();
|
| + canvasRect.move(rbmo->borderLeft() + rbmo->paddingLeft(),
|
| + rbmo->borderTop() + rbmo->paddingTop());
|
| + LayoutRect elementRect = enclosingLayoutRect(boundingRect);
|
| + elementRect.moveBy(canvasRect.location());
|
| +
|
| + axObjectCache->setCanvasObjectBounds(m_control.get(), elementRect);
|
| +}
|
| +
|
| +bool HitRegion::contains(const LayoutPoint& point) const
|
| +{
|
| + if (!m_path.boundingRect().contains(point))
|
| + return false;
|
| +
|
| + return m_path.contains(point, RULE_NONZERO);
|
| +}
|
| +
|
| +void HitRegion::removePixels(const Path& clearArea)
|
| +{
|
| + m_path.subtractPath(clearArea);
|
| +}
|
| +
|
| +void HitRegion::trace(Visitor* visitor)
|
| +{
|
| +#if ENABLE(OILPAN)
|
| + visitor->trace(m_control);
|
| +#endif
|
| +}
|
| +
|
| +void HitRegionManager::addHitRegion(PassRefPtrWillBeRawPtr<HitRegion> passHitRegion)
|
| +{
|
| + RefPtrWillBeRawPtr<HitRegion> hitRegion = passHitRegion;
|
| +
|
| + m_hitRegionList.add(hitRegion);
|
| +
|
| + if (!hitRegion->id().isEmpty())
|
| + m_hitRegionIdMap.set(hitRegion->id(), hitRegion);
|
| +
|
| + if (hitRegion->control())
|
| + m_hitRegionControlMap.set(hitRegion->control(), hitRegion);
|
| +}
|
| +
|
| +void HitRegionManager::removeHitRegion(HitRegion* hitRegion)
|
| +{
|
| + if (!hitRegion)
|
| + return;
|
| +
|
| + if (!hitRegion->id().isEmpty())
|
| + m_hitRegionIdMap.remove(hitRegion->id());
|
| +
|
| + if (hitRegion->control())
|
| + m_hitRegionControlMap.remove(hitRegion->control());
|
| +
|
| + m_hitRegionList.remove(hitRegion);
|
| +}
|
| +
|
| +void HitRegionManager::removeHitRegionById(const String& id)
|
| +{
|
| + if (!id.isEmpty())
|
| + removeHitRegion(getHitRegionById(id));
|
| +}
|
| +
|
| +void HitRegionManager::removeHitRegionByControl(Element* control)
|
| +{
|
| + removeHitRegion(getHitRegionByControl(control));
|
| +}
|
| +
|
| +void HitRegionManager::removeHitRegionsInRect(const FloatRect& rect, const AffineTransform& ctm)
|
| +{
|
| + Path clearArea;
|
| + clearArea.addRect(rect);
|
| + clearArea.transform(ctm);
|
| +
|
| + HitRegionIterator itEnd = m_hitRegionList.rend();
|
| +
|
| + for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) {
|
| + RefPtrWillBeRawPtr<HitRegion> hitRegion = *it;
|
| + hitRegion->removePixels(clearArea);
|
| + if (hitRegion->path().isEmpty())
|
| + removeHitRegion(hitRegion.get());
|
| + }
|
| +}
|
| +
|
| +void HitRegionManager::removeAllHitRegions()
|
| +{
|
| + m_hitRegionList.clear();
|
| + m_hitRegionIdMap.clear();
|
| +}
|
| +
|
| +HitRegion* HitRegionManager::getHitRegionById(const String& id) const
|
| +{
|
| + return m_hitRegionIdMap.get(id);
|
| +}
|
| +
|
| +HitRegion* HitRegionManager::getHitRegionByControl(Element* control) const
|
| +{
|
| + if (control)
|
| + return m_hitRegionControlMap.get(control);
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +HitRegion* HitRegionManager::getHitRegionAtPoint(const LayoutPoint& point) const
|
| +{
|
| + HitRegionIterator itEnd = m_hitRegionList.rend();
|
| +
|
| + for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) {
|
| + RefPtrWillBeRawPtr<HitRegion> hitRegion = *it;
|
| + if (hitRegion->contains(point))
|
| + return hitRegion.get();
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +unsigned HitRegionManager::getHitRegionsCount() const
|
| +{
|
| + return m_hitRegionList.size();
|
| +}
|
| +
|
| +void HitRegionManager::trace(Visitor* visitor)
|
| +{
|
| +#if ENABLE(OILPAN)
|
| + visitor->trace(m_hitRegionList);
|
| + visitor->trace(m_hitRegionIdMap);
|
| + visitor->trace(m_hitRegionControlMap);
|
| +#endif
|
| +}
|
| +
|
| +} // namespace WebCore
|
|
|