Esempio n. 1
0
static void deflateIfOverlapped(IntRect& a, IntRect& b)
{
    if (!a.intersects(b) || a.contains(b) || b.contains(a))
        return;

    static const int fudgeFactor = -2;

    // Avoid negative width or height values.
    if ((a.width() + 2 * fudgeFactor > 0) && (a.height() + 2 * fudgeFactor > 0))
        a.inflate(fudgeFactor);

    if ((b.width() + 2 * fudgeFactor > 0) && (b.height() + 2 * fudgeFactor > 0))
        b.inflate(fudgeFactor);
}
Esempio n. 2
0
void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
{
    float fractionFadedIn = pageOverlay->fractionFadedIn();

    Vector<IntRect> rects = rectsForTextMatches();

    // Draw the background.
    graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB);

    {
        GraphicsContextStateSaver stateSaver(graphicsContext);

        graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB);
        graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB);

        // Draw white frames around the holes.
        for (size_t i = 0; i < rects.size(); ++i) {
            IntRect whiteFrameRect = rects[i];
            whiteFrameRect.inflate(1);

            graphicsContext.fillRect(whiteFrameRect);
        }
    }

    graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB);

    // Clear out the holes.
    for (size_t i = 0; i < rects.size(); ++i)
        graphicsContext.fillRect(rects[i]);
}
void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
{
    Vector<IntRect> rects = rectsForTextMatches();

    // Draw the background.
    graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(), ColorSpaceSRGB);

    graphicsContext.save();
    graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB);

    graphicsContext.setFillColor(Color::white, ColorSpaceSRGB);

    // Draw white frames around the holes.
    for (size_t i = 0; i < rects.size(); ++i) {
        IntRect whiteFrameRect = rects[i];
        whiteFrameRect.inflate(1);

        graphicsContext.fillRect(whiteFrameRect);
    }

    graphicsContext.restore();

    graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB);

    // Clear out the holes.
    for (size_t i = 0; i < rects.size(); ++i)
        graphicsContext.fillRect(rects[i]);
}
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
{
    if (paintingDisabled())
        return;

    if (rects.isEmpty())
        return;

    // FIXME: We just unite all focus ring rects into one for now.
    // We should outline the edge of the full region.
    offset += (width - 1) / 2;
    IntRect finalFocusRect;

    for (unsigned i = 0; i < rects.size(); i++) {
        IntRect focusRect = rects[i];
        focusRect.inflate(offset);
        finalFocusRect.unite(focusRect);
    }

    StrokeStyle oldStyle = m_data->strokeStyle();
    Color oldStrokeColor = m_data->strokeColor();
    m_data->setStrokeStyle(DashedStroke);
    m_data->setStrokeColor(color);
    strokeRect(FloatRect(finalFocusRect), 1.f);
    m_data->setStrokeStyle(oldStyle);
    m_data->setStrokeColor(oldStrokeColor);
}
void RenderReplaced::adjustOverflowForBoxShadowAndReflect()
{
    IntRect overflow;
    for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
        if (boxShadow->style == Inset)
            continue;
        IntRect shadow = borderBoxRect();
        shadow.move(boxShadow->x, boxShadow->y);
        shadow.inflate(boxShadow->blur + boxShadow->spread);
        overflow.unite(shadow);
    }

    // Now that we have an overflow rect including shadow, let's make sure that
    // the reflection (which can also include the shadow) is also included.
    if (hasReflection()) {
        if (overflow.isEmpty())
            overflow = borderBoxRect();
        overflow.unite(reflectedRect(overflow));
    }

    if (!overflow.isEmpty()) {
        if (!gOverflowRectMap)
            gOverflowRectMap = new OverflowRectMap();
        overflow.unite(borderBoxRect());
        gOverflowRectMap->set(this, overflow);
        setReplacedHasOverflow(true);
    } else if (replacedHasOverflow()) {
        gOverflowRectMap->remove(this);
        setReplacedHasOverflow(false);
    }
}
IntRect WebPopupMenuProxyWin::clientRect() const
{
    IntRect clientRect = m_windowRect;
    clientRect.inflate(-popupWindowBorderWidth);
    clientRect.setLocation(IntPoint(0, 0));
    return clientRect;
}
Esempio n. 7
0
static void fillSmoothEdgedRect(GraphicsContext* context, const IntRect& rect, const Color& color)
{
    Color halfColor(color.red(), color.green(), color.blue(), color.alpha() / 2);

    IntRect topRect = rect;
    topRect.inflateX(-1);
    topRect.setHeight(1);
    context->fillRect(topRect, halfColor, ColorSpaceDeviceRGB);

    IntRect leftRect = rect;
    leftRect.inflateY(-1);
    leftRect.setWidth(1);
    context->fillRect(leftRect, halfColor, ColorSpaceDeviceRGB);

    IntRect centerRect = rect;
    centerRect.inflate(-1);
    context->fillRect(centerRect, color, ColorSpaceDeviceRGB);

    IntRect rightRect = rect;
    rightRect.inflateY(-1);
    rightRect.setX(centerRect.maxX());
    rightRect.setWidth(1);
    context->fillRect(rightRect, halfColor, ColorSpaceDeviceRGB);

    IntRect bottomRect = rect;
    bottomRect.inflateX(-1);
    bottomRect.setY(centerRect.maxY());
    bottomRect.setHeight(1);
    context->fillRect(bottomRect, halfColor, ColorSpaceDeviceRGB);
}
void GraphicsContext::drawFocusRing(const Color& color)
{
    if (paintingDisabled())
        return;

    int radius = (focusRingWidth() - 1) / 2;
    int offset = radius + focusRingOffset();

    const Vector<IntRect>& rects = focusRingRects();
    unsigned rectCount = rects.size();
    IntRect finalFocusRect;
    for (unsigned i = 0; i < rectCount; i++) {
        IntRect focusRect = rects[i];
        focusRect.inflate(offset);
        finalFocusRect.unite(focusRect);
    }

    cairo_t* cr = m_data->cr;
    cairo_save(cr);
    // FIXME: These rects should be rounded
    cairo_rectangle(cr, finalFocusRect.x(), finalFocusRect.y(), finalFocusRect.width(), finalFocusRect.height());

    // Force the alpha to 50%.  This matches what the Mac does with outline rings.
    Color ringColor(color.red(), color.green(), color.blue(), 127);
    setColor(cr, ringColor);
    cairo_stroke(cr);
    cairo_restore(cr);
}
IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
    if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
        return IntRect();

    // The selectionRect can project outside of the overflowRect, so take their union
    // for repainting to avoid selection painting glitches.
    IntRect r = unionRect(localSelectionRect(false), visualOverflowRect());

    RenderView* v = view();
    if (v) {
        // FIXME: layoutDelta needs to be applied in parts before/after transforms and
        // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
        r.move(v->layoutDelta());
    }

    if (style()) {
        if (style()->hasAppearance())
            // The theme may wish to inflate the rect used when repainting.
            theme()->adjustRepaintRect(this, r);
        if (v)
            r.inflate(style()->outlineSize());
    }
    computeRectForRepaint(repaintContainer, r);
    return r;
}
Esempio n. 10
0
bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
    GraphicsContext* context = paintInfo.context;

    context->fillRect(FloatRect(r), m_panelColor, ColorSpaceDeviceRGB);
    context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
                                        r.width(), m_mediaSliderHeight)), m_sliderColor, ColorSpaceDeviceRGB);

    RenderStyle* style = o->style();
    HTMLMediaElement* mediaElement = toParentMediaElement(o);

    if (!mediaElement)
        return false;

    // Draw the buffered ranges. This code is highly inspired from
    // Chrome for the gradient code.
    float mediaDuration = mediaElement->duration();
    RefPtr<TimeRanges> timeRanges = mediaElement->buffered();
    IntRect trackRect = r;
    int totalWidth = trackRect.width();

    trackRect.inflate(-style->borderLeftWidth());
    context->save();
    context->setStrokeStyle(NoStroke);

    for (unsigned index = 0; index < timeRanges->length(); ++index) {
        ExceptionCode ignoredException;
        float start = timeRanges->start(index, ignoredException);
        float end = timeRanges->end(index, ignoredException);
        int width = ((end - start) * totalWidth) / mediaDuration;
        IntRect rangeRect;
        if (!index) {
            rangeRect = trackRect;
            rangeRect.setWidth(width);
        } else {
            rangeRect.setLocation(IntPoint(trackRect.x() + start / mediaDuration* totalWidth, trackRect.y()));
            rangeRect.setSize(IntSize(width, trackRect.height()));
        }

        // Don't bother drawing empty range.
        if (rangeRect.isEmpty())
            continue;

        IntPoint sliderTopLeft = rangeRect.location();
        IntPoint sliderTopRight = sliderTopLeft;
        sliderTopRight.move(0, rangeRect.height());

        RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
        Color startColor = m_panelColor;
        gradient->addColorStop(0.0, startColor);
        gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));

        context->setFillGradient(gradient);
        context->fillRect(rangeRect);
    }

    context->restore();
    return false;
}
Esempio n. 11
0
void TouchEventHandler::drawTapHighlight()
{
    Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
    if (!elementUnderFatFinger)
        return;

    Element* element = elementForTapHighlight(elementUnderFatFinger);
    if (!element)
        return;

    // Get the element bounding rect in transformed coordinates so we can extract
    // the focus ring relative position each rect.
    RenderObject* renderer = element->renderer();
    ASSERT(renderer);

    Frame* elementFrame = element->document()->frame();
    ASSERT(elementFrame);

    FrameView* elementFrameView = elementFrame->view();
    if (!elementFrameView)
        return;

    // Tell the client if the element is either in a scrollable container or in a fixed positioned container.
    // On the client side, this info is being used to hide the tap highlight window on scroll.
    RenderLayer* layer = m_webPage->enclosingFixedPositionedAncestorOrSelfIfFixedPositioned(renderer->enclosingLayer());
    bool shouldHideTapHighlightRightAfterScrolling = !layer->renderer()->isRenderView();
    shouldHideTapHighlightRightAfterScrolling |= !!m_webPage->m_inRegionScroller->d->node();

    IntPoint framePos(m_webPage->frameOffset(elementFrame));

    // FIXME: We can get more precise on the <map> case by calculating the rect with HTMLAreaElement::computeRect().
    IntRect absoluteRect(renderer->absoluteClippedOverflowRect());
    absoluteRect.move(framePos.x(), framePos.y());

    IntRect clippingRect;
    if (elementFrame == m_webPage->mainFrame())
        clippingRect = IntRect(IntPoint(0, 0), elementFrameView->contentsSize());
    else
        clippingRect = m_webPage->mainFrame()->view()->windowToContents(m_webPage->getRecursiveVisibleWindowRect(elementFrameView, true /*noClipToMainFrame*/));
    clippingRect = intersection(absoluteRect, clippingRect);

    Vector<FloatQuad> focusRingQuads;
    renderer->absoluteFocusRingQuads(focusRingQuads);

    Platform::IntRectRegion region;
    for (size_t i = 0; i < focusRingQuads.size(); ++i) {
        IntRect rect = focusRingQuads[i].enclosingBoundingBox();
        rect.move(framePos.x(), framePos.y());
        IntRect clippedRect = intersection(clippingRect, rect);
        clippedRect.inflate(2);
        region = unionRegions(region, Platform::IntRect(clippedRect));
    }

    Color highlightColor = element->renderStyle()->tapHighlightColor();

    m_webPage->m_tapHighlight->draw(region,
                                    highlightColor.red(), highlightColor.green(), highlightColor.blue(), highlightColor.alpha(),
                                    shouldHideTapHighlightRightAfterScrolling);
}
Esempio n. 12
0
static bool paintMediaSlider(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
    HTMLMediaElement* mediaElement = toParentMediaElement(object);
    if (!mediaElement)
        return false;

    RenderStyle* style = object->style();
    GraphicsContext* context = paintInfo.context;

    // Draw the border of the time bar.
    // FIXME: this should be a rounded rect but need to fix GraphicsContextSkia first.
    // https://bugs.webkit.org/show_bug.cgi?id=30143
    context->save();
    context->setShouldAntialias(true);
    context->setStrokeStyle(SolidStroke);
    context->setStrokeColor(style->visitedDependentColor(CSSPropertyBorderLeftColor), ColorSpaceDeviceRGB);
    context->setStrokeThickness(style->borderLeftWidth());
    context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor), ColorSpaceDeviceRGB);
    context->drawRect(rect);
    context->restore();

    // Draw the buffered ranges.
    // FIXME: Draw multiple ranges if there are multiple buffered ranges.
    IntRect bufferedRect = rect;
    bufferedRect.inflate(-style->borderLeftWidth());

    double bufferedWidth = 0.0;
    if (mediaElement->percentLoaded() > 0.0) {
        // Account for the width of the slider thumb.
        Image* mediaSliderThumb = getMediaSliderThumb();
        double thumbWidth = mediaSliderThumb->width() / 2.0 + 1.0;
        double rectWidth = bufferedRect.width() - thumbWidth;
        if (rectWidth < 0.0)
            rectWidth = 0.0;
        bufferedWidth = rectWidth * mediaElement->percentLoaded() + thumbWidth;
    }
    bufferedRect.setWidth(bufferedWidth);

    // Don't bother drawing an empty area.
    if (!bufferedRect.isEmpty()) {
        IntPoint sliderTopLeft = bufferedRect.location();
        IntPoint sliderTopRight = sliderTopLeft;
        sliderTopRight.move(0, bufferedRect.height());

        RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
        Color startColor = object->style()->visitedDependentColor(CSSPropertyColor);
        gradient->addColorStop(0.0, startColor);
        gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));

        context->save();
        context->setStrokeStyle(NoStroke);
        context->setFillGradient(gradient);
        context->fillRect(bufferedRect);
        context->restore();
    }

    return true;
}
Esempio n. 13
0
void scrollIntoView(Element* element)
{
    // NOTE: Element's scrollIntoView method could had been used here, but
    // it is preferable to inflate |element|'s bounding rect a bit before
    // scrolling it for accurate reason.
    // Element's scrollIntoView method does not provide this flexibility.
    static const int fudgeFactor = 2;
    IntRect bounds = element->getRect();
    bounds.inflate(fudgeFactor);
    element->renderer()->enclosingLayer()->scrollRectToVisible(bounds);
}
Esempio n. 14
0
void GLWebViewState::addDirtyArea(const IntRect& rect)
{
    if (rect.isEmpty())
        return;

    IntRect inflatedRect = rect;
    inflatedRect.inflate(8);
    if (m_frameworkLayersInval.isEmpty())
        m_frameworkLayersInval = inflatedRect;
    else
        m_frameworkLayersInval.unite(inflatedRect);
}
Esempio n. 15
0
static void adjustRectForFocus(GtkWidget* widget, IntRect& rect, bool ignoreInteriorFocusProperty = false)
{
    gint focusWidth, focusPad;
    gboolean interiorFocus = 0;
    gtk_widget_style_get(widget,
                         "interior-focus", &interiorFocus,
                         "focus-line-width", &focusWidth,
                         "focus-padding", &focusPad, NULL);
    if (!ignoreInteriorFocusProperty && interiorFocus)
        return;
    rect.inflate(focusWidth + focusPad);
}
Esempio n. 16
0
void ScrollbarThemeOpus::paintThumb(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
{
    if (!clientOpacityMap->contains(scrollbar))
        return;
    int opacity = clientOpacityMap->get(scrollbar);
    if (!opacity)
        return;
    IntRect thumbRect = rect;
    thumbRect.inflate(-1);
    int scrollThickness = thumbRect.width() < thumbRect.height() ? thumbRect.width() : thumbRect.height();
    IntSize curveSize(scrollThickness / 2, scrollThickness / 2);
    Color fillColor(makeRGBA(128, 128, 128, opacity));
    context->fillRoundedRect(thumbRect, curveSize, curveSize, curveSize, curveSize, fillColor, ColorSpaceDeviceRGB);
}
Esempio n. 17
0
// It's called a "focus ring" but it's not a ring, it's a (possibly rounded) rect around 
// something that is highlighted, like a text input.
void GraphicsContext::drawFocusRing(const Color& color)
{
    if (paintingDisabled())
        return;

    const int radius = (focusRingWidth() - 1) / 2;
    const int offset = radius + focusRingOffset();

    const Vector<IntRect>& rects     = focusRingRects();
    unsigned               rectCount = rects.size();
    IntRect                finalFocusRect;

    for (unsigned i = 0; i < rectCount; i++)
    {
        IntRect focusRect = rects[i];

        focusRect.setLocation(focusRect.location() + origin());
        focusRect.inflate(offset);
        finalFocusRect.unite(focusRect);
    }

    bool useDefaultFocusRingDraw = true;
    EA::WebKit::ViewNotification* pVN = EA::WebKit::GetViewNotification();

    EA::WebKit::FocusRingDrawInfo focusInfo;
    
    EA::Raster::ISurface* pSurface = m_data->surface; 
    EA::WebKit::View* pView = NULL;
    if(pSurface)
        pView = static_cast<EA::WebKit::View*> (pSurface->GetUserData());  // Need to verify that this cast is always safe...
    
    focusInfo.mpView = pView;
    EA::WebKit::GetEARasterInstance()->IntRectToEARect(finalFocusRect, focusInfo.mFocusRect);
    focusInfo.mFocusRect.h -= 1;
    focusInfo.mFocusRect.w -= 1;
    focusInfo.mSuggestedColor.setRGB(color.rgb());
    focusInfo.mpSurface = m_data->surface;
    if(pVN)
    {
        useDefaultFocusRingDraw = !pVN->DrawFocusRing(focusInfo);
    }

    //default focus rect draw method
    if(useDefaultFocusRingDraw)
    {
        // Force the alpha to 50%. This matches what the Mac does with outline rings.
        const  EA::Raster::Color ringColor(color.red(), color.green(), color.blue(), 127);
        EA::WebKit::GetEARasterInstance()->RectangleColor(focusInfo.mpSurface, focusInfo.mFocusRect, ringColor);
    }
}
void RenderImage::areaElementFocusChanged(HTMLAreaElement* areaElement)
{
    ASSERT(areaElement->imageElement() == node());

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

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

    IntRect repaintRect = enclosingIntRect(path.boundingRect());
    repaintRect.moveBy(-absoluteContentBox().location());
    repaintRect.inflate(outlineWidth);

    repaintRectangle(repaintRect);
}
Esempio n. 19
0
IntRect LayerWebKitThread::mapFromTransformed(const IntRect& contentsRect, double scale)
{
    IntRect untransformedContentsRect = contentsRect;

    if (scale != 1.0) {
        TransformationMatrix matrix;
        matrix.scale(1.0 / scale);
        untransformedContentsRect = matrix.mapRect(contentsRect);

        // We extract from the contentsRect but draw a slightly larger region than
        // we were told to, in order to avoid pixels being rendered only partially.
        const int atLeastOneDevicePixel = static_cast<int>(ceilf(1.0 / scale));
        untransformedContentsRect.inflate(atLeastOneDevicePixel);
    }

    return untransformedContentsRect;
}
Esempio n. 20
0
bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
    GraphicsContext* context = paintInfo.context;

    context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace);
    context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
                                        r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace);

    RenderStyle* style = o->style();
    HTMLMediaElement* mediaElement = toParentMediaElement(o);

    if (!mediaElement)
        return false;

    // Draw the buffered ranges. This code is highly inspired from
    // Chrome.
    // FIXME: Draw multiple ranges if there are multiple buffered
    // ranges. The current implementation of the player is always
    // buffering a single range anyway.
    IntRect bufferedRect = r;
    bufferedRect.inflate(-style->borderLeftWidth());
    bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded()));

    // Don't bother drawing an empty area.
    if (bufferedRect.isEmpty())
        return false;

    IntPoint sliderTopLeft = bufferedRect.location();
    IntPoint sliderTopRight = sliderTopLeft;
    sliderTopRight.move(0, bufferedRect.height());

    RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
    Color startColor = m_panelColor;
    gradient->addColorStop(0.0, startColor);
    gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));

    context->save();
    context->setStrokeStyle(NoStroke);
    context->setFillGradient(gradient);
    context->fillRect(bufferedRect);
    context->restore();

    return false;
}
    virtual void paint(GraphicsContext* ctx, const IntRect& rect)
    {
        // Most of this code is copied from PluginView::paintMissingPluginIcon
        // with slight modification.

        static RefPtr<Image> image;
        if (!image) {
            image = Image::loadPlatformResource("togglePlugin");
        }

        IntRect imageRect(x(), y(), image->width(), image->height());

        int xOffset = (width() - imageRect.width()) >> 1;
        int yOffset = (height() - imageRect.height()) >> 1;

        imageRect.move(xOffset, yOffset);

        if (!rect.intersects(imageRect))
            return;

        // FIXME: We need to clip similarly to paintMissingPluginIcon but it is
        // way screwed up right now. It has something to do with how we tell
        // webkit the scroll position and it causes the placeholder to get
        // clipped very badly. http://b/issue?id=2533303

        ctx->save();
        ctx->clip(frameRect());

        ctx->setFillColor(Color::white, DeviceColorSpace);
        ctx->fillRect(frameRect());
        if (frameRect().contains(imageRect)) {
            // Leave a 2 pixel padding.
            const int pixelWidth = 2;
            IntRect innerRect = frameRect();
            innerRect.inflate(-pixelWidth);
            // Draw a 2 pixel light gray border.
            ctx->setStrokeColor(Color::lightGray, DeviceColorSpace);
            ctx->strokeRect(innerRect, pixelWidth);
        }

        // Draw the image in the center
        ctx->drawImage(image.get(), DeviceColorSpace, imageRect.location());
        ctx->restore();
    }
DrawingRecorder::DrawingRecorder(GraphicsContext& context, const DisplayItemClientWrapper& displayItemClient, DisplayItem::Type displayItemType, const FloatRect& cullRect)
    : m_context(context)
    , m_displayItemClient(displayItemClient)
    , m_displayItemType(displayItemType)
#if ENABLE(ASSERT)
    , m_displayItemPosition(m_context.displayItemList()->newDisplayItems().size())
    , m_underInvalidationCheckingMode(DrawingDisplayItem::CheckPicture)
#endif
{
    ASSERT(context.displayItemList());
    if (context.displayItemList()->displayItemConstructionIsDisabled())
        return;

    // Must check DrawingRecorder::useCachedDrawingIfPossible before creating the DrawingRecorder.
    ASSERT((RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled() && context.displayItemList()->paintOffsetWasInvalidated(displayItemClient.displayItemClient()))
        || RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
        || !useCachedDrawingIfPossible(m_context, m_displayItemClient, m_displayItemType));

    ASSERT(DisplayItem::isDrawingType(displayItemType));

#if ENABLE(ASSERT)
    context.setInDrawingRecorder(true);
#endif

    context.beginRecording(cullRect);

#if ENABLE(ASSERT)
    if (RuntimeEnabledFeatures::slimmingPaintStrictCullRectClippingEnabled()) {
        // Skia depends on the cull rect containing all of the display item commands. When strict
        // cull rect clipping is enabled, make this explicit. This allows us to identify potential
        // incorrect cull rects that might otherwise be masked due to Skia internal optimizations.
        context.save();
        IntRect verificationClip = enclosingIntRect(cullRect);
        // Expand the verification clip by one pixel to account for Skia's SkCanvas::getClipBounds()
        // expansion, used in testing cull rects.
        // TODO(schenney) This is not the best place to do this. Ideally, we would expand by one pixel
        // in device (pixel) space, but to do that we would need to add the verification mode to Skia.
        verificationClip.inflate(1);
        context.clipRect(verificationClip, NotAntiAliased, SkRegion::kIntersect_Op);
    }
#endif
}
Esempio n. 23
0
void RenderReplaced::adjustOverflowForBoxShadow()
{
    IntRect overflow;
    for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
        IntRect shadow = borderBox();
        shadow.move(boxShadow->x, boxShadow->y);
        shadow.inflate(boxShadow->blur);
        overflow.unite(shadow);
    }

    if (!overflow.isEmpty()) {
        if (!gOverflowRectMap)
            gOverflowRectMap = new OverflowRectMap();
        overflow.unite(borderBox());
        gOverflowRectMap->set(this, overflow);
        m_hasOverflow = true;
    } else if (m_hasOverflow) {
        gOverflowRectMap->remove(this);
        m_hasOverflow = false;
    }
}
Esempio n. 24
0
void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
{
    float fractionFadedIn = pageOverlay->fractionFadedIn();

    Vector<IntRect> rects = rectsForTextMatches();

    // Draw the background.
    graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB);

    {
        GraphicsContextStateSaver stateSaver(graphicsContext);

        graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB);
        graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB);

        // Draw white frames around the holes.
        for (size_t i = 0; i < rects.size(); ++i) {
            IntRect whiteFrameRect = rects[i];
            whiteFrameRect.inflate(1);

            graphicsContext.fillRect(whiteFrameRect);
        }
    }

    graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB);

    // Clear out the holes.
    for (size_t i = 0; i < rects.size(); ++i)
        graphicsContext.fillRect(rects[i]);

    if (!m_isShowingFindIndicator)
        return;

    if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) {
        IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection()->bounds()));

        if (findIndicatorRect != m_findIndicatorRect)
            hideFindIndicator();
    }
}
Esempio n. 25
0
void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
{
    Color overlayBackgroundColor(0.1f, 0.1f, 0.1f, 0.25f);

    Vector<IntRect> rects = rectsForTextMatches();

    // Draw the background.
    graphicsContext.fillRect(dirtyRect, overlayBackgroundColor, ColorSpaceSRGB);

    {
        GraphicsContextStateSaver stateSaver(graphicsContext);

#if ENABLE(LEGACY_FIND_INDICATOR_STYLE)
        graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB);
#endif
        graphicsContext.setFillColor(Color::white, ColorSpaceSRGB);

        // Draw white frames around the holes.
        for (auto& rect : rects) {
            IntRect whiteFrameRect = rect;
            whiteFrameRect.inflate(1);
            graphicsContext.fillRect(whiteFrameRect);
        }
    }

    // Clear out the holes.
    for (auto& rect : rects)
        graphicsContext.clearRect(rect);

    if (!m_isShowingFindIndicator)
        return;

    if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) {
        IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection().selectionBounds()));

        if (findIndicatorRect != m_findIndicatorRect)
            hideFindIndicator();
    }
}
Esempio n. 26
0
IntRect RenderReplaced::absoluteClippedOverflowRect()
{
    if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
        return IntRect();

    // The selectionRect can project outside of the overflowRect, so use
    // that for repainting to avoid selection painting glitches
    IntRect r = localSelectionRect(false);

    RenderView* v = view();
    if (v)
        r.move(v->layoutDelta());

    if (style()) {
        if (style()->hasAppearance())
            // The theme may wish to inflate the rect used when repainting.
            theme()->adjustRepaintRect(this, r);
        if (v)
            r.inflate(style()->outlineSize());
    }
    computeAbsoluteRepaintRect(r);
    return r;
}
Esempio n. 27
0
void LayerWebKitThread::paintContents(BlackBerry::Platform::Graphics::Buffer* buffer, const IntRect& contentsRect, double scale)
{
    if (!drawsContent() && !contents())
        return;

    if (!buffer)
        return;

    IntRect untransformedContentsRect = contentsRect;
    FloatRect clipRect = contentsRect;
    if (scale != 1.0) {
        TransformationMatrix matrix;
        matrix.scale(1.0 / scale);
        untransformedContentsRect = matrix.mapRect(contentsRect);
        clipRect = matrix.mapRect(clipRect);

        // We extract from the contentsRect but draw a slightly larger region than
        // we were told to, in order to avoid pixels being rendered only partially.
        const int atLeastOneDevicePixel = static_cast<int>(ceilf(1.0 / scale));
        untransformedContentsRect.inflate(atLeastOneDevicePixel);
    }

    PlatformGraphicsContext* platformContext = lockBufferDrawable(buffer);
    GraphicsContext graphicsContext(platformContext);
    if (contents()) {
        // Images needs to be centered and will be scaled to fit the bounds on the compositing thread
        if (!contents()->size().isEmpty())
            graphicsContext.drawImage(contents(), ColorSpaceDeviceRGB, IntPoint(0, 0));
    } else {
        graphicsContext.translate(-contentsRect.x(), -contentsRect.y());
        graphicsContext.scale(FloatSize(scale, scale));
        graphicsContext.clip(clipRect);
        m_owner->paintGraphicsLayerContents(graphicsContext, untransformedContentsRect);
    }

    releaseBufferDrawable(buffer);
}
Esempio n. 28
0
SkBitmap LayerWebKitThread::paintContents(const IntRect& contentsRect, double scale, bool* isSolidColor, Color* color)
{
    // Don't try to allocate image data bigger than this. This should be big
    // enough to accomodate a huge iScroll use case.
    // FIXME: This is a hack to work around a crash bug on maps.bing.com where
    // a (visually empty) layer becomes too big.
    static const int maximumBitmapSizeInBytes = 40 * 1024 * 1024;
    static const int bytesPerPixel = 4;

    if (isSolidColor)
        *isSolidColor = false;

    if (contentsRect.width() * contentsRect.height() * bytesPerPixel > maximumBitmapSizeInBytes)
        return SkBitmap();

    SkBitmap bitmap;

    // Keep the canvas alive until we're done extracting its pixels
    OwnPtr<InstrumentedPlatformCanvas> canvas;

    if (drawsContent()) { // Layer contents must be drawn into a canvas.
        IntRect untransformedContentsRect = contentsRect;

        canvas = adoptPtr(new InstrumentedPlatformCanvas(contentsRect.width(), contentsRect.height()));
        PlatformContextSkia skiaContext(canvas.get());

        GraphicsContext graphicsContext(&skiaContext);
        graphicsContext.translate(-contentsRect.x(), -contentsRect.y());

        if (scale != 1.0) {
            TransformationMatrix matrix;
            matrix.scale(1.0 / scale);
            untransformedContentsRect = matrix.mapRect(contentsRect);

            // We extract from the contentsRect but draw a slightly larger region than
            // we were told to, in order to avoid pixels being rendered only partially.
            const int atLeastOneDevicePixel = static_cast<int>(ceilf(1.0 / scale));
            untransformedContentsRect.inflate(atLeastOneDevicePixel);

            graphicsContext.scale(FloatSize(scale, scale));
        }

        // RenderLayerBacking doesn't always clip, so we need to do this by ourselves.
        graphicsContext.clip(untransformedContentsRect);
        m_owner->paintGraphicsLayerContents(graphicsContext, untransformedContentsRect);

        bitmap = canvas->getDevice()->accessBitmap(false);
        if (isSolidColor) {
            *isSolidColor = canvas->isSolidColor();
            if (color)
                *color = canvas->solidColor();
        }
    }

    ASSERT(!bitmap.isNull());

    // FIXME: do we need to support more image configurations?
    ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
    if (bitmap.config() != SkBitmap::kARGB_8888_Config)
        return SkBitmap();

    return bitmap;
}
Esempio n. 29
0
void TileGrid::prepareGL(GLWebViewState* state, float scale,
                         const IntRect& prepareArea, const IntRect& fullContentArea,
                         TilePainter* painter, int regionFlags, bool isLowResPrefetch,
                         bool updateWithBlit)
{
    // first, how many tiles do we need
    m_area = computeTilesArea(prepareArea, scale);
    if (m_area.isEmpty())
        return;

    ALOGV("prepare TileGrid %p with scale %.2f, prepareArea "
          " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
          this, scale,
          prepareArea.x(), prepareArea.y(),
          prepareArea.width(), prepareArea.height(),
          m_area.x(), m_area.y(),
          m_area.width(), m_area.height());

    bool goingDown = m_prevTileY < m_area.y();
    m_prevTileY = m_area.y();

    TilesManager* tilesManager = TilesManager::instance();
    if (scale != m_scale)
        tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale));

    m_scale = scale;

    // apply dirty region to affected tiles
    if (!m_dirtyRegion.isEmpty()) {
        for (unsigned int i = 0; i < m_tiles.size(); i++)
            m_tiles[i]->markAsDirty(m_dirtyRegion);

        // log inval region for the base surface
        if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) {
            SkRegion::Iterator iterator(m_dirtyRegion);
            while (!iterator.done()) {
                SkIRect r = iterator.rect();
                tilesManager->getProfiler()->nextInval(r, scale);
                iterator.next();
            }
        }
        m_dirtyRegion.setEmpty();
    }

    if (regionFlags & StandardRegion) {
        for (int i = 0; i < m_area.width(); i++) {
            if (goingDown) {
                for (int j = 0; j < m_area.height(); j++)
                    prepareTile(m_area.x() + i, m_area.y() + j,
                                painter, state, isLowResPrefetch, false, updateWithBlit);
            } else {
                for (int j = m_area.height() - 1; j >= 0; j--)
                    prepareTile(m_area.x() + i, m_area.y() + j,
                                painter, state, isLowResPrefetch, false, updateWithBlit);
            }
        }
    }

    if (regionFlags & ExpandedRegion) {
        IntRect fullArea = computeTilesArea(fullContentArea, scale);
        IntRect expandedArea = m_area;

        // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds
        if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory())
            expandedArea.inflate(EXPANDED_BOUNDS_INFLATE);

        if (isLowResPrefetch)
            expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE);

        // clip painting area to content
        expandedArea.intersect(fullArea);

        for (int i = expandedArea.x(); i < expandedArea.maxX(); i++)
            for (int j = expandedArea.y(); j < expandedArea.maxY(); j++)
                if (!m_area.contains(i, j))
                    prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit);
    }
}