예제 #1
0
IntSize PageScaleConstraintsSet::mainFrameSize(int contentWidthIncludingScrollbar) const
{
    // If there's no explicit minimum scale factor set, size the frame so that its width == content width
    // so there's no horizontal scrolling at the minimum scale.
    if (m_pageDefinedConstraints.minimumScale < finalConstraints().minimumScale
        && m_userAgentConstraints.minimumScale < finalConstraints().minimumScale
        && contentWidthIncludingScrollbar
        && m_viewSize.width()) {

        // Special case where the contents are exactly as wide as the viewport to prevent an off-by-one due
        // to floating point imprecision in the aspect ratio height calculation.
        if (contentWidthIncludingScrollbar == m_viewSize.width())
            return m_viewSize;

        return expandedIntSize(FloatSize(
            contentWidthIncludingScrollbar,
            computeHeightByAspectRatio(contentWidthIncludingScrollbar, m_viewSize)));
    }

    // If there is a minimum scale (or there's no content size yet), the frame size should match the viewport
    // size at minimum scale, since the viewport must always be contained by the frame.
    FloatSize frameSize(m_viewSize);
    frameSize.scale(1 / finalConstraints().minimumScale);
    return expandedIntSize(frameSize);
}
예제 #2
0
bool SVGRenderingContext::bufferForeground(std::unique_ptr<ImageBuffer>& imageBuffer)
{
    ASSERT(m_paintInfo);
    ASSERT(is<RenderSVGImage>(*m_renderer));
    FloatRect boundingBox = m_renderer->objectBoundingBox();

    // Invalidate an existing buffer if the scale is not correct.
    if (imageBuffer) {
        AffineTransform transform = m_paintInfo->context().getCTM(GraphicsContext::DefinitelyIncludeDeviceScale);
        IntSize expandedBoundingBox = expandedIntSize(boundingBox.size());
        IntSize bufferSize(static_cast<int>(ceil(expandedBoundingBox.width() * transform.xScale())), static_cast<int>(ceil(expandedBoundingBox.height() * transform.yScale())));
        if (bufferSize != imageBuffer->internalSize())
            imageBuffer.reset();
    }

    // Create a new buffer and paint the foreground into it.
    if (!imageBuffer) {
        if ((imageBuffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(boundingBox.size()), ColorSpaceSRGB, m_paintInfo->context()))) {
            GraphicsContext& bufferedRenderingContext = imageBuffer->context();
            bufferedRenderingContext.translate(-boundingBox.x(), -boundingBox.y());
            PaintInfo bufferedInfo(*m_paintInfo);
            bufferedInfo.setContext(bufferedRenderingContext);
            downcast<RenderSVGImage>(*m_renderer).paintForeground(bufferedInfo);
        } else
            return false;
    }

    m_paintInfo->context().drawImageBuffer(*imageBuffer, boundingBox);
    return true;
}
void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect,
    const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect)
{
    FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize);
    zoomedContainerRect.scale(zoom);

    // The ImageBuffer size needs to be scaled to match the final resolution.
    AffineTransform transform = context->getCTM();
    FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale());
    ASSERT(imageBufferScale.width());
    ASSERT(imageBufferScale.height());

    FloatRect imageBufferSize = zoomedContainerRect;
    imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height());

    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(imageBufferSize.size()), 1);
    if (!buffer) // Failed to allocate buffer.
        return;
    drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal);
    RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled);

    // Adjust the source rect and transform due to the image buffer's scaling.
    FloatRect scaledSrcRect = srcRect;
    scaledSrcRect.scale(imageBufferScale.width(), imageBufferScale.height());
    AffineTransform unscaledPatternTransform(patternTransform);
    unscaledPatternTransform.scale(1 / imageBufferScale.width(), 1 / imageBufferScale.height());

    image->drawPattern(context, scaledSrcRect, unscaledPatternTransform, phase, colorSpace, compositeOp, dstRect);
}
예제 #4
0
void SVGImage::drawPatternForContainer(GraphicsContext& context, const FloatSize& containerSize, float zoom, const FloatRect& srcRect,
    const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode)
{
    FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize);
    zoomedContainerRect.scale(zoom);

    // The ImageBuffer size needs to be scaled to match the final resolution.
    AffineTransform transform = context.getCTM();
    FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale());
    ASSERT(imageBufferScale.width());
    ASSERT(imageBufferScale.height());

    FloatRect imageBufferSize = zoomedContainerRect;
    imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height());

    std::unique_ptr<ImageBuffer> buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(imageBufferSize.size()), 1, ColorSpaceSRGB, context, true);
    if (!buffer) // Failed to allocate buffer.
        return;
    drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, CompositeSourceOver, BlendModeNormal);
    if (context.drawLuminanceMask())
        buffer->convertToLuminanceMask();

    RefPtr<Image> image = ImageBuffer::sinkIntoImage(WTFMove(buffer), Unscaled);
    if (!image)
        return;

    // Adjust the source rect and transform due to the image buffer's scaling.
    FloatRect scaledSrcRect = srcRect;
    scaledSrcRect.scale(imageBufferScale.width(), imageBufferScale.height());
    AffineTransform unscaledPatternTransform(patternTransform);
    unscaledPatternTransform.scale(1 / imageBufferScale.width(), 1 / imageBufferScale.height());

    context.setDrawLuminanceMask(false);
    image->drawPattern(context, scaledSrcRect, unscaledPatternTransform, phase, spacing, compositeOp, dstRect, blendMode);
}
예제 #5
0
void SVGImagePainter::paintForeground(const PaintInfo& paintInfo) {
  const LayoutImageResource* imageResource = m_layoutSVGImage.imageResource();
  IntSize imageViewportSize = expandedIntSize(computeImageViewportSize());
  if (imageViewportSize.isEmpty())
    return;

  RefPtr<Image> image = imageResource->image(
      imageViewportSize, m_layoutSVGImage.style()->effectiveZoom());
  FloatRect destRect = m_layoutSVGImage.objectBoundingBox();
  FloatRect srcRect(0, 0, image->width(), image->height());

  SVGImageElement* imageElement = toSVGImageElement(m_layoutSVGImage.element());
  imageElement->preserveAspectRatio()->currentValue()->transformRect(destRect,
                                                                     srcRect);

  InterpolationQuality interpolationQuality = InterpolationDefault;
  interpolationQuality = ImageQualityController::imageQualityController()
                             ->chooseInterpolationQuality(
                                 m_layoutSVGImage, image.get(), image.get(),
                                 LayoutSize(destRect.size()));

  InterpolationQuality previousInterpolationQuality =
      paintInfo.context.imageInterpolationQuality();
  paintInfo.context.setImageInterpolationQuality(interpolationQuality);
  paintInfo.context.drawImage(image.get(), destRect, &srcRect);
  paintInfo.context.setImageInterpolationQuality(previousInterpolationQuality);
}
예제 #6
0
void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect,
    const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& dstRect, blink::WebBlendMode blendMode, const IntSize& repeatSpacing)
{
    FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize);
    zoomedContainerRect.scale(zoom);

    // The ImageBuffer size needs to be scaled to match the final resolution.
    // FIXME: No need to get the full CTM here, we just need the scale.
    AffineTransform transform = context->getCTM();
    FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale());
    ASSERT(imageBufferScale.width());
    ASSERT(imageBufferScale.height());

    FloatSize scaleWithoutCTM(scale.width() / imageBufferScale.width(), scale.height() / imageBufferScale.height());

    FloatRect imageBufferSize = zoomedContainerRect;
    imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height());

    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(imageBufferSize.size()));
    if (!buffer) // Failed to allocate buffer.
        return;

    drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, CompositeSourceOver, blink::WebBlendModeNormal);
    RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled);

    // Adjust the source rect and transform due to the image buffer's scaling.
    FloatRect scaledSrcRect = srcRect;
    scaledSrcRect.scale(imageBufferScale.width(), imageBufferScale.height());

    image->drawPattern(context, scaledSrcRect, scaleWithoutCTM, phase, compositeOp, dstRect, blendMode, repeatSpacing);
}
예제 #7
0
void BitmapImage::drawPattern(GraphicsContext& ctxt, const FloatRect& tileRect, const AffineTransform& transform,
    const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
{
    if (tileRect.isEmpty())
        return;

    if (!ctxt.drawLuminanceMask()) {
        Image::drawPattern(ctxt, tileRect, transform, phase, spacing, op, destRect, blendMode);
        return;
    }
    if (!m_cachedImage) {
        auto buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(tileRect.size()), ctxt);
        if (!buffer)
            return;

        ImageObserver* observer = imageObserver();
        ASSERT(observer);

        // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout.
        setImageObserver(nullptr);

        draw(buffer->context(), tileRect, tileRect, op, blendMode, ImageOrientationDescription());

        setImageObserver(observer);
        buffer->convertToLuminanceMask();

        m_cachedImage = buffer->copyImage(DontCopyBackingStore, Unscaled);
        if (!m_cachedImage)
            return;
    }

    ctxt.setDrawLuminanceMask(false);
    m_cachedImage->drawPattern(ctxt, tileRect, transform, phase, spacing, op, destRect, blendMode);
}
예제 #8
0
void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& transform,
    const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
{
    if (tileRect.isEmpty())
        return;

    if (!ctxt->drawLuminanceMask()) {
        Image::drawPattern(ctxt, tileRect, transform, phase, styleColorSpace, op, destRect, blendMode);
        return;
    }
    if (!m_cachedImage) {
        OwnPtr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(tileRect.size()));
        ASSERT(buffer.get());

        ImageObserver* observer = imageObserver();
        ASSERT(observer);

        // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout.
        setImageObserver(0);

        draw(buffer->context(), tileRect, tileRect, styleColorSpace, op, blendMode);

        setImageObserver(observer);
        buffer->convertToLuminanceMask();

        m_cachedImage = buffer->copyImage(DontCopyBackingStore, Unscaled);
        m_cachedImage->setSpaceSize(spaceSize());

        setImageObserver(observer);
    }

    ctxt->setDrawLuminanceMask(false);
    m_cachedImage->drawPattern(ctxt, tileRect, transform, phase, styleColorSpace, op, destRect, blendMode);
}
예제 #9
0
IntSize TileController::tileSize() const
{
    if (m_inLiveResize || m_tileSizeLocked)
        return tileGrid().tileSize();

    const int kLowestCommonDenominatorMaxTileSize = 4 * 1024;
    IntSize maxTileSize(kLowestCommonDenominatorMaxTileSize, kLowestCommonDenominatorMaxTileSize);

#if USE(IOSURFACE)
    IntSize surfaceSizeLimit = IOSurface::maximumSize();
    surfaceSizeLimit.scale(1 / m_deviceScaleFactor);
    maxTileSize = maxTileSize.shrunkTo(surfaceSizeLimit);
#endif
    
    if (owningGraphicsLayer()->platformCALayerUseGiantTiles())
        return maxTileSize;

    IntSize tileSize(kDefaultTileSize, kDefaultTileSize);

    if (m_scrollability == NotScrollable) {
        IntSize scaledSize = expandedIntSize(boundsWithoutMargin().size() * tileGrid().scale());
        tileSize = scaledSize.constrainedBetween(IntSize(kDefaultTileSize, kDefaultTileSize), maxTileSize);
    } else if (m_scrollability == VerticallyScrollable)
        tileSize.setWidth(std::min(std::max<int>(ceilf(boundsWithoutMargin().width() * tileGrid().scale()), kDefaultTileSize), maxTileSize.width()));

    LOG_WITH_STREAM(Scrolling, stream << "TileController::tileSize newSize=" << tileSize);

    m_tileSizeLocked = true;
    return tileSize;
}
예제 #10
0
FloatSize PDFDocumentImage::size() const
{
    FloatSize expandedCropBoxSize = FloatSize(expandedIntSize(m_cropBox.size()));

    if (m_rotationDegrees == 90 || m_rotationDegrees == 270)
        return expandedCropBoxSize.transposedSize();
    return expandedCropBoxSize;
}
예제 #11
0
IntSize PageScaleConstraintsSet::mainFrameSize() const
{
    // The frame size should match the viewport size at minimum scale, since the
    // viewport must always be contained by the frame.
    FloatSize frameSize(m_viewSize);
    frameSize.scale(1 / finalConstraints().minimumScale);
    return expandedIntSize(frameSize);
}
예제 #12
0
IntRect TileController::boundsForSize(const FloatSize& size) const
{
    IntPoint boundsOriginIncludingMargin(-leftMarginWidth(), -topMarginHeight());
    IntSize boundsSizeIncludingMargin = expandedIntSize(size);
    boundsSizeIncludingMargin.expand(leftMarginWidth() + rightMarginWidth(), topMarginHeight() + bottomMarginHeight());

    return IntRect(boundsOriginIncludingMargin, boundsSizeIncludingMargin);
}
예제 #13
0
Image* SVGImageCache::lookupOrCreateBitmapImageForRenderer(const RenderObject* renderer)
{
    if (!renderer)
        return Image::nullImage();

    const CachedImageClient* client = renderer;

    // The cache needs to know the size of the renderer before querying an image for it.
    SizeAndScalesMap::iterator sizeIt = m_sizeAndScalesMap.find(renderer);
    if (sizeIt == m_sizeAndScalesMap.end())
        return Image::nullImage();

    IntSize size = sizeIt->second.size;
    float zoom = sizeIt->second.zoom;
    float scale = sizeIt->second.scale;

    // FIXME (85335): This needs to take CSS transform scale into account as well.
    Page* page = renderer->document()->page();
    if (!scale)
        scale = page->deviceScaleFactor() * page->pageScaleFactor();

    ASSERT(!size.isEmpty());

    // Lookup image for client in cache and eventually update it.
    ImageDataMap::iterator it = m_imageDataMap.find(client);
    if (it != m_imageDataMap.end()) {
        ImageData& data = it->second;

        // Common case: image size & zoom remained the same.
        if (data.sizeAndScales.size == size && data.sizeAndScales.zoom == zoom && data.sizeAndScales.scale == scale)
            return data.image.get();

        // If the image size for the client changed, we have to delete the buffer, remove the item from the cache and recreate it.
        delete data.buffer;
        m_imageDataMap.remove(it);
    }

    FloatSize scaledSize(size);
    scaledSize.scale(scale);

    // Create and cache new image and image buffer at requested size.
    OwnPtr<ImageBuffer> newBuffer = ImageBuffer::create(expandedIntSize(scaledSize), 1);
    if (!newBuffer)
        return Image::nullImage();

    m_svgImage->drawSVGToImageBuffer(newBuffer.get(), size, zoom, scale, SVGImage::DontClearImageBuffer);

    RefPtr<Image> newImage = newBuffer->copyImage(CopyBackingStore);
    Image* newImagePtr = newImage.get();
    ASSERT(newImagePtr);

    m_imageDataMap.add(client, ImageData(newBuffer.leakPtr(), newImage.release(), SizeAndScales(size, zoom, scale)));
    return newImagePtr;
}
예제 #14
0
IntPoint FrameView::clampOffsetAtScale(const IntPoint& offset, float scale) const
{
    FloatSize scaledSize = unscaledVisibleContentSize();
    if (scale)
        scaledSize.scale(1 / scale);

    IntPoint clampedOffset = offset;
    clampedOffset = clampedOffset.shrunkTo(
        IntPoint(size()) - expandedIntSize(scaledSize));
    return clampedOffset;
}
예제 #15
0
void LayerPool::addLayer(const RefPtr<PlatformCALayer>& layer)
{
    IntSize layerSize(expandedIntSize(layer->bounds().size()));
    if (!canReuseLayerWithSize(layerSize))
        return;

    listOfLayersWithSize(layerSize).prepend(layer);
    m_totalBytes += backingStoreBytesForSize(layerSize);
    
    m_lastAddTime = monotonicallyIncreasingTime();
    schedulePrune();
}
예제 #16
0
void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const String& layerId, String* snapshotId)
{
    GraphicsLayer* layer = layerById(errorString, layerId);
    if (!layer)
        return;

    GraphicsContextRecorder recorder;
    IntSize size = expandedIntSize(layer->size());
    GraphicsContext* context = recorder.record(size, layer->contentsOpaque());
    layer->paint(*context, IntRect(IntPoint(0, 0), size));
    RefPtr<GraphicsContextSnapshot> snapshot = recorder.stop();
    *snapshotId = String::number(++s_lastSnapshotId);
    bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
    ASSERT_UNUSED(newEntry, newEntry);
}
void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const String& layerId, String* snapshotId)
{
    GraphicsLayer* layer = layerById(errorString, layerId);
    if (!layer)
        return;

    IntSize size = expandedIntSize(layer->size());

    SkPictureBuilder pictureBuilder(FloatRect(0, 0, size.width(), size.height()));
    layer->paint(pictureBuilder.context(), IntRect(IntPoint(0, 0), size));

    RefPtr<PictureSnapshot> snapshot = adoptRef(new PictureSnapshot(pictureBuilder.endRecording()));

    *snapshotId = String::number(++s_lastSnapshotId);
    bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
    ASSERT_UNUSED(newEntry, newEntry);
}
예제 #18
0
void CCLayerTreeHostImpl::updateMaxScrollPosition()
{
    if (!m_scrollLayerImpl || !m_scrollLayerImpl->children().size())
        return;

    FloatSize viewBounds = m_viewportSize;
    viewBounds.scale(1 / m_pageScaleDelta);

    IntSize maxScroll = contentSize() - expandedIntSize(viewBounds);
    // The viewport may be larger than the contents in some cases, such as
    // having a vertical scrollbar but no horizontal overflow.
    maxScroll.clampNegativeToZero();

    m_scrollLayerImpl->setMaxScrollPosition(maxScroll);

    // TODO(aelias): Also update sublayers.
}
예제 #19
0
IntSize SVGImage::containerSize() const
{
    SVGSVGElement* rootElement = svgRootElement(m_page.get());
    if (!rootElement)
        return IntSize();

    LayoutSVGRoot* layoutObject = toLayoutSVGRoot(rootElement->layoutObject());
    if (!layoutObject)
        return IntSize();

    // If a container size is available it has precedence.
    IntSize containerSize = layoutObject->containerSize();
    if (!containerSize.isEmpty())
        return containerSize;

    // Assure that a container size is always given for a non-identity zoom level.
    ASSERT(layoutObject->style()->effectiveZoom() == 1);

    FloatSize intrinsicSize;
    double intrinsicRatio = 0;
    layoutObject->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio);

    if (intrinsicSize.isEmpty() && intrinsicRatio) {
        if (!intrinsicSize.width() && intrinsicSize.height())
            intrinsicSize.setWidth(intrinsicSize.height() * intrinsicRatio);
        else if (intrinsicSize.width() && !intrinsicSize.height())
            intrinsicSize.setHeight(intrinsicSize.width() / intrinsicRatio);
    }

    // TODO(davve): In order to maintain aspect ratio the intrinsic
    // size is faked from the viewBox as a last resort. This may cause
    // unwanted side effects. Preferably we should be able to signal
    // the intrinsic ratio in another way.
    if (intrinsicSize.isEmpty())
        intrinsicSize = rootElement->currentViewBoxRect().size();

    if (!intrinsicSize.isEmpty())
        return expandedIntSize(intrinsicSize);

    // As last resort, use CSS replaced element fallback size.
    return IntSize(300, 150);
}
예제 #20
0
void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const String& layerId, String* snapshotId)
{
    GraphicsLayer* layer = layerById(errorString, layerId);
    if (!layer)
        return;

    IntSize size = expandedIntSize(layer->size());

    GraphicsContext context(*layer->paintController());
    IntRect interestRect(IntPoint(0, 0), size);
    layer->paint(context, &interestRect);
    layer->paintController()->commitNewDisplayItems();

    context.beginRecording(interestRect);
    layer->paintController()->paintArtifact().replay(context);
    RefPtr<PictureSnapshot> snapshot = adoptRef(new PictureSnapshot(context.endRecording()));

    *snapshotId = String::number(++s_lastSnapshotId);
    bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
    ASSERT_UNUSED(newEntry, newEntry);
}
PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const WebGestureEvent& e)
{
    switch (e.type) {
    case WebInputEvent::GestureScrollBegin:
        m_type = PlatformEvent::GestureScrollBegin;
        m_data.m_scroll.m_resendingPluginId = e.resendingPluginId;
        break;
    case WebInputEvent::GestureScrollEnd:
        m_type = PlatformEvent::GestureScrollEnd;
        m_data.m_scroll.m_resendingPluginId = e.resendingPluginId;
        break;
    case WebInputEvent::GestureFlingStart:
        m_type = PlatformEvent::GestureFlingStart;
        m_data.m_scroll.m_velocityX = e.data.flingStart.velocityX;
        m_data.m_scroll.m_velocityY = e.data.flingStart.velocityY;
        break;
    case WebInputEvent::GestureScrollUpdate:
        m_type = PlatformEvent::GestureScrollUpdate;
        m_data.m_scroll.m_resendingPluginId = e.resendingPluginId;
        m_data.m_scroll.m_deltaX = scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaX);
        m_data.m_scroll.m_deltaY = scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaY);
        m_data.m_scroll.m_velocityX = e.data.scrollUpdate.velocityX;
        m_data.m_scroll.m_velocityY = e.data.scrollUpdate.velocityY;
        m_data.m_scroll.m_preventPropagation = e.data.scrollUpdate.preventPropagation;
        m_data.m_scroll.m_inertial = e.data.scrollUpdate.inertial;
        break;
    case WebInputEvent::GestureTap:
        m_type = PlatformEvent::GestureTap;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.tap.width, e.data.tap.height)));
        m_data.m_tap.m_tapCount = e.data.tap.tapCount;
        break;
    case WebInputEvent::GestureTapUnconfirmed:
        m_type = PlatformEvent::GestureTapUnconfirmed;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.tap.width, e.data.tap.height)));
        break;
    case WebInputEvent::GestureTapDown:
        m_type = PlatformEvent::GestureTapDown;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.tapDown.width, e.data.tapDown.height)));
        break;
    case WebInputEvent::GestureShowPress:
        m_type = PlatformEvent::GestureShowPress;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.showPress.width, e.data.showPress.height)));
        break;
    case WebInputEvent::GestureTapCancel:
        m_type = PlatformEvent::GestureTapDownCancel;
        break;
    case WebInputEvent::GestureDoubleTap:
        // DoubleTap gesture is now handled as PlatformEvent::GestureTap with tap_count = 2. So no
        // need to convert to a Platfrom DoubleTap gesture. But in WebViewImpl::handleGestureEvent
        // all WebGestureEvent are converted to PlatformGestureEvent, for completeness and not reach
        // the ASSERT_NOT_REACHED() at the end, convert the DoubleTap to a NoType.
        m_type = PlatformEvent::NoType;
        break;
    case WebInputEvent::GestureTwoFingerTap:
        m_type = PlatformEvent::GestureTwoFingerTap;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.twoFingerTap.firstFingerWidth, e.data.twoFingerTap.firstFingerHeight)));
        break;
    case WebInputEvent::GestureLongPress:
        m_type = PlatformEvent::GestureLongPress;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.longPress.width, e.data.longPress.height)));
        break;
    case WebInputEvent::GestureLongTap:
        m_type = PlatformEvent::GestureLongTap;
        m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.longPress.width, e.data.longPress.height)));
        break;
    case WebInputEvent::GesturePinchBegin:
        m_type = PlatformEvent::GesturePinchBegin;
        break;
    case WebInputEvent::GesturePinchEnd:
        m_type = PlatformEvent::GesturePinchEnd;
        break;
    case WebInputEvent::GesturePinchUpdate:
        m_type = PlatformEvent::GesturePinchUpdate;
        m_data.m_pinchUpdate.m_scale = e.data.pinchUpdate.scale;
        break;
    default:
        ASSERT_NOT_REACHED();
    }
    m_position = widget->convertFromRootFrame(flooredIntPoint(convertHitPointToRootFrame(widget, FloatPoint(e.x, e.y))));
    m_globalPosition = IntPoint(e.globalX, e.globalY);
    m_timestamp = e.timeStampSeconds;
    m_modifiers = e.modifiers;
    switch (e.sourceDevice) {
    case WebGestureDeviceTouchpad:
        m_source = PlatformGestureSourceTouchpad;
        break;
    case WebGestureDeviceTouchscreen:
        m_source = PlatformGestureSourceTouchscreen;
        break;
    case WebGestureDeviceUninitialized:
        ASSERT_NOT_REACHED();
    }
}
FloatRect TileController::computeTileCoverageRect(const FloatSize& newSize, const FloatRect& previousVisibleRect, const FloatRect& visibleRect, float contentsScale) const
{
    // If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
    if (!m_isInWindow)
        return visibleRect;

#if PLATFORM(IOS)
    // FIXME: unify the iOS and Mac code.
    UNUSED_PARAM(previousVisibleRect);
    
    if (m_tileCoverage == CoverageForVisibleArea || MemoryPressureHandler::singleton().isUnderMemoryPressure())
        return visibleRect;

    double horizontalMargin = tileSize().width() / contentsScale;
    double verticalMargin = tileSize().height() / contentsScale;

    double currentTime = monotonicallyIncreasingTime();
    double timeDelta = currentTime - m_velocity.lastUpdateTime;

    FloatRect futureRect = visibleRect;
    futureRect.setLocation(FloatPoint(
        futureRect.location().x() + timeDelta * m_velocity.horizontalVelocity,
        futureRect.location().y() + timeDelta * m_velocity.verticalVelocity));

    if (m_velocity.horizontalVelocity) {
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        if (m_velocity.horizontalVelocity < 0)
            futureRect.setX(futureRect.x() - horizontalMargin);
    }

    if (m_velocity.verticalVelocity) {
        futureRect.setHeight(futureRect.height() + verticalMargin);
        if (m_velocity.verticalVelocity < 0)
            futureRect.setY(futureRect.y() - verticalMargin);
    }

    if (!m_velocity.horizontalVelocity && !m_velocity.verticalVelocity) {
        if (m_velocity.scaleChangeRate > 0)
            return visibleRect;
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        futureRect.setHeight(futureRect.height() + verticalMargin);
        futureRect.setX(futureRect.x() - horizontalMargin / 2);
        futureRect.setY(futureRect.y() - verticalMargin / 2);
    }

    // Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
    // hasn't been updated for the current commit.
    IntSize contentSize = expandedIntSize(newSize);
    if (futureRect.maxX() > contentSize.width())
        futureRect.setX(contentSize.width() - futureRect.width());
    if (futureRect.maxY() > contentSize.height())
        futureRect.setY(contentSize.height() - futureRect.height());
    if (futureRect.x() < 0)
        futureRect.setX(0);
    if (futureRect.y() < 0)
        futureRect.setY(0);

    return futureRect;
#else
    UNUSED_PARAM(contentsScale);

    // FIXME: look at how far the document can scroll in each dimension.
    float coverageHorizontalSize = visibleRect.width();
    float coverageVerticalSize = visibleRect.height();

    bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);

    // Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
    // These values were chosen because it's more common to have tall pages and to scroll vertically,
    // so we keep more tiles above and below the current area.

    if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
        coverageHorizontalSize *= 2;

    if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
        coverageVerticalSize *= 3;

    coverageVerticalSize += topMarginHeight() + bottomMarginHeight();
    coverageHorizontalSize += leftMarginWidth() + rightMarginWidth();

    // Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
    // hasn't been updated for the current commit.
    FloatRect coverageBounds = boundsForSize(newSize);
    float coverageLeft = visibleRect.x() - (coverageHorizontalSize - visibleRect.width()) / 2;
    coverageLeft = std::min(coverageLeft, coverageBounds.maxX() - coverageHorizontalSize);
    coverageLeft = std::max(coverageLeft, coverageBounds.x());

    float coverageTop = visibleRect.y() - (coverageVerticalSize - visibleRect.height()) / 2;
    coverageTop = std::min(coverageTop, coverageBounds.maxY() - coverageVerticalSize);
    coverageTop = std::max(coverageTop, coverageBounds.y());

    return FloatRect(coverageLeft, coverageTop, coverageHorizontalSize, coverageVerticalSize);
#endif
}
예제 #23
0
void TileController::adjustTileCoverageRect(FloatRect& coverageRect, const FloatSize& newSize, const FloatRect& previousVisibleRect, const FloatRect& visibleRect, float contentsScale) const
{
    // If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
    if (!m_isInWindow) {
        coverageRect = visibleRect;
        return;
    }

#if PLATFORM(IOS)
    // FIXME: unify the iOS and Mac code.
    UNUSED_PARAM(previousVisibleRect);
    
    if (m_tileCoverage == CoverageForVisibleArea || MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
        coverageRect = visibleRect;
        return;
    }

    double horizontalMargin = kDefaultTileSize / contentsScale;
    double verticalMargin = kDefaultTileSize / contentsScale;

    double currentTime = monotonicallyIncreasingTime();
    double timeDelta = currentTime - m_velocity.lastUpdateTime;

    FloatRect futureRect = visibleRect;
    futureRect.setLocation(FloatPoint(
        futureRect.location().x() + timeDelta * m_velocity.horizontalVelocity,
        futureRect.location().y() + timeDelta * m_velocity.verticalVelocity));

    if (m_velocity.horizontalVelocity) {
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        if (m_velocity.horizontalVelocity < 0)
            futureRect.setX(futureRect.x() - horizontalMargin);
    }

    if (m_velocity.verticalVelocity) {
        futureRect.setHeight(futureRect.height() + verticalMargin);
        if (m_velocity.verticalVelocity < 0)
            futureRect.setY(futureRect.y() - verticalMargin);
    }

    if (!m_velocity.horizontalVelocity && !m_velocity.verticalVelocity) {
        if (m_velocity.scaleChangeRate > 0) {
            coverageRect = visibleRect;
            return;
        }
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        futureRect.setHeight(futureRect.height() + verticalMargin);
        futureRect.setX(futureRect.x() - horizontalMargin / 2);
        futureRect.setY(futureRect.y() - verticalMargin / 2);
    }

    // Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
    // hasn't been updated for the current commit.
    IntSize contentSize = expandedIntSize(newSize);
    if (futureRect.maxX() > contentSize.width())
        futureRect.setX(contentSize.width() - futureRect.width());
    if (futureRect.maxY() > contentSize.height())
        futureRect.setY(contentSize.height() - futureRect.height());
    if (futureRect.x() < 0)
        futureRect.setX(0);
    if (futureRect.y() < 0)
        futureRect.setY(0);

    coverageRect.unite(futureRect);
    return;
#else
    UNUSED_PARAM(contentsScale);

    // FIXME: look at how far the document can scroll in each dimension.
    FloatSize coverageSize = visibleRect.size();

    bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);

    // Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
    // These values were chosen because it's more common to have tall pages and to scroll vertically,
    // so we keep more tiles above and below the current area.
    float widthScale = 1;
    float heightScale = 1;

    if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
        widthScale = 2;

    if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
        heightScale = 3;
    
    coverageSize.scale(widthScale, heightScale);

    FloatRect coverageBounds = boundsForSize(newSize);
    
    FloatRect coverage = expandRectWithinRect(visibleRect, coverageSize, coverageBounds);
    LOG_WITH_STREAM(Scrolling, stream << "TileController::computeTileCoverageRect newSize=" << newSize << " mode " << m_tileCoverage << " expanded to " << coverageSize << " bounds with margin " << coverageBounds << " coverage " << coverage);
    coverageRect.unite(coverage);
#endif
}
예제 #24
0
IntRect TileController::boundsWithoutMargin() const
{
    return IntRect(IntPoint(), expandedIntSize(m_tileCacheLayer->bounds().size()));
}
예제 #25
0
IntRect PageOverlay::computeInterestRect(const GraphicsLayer* graphicsLayer,
                                         const IntRect&) const {
  return IntRect(IntPoint(), expandedIntSize(m_layer->size()));
}
예제 #26
0
PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const WebGestureEvent& e)
{
    float scale = widgetInputEventsScaleFactor(widget);
    IntSize offset = widgetInputEventsOffset(widget);

    switch (e.type) {
    case WebInputEvent::GestureScrollBegin:
        m_type = PlatformEvent::GestureScrollBegin;
        break;
    case WebInputEvent::GestureScrollEnd:
        m_type = PlatformEvent::GestureScrollEnd;
        break;
    case WebInputEvent::GestureFlingStart:
        m_type = PlatformEvent::GestureFlingStart;
        break;
    case WebInputEvent::GestureScrollUpdate:
        m_type = PlatformEvent::GestureScrollUpdate;
        m_data.m_scrollUpdate.m_deltaX = e.data.scrollUpdate.deltaX / scale;
        m_data.m_scrollUpdate.m_deltaY = e.data.scrollUpdate.deltaY / scale;
        m_data.m_scrollUpdate.m_velocityX = e.data.scrollUpdate.velocityX;
        m_data.m_scrollUpdate.m_velocityY = e.data.scrollUpdate.velocityY;
        break;
    case WebInputEvent::GestureScrollUpdateWithoutPropagation:
        m_type = PlatformEvent::GestureScrollUpdateWithoutPropagation;
        m_data.m_scrollUpdate.m_deltaX = e.data.scrollUpdate.deltaX / scale;
        m_data.m_scrollUpdate.m_deltaY = e.data.scrollUpdate.deltaY / scale;
        m_data.m_scrollUpdate.m_velocityX = e.data.scrollUpdate.velocityX;
        m_data.m_scrollUpdate.m_velocityY = e.data.scrollUpdate.velocityY;
        break;
    case WebInputEvent::GestureTap:
        m_type = PlatformEvent::GestureTap;
        m_area = expandedIntSize(FloatSize(e.data.tap.width / scale, e.data.tap.height / scale));
        m_data.m_tap.m_tapCount = e.data.tap.tapCount;
        break;
    case WebInputEvent::GestureTapUnconfirmed:
        m_type = PlatformEvent::GestureTapUnconfirmed;
        m_area = expandedIntSize(FloatSize(e.data.tap.width / scale, e.data.tap.height / scale));
        break;
    case WebInputEvent::GestureTapDown:
        m_type = PlatformEvent::GestureTapDown;
        m_area = expandedIntSize(FloatSize(e.data.tapDown.width / scale, e.data.tapDown.height / scale));
        break;
    case WebInputEvent::GestureShowPress:
        m_type = PlatformEvent::GestureShowPress;
        m_area = expandedIntSize(FloatSize(e.data.showPress.width / scale, e.data.showPress.height / scale));
        break;
    case WebInputEvent::GestureTapCancel:
        m_type = PlatformEvent::GestureTapDownCancel;
        break;
    case WebInputEvent::GestureDoubleTap:
        // DoubleTap gesture is now handled as PlatformEvent::GestureTap with tap_count = 2. So no
        // need to convert to a Platfrom DoubleTap gesture. But in WebViewImpl::handleGestureEvent
        // all WebGestureEvent are converted to PlatformGestureEvent, for completeness and not reach
        // the ASSERT_NOT_REACHED() at the end, convert the DoubleTap to a NoType.
        m_type = PlatformEvent::NoType;
        break;
    case WebInputEvent::GestureTwoFingerTap:
        m_type = PlatformEvent::GestureTwoFingerTap;
        m_area = expandedIntSize(FloatSize(e.data.twoFingerTap.firstFingerWidth / scale, e.data.twoFingerTap.firstFingerHeight / scale));
        break;
    case WebInputEvent::GestureLongPress:
        m_type = PlatformEvent::GestureLongPress;
        m_area = expandedIntSize(FloatSize(e.data.longPress.width / scale, e.data.longPress.height / scale));
        break;
    case WebInputEvent::GestureLongTap:
        m_type = PlatformEvent::GestureLongTap;
        m_area = expandedIntSize(FloatSize(e.data.longPress.width / scale, e.data.longPress.height / scale));
        break;
    case WebInputEvent::GesturePinchBegin:
        m_type = PlatformEvent::GesturePinchBegin;
        break;
    case WebInputEvent::GesturePinchEnd:
        m_type = PlatformEvent::GesturePinchEnd;
        break;
    case WebInputEvent::GesturePinchUpdate:
        m_type = PlatformEvent::GesturePinchUpdate;
        m_data.m_pinchUpdate.m_scale = e.data.pinchUpdate.scale;
        break;
    default:
        ASSERT_NOT_REACHED();
    }
    m_position = widget->convertFromContainingWindow(IntPoint((e.x - offset.width()) / scale, (e.y - offset.height()) / scale));
    m_globalPosition = IntPoint(e.globalX, e.globalY);
    m_timestamp = e.timeStampSeconds;

    m_modifiers = 0;
    if (e.modifiers & WebInputEvent::ShiftKey)
        m_modifiers |= PlatformEvent::ShiftKey;
    if (e.modifiers & WebInputEvent::ControlKey)
        m_modifiers |= PlatformEvent::CtrlKey;
    if (e.modifiers & WebInputEvent::AltKey)
        m_modifiers |= PlatformEvent::AltKey;
    if (e.modifiers & WebInputEvent::MetaKey)
        m_modifiers |= PlatformEvent::MetaKey;
}
예제 #27
0
 IntRect visibleContentRect(IncludeScrollbarsInRect) const override {
   FloatSize size(m_viewportSize);
   size.scale(1 / m_scale);
   return IntRect(IntPoint(flooredIntSize(getScrollOffset())),
                  expandedIntSize(size));
 }