Ejemplo n.º 1
0
IntRect LayerAndroid::visibleContentArea(bool force3dContentVisible) const
{
    IntRect area = fullContentArea();
    if (subclassType() == LayerAndroid::FixedBackgroundImageLayer)
       return area;

    // If transform isn't limited to 2D space, return the entire content area.
    // Transforming from layers to content coordinates and back doesn't
    // preserve 3D.
    if (force3dContentVisible && GLUtils::has3dTransform(m_drawTransform))
            return area;

    // First, we get the transformed area of the layer,
    // in content coordinates
    IntRect rect = m_drawTransform.mapRect(area);

    // Then we apply the clipping
    IntRect clip(m_clippingRect);
    rect.intersect(clip);

    // Now clip with the viewport in content coordinate
    IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
    rect.intersect(contentViewport);

    // Finally, let's return the visible area, in layers coordinate
    return m_drawTransform.inverse().mapRect(rect);
}
Ejemplo n.º 2
0
void TiledBackingStore::adjustForContentsRect(IntRect& rect) const
{
    IntRect bounds = contentsRect();
    IntSize candidateSize = rect.size();

    // We will try to keep the cover and keep rect the same size at all time, which
    // might not be the case when at the content edges.

    // We start by moving when at the edges.
    rect.move(std::max(0, bounds.x() - rect.x()), std::max(0, bounds.y() - rect.y()));
    rect.move(std::min(0, bounds.maxX() - rect.maxX()), std::min(0, bounds.maxY() - rect.maxY()));

    rect.intersect(bounds);

    if (rect.size() == candidateSize)
        return;

    // Even now we might cover more than the content area so let's inflate in the
    // opposite directions.
    int pixelsCovered = candidateSize.width() * candidateSize.height();

    if (rect.width() != candidateSize.width())
        rect.inflateY(((pixelsCovered / rect.width()) - rect.height()) / 2);
    if (rect.height() != candidateSize.height())
        rect.inflateX(((pixelsCovered / rect.height()) - rect.width()) / 2);

    rect.intersect(bounds);
}
Ejemplo n.º 3
0
IntRect ContentLayerChromium::visibleLayerRect(const IntRect& targetSurfaceRect)
{
    if (targetSurfaceRect.isEmpty())
        return targetSurfaceRect;

    const IntRect layerBoundRect = layerBounds();
    const TransformationMatrix transform = tilingTransform();

    // Is this layer fully contained within the target surface?
    IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
    if (targetSurfaceRect.contains(layerInSurfaceSpace))
        return layerBoundRect;

    // If the layer doesn't fill up the entire surface, then find the part of
    // the surface rect where the layer could be visible. This avoids trying to
    // project surface rect points that are behind the projection point.
    IntRect minimalSurfaceRect = targetSurfaceRect;
    minimalSurfaceRect.intersect(layerInSurfaceSpace);

    // Project the corners of the target surface rect into the layer space.
    // This bounding rectangle may be larger than it needs to be (being
    // axis-aligned), but is a reasonable filter on the space to consider.
    // Non-invertible transforms will create an empty rect here.
    const TransformationMatrix surfaceToLayer = transform.inverse();
    IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
    layerRect.intersect(layerBoundRect);
    return layerRect;
}
Ejemplo n.º 4
0
void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
{
    if (platformWidget()) {
        Widget::paint(context, rect);
        return;
    }

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

    notifyPageThatContentAreaWillPaint();

    // If we encounter any overlay scrollbars as we paint, this will be set to true.
    m_containsScrollableAreaWithOverlayScrollbars = false;
    
    IntRect documentDirtyRect = rect;
    documentDirtyRect.intersect(frameRect());

    context->save();

    context->translate(x(), y());
    documentDirtyRect.move(-x(), -y());

    if (!paintsEntireContents()) {
        context->translate(-scrollX(), -scrollY());
        documentDirtyRect.move(scrollX(), scrollY());

        context->clip(visibleContentRect());
    }

    paintContents(context, documentDirtyRect);

    context->restore();

    IntRect horizontalOverhangRect;
    IntRect verticalOverhangRect;
    calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);

    if (rect.intersects(horizontalOverhangRect) || rect.intersects(verticalOverhangRect))
        paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, rect);

    // Now paint the scrollbars.
    if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
        context->save();
        IntRect scrollViewDirtyRect = rect;
        scrollViewDirtyRect.intersect(frameRect());
        context->translate(x(), y());
        scrollViewDirtyRect.move(-x(), -y());

        paintScrollbars(context, scrollViewDirtyRect);

        context->restore();
    }

    // Paint the panScroll Icon
    if (m_drawPanScrollIcon)
        paintPanScrollIcon(context);
}
Ejemplo n.º 5
0
void ScrollView::scrollContents(const IntSize& scrollDelta)
{
    if (!hostWindow())
        return;

    // Since scrolling is double buffered, we will be blitting the scroll view's intersection
    // with the clip rect every time to keep it smooth.
    IntRect clipRect = windowClipRect();
    IntRect scrollViewRect = convertToContainingWindow(IntRect(0, 0, visibleWidth(), visibleHeight()));
    if (hasOverlayScrollbars()) {
        int verticalScrollbarWidth = verticalScrollbar() ? verticalScrollbar()->width() : 0;
        int horizontalScrollbarHeight = horizontalScrollbar() ? horizontalScrollbar()->height() : 0;

        scrollViewRect.setWidth(scrollViewRect.width() - verticalScrollbarWidth);
        scrollViewRect.setHeight(scrollViewRect.height() - horizontalScrollbarHeight);
    }
    
    IntRect updateRect = clipRect;
    updateRect.intersect(scrollViewRect);

    // Invalidate the window (not the backing store).
    hostWindow()->invalidateWindow(updateRect, false /*immediate*/);

    if (m_drawPanScrollIcon) {
        // FIXME: the pan icon is broken when accelerated compositing is on, since it will draw under the compositing layers.
        // https://bugs.webkit.org/show_bug.cgi?id=47837
        int panIconDirtySquareSizeLength = 2 * (panIconSizeLength + max(abs(scrollDelta.width()), abs(scrollDelta.height()))); // We only want to repaint what's necessary
        IntPoint panIconDirtySquareLocation = IntPoint(m_panScrollIconPoint.x() - (panIconDirtySquareSizeLength / 2), m_panScrollIconPoint.y() - (panIconDirtySquareSizeLength / 2));
        IntRect panScrollIconDirtyRect = IntRect(panIconDirtySquareLocation , IntSize(panIconDirtySquareSizeLength, panIconDirtySquareSizeLength));
        panScrollIconDirtyRect.intersect(clipRect);
        hostWindow()->invalidateContentsAndWindow(panScrollIconDirtyRect, false /*immediate*/);
    }

    if (canBlitOnScroll()) { // The main frame can just blit the WebView window
        // FIXME: Find a way to scroll subframes with this faster path
        if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect))
            scrollContentsSlowPath(updateRect);
    } else { 
       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
       // windowed plugins.
       scrollContentsSlowPath(updateRect);
    }

    // Invalidate the overhang areas if they are visible.
    IntRect horizontalOverhangRect;
    IntRect verticalOverhangRect;
    calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
    if (!horizontalOverhangRect.isEmpty())
        hostWindow()->invalidateContentsAndWindow(horizontalOverhangRect, false /*immediate*/);
    if (!verticalOverhangRect.isEmpty())
        hostWindow()->invalidateContentsAndWindow(verticalOverhangRect, false /*immediate*/);

    // This call will move children with native widgets (plugins) and invalidate them as well.
    frameRectsChanged();

    // Now blit the backingstore into the window which should be very fast.
    hostWindow()->invalidateWindow(IntRect(), true);
}
Ejemplo n.º 6
0
void TiledLayerChromium::updateCompositorResources(GraphicsContext3D* context)
{
    // Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update.
    if (m_skipsDraw || m_updateRect.isEmpty() || !m_tiler->numTiles())
        return;

    int left, top, right, bottom;
    m_tiler->contentRectToTileIndices(m_updateRect, left, top, right, bottom);
    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            UpdatableTile* tile = tileAt(i, j);
            if (!tile)
                tile = createTile(i, j);
            else if (!tile->dirty())
                continue;

            // Calculate page-space rectangle to copy from.
            IntRect sourceRect = m_tiler->tileContentRect(tile);
            const IntPoint anchor = sourceRect.location();
            sourceRect.intersect(m_tiler->layerRectToContentRect(tile->m_dirtyLayerRect));
            // Paint rect not guaranteed to line up on tile boundaries, so
            // make sure that sourceRect doesn't extend outside of it.
            sourceRect.intersect(m_paintRect);
            if (sourceRect.isEmpty())
                continue;

            ASSERT(tile->texture()->isReserved());

            // Calculate tile-space rectangle to upload into.
            IntRect destRect(IntPoint(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()), sourceRect.size());
            if (destRect.x() < 0)
                CRASH();
            if (destRect.y() < 0)
                CRASH();

            // Offset from paint rectangle to this tile's dirty rectangle.
            IntPoint paintOffset(sourceRect.x() - m_paintRect.x(), sourceRect.y() - m_paintRect.y());
            if (paintOffset.x() < 0)
                CRASH();
            if (paintOffset.y() < 0)
                CRASH();
            if (paintOffset.x() + destRect.width() > m_paintRect.width())
                CRASH();
            if (paintOffset.y() + destRect.height() > m_paintRect.height())
                CRASH();

            tile->texture()->bindTexture(context);
            const GC3Dint filter = m_tiler->hasBorderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST;
            GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, filter));
            GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, filter));
            GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0));

            textureUpdater()->updateTextureRect(context, tile->texture(), sourceRect, destRect);
            tile->clearDirty();
        }
    }
}
Ejemplo n.º 7
0
bool Surface::blitFromContents(Tile* tile)
{
    if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content())
        return false;
    LayerContent* content = getFirstLayer()->content();
    // Extract the dirty rect from the region. Note that this is *NOT* constrained
    // to this tile
    IntRect dirtyRect = tile->dirtyArea().getBounds();
    IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(),
                               tile->y() * TilesManager::tileHeight(),
                               TilesManager::tileWidth(),
                               TilesManager::tileHeight());
    FloatRect tileRectInDoc = tileRect;
    tileRectInDoc.scale(1 / tile->scale());
    dirtyRect.intersect(enclosingIntRect(tileRectInDoc));
    PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect);
    if (!prerenderedInval || prerenderedInval->bitmap.isNull())
        return false;
    SkBitmap sourceBitmap = prerenderedInval->bitmap;
    // Calculate the screen rect that is dirty, then intersect it with the
    // tile's screen rect so that we end up with the pixels we need to blit
    FloatRect screenDirty = dirtyRect;
    screenDirty.scale(tile->scale());
    IntRect enclosingScreenDirty = enclosingIntRect(screenDirty);
    enclosingScreenDirty.intersect(tileRect);
    if (enclosingScreenDirty.isEmpty())
        return false;
    // Make sure the screen area we want to blit is contained by the
    // prerendered screen area
    if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) {
        ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain "
              "enclosingScreenDirty " INT_RECT_FORMAT,
              INT_RECT_ARGS(prerenderedInval->screenArea),
              INT_RECT_ARGS(enclosingScreenDirty));
        return false;
    }
    IntPoint origin = prerenderedInval->screenArea.location();
    SkBitmap subset;
    subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(),
                     enclosingScreenDirty.height());
    subset.allocPixels();

    int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y();
    int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x();
    if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset))
        return false;
    // Now upload
    SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(),
                           enclosingScreenDirty.y() - tileRect.y(),
                           enclosingScreenDirty.width(),
                           enclosingScreenDirty.height());
    GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId,
                                     subset, textureInval);
    tile->onBlitUpdate();
    return true;
}
Ejemplo n.º 8
0
void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
{
    if (platformWidget()) {
        Widget::paint(context, rect);
        return;
    }

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

    scrollAnimator()->contentAreaWillPaint();
    
    IntRect documentDirtyRect = rect;
    documentDirtyRect.intersect(frameRect());

    context->save();

    context->translate(x(), y());
    documentDirtyRect.move(-x(), -y());

    if (!paintsEntireContents()) {
        context->translate(-scrollX(), -scrollY());
        documentDirtyRect.move(scrollX(), scrollY());

        context->clip(visibleContentRect());
    }

    paintContents(context, documentDirtyRect);

    context->restore();

    IntRect horizontalOverhangRect;
    IntRect verticalOverhangRect;
    calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);

    if (!horizontalOverhangRect.isEmpty() || !verticalOverhangRect.isEmpty())
        paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, rect);

    // Now paint the scrollbars.
    if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
        context->save();
        IntRect scrollViewDirtyRect = rect;
        scrollViewDirtyRect.intersect(frameRect());
        context->translate(x(), y());
        scrollViewDirtyRect.move(-x(), -y());

        paintScrollbars(context, scrollViewDirtyRect);

        context->restore();
    }

    // Paint the panScroll Icon
    if (m_drawPanScrollIcon)
        paintPanScrollIcon(context);
}
void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
{
#if PLATFORM(ANDROID)
    if (platformProhibitsScrolling())
        return;
#endif
    // FIXME: This method is not transform-aware.  It should just be moved to FrameView so that an accurate
    // position for the child view can be determined.
    IntRect rect = r;
    ScrollView* view = this;
    while (view) {
        if (view->prohibitsScrolling()) // Allow the views to scroll into view recursively until we hit one that prohibits scrolling.
            return;
        view->setScrollPosition(rect.location());
        rect.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height());
        if (view->parent())
            rect.intersect(view->frameRect());
        view = view->parent();
    }
    
    // We may be embedded inside some containing platform scroll view that we don't manage.  This is the case
    // in Mail.app on OS X, for example, where the WebKit view for message bodies is inside a Cocoa NSScrollView
    // that contains both it and message headers.  Let the HostWindow know about this scroll so that it can pass the message
    // on up the view chain.
    // This rect is not clamped, since Mail actually relies on receiving an unclamped rect with negative coordinates in order to
    // expose the headers.
    if (hostWindow())
        hostWindow()->scrollRectIntoView(rect, this);
}
Ejemplo n.º 10
0
void Widget::invalidateRect(const IntRect& r)
{
    if (data->suppressInvalidation)
        return;

    if (!parent()) {
        RECT rect = r;
        ::InvalidateRect(containingWindow(), &rect, false);
        if (isFrameView())
            static_cast<FrameView*>(this)->addToDirtyRegion(r);
        return;
    }

    // Get the root widget.
    ScrollView* outermostView = parent();
    while (outermostView && outermostView->parent())
        outermostView = outermostView->parent();
    if (!outermostView)
        return;

    IntRect windowRect = convertToContainingWindow(r);

    // Get our clip rect and intersect with it to ensure we don't invalidate too much.
    IntRect clipRect = windowClipRect();
    windowRect.intersect(clipRect);

    RECT rect = windowRect;
    ::InvalidateRect(containingWindow(), &rect, false);
    outermostView->addToDirtyRegion(windowRect);
}
Ejemplo n.º 11
0
void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects,
                                              const IntPoint& additionalOffset,
                                              const IntRect& clipRect)
{
    if (rects.isEmpty())
        return;
    int layerId = layer ? layer->uniqueId() : 0;
    SkRegion* region = m_highlightRegions.get(layerId);
    if (!region) {
        region = new SkRegion();
        m_highlightRegions.set(layerId, region);
    }
    IntPoint offset = additionalOffset;
    WebViewCore::layerToAbsoluteOffset(layer, offset);
    for (size_t i = 0; i < rects.size(); i++) {
        IntRect r = rects.at(i);
        if (!clipRect.isEmpty()) {
            r.intersect(clipRect);
            if (r.isEmpty())
                continue; // don't add it to the region
        }
        r.move(-offset.x(), -offset.y());
        region->op(r.x(), r.y(), r.maxX(), r.maxY(), SkRegion::kUnion_Op);
    }
}
Ejemplo n.º 12
0
void WebViewPrivate::repaint(const WebCore::IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
{
    if (windowRect.isEmpty())
        return;
    IntRect rect = windowRect;
    rect.intersect(m_rect);
    
    if (rect.isEmpty())
        return;

    if (contentChanged) {
        m_webView->addToDirtyRegion(rect);
        /*Frame* focusedFrame = m_webView->page()->focusController()->focusedFrame();
        if (focusedFrame) {
            Scrollbar* hBar = focusedFrame->view()->horizontalScrollbar();
            Scrollbar* vBar = focusedFrame->view()->verticalScrollbar();
            
            // TODO : caculate the scroll delta and test this.
            //if (dx && hBar)
            if (hBar)
                m_webView->addToDirtyRegion(IntRect(focusedFrame->view()->windowClipRect().x() + hBar->x(), focusedFrame->view()->windowClipRect().y() + hBar->y(), hBar->width(), hBar->height()));
            //if (dy && vBar)
            if (vBar)
                m_webView->addToDirtyRegion(IntRect(focusedFrame->view()->windowClipRect().x() + vBar->x(), focusedFrame->view()->windowClipRect().y() + vBar->y(), vBar->width(), vBar->height()));
        }*/
    }
    if (!repaintContentOnly)
        sendExposeEvent(rect);
    if (immediate) {
        if (repaintContentOnly)
            m_webView->updateBackingStore(core(m_webView->topLevelFrame())->view());
        else
            sendExposeEvent(rect);
    }
}
Ejemplo n.º 13
0
void PicturePile::drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion,
                                        int index)
{
    // TODO: Add some debug visualizations of this
    if (index < 0 || clipRegion.isEmpty())
        return;
    PictureContainer& pc = m_pile[index];
    IntRect intersection = clipRegion.getBounds();
    intersection.intersect(pc.area);
    if (pc.picture && !intersection.isEmpty()) {
// SAMSUNG CHANGE ++ : Animation GIF frame remain in Base Picture
// As the previous logic : Base Picture draws picture already drawn by other pile due to only using RECT.
// It uses PATH and RECT, both now.
		SkPath pathClip;
		clipRegion.getBoundaryPath(&pathClip);
// SAMSUNG CHANGE --
        clipRegion.op(intersection, SkRegion::kDifference_Op);
        drawWithClipRecursive(canvas, clipRegion, index - 1);
        int saved = canvas->save();
        canvas->clipRect(intersection);
		canvas->clipPath(pathClip);	// SAMSUNG CHANGE : Animation GIF frame remain in Base Picture
        canvas->translate(pc.area.x(), pc.area.y());
        canvas->drawPicture(*pc.picture);
        canvas->restoreToCount(saved);
    } else
        drawWithClipRecursive(canvas, clipRegion, index - 1);
}
void GraphicsLayerTextureMapper::updateBackingStoreIfNeeded()
{
    TextureMapper* textureMapper = m_layer->textureMapper();
    if (!textureMapper)
        return;

    if (!shouldHaveBackingStore()) {
        ASSERT(!m_backingStore);
        return;
    }
    ASSERT(m_backingStore);

    IntRect dirtyRect = enclosingIntRect(FloatRect(FloatPoint::zero(), m_size));
    if (!m_needsDisplay)
        dirtyRect.intersect(enclosingIntRect(m_needsDisplayRect));
    if (dirtyRect.isEmpty())
        return;

#if PLATFORM(QT) && !defined(QT_NO_DYNAMIC_CAST)
    ASSERT(dynamic_cast<TextureMapperTiledBackingStore*>(m_backingStore.get()));
#endif
    TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get());

    backingStore->updateContents(textureMapper, this, m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);

    m_needsDisplay = false;
    m_needsDisplayRect = IntRect();
}
Ejemplo n.º 15
0
IntRect Surface::computePrepareArea()
{
    IntRect area;

    if (!getFirstLayer()->contentIsScrollable()
        && !isBase()
        && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {

        area = fullContentArea();

        double total = ((double) area.width()) * ((double) area.height());
        if (total > MAX_FULL_CONTENT_AREA)
            area = visibleContentArea();
        /// M: Willy, limit the max number of tile is 64. @{
        else {
            float scale = getFirstLayer()->state()->scale();
            int x = ((double)area.width() * scale) / TilesManager::tileWidth();
            int y = ((double)area.height() * scale) / TilesManager::tileHeight();
            if ((x * y) > 64) {
                IntRect a = visibleContentArea();
                IntRect tmpArea = a;
                tmpArea.inflateX(TilesManager::tileWidth() << 1);
                tmpArea.inflateY(TilesManager::tileHeight() << 1);
                tmpArea.intersect(area);
                area = tmpArea;
            }
        }
        /// @}
    } else
        area = visibleContentArea();

    return area;
}
Ejemplo n.º 16
0
void Widget::invalidateRect(const IntRect& r)
{
    if (data->m_widget) //plugins
        return data->m_widget->update(r);

    IntRect windowRect = convertToContainingWindow(r);

    // Get our clip rect and intersect with it to ensure we don't invalidate too much.
    IntRect clipRect = windowClipRect();
    windowRect.intersect(clipRect);

    QWidget *canvas = qwidget(); //regular frameview
    if (!canvas && parent())
        canvas = parent()->qwidget(); //scrollbars

    if (!canvas)  // not visible anymore
        return;

    bool painting = canvas->testAttribute(Qt::WA_WState_InPaintEvent);
    if (painting) {
        QWebPage *page = qobject_cast<QWebPage*>(canvas);
        QPainter p(page);
        page->mainFrame()->render(&p, windowRect);
    } else {
        canvas->update(windowRect);
    }
}
Ejemplo n.º 17
0
void GraphicsLayerTextureMapper::updateBackingStoreIfNeeded()
{
    TextureMapper* textureMapper = m_layer.textureMapper();
    if (!textureMapper)
        return;

    if (!shouldHaveBackingStore()) {
        ASSERT(!m_backingStore);
        return;
    }
    ASSERT(m_backingStore);

    IntRect dirtyRect = enclosingIntRect(FloatRect(FloatPoint::zero(), m_size));
    if (!m_needsDisplay)
        dirtyRect.intersect(enclosingIntRect(m_needsDisplayRect));
    if (dirtyRect.isEmpty())
        return;

    TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get());
    backingStore->updateContentsScale(pageScaleFactor() * deviceScaleFactor());

    dirtyRect.scale(pageScaleFactor() * deviceScaleFactor());
    backingStore->updateContents(*textureMapper, this, m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);

    m_needsDisplay = false;
    m_needsDisplayRect = IntRect();
}
Ejemplo n.º 18
0
void ScrollView::ScrollViewPrivate::scrollBackingStore(const IntSize& scrollDelta)
{
    // Since scrolling is double buffered, we will be blitting the scroll view's intersection
    // with the clip rect every time to keep it smooth.
    HWND containingWindowHandle = m_view->containingWindow();
    IntRect clipRect = m_view->windowClipRect();
    IntRect scrollViewRect = m_view->convertToContainingWindow(IntRect(0, 0, m_view->visibleWidth(), m_view->visibleHeight()));
    IntRect updateRect = clipRect;
    updateRect.intersect(scrollViewRect);
    RECT r = updateRect;
    ::InvalidateRect(containingWindowHandle, &r, false);

    if (!m_hasStaticBackground) // The main frame can just blit the WebView window
       // FIXME: Find a way to blit subframes without blitting overlapping content
       m_view->scrollBackingStore(-scrollDelta.width(), -scrollDelta.height(), scrollViewRect, clipRect);
    else  {
       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
       // plugins.
       m_view->addToDirtyRegion(updateRect);
       m_view->updateBackingStore();
    }

    // This call will move child HWNDs (plugins) and invalidate them as well.
    m_view->geometryChanged();

    // Now update the window (which should do nothing but a blit of the backing store's updateRect and so should
    // be very fast).
    ::UpdateWindow(containingWindowHandle);
}
Ejemplo n.º 19
0
IntRect FrameView::windowClipRect(bool clipToContents) const
{
    ASSERT(m_frame->view() == this);

    // Set our clip rect to be our contents.
    IntRect clipRect;
    if (clipToContents)
        clipRect = enclosingIntRect(visibleContentRect());
    else
        clipRect = IntRect(contentsX(), contentsY(), width(), height());
    clipRect = contentsToWindow(clipRect);

    if (!m_frame || !m_frame->document() || !m_frame->document()->ownerElement())
        return clipRect;

    // Take our owner element and get the clip rect from the enclosing layer.
    Element* elt = m_frame->document()->ownerElement();
    RenderLayer* layer = elt->renderer()->enclosingLayer();
    // FIXME: layer should never be null, but sometimes seems to be anyway.
    if (!layer)
        return clipRect;
    FrameView* parentView = elt->document()->view();
    clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
    return clipRect;
}
Ejemplo n.º 20
0
void ContentLayerChromium::calculateClippedUpdateRect(IntRect& dirtyRect, IntRect& drawRect) const
{
    // For the given layer size and content rect, calculate:
    // 1) The minimal texture space rectangle to be uploaded, returned in dirtyRect.
    // 2) The rectangle to draw this texture in relative to the target render surface, returned in drawRect.

    ASSERT(m_targetRenderSurface);
    const IntRect clipRect = m_targetRenderSurface->contentRect();

    TransformationMatrix layerOriginTransform = drawTransform();
    layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0);

    // For now we apply the large layer treatment only for layers that are either untransformed
    // or are purely translated. Their matrix is expected to be invertible.
    ASSERT(layerOriginTransform.isInvertible());

    TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
    IntRect clipRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
    clipRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height()));

    dirtyRect = clipRectInLayerCoords;

    // Map back to the target surface coordinate system.
    drawRect = layerOriginTransform.mapRect(dirtyRect);
}
Ejemplo n.º 21
0
IntRect TiledDrawingAreaProxy::calculateCoverRect(const IntRect& visibleRect) const
{
    IntRect result = visibleRect;
    result.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1));
    result.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1));
    result.intersect(contentsRect());
    return result;
}
void FocusController::findHorizontallyFocusableNodeInRect(FocusDirection direction, Node* start, KeyboardEvent* event, const IntRect* rect, Node** candidateNode, IntRect& candidateNodeRect)
{
#if PLATFORM(WKC)
    CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT);
#endif
//    ASSERT(direction == FocusDirectionLeft || direction == FocusDirectionRight);
    if (!start)
        return ;

    Node* node = start;
    HTMLFrameOwnerElement* owner;
    Document* document;
    IntRect nodeRect;

    while (node) {
        if (!isNodeInSpecificRect(node, rect)) {
            node = getClosestNode(node, direction);
            continue;
        }
        owner = 0;
        if (node->isFrameOwnerElement()) {
            owner = static_cast<HTMLFrameOwnerElement*>(node);
            if (!owner->contentFrame()) {
                *candidateNode = 0;
                return;
            }
            document = owner->contentFrame()->document();
            findHorizontallyFocusableNodeInRect(direction, document, event, rect, candidateNode, candidateNodeRect);
        } else if (isScrollableContainerNode(node) && !node->renderer()->isTextArea()) {
            findHorizontallyFocusableNodeInRect(direction, node->firstChild(), event, rect, candidateNode, candidateNodeRect);
        } else {
            if (node->isFocusable() && !node->isFrameOwnerElement()) {
                nodeRect = node->renderer()->absoluteBoundingBoxRect();
                FrameView* frameView = node->document()->view();
                if (!frameView) {
                    *candidateNode = 0;
                    return;
                }                
                nodeRect = frameView->contentsToWindow(nodeRect);
                nodeRect.intersect(*rect);
                if (!nodeRect.isEmpty()) {
                    if (candidateNodeRect.isEmpty()) {
                        *candidateNode = node;
                        candidateNodeRect = nodeRect;
                    }
                    if (direction == FocusDirectionRight && candidateNodeRect.x() > nodeRect.x()) {
                        *candidateNode = node;
                        candidateNodeRect = nodeRect;
                    } else if (direction == FocusDirectionLeft && candidateNodeRect.x() < nodeRect.x()) {
                        *candidateNode = node;
                        candidateNodeRect = nodeRect;
                    }
                }
            }
        }
        node = getClosestNode(node, direction);
    }
}
void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
{
    for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
        CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
        RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
        ASSERT(renderSurface);

        // Make sure any renderSurfaceLayer is associated with this layerRenderer.
        // This is a defensive assignment in case the owner of this layer hasn't
        // set the layerRenderer on this layer already.
        renderSurfaceLayer->setLayerRenderer(this);

        // Render surfaces whose drawable area has zero width or height
        // will have no layers associated with them and should be skipped.
        if (!renderSurface->m_layerList.size())
            continue;

        LayerList& layerList = renderSurface->m_layerList;
        ASSERT(layerList.size());
        for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
            CCLayerImpl* ccLayerImpl = layerList[layerIndex].get();

            // Layers that start a new render surface will be painted when the render
            // surface's list is processed.
            if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface)
                continue;

            LayerChromium* layer = ccLayerImpl->owner();

            layer->setLayerRenderer(this);

            if (layer->maskLayer())
                layer->maskLayer()->setLayerRenderer(this);
            if (layer->replicaLayer()) {
                layer->replicaLayer()->setLayerRenderer(this);
                if (layer->replicaLayer()->maskLayer())
                    layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
            }

            if (layer->bounds().isEmpty())
              continue;

            IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
            IntRect scissorRect = layer->ccLayerImpl()->scissorRect();
            if (!scissorRect.isEmpty())
                targetSurfaceRect.intersect(scissorRect);

            if (layer->drawsContent())
                layer->paintContentsIfDirty(targetSurfaceRect);
            if (layer->maskLayer() && layer->maskLayer()->drawsContent())
                layer->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
            if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
                layer->replicaLayer()->paintContentsIfDirty(targetSurfaceRect);
            if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
                layer->replicaLayer()->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
        }
    }
}
Ejemplo n.º 24
0
void GraphicsLayerTextureMapper::prepareBackingStore()
{
    TextureMapper* textureMapper = m_layer->textureMapper();
    if (!textureMapper)
        return;

    if (!shouldHaveBackingStore()) {
        m_backingStore.clear();
        return;
    }

    IntRect dirtyRect = enclosingIntRect(FloatRect(FloatPoint::zero(), m_size));
    if (!m_needsDisplay)
        dirtyRect.intersect(enclosingIntRect(m_needsDisplayRect));
    if (dirtyRect.isEmpty())
        return;

    if (!m_backingStore)
        m_backingStore = TextureMapperTiledBackingStore::create();

#if PLATFORM(QT)
    ASSERT(dynamic_cast<TextureMapperTiledBackingStore*>(m_backingStore.get()));
#endif
    TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get());

    if (isShowingRepaintCounter())
        incrementRepaintCount();

    // Paint into an intermediate buffer to avoid painting content more than once.
    bool paintOnce = true;
    const IntSize maxTextureSize = textureMapper->maxTextureSize();
    // We need to paint directly if the dirty rect exceeds one of the maximum dimensions.
    if (dirtyRect.width() > maxTextureSize.width() || dirtyRect.height() > maxTextureSize.height())
        paintOnce = false;

    if (paintOnce) {
        OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(dirtyRect.size());
        GraphicsContext* context = imageBuffer->context();
        context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
        context->setTextDrawingMode(textureMapper->textDrawingMode());
        context->translate(-dirtyRect.x(), -dirtyRect.y());
        paintGraphicsLayerContents(*context, dirtyRect);

        if (isShowingRepaintCounter())
            drawRepaintCounter(context);

        RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore);
        backingStore->updateContents(textureMapper, image.get(), m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);
    } else
        backingStore->updateContents(textureMapper, this, m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);

    backingStore->setShowDebugBorders(isShowingDebugBorder());
    backingStore->setDebugBorder(m_debugBorderColor, m_debugBorderWidth);

    m_needsDisplay = false;
    m_needsDisplayRect = IntRect();
}
Ejemplo n.º 25
0
void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
{
    if (platformWidget()) {
        Widget::paint(context, rect);
        return;
    }

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

    IntRect documentDirtyRect = rect;
    documentDirtyRect.intersect(frameRect());

    context->save();

    context->translate(x(), y());
    documentDirtyRect.move(-x(), -y());

    context->translate(-scrollX(), -scrollY());
    documentDirtyRect.move(scrollX(), scrollY());

    context->clip(visibleContentRect());

    paintContents(context, documentDirtyRect);

    context->restore();

    // Now paint the scrollbars.
    if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
        context->save();
        IntRect scrollViewDirtyRect = rect;
        scrollViewDirtyRect.intersect(frameRect());
        context->translate(x(), y());
        scrollViewDirtyRect.move(-x(), -y());

        paintScrollbars(context, scrollViewDirtyRect);

        context->restore();
    }

    // Paint the panScroll Icon
    if (m_drawPanScrollIcon)
        paintPanScrollIcon(context);
}
void PluginControllerProxy::invalidate(const IntRect& rect)
{
    IntRect dirtyRect = rect;

    // Make sure that the dirty rect is not greater than the plug-in itself.
    dirtyRect.intersect(IntRect(IntPoint(), m_pluginSize));
    m_dirtyRect.unite(dirtyRect);

    startPaintTimer();
}
Ejemplo n.º 27
0
IntRect TiledBackingStore::computeKeepRect(const IntRect& visibleRect) const
{
    IntRect result = visibleRect;
    // Inflates to both sides, so divide the inflate delta by 2.
    result.inflateX(visibleRect.width() * (m_keepAreaMultiplier - 1) / 2);
    result.inflateY(visibleRect.height() * (m_keepAreaMultiplier - 1) / 2);
    result.intersect(contentsRect());

    return result;
}
Ejemplo n.º 28
0
void FramePainter::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
{
    bool needsBackground = bar->isCustomScrollbar() && m_frameView.frame().isMainFrame();
    if (needsBackground) {
        IntRect toFill = bar->frameRect();
        toFill.intersect(rect);
        context->fillRect(toFill, m_frameView.baseBackgroundColor());
    }

    bar->paint(context, rect);
}
Ejemplo n.º 29
0
void FramePainter::paintScrollbar(GraphicsContext& context, Scrollbar& bar, const IntRect& rect)
{
    bool needsBackground = bar.isCustomScrollbar() && frameView().frame().isMainFrame();
    if (needsBackground) {
        IntRect toFill = bar.frameRect();
        toFill.intersect(rect);
        context.fillRect(toFill, frameView().baseBackgroundColor());
    }

    bar.paint(context, CullRect(rect));
}
Ejemplo n.º 30
0
void RenderSVGRoot::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed)
{
    // Apply our local transforms (except for x/y translation), then our shadow, 
    // and then call RenderBox's method to handle all the normal CSS Box model bits
    repaintRect = localToBorderBoxTransform().mapRect(repaintRect);

    // Apply initial viewport clip - not affected by overflow settings    
    repaintRect.intersect(enclosingIntRect(FloatRect(FloatPoint(), m_viewportSize)));

    style()->svgStyle()->inflateForShadow(repaintRect);
    RenderBox::computeRectForRepaint(repaintContainer, repaintRect, fixed);
}