Example #1
0
HitRegion* HitRegionManager::getHitRegionAtPoint(
    const FloatPoint& point) const {
  HitRegionIterator itEnd = m_hitRegionList.rend();

  for (HitRegionIterator it = m_hitRegionList.rbegin(); it != itEnd; ++it) {
    HitRegion* hitRegion = *it;
    if (hitRegion->contains(point))
      return hitRegion;
  }

  return nullptr;
}
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);
}
Example #3
0
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());
}
HitTestCanvasResult* CanvasRenderingContext2D::getControlAndIdIfHitRegionExists(
    const LayoutPoint& location) {
  if (hitRegionsCount() <= 0)
    return HitTestCanvasResult::create(String(), nullptr);

  LayoutBox* box = canvas()->layoutBox();
  FloatPoint localPos =
      box->absoluteToLocal(FloatPoint(location), UseTransforms);
  if (box->hasBorderOrPadding())
    localPos.move(-box->contentBoxOffset());
  localPos.scale(canvas()->width() / box->contentWidth(),
                 canvas()->height() / box->contentHeight());

  HitRegion* hitRegion = hitRegionAtPoint(localPos);
  if (hitRegion) {
    Element* control = hitRegion->control();
    if (control && canvas()->isSupportedInteractiveCanvasFallback(*control))
      return HitTestCanvasResult::create(hitRegion->id(), hitRegion->control());
    return HitTestCanvasResult::create(hitRegion->id(), nullptr);
  }
  return HitTestCanvasResult::create(String(), nullptr);
}