void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
{
    Document* document = this->document();

    if (document->printing() || !document->frame()->selection()->isFocusedAndActive())
        return;

    if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
        return;

    Element* focusedElement = document->focusedElement();
    if (!focusedElement || !isHTMLAreaElement(focusedElement))
        return;

    HTMLAreaElement* areaElement = toHTMLAreaElement(focusedElement);
    if (areaElement->imageElement() != node())
        return;

    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
    // an area within an image, so we don't call RenderTheme::supportsFocusRing here.

    Path path = areaElement->computePath(this);
    if (path.isEmpty())
        return;

    RenderStyle* areaElementStyle = areaElement->computedStyle();
    unsigned short outlineWidth = areaElementStyle->outlineWidth();
    if (!outlineWidth)
        return;

    // FIXME: Clip path instead of context when Skia pathops is ready.
    // https://crbug.com/251206
    GraphicsContextStateSaver savedContext(*paintInfo.context);
    paintInfo.context->clip(absoluteContentBox());
    paintInfo.context->drawFocusRing(path, outlineWidth,
        areaElementStyle->outlineOffset(),
        resolveColor(areaElementStyle, CSSPropertyOutlineColor));
}
Esempio n. 2
0
void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
{
    Document* document = this->document();
    
    if (document->printing() || !document->frame()->selection()->isFocusedAndActive())
        return;
    
    if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
        return;

    Node* focusedNode = document->focusedNode();
    if (!focusedNode || !focusedNode->hasTagName(areaTag))
        return;

    HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(focusedNode);
    if (areaElement->imageElement() != node())
        return;

    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
    // an area within an image, so we don't call RenderTheme::supportsFocusRing here.

    Path path = areaElement->computePath(this);
    if (path.isEmpty())
        return;

    // FIXME: Do we need additional code to clip the path to the image's bounding box?

    RenderStyle* areaElementStyle = areaElement->computedStyle();
    unsigned short outlineWidth = areaElementStyle->outlineWidth();
    if (!outlineWidth)
        return;

    paintInfo.context->drawFocusRing(path, outlineWidth,
        areaElementStyle->outlineOffset(),
        areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor));
}
Esempio n. 3
0
void RenderImage::readyWRATHWidgetAreaElementFocusRing(PaintedWidgetsOfWRATHHandle& handle, PaintInfoOfWRATH& paintInfo)
{
    RenderImage_ReadyWRATHWidgetAreaElementFocusRing *d(RenderImage_ReadyWRATHWidgetAreaElementFocusRing::object(this, handle));
    ContextOfWRATH::AutoPushNode autoPushRoot(paintInfo.wrath_context, d->m_root_node);

    if (d->m_focus_ring.widget())
        d->m_focus_ring.widget()->visible(false);

    Document* document = this->document();

    if (document->printing() || !document->frame()->selection()->isFocusedAndActive())
        return;

    /*
    if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
        return;
    */

    Node* focusedNode = document->focusedNode();
    if (!focusedNode || !focusedNode->hasTagName(areaTag))
        return;

    HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(focusedNode);
    if (areaElement->imageElement() != node())
        return;

    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
    // an area within an image, so we don't call RenderTheme::supportsFocusRing here.

    Path path = areaElement->computePath(this);
    if (path.isEmpty())
        return;

    // FIXME: Do we need additional code to clip the path to the image's bounding box?

    RenderStyle* areaElementStyle = areaElement->computedStyle();
    unsigned short outlineWidth = areaElementStyle->outlineWidth();
    if (!outlineWidth)
        return;

    if (!d->m_focus_ring_shape || d->m_focus_ring_dirty) {
        if (!d->m_focus_ring_shape) {
            d->m_focus_ring_shape = WRATHNew WRATHShapeF;
        }

        d->m_focus_ring_shape->clear();
        d->m_focus_ring_shape->new_outline();

        QPainterPath qpath = path.platformPath();

        // Skip the first element, it is not needed because it's the same as the last
        for (int i = 1; i < qpath.elementCount(); ++i) {
            const QPainterPath::Element & cur = qpath.elementAt(i);

            switch (cur.type) {
            case QPainterPath::MoveToElement: {
                ASSERT_NOT_REACHED();
                break;
            }
            case QPainterPath::LineToElement: {
                QPointF p(cur);
                d->m_focus_ring_shape->current_outline() << vec2(p.x(), p.y());
                break;
            }
            case QPainterPath::CurveToElement: {
                QPainterPath::Element c1 = qpath.elementAt(i+1);
                QPainterPath::Element c2 = qpath.elementAt(i+2);

                ASSERT(c1.type == QPainterPath::CurveToDataElement);
                ASSERT(c2.type == QPainterPath::CurveToDataElement);

                QPointF p1(cur);
                QPointF p2(c1);
                QPointF p3(c2);

                d->m_focus_ring_shape->current_outline() <<
                        WRATHOutlineF::control_point(vec2(p1.x(), p1.y())) <<
                        WRATHOutlineF::control_point(vec2(p2.x(), p2.y())) <<
                        vec2(p3.x(), p3.y());

                i += 2;

                break;
            }
            case QPainterPath::CurveToDataElement: {
                ASSERT_NOT_REACHED();
                break;
            }
            }
        }
    }

    vec4 c;
    Color wc = areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor);
    wc.getRGBA(c.x(), c.y(), c.z(), c.w());

    paintInfo.wrath_context->add_stroked_shape(d->m_focus_ring,
            WRATHWidgetGenerator::ColorProperties(c),
            WRATHWidgetGenerator::shape_value(*d->m_focus_ring_shape),
            WRATHWidgetGenerator::StrokingParameters()
            .close_outline(true)
            .width(outlineWidth)
            .stroke_curves(WRATHWidgetGenerator::dashed_stroke));
    d->m_focus_ring.widget()->visible(true);
}