void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions& options, ExceptionState& exceptionState) { if (options.id().isEmpty() && !options.control()) { exceptionState.throwDOMException(NotSupportedError, "Both id and control are null."); return; } if (options.control() && !canvas()->isSupportedInteractiveCanvasFallback(*options.control())) { exceptionState.throwDOMException(NotSupportedError, "The control is neither null nor a " "supported interactive canvas fallback " "element."); return; } Path hitRegionPath = options.hasPath() ? options.path()->path() : m_path; SkCanvas* c = drawingCanvas(); if (hitRegionPath.isEmpty() || !c || !state().isTransformInvertible() || !c->getClipDeviceBounds(0)) { exceptionState.throwDOMException(NotSupportedError, "The specified path has no pixels."); return; } hitRegionPath.transform(state().transform()); if (state().hasClip()) { hitRegionPath.intersectPath(state().getCurrentClipPath()); if (hitRegionPath.isEmpty()) exceptionState.throwDOMException(NotSupportedError, "The specified path has no pixels."); } if (!m_hitRegionManager) m_hitRegionManager = HitRegionManager::create(); // Remove previous region (with id or control) m_hitRegionManager->removeHitRegionById(options.id()); m_hitRegionManager->removeHitRegionByControl(options.control()); HitRegion* hitRegion = HitRegion::create(hitRegionPath, options); Element* element = hitRegion->control(); if (element && element->isDescendantOf(canvas())) updateElementAccessibility(hitRegion->path(), hitRegion->control()); m_hitRegionManager->addHitRegion(hitRegion); }
void HitRegionManager::removeHitRegionsInRect(const FloatRect& rect, const AffineTransform& ctm) { Path clearArea; clearArea.addRect(rect); clearArea.transform(ctm); HitRegionIterator itEnd = m_hitRegionList.rend(); HitRegionList toBeRemoved; for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) { HitRegion* hitRegion = *it; hitRegion->removePixels(clearArea); if (hitRegion->path().isEmpty()) toBeRemoved.add(hitRegion); } itEnd = toBeRemoved.rend(); for (HitRegionIterator it = toBeRemoved.rbegin(); it != itEnd; ++it) removeHitRegion(it->get()); }