예제 #1
0
void FEGaussianBlur::platformApplySoftware()
{
    FilterEffect* in = inputEffect(0);

    Uint8ClampedArray* srcPixelArray = createPremultipliedImageResult();
    if (!srcPixelArray)
        return;

    setIsAlphaImage(in->isAlphaImage());

    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    in->copyPremultipliedImage(srcPixelArray, effectDrawingRect);

    if (!m_stdX && !m_stdY)
        return;

    IntSize kernelSize = calculateKernelSize(filter(), FloatPoint(m_stdX, m_stdY));
    kernelSize.scale(filter().filterScale());

    IntSize paintSize = absolutePaintRect().size();
    paintSize.scale(filter().filterScale());
    RefPtr<Uint8ClampedArray> tmpImageData = Uint8ClampedArray::createUninitialized((paintSize.area() * 4).unsafeGet());
    if (!tmpImageData) {
        WTFLogAlways("FEGaussianBlur::platformApplySoftware Unable to create buffer. Requested size was %d x %d\n", paintSize.width(), paintSize.height());
        return;
    }

    platformApply(srcPixelArray, tmpImageData.get(), kernelSize.width(), kernelSize.height(), paintSize);
}
예제 #2
0
void RenderStyle::getBorderRadiiForRect(const IntRect& r, IntSize& topLeft, IntSize& topRight, IntSize& bottomLeft, IntSize& bottomRight) const
{
    topLeft = surround->border.topLeft;
    topRight = surround->border.topRight;
    
    bottomLeft = surround->border.bottomLeft;
    bottomRight = surround->border.bottomRight;

    // Constrain corner radii using CSS3 rules:
    // http://www.w3.org/TR/css3-background/#the-border-radius
    
    float factor = 1;
    unsigned radiiSum;

    // top
    radiiSum = static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()); // Casts to avoid integer overflow.
    if (radiiSum > static_cast<unsigned>(r.width()))
        factor = min(static_cast<float>(r.width()) / radiiSum, factor);

    // bottom
    radiiSum = static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width());
    if (radiiSum > static_cast<unsigned>(r.width()))
        factor = min(static_cast<float>(r.width()) / radiiSum, factor);
    
    // left
    radiiSum = static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height());
    if (radiiSum > static_cast<unsigned>(r.height()))
        factor = min(static_cast<float>(r.height()) / radiiSum, factor);
    
    // right
    radiiSum = static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height());
    if (radiiSum > static_cast<unsigned>(r.height()))
        factor = min(static_cast<float>(r.height()) / radiiSum, factor);
    
    // Scale all radii by f if necessary.
    if (factor < 1) {
        // If either radius on a corner becomes zero, reset both radii on that corner.
        topLeft.scale(factor);
        if (!topLeft.width() || !topLeft.height())
            topLeft = IntSize();
        topRight.scale(factor);
        if (!topRight.width() || !topRight.height())
            topRight = IntSize();
        bottomLeft.scale(factor);
        if (!bottomLeft.width() || !bottomLeft.height())
            bottomLeft = IntSize();
        bottomRight.scale(factor);
        if (!bottomRight.width() || !bottomRight.height())
            bottomRight = IntSize();
    }
}
예제 #3
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;
}
예제 #4
0
void CCLayerTreeHostImpl::computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo)
{
    float pageScale = m_pageScaleAnimation->finalPageScale();
    IntSize scrollOffset = m_pageScaleAnimation->finalScrollOffset();
    scrollOffset.scale(m_pageScale / pageScale);
    makeScrollAndScaleSet(scrollInfo, scrollOffset, pageScale);
}
예제 #5
0
IntSize CCPageScaleAnimation::scrollOffsetAtRatio(float ratio) const
{
    if (ratio <= 0)
        return m_scrollStart;
    if (ratio >= 1)
        return m_scrollEnd;

    float currentPageScale = pageScaleAtRatio(ratio);
    IntSize currentScrollOffset;
    if (m_anchorMode) {
        // Keep the anchor stable on the screen at the current scale.
        IntSize documentAnchor = m_scrollStart + m_anchor;
        documentAnchor.scale(currentPageScale / m_pageScaleStart);
        currentScrollOffset = documentAnchor - m_anchor;
    } else {
        // First move both scroll offsets to the current coordinate space.
        FloatSize scaledStartScroll(m_scrollStart);
        scaledStartScroll.scale(currentPageScale / m_pageScaleStart);
        FloatSize scaledEndScroll(m_scrollEnd);
        scaledEndScroll.scale(currentPageScale / m_pageScaleEnd);

        // Linearly interpolate between them.
        FloatSize delta = scaledEndScroll - scaledStartScroll;
        delta.scale(ratio);
        currentScrollOffset = roundedIntSize(scaledStartScroll + delta);
    }

    return currentScrollOffset;
}
예제 #6
0
bool FindController::getFindIndicatorBitmapAndRect(Frame* frame, ShareableBitmap::Handle& handle, IntRect& selectionRect)
{
    selectionRect = enclosingIntRect(frame->selection()->bounds());

    // Selection rect can be empty for matches that are currently obscured from view.
    if (selectionRect.isEmpty())
        return false;

    IntSize backingStoreSize = selectionRect.size();
    backingStoreSize.scale(m_webPage->corePage()->deviceScaleFactor());

    // Create a backing store and paint the find indicator text into it.
    RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha);
    if (!findIndicatorTextBackingStore)
        return false;

    OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext();
    graphicsContext->scale(FloatSize(m_webPage->corePage()->deviceScaleFactor(), m_webPage->corePage()->deviceScaleFactor()));

    IntRect paintRect = selectionRect;
    paintRect.move(frame->view()->frameRect().x(), frame->view()->frameRect().y());
    paintRect.move(-frame->view()->scrollOffset());

    graphicsContext->translate(-paintRect.x(), -paintRect.y());
    frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers);
    frame->document()->updateLayout();

    frame->view()->paint(graphicsContext.get(), paintRect);
    frame->view()->setPaintBehavior(PaintBehaviorNormal);

    if (!findIndicatorTextBackingStore->createHandle(handle))
        return false;
    return true;
}
예제 #7
0
IntSize DrawingBuffer::adjustSize(const IntSize& size) {
    IntSize adjustedSize = size;

    // Clamp if the desired size is greater than the maximum texture size for the device.
    if (adjustedSize.height() > m_maxTextureSize)
        adjustedSize.setHeight(m_maxTextureSize);

    if (adjustedSize.width() > m_maxTextureSize)
        adjustedSize.setWidth(m_maxTextureSize);

    // Try progressively smaller sizes until we find a size that fits or reach a scale limit.
    int scaleAttempts = 0;
    while ((s_currentResourceUsePixels + pixelDelta(adjustedSize)) > s_maximumResourceUsePixels) {
        scaleAttempts++;
        if (scaleAttempts > s_maxScaleAttempts)
            return IntSize();

        adjustedSize.scale(s_resourceAdjustedRatio);

        if (adjustedSize.isEmpty())
            return IntSize();
    }

    return adjustedSize;
}
std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend()
{
#if PLATFORM(GTK) && PLATFORM(X11)
    const auto& sharedDisplay = PlatformDisplay::sharedDisplay();
    if (is<PlatformDisplayX11>(sharedDisplay)) {
        GdkVisual* visual = gtk_widget_get_visual(m_webPageProxy.viewWidget());
        GdkScreen* screen = gdk_visual_get_screen(visual);
        ASSERT(downcast<PlatformDisplayX11>(sharedDisplay).native() == GDK_SCREEN_XDISPLAY(screen));
        return std::make_unique<BackingStoreBackendCairoX11>(downcast<PlatformDisplayX11>(sharedDisplay).native(), GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
            GDK_VISUAL_XVISUAL(visual), gdk_visual_get_depth(visual), m_size, m_deviceScaleFactor);
    }
#endif

    IntSize scaledSize = m_size;
    scaledSize.scale(m_deviceScaleFactor);

#if PLATFORM(GTK)
    RefPtr<cairo_surface_t> surface = adoptRef(gdk_window_create_similar_surface(gtk_widget_get_window(m_webPageProxy.viewWidget()),
        CAIRO_CONTENT_COLOR_ALPHA, scaledSize.width(), scaledSize.height()));
#else
    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height()));
#endif

    cairoSurfaceSetDeviceScale(surface.get(), m_deviceScaleFactor, m_deviceScaleFactor);
    return std::make_unique<BackingStoreBackendCairoImpl>(surface.get(), m_size);
}
예제 #9
0
static PassRefPtr<WebImage> imageForRect(FrameView* frameView, const IntRect& rect, SnapshotOptions options)
{
    IntSize bitmapSize = rect.size();
    float scaleFactor = frameView->frame().page()->deviceScaleFactor();
    bitmapSize.scale(scaleFactor);

    auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
    if (!snapshot->bitmap())
        return 0;

    auto graphicsContext = snapshot->bitmap()->createGraphicsContext();
    graphicsContext->clearRect(IntRect(IntPoint(), bitmapSize));
    graphicsContext->applyDeviceScaleFactor(scaleFactor);
    graphicsContext->translate(-rect.x(), -rect.y());

    FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
    if (options & SnapshotOptionsExcludeSelectionHighlighting)
        shouldPaintSelection = FrameView::ExcludeSelection;

    PaintBehavior paintBehavior = frameView->paintBehavior() | PaintBehaviorFlattenCompositingLayers;
    if (options & SnapshotOptionsForceBlackText)
        paintBehavior |= PaintBehaviorForceBlackText;
    if (options & SnapshotOptionsForceWhiteText)
        paintBehavior |= PaintBehaviorForceWhiteText;

    PaintBehavior oldPaintBehavior = frameView->paintBehavior();
    frameView->setPaintBehavior(paintBehavior);
    frameView->paintContentsForSnapshot(*graphicsContext.get(), rect, shouldPaintSelection, FrameView::DocumentCoordinates);
    frameView->setPaintBehavior(oldPaintBehavior);

    return snapshot;
}
void ScrollableAreaPainter::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
{
    float deviceScaleFactor = blink::deviceScaleFactor(m_scrollableArea.box().frame());

    RefPtr<Image> resizeCornerImage;
    IntSize cornerResizerSize;
    if (deviceScaleFactor >= 2) {
        DEFINE_STATIC_REF(Image, resizeCornerImageHiRes, (Image::loadPlatformResource("textAreaResizeCorner@2x")));
        resizeCornerImage = resizeCornerImageHiRes;
        cornerResizerSize = resizeCornerImage->size();
        cornerResizerSize.scale(0.5f);
    } else {
        DEFINE_STATIC_REF(Image, resizeCornerImageLoRes, (Image::loadPlatformResource("textAreaResizeCorner")));
        resizeCornerImage = resizeCornerImageLoRes;
        cornerResizerSize = resizeCornerImage->size();
    }

    if (m_scrollableArea.box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
        context->save();
        context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
        context->scale(-1.0, 1.0);
        context->drawImage(resizeCornerImage.get(), IntRect(IntPoint(), cornerResizerSize));
        context->restore();
        return;
    }
    IntRect imageRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, cornerResizerSize);
    context->drawImage(resizeCornerImage.get(), imageRect);
}
예제 #11
0
bool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay, bool shouldAnimate)
{
    if (!selectedFrame)
        return false;

    IntRect selectionRect = enclosingIntRect(selectedFrame->selection()->bounds());
    
    // Selection rect can be empty for matches that are currently obscured from view.
    if (selectionRect.isEmpty())
        return false;

    // We want the selection rect in window coordinates.
    IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(selectionRect);
    
    Vector<FloatRect> textRects;
    selectedFrame->selection()->getClippedVisibleTextRectangles(textRects);

    IntSize backingStoreSize = selectionRect.size();
    backingStoreSize.scale(m_webPage->corePage()->deviceScaleFactor());

    // Create a backing store and paint the find indicator text into it.
    RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha);
    if (!findIndicatorTextBackingStore)
        return false;
    
    OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext();
    graphicsContext->scale(FloatSize(m_webPage->corePage()->deviceScaleFactor(), m_webPage->corePage()->deviceScaleFactor()));

    IntRect paintRect = selectionRect;
    paintRect.move(selectedFrame->view()->frameRect().x(), selectedFrame->view()->frameRect().y());
    paintRect.move(-selectedFrame->view()->scrollOffset());

    graphicsContext->translate(-paintRect.x(), -paintRect.y());
    selectedFrame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers);
    selectedFrame->document()->updateLayout();

    selectedFrame->view()->paint(graphicsContext.get(), paintRect);
    selectedFrame->view()->setPaintBehavior(PaintBehaviorNormal);
    
    ShareableBitmap::Handle handle;
    if (!findIndicatorTextBackingStore->createHandle(handle))
        return false;

    // We want the text rects in selection rect coordinates.
    Vector<FloatRect> textRectsInSelectionRectCoordinates;
    
    for (size_t i = 0; i < textRects.size(); ++i) {
        IntRect textRectInSelectionRectCoordinates = selectedFrame->view()->contentsToWindow(enclosingIntRect(textRects[i]));
        textRectInSelectionRectCoordinates.move(-selectionRectInWindowCoordinates.x(), -selectionRectInWindowCoordinates.y());

        textRectsInSelectionRectCoordinates.append(textRectInSelectionRectCoordinates);
    }            

    m_webPage->send(Messages::WebPageProxy::SetFindIndicator(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, m_webPage->corePage()->deviceScaleFactor(), handle, !isShowingOverlay, shouldAnimate));
    m_findIndicatorRect = selectionRectInWindowCoordinates;
    m_isShowingFindIndicator = true;

    return true;
}
예제 #12
0
void CoordinatedDrawingArea::display(UpdateInfo& updateInfo)
{
    ASSERT(!m_isPaintingSuspended);
    ASSERT(!m_layerTreeHost);
    ASSERT(!m_webPage.size().isEmpty());

    m_webPage.layoutIfNeeded();

    // The layout may have put the page into accelerated compositing mode. If the LayerTreeHost is
    // in charge of displaying, we have nothing more to do.
    if (m_layerTreeHost)
        return;

    updateInfo.viewSize = m_webPage.size();
    updateInfo.deviceScaleFactor = m_webPage.corePage()->deviceScaleFactor();

    IntRect bounds = m_dirtyRegion.bounds();
    ASSERT(m_webPage.bounds().contains(bounds));

    IntSize bitmapSize = bounds.size();
    float deviceScaleFactor = m_webPage.corePage()->deviceScaleFactor();
    bitmapSize.scale(deviceScaleFactor);
    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bitmapSize, ShareableBitmap::SupportsAlpha);
    if (!bitmap)
        return;

    if (!bitmap->createHandle(updateInfo.bitmapHandle))
        return;

    Vector<IntRect> rects = m_dirtyRegion.rects();

    if (shouldPaintBoundsRect(bounds, rects)) {
        rects.clear();
        rects.append(bounds);
    }

    updateInfo.scrollRect = m_scrollRect;
    updateInfo.scrollOffset = m_scrollOffset;

    m_dirtyRegion = Region();
    m_scrollRect = IntRect();
    m_scrollOffset = IntSize();

    auto graphicsContext = bitmap->createGraphicsContext();
    graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);

    updateInfo.updateRectBounds = bounds;

    graphicsContext->translate(-bounds.x(), -bounds.y());

    for (auto& rect : rects) {
        m_webPage.drawRect(*graphicsContext, rect);
        updateInfo.updateRects.append(rect);
    }

    // Layout can trigger more calls to setNeedsDisplay and we don't want to process them
    // until the UI process has painted the update, so we stop the timer here.
    m_displayTimer.stop();
}
예제 #13
0
void CCLayerTreeHostImpl::adjustScrollsForPageScaleChange(float pageScaleChange)
{
    if (pageScaleChange == 1)
        return;

    // We also need to convert impl-side scroll deltas to pageScale space.
    if (m_scrollLayerImpl) {
        IntSize scrollDelta = m_scrollLayerImpl->scrollDelta();
        scrollDelta.scale(pageScaleChange);
        m_scrollLayerImpl->setScrollDelta(scrollDelta);
    }
}
예제 #14
0
void DrawingBuffer::reset(const IntSize& newSize)
{
    if (!m_context)
        return;

    IntSize adjustedSize;
    bool evictContext = false;
    bool isNewContext = m_size.isEmpty();
    if (s_allowContextEvictionOnCreate && isNewContext)
        adjustedSize = adjustSizeWithContextEviction(newSize, evictContext);
    else
        adjustedSize = adjustSize(newSize);

    if (adjustedSize.isEmpty())
        return;

    if (evictContext)
        m_contextEvictionManager->forciblyLoseOldestContext("WARNING: WebGL contexts have exceeded the maximum allowed backbuffer area. Oldest context will be lost.");

    if (adjustedSize != m_size) {
        do {
            // resize multisample FBO
            if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffer(adjustedSize)) {
                adjustedSize.scale(s_resourceAdjustedRatio);
                continue;
            }
            break;
        } while (!adjustedSize.isEmpty());

        setSize(adjustedSize);

        if (adjustedSize.isEmpty())
            return;
    }

    m_context->disable(GL_SCISSOR_TEST);
    m_context->clearColor(0, 0, 0, 0);
    m_context->colorMask(true, true, true, true);

    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
    if (m_attributes.depth) {
        m_context->clearDepth(1.0f);
        clearMask |= GL_DEPTH_BUFFER_BIT;
        m_context->depthMask(true);
    }
    if (m_attributes.stencil) {
        m_context->clearStencil(0);
        clearMask |= GL_STENCIL_BUFFER_BIT;
        m_context->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
    }

    clearFramebuffers(clearMask);
}
BackingStoreBackendCairoX11::BackingStoreBackendCairoX11(unsigned long rootWindowID, Visual* visual, int depth, const IntSize& size, float deviceScaleFactor)
    : BackingStoreBackendCairo(size)
{
    IntSize scaledSize = size;
    scaledSize.scale(deviceScaleFactor);

    auto* display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native();
    m_pixmap = XCreatePixmap(display, rootWindowID, scaledSize.width(), scaledSize.height(), depth);
    m_gc.reset(XCreateGC(display, m_pixmap.get(), 0, nullptr));

    m_surface = adoptRef(cairo_xlib_surface_create(display, m_pixmap.get(), visual, scaledSize.width(), scaledSize.height()));
    cairoSurfaceSetDeviceScale(m_surface.get(), deviceScaleFactor, deviceScaleFactor);
}
예제 #16
0
PassRefPtr<WebImage> InjectedBundleRangeHandle::renderedImage(SnapshotOptions options)
{
    Document& ownerDocument = m_range->ownerDocument();
    Frame* frame = ownerDocument.frame();
    if (!frame)
        return nullptr;

    FrameView* frameView = frame->view();
    if (!frameView)
        return nullptr;

    Ref<Frame> protector(*frame);

    VisibleSelection oldSelection = frame->selection().selection();
    frame->selection().setSelection(VisibleSelection(*m_range));

    float scaleFactor = (options & SnapshotOptionsExcludeDeviceScaleFactor) ? 1 : frame->page()->deviceScaleFactor();
    IntRect paintRect = enclosingIntRect(m_range->absoluteBoundingRect());
    IntSize backingStoreSize = paintRect.size();
    backingStoreSize.scale(scaleFactor);

    RefPtr<ShareableBitmap> backingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha);
    if (!backingStore)
        return nullptr;

    auto graphicsContext = backingStore->createGraphicsContext();
    graphicsContext->scale(scaleFactor);

    paintRect.move(frameView->frameRect().x(), frameView->frameRect().y());
    paintRect.moveBy(-frameView->scrollPosition());

    graphicsContext->translate(-paintRect.x(), -paintRect.y());

    PaintBehavior oldPaintBehavior = frameView->paintBehavior();
    PaintBehavior paintBehavior = oldPaintBehavior | PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers;
    if (options & SnapshotOptionsForceBlackText)
        paintBehavior |= PaintBehaviorForceBlackText;
    if (options & SnapshotOptionsForceWhiteText)
        paintBehavior |= PaintBehaviorForceWhiteText;

    frameView->setPaintBehavior(paintBehavior);
    ownerDocument.updateLayout();

    frameView->paint(*graphicsContext, paintRect);
    frameView->setPaintBehavior(oldPaintBehavior);

    frame->selection().setSelection(oldSelection);

    return WebImage::create(backingStore);
}
예제 #17
0
void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem)
{
    if (!context().isAcceleratedContext()) {
        IntRect scaledSourceRect = sourceRect;
        IntSize scaledSourceSize = sourceSize;
        if (coordinateSystem == LogicalCoordinateSystem) {
            scaledSourceRect.scale(m_resolutionScale);
            scaledSourceSize.scale(m_resolutionScale);
        }

        m_data.putData(source, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), false, multiplied == Unmultiplied, 1);
        return;
    }

#if USE(IOSURFACE_CANVAS_BACKING_STORE)
    // Make a copy of the source to ensure the bits don't change before being drawn
    IntSize sourceCopySize(sourceRect.width(), sourceRect.height());
    // FIXME (149431): Should this ImageBuffer be unconditionally unaccelerated? Making it match the context seems to break putData().
    std::unique_ptr<ImageBuffer> sourceCopy = ImageBuffer::create(sourceCopySize, Unaccelerated, 1, ColorSpaceDeviceRGB);
    if (!sourceCopy)
        return;

    sourceCopy->m_data.putData(source, sourceSize, sourceRect, IntPoint(-sourceRect.x(), -sourceRect.y()), sourceCopy->internalSize(), sourceCopy->context().isAcceleratedContext(), multiplied == Unmultiplied, 1);

    // Set up context for using drawImage as a direct bit copy
    CGContextRef destContext = context().platformContext();
    CGContextSaveGState(destContext);
    if (coordinateSystem == LogicalCoordinateSystem)
        CGContextConcatCTM(destContext, AffineTransform(wkGetUserToBaseCTM(destContext)).inverse());
    else
        CGContextConcatCTM(destContext, AffineTransform(CGContextGetCTM(destContext)).inverse());
    CGContextResetClip(destContext);
    CGContextSetInterpolationQuality(destContext, kCGInterpolationNone);
    CGContextSetAlpha(destContext, 1.0);
    CGContextSetBlendMode(destContext, kCGBlendModeCopy);
    CGContextSetShadowWithColor(destContext, CGSizeZero, 0, 0);

    // Draw the image in CG coordinate space
    FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.backingStoreSize, internalSize());
    IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), scaledDestSize.height() - (destPoint.y() + sourceRect.y()) - sourceRect.height());
    IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize);
    CGContextClipToRect(destContext, destRectInCGCoords);

    RetainPtr<CGImageRef> sourceCopyImage = sourceCopy->copyNativeImage();
    FloatRect backingStoreInDestRect = FloatRect(FloatPoint(destPointInCGCoords.x(), destPointInCGCoords.y() + sourceCopySize.height() - (int)CGImageGetHeight(sourceCopyImage.get())), FloatSize(CGImageGetWidth(sourceCopyImage.get()), CGImageGetHeight(sourceCopyImage.get())));
    CGContextDrawImage(destContext, backingStoreInDestRect, sourceCopyImage.get());
    CGContextRestoreGState(destContext);
#endif
}
예제 #18
0
void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTimeMs, double durationMs)
{
    if (!m_scrollLayerImpl)
        return;

    IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
    scrollTotal.scale(m_pageScaleDelta);
    float scaleTotal = m_pageScale * m_pageScaleDelta;
    IntSize scaledContentSize = contentSize();
    scaledContentSize.scale(m_pageScaleDelta);

    m_pageScaleAnimation = CCPageScaleAnimation::create(scrollTotal, scaleTotal, m_viewportSize, scaledContentSize, startTimeMs);

    if (anchorPoint) {
        IntSize windowAnchor(targetPosition);
        windowAnchor.scale(scaleTotal / pageScale);
        windowAnchor -= scrollTotal;
        m_pageScaleAnimation->zoomWithAnchor(windowAnchor, pageScale, durationMs);
    } else
        m_pageScaleAnimation->zoomTo(targetPosition, pageScale, durationMs);

    m_client->setNeedsRedrawOnImplThread();
    m_client->setNeedsCommitOnImplThread();
}
예제 #19
0
void BackingStore::incorporateUpdate(const UpdateInfo& updateInfo)
{
    ASSERT(m_size == updateInfo.viewSize);
    
    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(updateInfo.bitmapHandle);
    if (!bitmap)
        return;

#if !ASSERT_DISABLED
    IntSize updateSize = updateInfo.updateRectBounds.size();
    updateSize.scale(m_deviceScaleFactor);
    ASSERT(bitmap->size() == updateSize);
#endif
    
    incorporateUpdate(bitmap.get(), updateInfo);
}
void RenderVideo::updateIntrinsicSize()
{
    IntSize size = calculateIntrinsicSize();
    size.scale(style()->effectiveZoom());

    // Never set the element size to zero when in a media document.
    if (size.isEmpty() && node()->ownerDocument() && node()->ownerDocument()->isMediaDocument())
        return;

    if (size == intrinsicSize())
        return;

    setIntrinsicSize(size);
    setPreferredLogicalWidthsDirty(true);
    setNeedsLayout(true);
}
예제 #21
0
bool PluginProxy::updateBackingStore()
{
    if (m_pluginSize.isEmpty() || !needsBackingStore())
        return false;

    IntSize backingStoreSize = m_pluginSize;
    backingStoreSize.scale(contentsScaleFactor());

    if (m_backingStore) {
        if (m_backingStore->size() == backingStoreSize)
            return false;
        m_backingStore = nullptr; // Give malloc a chance to recycle our backing store.
    }

    m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha);
    return !!m_backingStore;
}
예제 #22
0
void PluginProxy::geometryDidChange()
{
    ASSERT(m_isStarted);

    float contentsScaleFactor = controller()->contentsScaleFactor();

    if (m_frameRect.isEmpty() || !needsBackingStore()) {
        ShareableBitmap::Handle pluginBackingStoreHandle;
        m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_frameRect, m_clipRect, contentsScaleFactor, pluginBackingStoreHandle), m_pluginInstanceID, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply);
        return;
    }

    bool didUpdateBackingStore = false;
    IntSize backingStoreSize = m_frameRect.size();
    backingStoreSize.scale(contentsScaleFactor);

    if (!m_backingStore) {
        m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha);
        didUpdateBackingStore = true;
    } else if (backingStoreSize != m_backingStore->size()) {
        // The backing store already exists, just resize it.
        if (!m_backingStore->resize(backingStoreSize))
            return;

        didUpdateBackingStore = true;
    }

    ShareableBitmap::Handle pluginBackingStoreHandle;

    if (didUpdateBackingStore) {
        // Create a new plug-in backing store.
        m_pluginBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha);
        if (!m_pluginBackingStore)
            return;

        // Create a handle to the plug-in backing store so we can send it over.
        if (!m_pluginBackingStore->createHandle(pluginBackingStoreHandle)) {
            m_pluginBackingStore = nullptr;
            return;
        }

        m_pluginBackingStoreContainsValidData = false;
    }

    m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_frameRect, m_clipRect, contentsScaleFactor, pluginBackingStoreHandle), m_pluginInstanceID, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply);
}
예제 #23
0
WidgetBackingStoreGtkX11::WidgetBackingStoreGtkX11(GtkWidget* widget, const IntSize& size, float deviceScaleFactor)
    : WidgetBackingStore(size, deviceScaleFactor)
{
    IntSize scaledSize = size;
    scaledSize.scale(deviceScaleFactor);

    GdkVisual* visual = gtk_widget_get_visual(widget);
    GdkScreen* screen = gdk_visual_get_screen(visual);
    m_display = GDK_SCREEN_XDISPLAY(screen);
    m_pixmap = XCreatePixmap(m_display, GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
        scaledSize.width(), scaledSize.height(), gdk_visual_get_depth(visual));
    m_gc = XCreateGC(m_display, m_pixmap, 0, 0);

    m_surface = adoptRef(cairo_xlib_surface_create(m_display, m_pixmap,
        GDK_VISUAL_XVISUAL(visual), scaledSize.width(), scaledSize.height()));

    cairoSurfaceSetDeviceScale(m_surface.get(), deviceScaleFactor, deviceScaleFactor);
}
예제 #24
0
IntSize RenderImage::imageSizeForError(CachedImage* newImage) const
{
    ASSERT_ARG(newImage, newImage);
    ASSERT_ARG(newImage, newImage->image());

    IntSize imageSize;
    if (newImage->willPaintBrokenImage()) {
        float deviceScaleFactor = Page::deviceScaleFactor(frame());
        pair<Image*, float> brokenImageAndImageScaleFactor = newImage->brokenImage(deviceScaleFactor);
        imageSize = brokenImageAndImageScaleFactor.first->size();
        imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
    } else
        imageSize = newImage->image()->size();

    // imageSize() returns 0 for the error image. We need the true size of the
    // error image, so we have to get it by grabbing image() directly.
    return IntSize(paddingWidth + imageSize.width() * style()->effectiveZoom(), paddingHeight + imageSize.height() * style()->effectiveZoom());
}
예제 #25
0
void CCLayerTreeHostImpl::animatePageScale(double frameBeginTimeMs)
{
    if (!m_pageScaleAnimation)
        return;

    IntSize scrollTotal = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());

    setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(frameBeginTimeMs) / m_pageScale);
    IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(frameBeginTimeMs);
    nextScroll.scale(1 / m_pageScaleDelta);
    m_scrollLayerImpl->scrollBy(nextScroll - scrollTotal);
    m_client->setNeedsRedrawOnImplThread();

    if (m_pageScaleAnimation->isAnimationCompleteAtTime(frameBeginTimeMs)) {
        m_pageScaleAnimation.clear();
        m_client->setNeedsCommitOnImplThread();
    }
}
예제 #26
0
void GestureHandler::handlePanFinished()
{
    ASSERT(m_panAnimator);
    ecore_animator_del(m_panAnimator);
    m_panAnimator = 0;

    if (!m_history.isEmpty()) {
        // Calculate offset to move during one frame.
        const HistoryItem& oldestHistoryItem = m_history[m_oldestHistoryItemIndex];
        double frame = (ecore_time_get() - oldestHistoryItem.timestamp) / ecore_animator_frametime_get();
        IntSize offset = oldestHistoryItem.point - m_currentPoint;
        offset.scale(1 / frame);
        handleFlick(offset);
    }

    m_oldestHistoryItemIndex = 0;
    if (m_history.size())
        m_history.resize(0);
}
예제 #27
0
void PluginView::setNPWindowRect(const IntRect& rect)
{
    if (!m_isStarted)
        return;

    float scaleFactor = deviceScaleFactor();

    IntPoint p = downcast<FrameView>(*parent()).contentsToWindow(rect.location());
    p.scale(scaleFactor, scaleFactor);

    IntSize s = rect.size();
    s.scale(scaleFactor);

    m_npWindow.x = p.x();
    m_npWindow.y = p.y();

    m_npWindow.width = s.width();
    m_npWindow.height = s.height();

    m_npWindow.clipRect.right = s.width();
    m_npWindow.clipRect.bottom = s.height();
    m_npWindow.clipRect.left = 0;
    m_npWindow.clipRect.top = 0;

    if (m_plugin->pluginFuncs()->setwindow) {
        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM());
        setCallingPlugin(true);
        m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
        setCallingPlugin(false);

        m_haveCalledSetWindow = true;

        if (!m_isWindowed)
            return;

        ASSERT(platformPluginWidget());

        WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC);
        if (currentWndProc != PluginViewWndProc)
            m_pluginWndProc = (WNDPROC)SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG_PTR)PluginViewWndProc);
    }
}
예제 #28
0
LayoutRect RenderSnapshottedPlugIn::tryToFitStartLabel(LabelSize size, const LayoutRect& contentBox) const
{
    Image* labelImage = startLabelImage(size);
    if (!labelImage)
        return LayoutRect();

    // Assume that the labelImage has been provided to match our device scale.
    float scaleFactor = 1;
    if (document()->page())
        scaleFactor = document()->page()->deviceScaleFactor();
    IntSize labelImageSize = labelImage->size();
    labelImageSize.scale(1 / (scaleFactor ? scaleFactor : 1));

    LayoutSize labelSize = labelImageSize - LayoutSize(2 * startLabelInset, 2 * startLabelInset);
    LayoutRect candidateRect(contentBox.maxXMinYCorner() + LayoutSize(-startLabelPadding, startLabelPadding) + LayoutSize(-labelSize.width(), 0), labelSize);
    // The minimum allowed content box size is the label image placed in the center of the box, surrounded by startLabelPadding.
    if (candidateRect.x() < startLabelPadding || candidateRect.maxY() > contentBox.height() - startLabelPadding)
        return LayoutRect();
    return candidateRect;
}
예제 #29
0
bool PluginProxy::updateBackingStore()
{
    if (m_pluginSize.isEmpty() || !needsBackingStore())
        return false;

    IntSize backingStoreSize = m_pluginSize;
    backingStoreSize.scale(contentsScaleFactor());
    
    if (!m_backingStore) {
        m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha);
        return true;
    }

    if (backingStoreSize != m_backingStore->size()) {
        // The backing store already exists, just resize it.
        return m_backingStore->resize(backingStoreSize);
    }

    return false;
}
예제 #30
0
bool DrawingBuffer::reset(const IntSize& newSize)
{
    ASSERT(!newSize.isEmpty());
    IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize);
    if (adjustedSize.isEmpty())
        return false;

    if (adjustedSize != m_size) {
        do {
            if (!resizeDefaultFramebuffer(adjustedSize)) {
                adjustedSize.scale(s_resourceAdjustedRatio);
                continue;
            }
            break;
        } while (!adjustedSize.isEmpty());

        setSize(adjustedSize);

        if (adjustedSize.isEmpty())
            return false;
    }

    m_gl->Disable(GL_SCISSOR_TEST);
    m_gl->ClearColor(0, 0, 0, defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
    m_gl->ColorMask(true, true, true, true);

    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
    if (!!m_depthStencilBuffer) {
        m_gl->ClearDepthf(1.0f);
        clearMask |= GL_DEPTH_BUFFER_BIT;
        m_gl->DepthMask(true);
    }
    if (!!m_depthStencilBuffer) {
        m_gl->ClearStencil(0);
        clearMask |= GL_STENCIL_BUFFER_BIT;
        m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
    }

    clearFramebuffers(clearMask);
    return true;
}