bool ScrollingTree::shouldHandleWheelEventSynchronously(const PlatformWheelEvent& wheelEvent) { // This method is invoked by the event handling thread MutexLocker lock(m_mutex); if (m_hasWheelEventHandlers) return true; bool shouldSetLatch = wheelEvent.shouldConsiderLatching(); if (hasLatchedNode() && !shouldSetLatch) return false; if (shouldSetLatch) m_latchedNode = 0; if (!m_nonFastScrollableRegion.isEmpty()) { // FIXME: This is not correct for non-default scroll origins. FloatPoint position = wheelEvent.position(); position.moveBy(m_mainFrameScrollPosition); if (m_nonFastScrollableRegion.contains(roundedIntPoint(position))) return true; } return false; }
void WebViewNix::didChangeContentScaleFactor(float scaleFactor) { if (isSuspended()) return; page()->scalePage(scaleFactor, roundedIntPoint(contentPosition())); updateViewportSize(); }
void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.isBoxModelObject()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); if (!layer || !layer->paintsWithTransform(GlobalPaintNormalPhase)) return; } if (context.paintOffset == LayoutPoint()) return; // We should use the same subpixel paint offset values for snapping regardless of whether a // transform is present. If there is a transform we round the paint offset but keep around // the residual fractional component for the transformed content to paint with. // In spv1 this was called "subpixel accumulation". For more information, see // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragmentByApplyingTransform. IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); LayoutPoint fractionalPaintOffset = LayoutPoint(context.paintOffset - roundedPaintOffset); RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), context.currentTransform); context.currentTransform = paintOffsetTranslation.get(); context.paintOffset = fractionalPaintOffset; object.getMutableForPainting().ensureObjectPaintProperties().setPaintOffsetTranslation(paintOffsetTranslation.release()); }
void BackgroundImageGeometry::useFixedAttachment( const LayoutPoint& attachmentPoint) { LayoutPoint alignedPoint = attachmentPoint; m_phase.move(std::max(alignedPoint.x() - m_destRect.x(), LayoutUnit()), std::max(alignedPoint.y() - m_destRect.y(), LayoutUnit())); setPhase(LayoutPoint(roundedIntPoint(m_phase))); }
void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { IntPoint contentPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location()); // Tell the widget to paint now. This is the only time the widget is allowed // to paint itself. That way it will composite properly with z-indexed layers. LayoutRect paintRect = paintInfo.rect; IntPoint widgetLocation = m_widget->frameRect().location(); IntSize widgetPaintOffset = contentPaintOffset - widgetLocation; // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer, // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing. if (!widgetPaintOffset.isZero()) { paintInfo.context->translate(widgetPaintOffset); paintRect.move(-widgetPaintOffset); } // FIXME: Remove repaintrect encolsing/integral snapping when RenderWidget becomes device pixel snapped. m_widget->paint(paintInfo.context, snappedIntRect(paintRect)); if (!widgetPaintOffset.isZero()) paintInfo.context->translate(-widgetPaintOffset); if (is<FrameView>(*m_widget)) { FrameView& frameView = downcast<FrameView>(*m_widget); bool runOverlapTests = !frameView.useSlowRepaintsIfNotOverlapped(); if (paintInfo.overlapTestRequests && runOverlapTests) { ASSERT(!paintInfo.overlapTestRequests->contains(this)); paintInfo.overlapTestRequests->set(this, m_widget->frameRect()); } } }
void WebViewNix::viewportInteractionStop() { if (page()->pageScaleFactor() != contentScaleFactor()) page()->scalePage(contentScaleFactor(), roundedIntPoint(contentPosition())); updateViewportSize(); resumeActiveDOMObjectsAndAnimations(); }
// Generate a synthetic WebMouseEvent given a TouchEvent (eg. for emulating a mouse // with touch input for plugins that don't support touch input). WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const LayoutObject* layoutObject, const TouchEvent& event) { if (!event.touches()) return; if (event.touches()->length() != 1) { if (event.touches()->length() || event.type() != EventTypeNames::touchend || !event.changedTouches() || event.changedTouches()->length() != 1) return; } const Touch* touch = event.touches()->length() == 1 ? event.touches()->item(0) : event.changedTouches()->item(0); if (touch->identifier()) return; if (event.type() == EventTypeNames::touchstart) type = MouseDown; else if (event.type() == EventTypeNames::touchmove) type = MouseMove; else if (event.type() == EventTypeNames::touchend) type = MouseUp; else return; timeStampSeconds = event.platformTimeStamp(); modifiers = event.modifiers(); // The mouse event co-ordinates should be generated from the co-ordinates of the touch point. FrameView* view = toFrameView(widget->parent()); // FIXME: if view == nullptr, pointInRootFrame will really be pointInRootContent. IntPoint pointInRootFrame = roundedIntPoint(touch->absoluteLocation()); if (view) pointInRootFrame = view->contentsToRootFrame(pointInRootFrame); IntPoint screenPoint = roundedIntPoint(touch->screenLocation()); globalX = screenPoint.x(); globalY = screenPoint.y(); windowX = pointInRootFrame.x(); windowY = pointInRootFrame.y(); button = WebMouseEvent::ButtonLeft; modifiers |= WebInputEvent::LeftButtonDown; clickCount = (type == MouseDown || type == MouseUp); IntPoint localPoint = convertAbsoluteLocationForLayoutObject(touch->absoluteLocation(), *layoutObject); x = localPoint.x(); y = localPoint.y(); pointerType = WebPointerProperties::PointerType::Touch; }
IntRect FrameView::convertToRenderer(const RenderObject& renderer, const IntRect& viewRect) const { IntRect rect = viewRect; // FIXME: we don't have a way to map an absolute rect down to a local quad, so just // move the rect for now. rect.setLocation(roundedIntPoint(renderer.absoluteToLocal(rect.location(), UseTransforms))); return rect; }
void RenderRegion::adjustRegionBoundsFromFlowThreadPortionRect(const IntPoint& layerOffset, IntRect& regionBounds) { LayoutRect flippedFlowThreadPortionRect = flowThreadPortionRect(); flowThread()->flipForWritingMode(flippedFlowThreadPortionRect); regionBounds.moveBy(roundedIntPoint(flippedFlowThreadPortionRect.location())); UNUSED_PARAM(layerOffset); }
bool RenderTheme::hitTestMediaControlPart(RenderObject* o, const IntPoint& absPoint) { if (!o->isBox()) return false; FloatPoint localPoint = o->absoluteToLocal(absPoint, false, true); // respect transforms return toRenderBox(o)->borderBoxRect().contains(roundedIntPoint(localPoint)); }
void ThreadedCoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector, float scale) { m_coordinator->setVisibleContentsRect(rect, trajectoryVector); if (m_lastScrollPosition != roundedIntPoint(rect.location())) { m_lastScrollPosition = roundedIntPoint(rect.location()); if (!m_webPage->corePage()->mainFrame().view()->useFixedLayout()) m_webPage->corePage()->mainFrame().view()->notifyScrollPositionChanged(m_lastScrollPosition); } if (m_lastScaleFactor != scale) { m_lastScaleFactor = scale; didScaleFactorChanged(m_lastScaleFactor, m_lastScrollPosition); } scheduleLayerFlush(); }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // An empty viewport disables rendering. if (pixelSnappedBorderBoxRect().isEmpty()) return; // Don't paint, if the context explicitly disabled it. if (paintInfo.context->paintingDisabled()) return; // SVG outlines are painted during PaintPhaseForeground. if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) return; // An empty viewBox also disables rendering. // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute) SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); if (svg->hasEmptyViewBox()) return; // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild()) { SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this); if (!resources || !resources->filter()) return; } // Make a copy of the PaintInfo because applyTransform will modify the damage rect. PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Apply initial viewport clip if (shouldApplyViewportClip()) childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset))); // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset); childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform()); // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter. { SVGRenderingContext renderingContext; bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) { renderingContext.prepareToRenderSVGContent(this, childPaintInfo); continueRendering = renderingContext.isRenderingPrepared(); } if (continueRendering) RenderBox::paint(childPaintInfo, LayoutPoint()); } childPaintInfo.context->restore(); }
VisiblePosition WebLocalFrameImpl::visiblePositionForWindowPoint(const WebPoint& point) { HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping; HitTestResult result(frame()->view()->windowToContents(roundedIntPoint(FloatPoint(point)))); frame()->document()->renderView()->hitTest(request, result.hitTestLocation(), result); if (Node* node = result.targetNode()) return frame()->selection().selection().visiblePositionRespectingEditingBoundary(result.localPoint(), node); return VisiblePosition(); }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // An empty viewport disables rendering. if (pixelSnappedBorderBoxRect().isEmpty()) return; // Don't paint, if the context explicitely disabled it. if (paintInfo.context->paintingDisabled()) return; Page* page = 0; if (Frame* frame = this->frame()) page = frame->page(); // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild()) { SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this); if (!resources || !resources->filter()) { if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantUnpaintedObject(this, visualOverflowRect()); return; } } if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantRepaintedObject(this, visualOverflowRect()); // Make a copy of the PaintInfo because applyTransform will modify the damage rect. PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Apply initial viewport clip - not affected by overflow handling childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset, paintInfo.renderRegion))); // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset); childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform()); // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter. { SVGRenderingContext renderingContext; bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) { renderingContext.prepareToRenderSVGContent(this, childPaintInfo); continueRendering = renderingContext.isRenderingPrepared(); } if (continueRendering) RenderBox::paint(childPaintInfo, LayoutPoint()); } childPaintInfo.context->restore(); }
void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { bool usesPaintOffsetTranslation = false; if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && object.isLayoutView()) { // Root layer scrolling always creates a translation node for LayoutView to // ensure fixed and absolute contexts use the correct transform space. usesPaintOffsetTranslation = true; } else if (object.isBoxModelObject() && context.current.paintOffset != LayoutPoint()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) usesPaintOffsetTranslation = true; } // We should use the same subpixel paint offset values for snapping // regardless of whether a transform is present. If there is a transform // we round the paint offset but keep around the residual fractional // component for the transformed content to paint with. In spv1 this was // called "subpixel accumulation". For more information, see // PaintLayer::subpixelAccumulation() and // PaintLayerPainter::paintFragmentByApplyingTransform. IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset - roundedPaintOffset); if (usesPaintOffsetTranslation) { object.getMutableForPainting() .ensurePaintProperties() .updatePaintOffsetTranslation( context.current.transform, TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); } else { if (auto* properties = object.getMutableForPainting().paintProperties()) properties->clearPaintOffsetTranslation(); } const auto* properties = object.paintProperties(); if (properties && properties->paintOffsetTranslation()) { context.current.transform = properties->paintOffsetTranslation(); context.current.paintOffset = fractionalPaintOffset; if (RuntimeEnabledFeatures::rootLayerScrollingEnabled() && object.isLayoutView()) { context.absolutePosition.transform = properties->paintOffsetTranslation(); context.fixedPosition.transform = properties->paintOffsetTranslation(); context.absolutePosition.paintOffset = LayoutPoint(); context.fixedPosition.paintOffset = LayoutPoint(); } } }
static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpaceQuad, LayoutObject* targetLayoutObject, const LayoutBoxModelObject& paintInvalidationContainer, FloatQuad& compositedSpaceQuad) { DCHECK(targetLayoutObject); for (unsigned i = 0; i < 4; ++i) { IntPoint point; switch (i) { case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; } // FIXME: this does not need to be absolute, just in the paint invalidation container's space. point = targetLayoutObject->frame()->view()->contentsToRootFrame(point); point = paintInvalidationContainer.frame()->view()->rootFrameToContents(point); FloatPoint floatPoint = paintInvalidationContainer.absoluteToLocal(point, UseTransforms); PaintLayer::mapPointInPaintInvalidationContainerToBacking(paintInvalidationContainer, floatPoint); switch (i) { case 0: compositedSpaceQuad.setP1(floatPoint); break; case 1: compositedSpaceQuad.setP2(floatPoint); break; case 2: compositedSpaceQuad.setP3(floatPoint); break; case 3: compositedSpaceQuad.setP4(floatPoint); break; } } }
bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent); // Early exit if local point is not contained in clipped viewport area if (SVGRenderSupport::isOverflowHidden(this) && !m_viewport.contains(localPoint)) return false; IntPoint roundedLocalPoint = roundedIntPoint(localPoint); return RenderBlock::nodeAtPoint(request, result, roundedLocalPoint.x(), roundedLocalPoint.y(), 0, 0, hitTestAction); }
WebVector<WebFloatQuad> WebRange::textQuads() const { if (isNull()) return WebVector<WebFloatQuad>(); Frame* frame = m_private->ownerDocument() ? m_private->ownerDocument()->frame() : 0; if (!frame) return WebVector<WebFloatQuad>(); Vector<FloatQuad> quads; m_private->textQuads(quads); for (unsigned i = 0; i < quads.size(); ++i) { quads[i].setP1(frame->view()->contentsToWindow(roundedIntPoint(quads[i].p1()))); quads[i].setP2(frame->view()->contentsToWindow(roundedIntPoint(quads[i].p2()))); quads[i].setP3(frame->view()->contentsToWindow(roundedIntPoint(quads[i].p3()))); quads[i].setP4(frame->view()->contentsToWindow(roundedIntPoint(quads[i].p4()))); } return quads; }
void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (!shouldPaint(paintInfo, paintOffset)) return; LayoutPoint adjustedPaintOffset = paintOffset + location(); if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) paintBoxDecorations(paintInfo, adjustedPaintOffset); if (paintInfo.phase == PaintPhaseMask) { paintMask(paintInfo, adjustedPaintOffset); return; } if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && hasOutline()) paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size())); if (paintInfo.phase != PaintPhaseForeground) return; #if PLATFORM(MAC) if (style().highlight() != nullAtom && !paintInfo.context->paintingDisabled()) paintCustomHighlight(paintOffset, style().highlight(), true); #endif if (style().hasBorderRadius()) { LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size()); if (borderRect.isEmpty()) return; // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. paintInfo.context->save(); RoundedRect roundedInnerRect = style().getRoundedInnerBorderFor(borderRect, paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true); clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect); } if (m_widget) paintContents(paintInfo, paintOffset); if (style().hasBorderRadius()) paintInfo.context->restore(); // Paint a partially transparent wash over selected widgets. if (isSelected() && !document().printing()) { // FIXME: selectionRect() is in absolute, not painting coordinates. paintInfo.context->fillRect(pixelSnappedIntRect(selectionRect()), selectionBackgroundColor(), style().colorSpace()); } if (hasLayer() && layer()->canResize()) layer()->paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect); }
void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this); if (!shouldPaint(paintInfo, paintOffset)) return; LayoutPoint adjustedPaintOffset = paintOffset + location(); if (hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) paintBoxDecorationBackground(paintInfo, adjustedPaintOffset); if (paintInfo.phase == PaintPhaseMask) { paintMask(paintInfo, adjustedPaintOffset); return; } if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->hasOutline()) paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size())); if (paintInfo.phase != PaintPhaseForeground) return; if (style()->hasBorderRadius()) { LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size()); if (borderRect.isEmpty()) return; // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. paintInfo.context->save(); RoundedRect roundedInnerRect = style()->getRoundedInnerBorderFor(borderRect, paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true); BoxPainter::clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect); } Widget* widget = this->widget(); if (widget) paintContents(paintInfo, paintOffset); if (style()->hasBorderRadius()) paintInfo.context->restore(); // Paint a partially transparent wash over selected widgets. if (isSelected() && !document().printing()) { LayoutRect rect = localSelectionRect(); rect.moveBy(adjustedPaintOffset); paintInfo.context->fillRect(pixelSnappedIntRect(rect), selectionBackgroundColor()); } if (canResize()) layer()->scrollableArea()->paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect); }
FloatPoint RenderGeometryMap::mapToContainer(const FloatPoint& p, const RenderLayerModelObject* container) const { FloatPoint result; if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() && (!container || (m_mapping.size() && container == m_mapping[0].m_renderer))) result = p + roundedIntSize(m_accumulatedOffset); else { TransformState transformState(TransformState::ApplyTransformDirection, p); mapToContainer(transformState, container); result = transformState.lastPlanarPoint(); } #if !ASSERT_DISABLED FloatPoint rendererMappedResult = m_mapping.last().m_renderer->localToAbsolute(p, m_mapCoordinatesFlags); ASSERT(roundedIntPoint(rendererMappedResult) == roundedIntPoint(result)); // if (roundedIntPoint(rendererMappedResult) != roundedIntPoint(result)) // fprintf(stderr, "Mismatched point\n"); #endif return result; }
static WebSelectionBound getWebSelectionBound(const CompositedSelection& selection, bool isStart) { ASSERT(selection.type != NoSelection); const CompositedSelectionBound& bound = isStart ? selection.start : selection.end; ASSERT(bound.layer); WebSelectionBound::Type type = WebSelectionBound::Caret; if (selection.type == RangeSelection) { if (isStart) type = bound.isTextDirectionRTL ? WebSelectionBound::SelectionRight : WebSelectionBound::SelectionLeft; else type = bound.isTextDirectionRTL ? WebSelectionBound::SelectionLeft : WebSelectionBound::SelectionRight; } WebSelectionBound result(type); result.layerId = bound.layer->platformLayer()->id(); result.edgeTopInLayer = roundedIntPoint(bound.edgeTopInLayer); result.edgeBottomInLayer = roundedIntPoint(bound.edgeBottomInLayer); result.isTextDirectionRTL = bound.isTextDirectionRTL; return result; }
WheelEvent::WheelEvent(const FloatPoint& wheelTicks, const FloatPoint& rawDelta, Granularity granularity, PassRefPtr<AbstractView> view, const IntPoint& screenLocation, const IntPoint& pageLocation, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) : MouseRelatedEvent(eventNames().mousewheelEvent, true, true, view, 0, screenLocation, pageLocation, ctrlKey, altKey, shiftKey, metaKey) , m_wheelDelta(IntPoint(static_cast<int>(wheelTicks.x() * 120), static_cast<int>(wheelTicks.y() * 120))) , m_rawDelta(roundedIntPoint(rawDelta)) , m_granularity(granularity) { }
void LayoutSVGForeignObject::layout() { ASSERT(needsLayout()); SVGForeignObjectElement* foreign = toSVGForeignObjectElement(node()); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { m_localTransform = foreign->calculateAnimatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } FloatRect oldViewport = m_viewport; // Cache viewport boundaries SVGLengthContext lengthContext(foreign); FloatPoint viewportLocation( lengthContext.valueForLength(styleRef().svgStyle().x(), styleRef(), SVGLengthMode::Width), lengthContext.valueForLength(styleRef().svgStyle().y(), styleRef(), SVGLengthMode::Height)); m_viewport = FloatRect( viewportLocation, FloatSize(lengthContext.valueForLength(styleRef().width(), styleRef(), SVGLengthMode::Width), lengthContext.valueForLength(styleRef().height(), styleRef(), SVGLengthMode::Height))); if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldViewport != m_viewport; // Set box origin to the foreignObject x/y translation, so positioned objects // in XHTML content get correct positions. A regular LayoutBoxModelObject // would pull this information from ComputedStyle - in SVG those properties // are ignored for non <svg> elements, so we mimic what happens when // specifying them through CSS. // FIXME: Investigate in location rounding issues - only affects // LayoutSVGForeignObject & LayoutSVGText setLocation(roundedIntPoint(viewportLocation)); bool layoutChanged = everHadLayout() && selfNeedsLayout(); LayoutBlock::layout(); ASSERT(!needsLayout()); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) LayoutSVGBlock::setNeedsBoundariesUpdate(); // Invalidate all resources of this client if our layout changed. if (layoutChanged) SVGResourcesCache::clientLayoutChanged(this); }
CursorDirective RenderFrameSet::getCursor(const LayoutPoint& point, Cursor& cursor) const { IntPoint roundedPoint = roundedIntPoint(point); if (canResizeRow(roundedPoint)) { cursor = rowResizeCursor(); return SetCursor; } if (canResizeColumn(roundedPoint)) { cursor = columnResizeCursor(); return SetCursor; } return RenderBox::getCursor(point, cursor); }
void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(ScrollingNodeID scrollingNodeID, const FloatPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction) { ASSERT(isMainThread()); if (!m_page) return; FrameView* frameView = m_page->mainFrame().view(); if (!frameView) return; bool oldProgrammaticScroll = frameView->inProgrammaticScroll(); frameView->setInProgrammaticScroll(programmaticScroll); frameView->setConstrainsScrollingToContentEdge(false); frameView->notifyScrollPositionChanged(roundedIntPoint(scrollPosition)); frameView->setConstrainsScrollingToContentEdge(true); frameView->setInProgrammaticScroll(oldProgrammaticScroll); if (scrollingNodeID == frameView->scrollLayerID()) { if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) { GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView); GraphicsLayer* headerLayer = headerLayerForFrameView(frameView); GraphicsLayer* footerLayer = footerLayerForFrameView(frameView); IntSize scrollOffsetForFixed = frameView->scrollOffsetForFixedPosition(); if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) { scrollLayer->setPosition(-frameView->scrollPosition()); if (counterScrollingLayer) counterScrollingLayer->setPosition(IntPoint(scrollOffsetForFixed)); if (headerLayer) headerLayer->setPosition(FloatPoint(scrollOffsetForFixed.width(), 0)); if (footerLayer) footerLayer->setPosition(FloatPoint(scrollOffsetForFixed.width(), frameView->totalContentsSize().height() - frameView->footerHeight())); } else { scrollLayer->syncPosition(-frameView->scrollPosition()); if (counterScrollingLayer) counterScrollingLayer->syncPosition(IntPoint(scrollOffsetForFixed)); if (headerLayer) headerLayer->syncPosition(FloatPoint(scrollOffsetForFixed.width(), 0)); if (footerLayer) footerLayer->syncPosition(FloatPoint(scrollOffsetForFixed.width(), frameView->totalContentsSize().height() - frameView->footerHeight())); LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); syncChildPositions(viewportRect); } } } // FIXME: handle non-main scrolling nodes. }
void RenderFlowThread::paintFlowThreadPortionInRegion(PaintInfo& paintInfo, RenderRegion* region, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const LayoutPoint& paintOffset) const { GraphicsContext* context = paintInfo.context; if (!context) return; // Adjust the clipping rect for the region. // paintOffset contains the offset where the painting should occur // adjusted with the region padding and border. LayoutRect regionClippingRect = computeRegionClippingRect(paintOffset, flowThreadPortionRect, flowThreadPortionOverflowRect); PaintInfo info(paintInfo); info.rect.intersect(pixelSnappedIntRect(regionClippingRect)); if (!info.rect.isEmpty()) { context->save(); context->clip(regionClippingRect); // RenderFlowThread should start painting its content in a position that is offset // from the region rect's current position. The amount of offset is equal to the location of // the flow thread portion in the flow thread's local coordinates. IntPoint renderFlowThreadOffset; if (style()->isFlippedBlocksWritingMode()) { LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect); flipForWritingMode(flippedFlowThreadPortionRect); renderFlowThreadOffset = roundedIntPoint(paintOffset - flippedFlowThreadPortionRect.location()); } else renderFlowThreadOffset = roundedIntPoint(paintOffset - flowThreadPortionRect.location()); context->translate(renderFlowThreadOffset.x(), renderFlowThreadOffset.y()); info.rect.moveBy(-renderFlowThreadOffset); layer()->paint(context, info.rect, 0, 0, region, RenderLayer::PaintLayerTemporaryClipRects); context->restore(); } }
void RenderSlider::forwardEvent(Event* event) { if (event->isMouseEvent()) { MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); if (event->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) { if (!mouseEventIsInThumb(mouseEvent)) { IntPoint eventOffset = roundedIntPoint(absoluteToLocal(mouseEvent->absoluteLocation(), false, true)); setValueForPosition(positionForOffset(eventOffset)); } } } m_thumb->defaultEventHandler(event); }
void SpinButtonElement::defaultEventHandler(Event* evt) { if (!evt->isMouseEvent()) { if (!evt->defaultHandled()) HTMLDivElement::defaultEventHandler(evt); return; } const MouseEvent* mevt = static_cast<MouseEvent*>(evt); if (mevt->button() != LeftButton) { if (!evt->defaultHandled()) HTMLDivElement::defaultEventHandler(evt); return; } HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode()); IntPoint local = roundedIntPoint(renderBox()->absoluteToLocal(mevt->absoluteLocation(), false, true)); if (evt->type() == eventNames().clickEvent) { if (renderBox()->borderBoxRect().contains(local)) { input->focus(); input->select(); if (local.y() < renderBox()->y() + renderBox()->height() / 2) input->stepUpFromRenderer(1); else input->stepUpFromRenderer(-1); evt->setDefaultHandled(); } } else if (evt->type() == eventNames().mousemoveEvent) { if (renderBox()->borderBoxRect().contains(local)) { if (!m_capturing) { if (Frame* frame = document()->frame()) { frame->eventHandler()->setCapturingMouseEventsNode(input); m_capturing = true; } } bool oldOnUpButton = m_onUpButton; m_onUpButton = local.y() < renderBox()->y() + renderBox()->height() / 2; if (m_onUpButton != oldOnUpButton) renderer()->repaint(); } else { if (m_capturing) { if (Frame* frame = document()->frame()) { frame->eventHandler()->setCapturingMouseEventsNode(0); m_capturing = false; } } } } if (!evt->defaultHandled()) HTMLDivElement::defaultEventHandler(evt); }
// Return a set of rectangles that should not be overdrawn by the // plugin ("cutouts"). This helps implement the "iframe shim" // technique of overlaying a windowed plugin with content from the // page. In a nutshell, iframe elements should occlude plugins when // they occur higher in the stacking order. void WebPluginContainerImpl::windowCutOutRects(const IntRect& frameRect, Vector<IntRect>& cutOutRects) { RenderObject* pluginNode = m_element->renderer(); ASSERT(pluginNode); if (!pluginNode->style()) return; Vector<const RenderObject*> pluginZstack; Vector<const RenderObject*> iframeZstack; getObjectStack(pluginNode, &pluginZstack); // Get the parent widget Widget* parentWidget = this->parent(); if (!parentWidget->isFrameView()) return; FrameView* parentFrameView = static_cast<FrameView*>(parentWidget); const HashSet<RefPtr<Widget> >* children = parentFrameView->children(); for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != children->end(); ++it) { // We only care about FrameView's because iframes show up as FrameViews. if (!(*it)->isFrameView()) continue; const FrameView* frameView = static_cast<const FrameView*>((*it).get()); // Check to make sure we can get both the element and the RenderObject // for this FrameView, if we can't just move on to the next object. if (!frameView->frame() || !frameView->frame()->ownerElement() || !frameView->frame()->ownerElement()->renderer()) continue; HTMLElement* element = frameView->frame()->ownerElement(); RenderObject* iframeRenderer = element->renderer(); if (element->hasTagName(HTMLNames::iframeTag) && iframeRenderer->absoluteBoundingBoxRect().intersects(frameRect) && (!iframeRenderer->style() || iframeRenderer->style()->visibility() == VISIBLE)) { getObjectStack(iframeRenderer, &iframeZstack); if (checkStackOnTop(iframeZstack, pluginZstack)) { IntPoint point = roundedIntPoint(iframeRenderer->localToAbsolute()); RenderBox* rbox = toRenderBox(iframeRenderer); IntSize size(rbox->width(), rbox->height()); cutOutRects.append(IntRect(point, size)); } } } }