Example #1
0
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;
}
Example #2
0
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)));
}
Example #5
0
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());
        }
    }
}
Example #6
0
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;
}
Example #8
0
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;
}
Example #9
0
void RenderRegion::adjustRegionBoundsFromFlowThreadPortionRect(const IntPoint& layerOffset, IntRect& regionBounds)
{
    LayoutRect flippedFlowThreadPortionRect = flowThreadPortionRect();
    flowThread()->flipForWritingMode(flippedFlowThreadPortionRect);
    regionBounds.moveBy(roundedIntPoint(flippedFlowThreadPortionRect.location()));

    UNUSED_PARAM(layerOffset);
}
Example #10
0
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();
}
Example #13
0
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();
}
Example #14
0
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);
}
Example #18
0
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;
}
Example #19
0
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);
}
Example #20
0
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);
}
Example #21
0
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;
}
Example #22
0
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;
}
Example #23
0
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);
}
Example #25
0
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);
}
Example #26
0
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.
}
Example #27
0
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();
    }
}
Example #28
0
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));
            }
        }
    }
}