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); }
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); }
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; }
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); }
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); }
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(); } } }
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; }
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); }
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); }
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); } }
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); } }
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(); }
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; }
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); } }
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(); }
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); }
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; }
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); }
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); } } }
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(); }
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(); }
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; }
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); }
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)); }
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); }