bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
{
    FloatPoint point = nodeAtPoint;
    if (!SVGRenderSupport::pointInClippingArea(*this, point))
        return false;

    if (clipPathElement().clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        AffineTransform transform;
        transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
        transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
        point = transform.inverse().valueOr(AffineTransform()).mapPoint(point);
    }

    point = clipPathElement().animatedLocalTransform().inverse().valueOr(AffineTransform()).mapPoint(point);

    for (Node* childNode = clipPathElement().firstChild(); childNode; childNode = childNode->nextSibling()) {
        RenderObject* renderer = childNode->renderer();
        if (!childNode->isSVGElement() || !renderer)
            continue;
        if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
            continue;
        IntPoint hitPoint;
        HitTestResult result(hitPoint);
        if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent | HitTestRequest::DisallowUserAgentShadowContent), result, point, HitTestForeground))
            return true;
    }

    return false;
}
示例#2
0
bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
{
    FloatPoint point = nodeAtPoint;
    if (!SVGRenderSupport::pointInClippingArea(this, point))
        return false;

    if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        AffineTransform transform;
        transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
        transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
        point = transform.inverse().mapPoint(point);
    }

    for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
        RenderObject* renderer = childNode->renderer();
        if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
            continue;
        if (!renderer->isSVGPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer())
            continue;
        IntPoint hitPoint;
        HitTestResult result(hitPoint);
        if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent), result, point, HitTestForeground))
            return true;
    }

    return false;
}
示例#3
0
TEST_F(ChromeClientTest, SetToolTipFlood) {
  ChromeClientToolTipLogger logger;
  ChromeClient* client = &logger;
  HitTestResult result(HitTestRequest(HitTestRequest::Move),
                       LayoutPoint(10, 20));
  Document* doc = Document::create();
  Element* element = HTMLElement::create(HTMLNames::divTag, *doc);
  element->setAttribute(HTMLNames::titleAttr, "tooltip");
  result.setInnerNode(element);

  client->setToolTip(*doc->frame(), result);
  EXPECT_EQ("tooltip", logger.toolTipForLastSetToolTip());

  // seToolTip(HitTestResult) again in the same condition.
  logger.clearToolTipForLastSetToolTip();
  client->setToolTip(*doc->frame(), result);
  // setToolTip(String,TextDirection) should not be called.
  EXPECT_EQ(String(), logger.toolTipForLastSetToolTip());

  // Cancel the tooltip, and setToolTip(HitTestResult) again.
  client->clearToolTip(*doc->frame());
  logger.clearToolTipForLastSetToolTip();
  client->setToolTip(*doc->frame(), result);
  // setToolTip(String,TextDirection) should not be called.
  EXPECT_EQ(String(), logger.toolTipForLastSetToolTip());

  logger.clearToolTipForLastSetToolTip();
  element->setAttribute(HTMLNames::titleAttr, "updated");
  client->setToolTip(*doc->frame(), result);
  // setToolTip(String,TextDirection) should be called because tooltip string
  // is different from the last one.
  EXPECT_EQ("updated", logger.toolTipForLastSetToolTip());
}
bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
{
    FloatPoint point = nodeAtPoint;
    if (!SVGRenderSupport::pointInClippingArea(this, point))
        return false;

    if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        AffineTransform transform;
        transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
        transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
        point = transform.inverse().mapPoint(point);
    }

    AffineTransform animatedLocalTransform = toSVGClipPathElement(element())->animatedLocalTransform();
    if (!animatedLocalTransform.isInvertible())
        return false;

    point = animatedLocalTransform.inverse().mapPoint(point);

    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
        RenderObject* renderer = childElement->renderer();
        if (!renderer)
            continue;
        if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement))
            continue;
        IntPoint hitPoint;
        HitTestResult result(hitPoint);
        if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent), result, point, HitTestForeground))
            return true;
    }

    return false;
}
示例#5
0
HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point)
{
    HitTestResult result(point);
    if (!m_frame.contentRenderer())
        return result;
    m_frame.contentRenderer()->hitTest(HitTestRequest(HitTestRequest::ReadOnly), result);
    return result;
}