bool RenderWidget::setWidgetGeometry(const LayoutRect& frame) { IntRect clipRect = roundedIntRect(enclosingLayer()->childrenClipRect()); IntRect newFrameRect = roundedIntRect(frame); IntRect oldFrameRect = m_widget->frameRect(); bool clipChanged = m_clipRect != clipRect; bool boundsChanged = oldFrameRect != newFrameRect; if (!boundsChanged && !clipChanged) return false; m_clipRect = clipRect; WeakPtr<RenderWidget> weakThis = createWeakPtr(); // These calls *may* cause this renderer to disappear from underneath... if (boundsChanged) m_widget->setFrameRect(newFrameRect); else if (clipChanged) m_widget->clipRectChanged(); // ...so we follow up with a sanity check. if (!weakThis) return true; #if USE(ACCELERATED_COMPOSITING) if (boundsChanged && hasLayer() && layer()->isComposited()) layer()->backing()->updateAfterWidgetResize(); #endif return oldFrameRect.size() != newFrameRect.size(); }
bool RenderWidget::setWidgetGeometry(const LayoutRect& frame) { if (!node()) return false; IntRect clipRect = roundedIntRect(enclosingLayer()->childrenClipRect()); IntRect newFrame = roundedIntRect(frame); bool clipChanged = m_clipRect != clipRect; bool frameRectChanged = m_widget->frameRect() != newFrame; if (!frameRectChanged && !clipChanged) return false; m_clipRect = clipRect; RefPtr<RenderWidget> protector(this); RefPtr<Node> protectedNode(node()); m_widget->setFrameRect(newFrame); if (clipChanged && !frameRectChanged) m_widget->clipRectChanged(); if (hasLayer() && layer()->compositingState() == PaintsIntoOwnBacking) layer()->compositedLayerMapping()->updateAfterWidgetResize(); bool boundsChanged = m_widget->frameRect().size() != newFrame.size(); return boundsChanged; }
void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, float scale, const FloatPoint& trajectoryVector) { bool contentsRectDidChange = rect != m_visibleContentsRect; bool contentsScaleDidChange = scale != m_contentsScale; // A zero trajectoryVector indicates that tiles all around the viewport are requested. toCoordinatedGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRectTrajectoryVector(trajectoryVector); if (contentsRectDidChange || contentsScaleDidChange) { m_visibleContentsRect = rect; m_contentsScale = scale; HashSet<WebCore::CoordinatedGraphicsLayer*>::iterator end = m_registeredLayers.end(); for (HashSet<WebCore::CoordinatedGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it) { if (contentsScaleDidChange) (*it)->setContentsScale(scale); if (contentsRectDidChange) (*it)->setNeedsVisibleRectAdjustment(); } } scheduleLayerFlush(); if (m_webPage->useFixedLayout()) { // Round the rect instead of enclosing it to make sure that its size stays // the same while panning. This can have nasty effects on layout. m_webPage->setFixedVisibleContentRect(roundedIntRect(rect)); } if (contentsRectDidChange) m_shouldSendScrollPositionUpdate = true; }
// Return true if the rectangle is aligned to integer boundaries. // See comments for computeBitmapDrawRects() for how this is used. static bool areBoundariesIntegerAligned(const SkRect& rect) { // Value is 1.19209e-007. This is the tolerance threshold. const float epsilon = std::numeric_limits<float>::epsilon(); SkIRect roundedRect = roundedIntRect(rect); return fabs(rect.x() - roundedRect.x()) < epsilon && fabs(rect.y() - roundedRect.y()) < epsilon && fabs(rect.right() - roundedRect.right()) < epsilon && fabs(rect.bottom() - roundedRect.bottom()) < epsilon; }
bool LayoutPart::setWidgetGeometry(const LayoutRect& frame) { if (!node()) return false; Widget* widget = this->widget(); ASSERT(widget); IntRect newFrame = roundedIntRect(frame); if (widget->frameRect() == newFrame) return false; RefPtr<LayoutPart> protector(this); RawPtr<Node> protectedNode(node()); widget->setFrameRect(newFrame); return widget->frameRect().size() != newFrame.size(); }
void CoordinatedGraphicsLayer::computePixelAlignment(FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) { if (isIntegral(effectiveContentsScale())) { position = m_position; size = m_size; anchorPoint = m_anchorPoint; alignmentOffset = FloatSize(); return; } FloatPoint positionRelativeToBase = computePositionRelativeToBase(); FloatRect baseRelativeBounds(positionRelativeToBase, m_size); FloatRect scaledBounds = baseRelativeBounds; // Scale by the effective scale factor to compute the screen-relative bounds. scaledBounds.scale(effectiveContentsScale()); // Round to integer boundaries. // NOTE: When using enclosingIntRect (as mac) it will have different sizes depending on position. FloatRect alignedBounds = roundedIntRect(scaledBounds); // Convert back to layer coordinates. alignedBounds.scale(1 / effectiveContentsScale()); // Convert back to layer coordinates. alignmentOffset = baseRelativeBounds.location() - alignedBounds.location(); position = m_position - alignmentOffset; size = alignedBounds.size(); // Now we have to compute a new anchor point which compensates for rounding. float anchorPointX = m_anchorPoint.x(); float anchorPointY = m_anchorPoint.y(); if (alignedBounds.width()) anchorPointX = (baseRelativeBounds.width() * anchorPointX + alignmentOffset.width()) / alignedBounds.width(); if (alignedBounds.height()) anchorPointY = (baseRelativeBounds.height() * anchorPointY + alignmentOffset.height()) / alignedBounds.height(); anchorPoint = FloatPoint3D(anchorPointX, anchorPointY, m_anchorPoint.z() * effectiveContentsScale()); }
// FIXME: Remove this code when SkCanvas accepts SkRect as source rectangle. // See crbug.com/117597 for background. // // WebKit wants to draw a sub-rectangle (FloatRect) in a bitmap and scale it to // another FloatRect. However Skia only allows bitmap to be addressed by a // IntRect. This function computes the appropriate IntRect that encloses the // source rectangle and the corresponding enclosing destination rectangle, // while maintaining the scale factor. // // |srcRect| is the source rectangle in the bitmap. Return true if fancy // alignment is required. User of this function needs to clip to |dstRect|. // Return false if clipping is not needed. // // |dstRect| is the input rectangle that |srcRect| is scaled to. // // |outSrcRect| and |outDstRect| are the corresponding output rectangles. // // ALGORITHM // // The objective is to (a) find an enclosing IntRect for the source rectangle // and (b) the corresponding FloatRect in destination space. // // These are the steps performed: // // 1. IntRect enclosingSrcRect = enclosingIntRect(srcRect) // // Compute the enclosing IntRect for |srcRect|. This ensures the bitmap // image is addressed with integer boundaries. // // 2. FloatRect enclosingDestRect = mapSrcToDest(enclosingSrcRect) // // Map the enclosing source rectangle to destination coordinate space. // // The output will be enclosingSrcRect and enclosingDestRect from the // algorithm above. static bool computeBitmapDrawRects(const SkISize& bitmapSize, const SkRect& srcRect, const SkRect& dstRect, SkIRect* outSrcRect, SkRect* outDstRect) { if (areBoundariesIntegerAligned(srcRect)) { *outSrcRect = roundedIntRect(srcRect); *outDstRect = dstRect; return false; } SkIRect bitmapRect = SkIRect::MakeSize(bitmapSize); SkIRect enclosingSrcRect = enclosingIntRect(srcRect); enclosingSrcRect.intersect(bitmapRect); // Clip to bitmap rectangle. SkRect enclosingDstRect; enclosingDstRect.set(enclosingSrcRect); SkMatrix transform; transform.setRectToRect(srcRect, dstRect, SkMatrix::kFill_ScaleToFit); transform.mapRect(&enclosingDstRect); *outSrcRect = enclosingSrcRect; *outDstRect = enclosingDstRect; return true; }
void CompositingCoordinator::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector) { // A zero trajectoryVector indicates that tiles all around the viewport are requested. if (CoordinatedGraphicsLayer* contentsLayer = mainContentsLayer()) contentsLayer->setVisibleContentRectTrajectoryVector(trajectoryVector); bool contentsRectDidChange = rect != m_visibleContentsRect; if (contentsRectDidChange) { m_visibleContentsRect = rect; for (auto& registeredLayer : m_registeredLayers.values()) registeredLayer->setNeedsVisibleRectAdjustment(); } FrameView* view = m_page->mainFrame().view(); if (view->useFixedLayout() && contentsRectDidChange) { // Round the rect instead of enclosing it to make sure that its size stays // the same while panning. This can have nasty effects on layout. view->setFixedVisibleContentRect(roundedIntRect(rect)); } }
void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector) { // A zero trajectoryVector indicates that tiles all around the viewport are requested. toCoordinatedGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRectTrajectoryVector(trajectoryVector); bool contentsRectDidChange = rect != m_visibleContentsRect; if (contentsRectDidChange) { m_visibleContentsRect = rect; LayerMap::iterator end = m_registeredLayers.end(); for (LayerMap::iterator it = m_registeredLayers.begin(); it != end; ++it) { it->value->setNeedsVisibleRectAdjustment(); } } scheduleLayerFlush(); if (m_webPage->useFixedLayout()) { // Round the rect instead of enclosing it to make sure that its size stays // the same while panning. This can have nasty effects on layout. m_webPage->setFixedVisibleContentRect(roundedIntRect(rect)); } }
LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY) { LayoutRect localExposeRect(box().absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox()); LayoutRect layerBounds(0, 0, box().clientWidth(), box().clientHeight()); LayoutRect r = ScrollAlignment::getRectToExpose(layerBounds, localExposeRect, alignX, alignY); IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset() + toIntSize(roundedIntRect(r).location())); if (clampedScrollOffset == adjustedScrollOffset()) return rect; IntSize oldScrollOffset = adjustedScrollOffset(); scrollToOffset(clampedScrollOffset); IntSize scrollOffsetDifference = adjustedScrollOffset() - oldScrollOffset; localExposeRect.move(-scrollOffsetDifference); return LayoutRect(box().localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox()); }