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); }
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(); } }
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; }
void CCLayerTreeHostImpl::computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo) { float pageScale = m_pageScaleAnimation->finalPageScale(); IntSize scrollOffset = m_pageScaleAnimation->finalScrollOffset(); scrollOffset.scale(m_pageScale / pageScale); makeScrollAndScaleSet(scrollInfo, scrollOffset, pageScale); }
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; }
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; }
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); }
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); }
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; }
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(); }
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); } }
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); }
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); }
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 }
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(); }
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); }
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; }
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); }
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); }
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()); }
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(); } }
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); }
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); } }
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; }
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; }
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; }