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); }
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); }
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); }
bool Surface::blitFromContents(Tile* tile) { if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content()) return false; LayerContent* content = getFirstLayer()->content(); // Extract the dirty rect from the region. Note that this is *NOT* constrained // to this tile IntRect dirtyRect = tile->dirtyArea().getBounds(); IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(), tile->y() * TilesManager::tileHeight(), TilesManager::tileWidth(), TilesManager::tileHeight()); FloatRect tileRectInDoc = tileRect; tileRectInDoc.scale(1 / tile->scale()); dirtyRect.intersect(enclosingIntRect(tileRectInDoc)); PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect); if (!prerenderedInval || prerenderedInval->bitmap.isNull()) return false; SkBitmap sourceBitmap = prerenderedInval->bitmap; // Calculate the screen rect that is dirty, then intersect it with the // tile's screen rect so that we end up with the pixels we need to blit FloatRect screenDirty = dirtyRect; screenDirty.scale(tile->scale()); IntRect enclosingScreenDirty = enclosingIntRect(screenDirty); enclosingScreenDirty.intersect(tileRect); if (enclosingScreenDirty.isEmpty()) return false; // Make sure the screen area we want to blit is contained by the // prerendered screen area if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) { ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain " "enclosingScreenDirty " INT_RECT_FORMAT, INT_RECT_ARGS(prerenderedInval->screenArea), INT_RECT_ARGS(enclosingScreenDirty)); return false; } IntPoint origin = prerenderedInval->screenArea.location(); SkBitmap subset; subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(), enclosingScreenDirty.height()); subset.allocPixels(); int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y(); int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x(); if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset)) return false; // Now upload SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(), enclosingScreenDirty.y() - tileRect.y(), enclosingScreenDirty.width(), enclosingScreenDirty.height()); GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId, subset, textureInval); tile->onBlitUpdate(); return true; }
void TileCoverageMap::update() { FloatRect containerBounds = m_controller.bounds(); FloatRect visibleRect = m_controller.visibleRect(); FloatRect coverageRect = m_controller.coverageRect(); visibleRect.contract(4, 4); // Layer is positioned 2px from top and left edges. float widthScale = 1; float scale = 1; if (!containerBounds.isEmpty()) { widthScale = std::min<float>(visibleRect.width() / containerBounds.width(), 0.1); float visibleHeight = visibleRect.height() - std::min(m_controller.topContentInset(), visibleRect.y()); scale = std::min(widthScale, visibleHeight / containerBounds.height()); } float indicatorScale = scale * m_controller.tileGrid().scale(); FloatRect mapBounds = containerBounds; mapBounds.scale(indicatorScale, indicatorScale); m_layer.get().setPosition(m_position + FloatPoint(2, 2)); m_layer.get().setBounds(mapBounds); m_layer.get().setNeedsDisplay(); visibleRect.scale(indicatorScale, indicatorScale); visibleRect.expand(2, 2); m_visibleRectIndicatorLayer->setPosition(visibleRect.location()); m_visibleRectIndicatorLayer->setBounds(FloatRect(FloatPoint(), visibleRect.size())); coverageRect.scale(indicatorScale, indicatorScale); coverageRect.expand(2, 2); m_coverageRectIndicatorLayer->setPosition(coverageRect.location()); m_coverageRectIndicatorLayer->setBounds(FloatRect(FloatPoint(), coverageRect.size())); Color visibleRectIndicatorColor; switch (m_controller.indicatorMode()) { case SynchronousScrollingBecauseOfStyleIndication: visibleRectIndicatorColor = Color(255, 0, 0); break; case SynchronousScrollingBecauseOfEventHandlersIndication: visibleRectIndicatorColor = Color(255, 255, 0); break; case AsyncScrollingIndication: visibleRectIndicatorColor = Color(0, 200, 0); break; } m_visibleRectIndicatorLayer.get().setBorderColor(visibleRectIndicatorColor); }
void GeneratorGeneratedImage::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator compositeOp, const FloatRect& destRect) { // Allow the generator to provide visually-equivalent tiling parameters for better performance. IntSize adjustedSize = m_size; FloatRect adjustedSrcRect = srcRect; m_generator->adjustParametersForTiledDrawing(adjustedSize, adjustedSrcRect); // Factor in the destination context's scale to generate at the best resolution AffineTransform destContextCTM = destContext->getCTM(); double xScale = fabs(destContextCTM.xScale()); double yScale = fabs(destContextCTM.yScale()); AffineTransform adjustedPatternCTM = patternTransform; adjustedPatternCTM.scale(1.0 / xScale, 1.0 / yScale); adjustedSrcRect.scale(xScale, yScale); // Create a BitmapImage and call drawPattern on it. OwnPtr<ImageBuffer> imageBuffer = destContext->createCompatibleBuffer(adjustedSize); if (!imageBuffer) return; // Fill with the generated image. GraphicsContext* graphicsContext = imageBuffer->context(); graphicsContext->fillRect(FloatRect(FloatPoint(), adjustedSize), *m_generator.get()); // Tile the image buffer into the context. imageBuffer->drawPattern(destContext, adjustedSrcRect, adjustedPatternCTM, phase, styleColorSpace, compositeOp, destRect); }
void FEOffset::apply(Filter* filter) { m_in->apply(filter); if (!m_in->resultImage()) return; GraphicsContext* filterContext = getEffectContext(); if (!filterContext) return; setIsAlphaImage(m_in->isAlphaImage()); FloatRect sourceImageRect = filter->sourceImageRect(); sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); if (filter->effectBoundingBoxMode()) { m_dx *= sourceImageRect.width(); m_dy *= sourceImageRect.height(); } m_dx *= filter->filterResolution().width(); m_dy *= filter->filterResolution().height(); FloatRect dstRect = FloatRect(m_dx + m_in->scaledSubRegion().x() - scaledSubRegion().x(), m_dy + m_in->scaledSubRegion().y() - scaledSubRegion().y(), m_in->scaledSubRegion().width(), m_in->scaledSubRegion().height()); filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, dstRect); }
void GeneratorGeneratedImage::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect, BlendMode) { // Allow the generator to provide visually-equivalent tiling parameters for better performance. IntSize adjustedSize = m_size; FloatRect adjustedSrcRect = srcRect; m_gradient->adjustParametersForTiledDrawing(adjustedSize, adjustedSrcRect); // Factor in the destination context's scale to generate at the best resolution. // FIXME: No need to get the full CTM here, we just need the scale. AffineTransform destContextCTM = destContext->getCTM(GraphicsContext::DefinitelyIncludeDeviceScale); float xScale = fabs(destContextCTM.xScale()); float yScale = fabs(destContextCTM.yScale()); FloatSize scaleWithoutCTM(scale.width() / xScale, scale.height() / yScale); adjustedSrcRect.scale(xScale, yScale); unsigned generatorHash = m_gradient->hash(); if (!m_cachedImageBuffer || m_cachedGeneratorHash != generatorHash || m_cachedAdjustedSize != adjustedSize || !destContext->isCompatibleWithBuffer(m_cachedImageBuffer.get())) { m_cachedImageBuffer = destContext->createCompatibleBuffer(adjustedSize, m_gradient->hasAlpha()); if (!m_cachedImageBuffer) return; // Fill with the generated image. m_cachedImageBuffer->context()->setFillGradient(m_gradient); m_cachedImageBuffer->context()->fillRect(FloatRect(FloatPoint(), adjustedSize)); m_cachedGeneratorHash = generatorHash; m_cachedAdjustedSize = adjustedSize; } // Tile the image buffer into the context. m_cachedImageBuffer->drawPattern(destContext, adjustedSrcRect, scaleWithoutCTM, phase, compositeOp, destRect); m_cacheTimer.restart(); }
FloatRect VisualViewport::rootFrameToViewport( const FloatRect& rectInRootFrame) const { FloatRect rectInViewport = rectInRootFrame; rectInViewport.move(-getScrollOffset()); rectInViewport.scale(scale()); return rectInViewport; }
FloatRect VisualViewport::viewportToRootFrame( const FloatRect& rectInViewport) const { FloatRect rectInRootFrame = rectInViewport; rectInRootFrame.scale(1 / scale()); rectInRootFrame.move(getScrollOffset()); return rectInRootFrame; }
void GeneratorGeneratedImage::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator compositeOp, const FloatRect& destRect, BlendMode) { // Allow the generator to provide visually-equivalent tiling parameters for better performance. IntSize adjustedSize = m_size; FloatRect adjustedSrcRect = srcRect; m_gradient->adjustParametersForTiledDrawing(adjustedSize, adjustedSrcRect); // Factor in the destination context's scale to generate at the best resolution AffineTransform destContextCTM = destContext->getCTM(GraphicsContext::DefinitelyIncludeDeviceScale); double xScale = fabs(destContextCTM.xScale()); double yScale = fabs(destContextCTM.yScale()); AffineTransform adjustedPatternCTM = patternTransform; adjustedPatternCTM.scale(1.0 / xScale, 1.0 / yScale); adjustedSrcRect.scale(xScale, yScale); unsigned generatorHash = m_gradient->hash(); if (!m_cachedImageBuffer || m_cachedGeneratorHash != generatorHash || m_cachedAdjustedSize != adjustedSize || !destContext->isCompatibleWithBuffer(m_cachedImageBuffer.get())) { m_cachedImageBuffer = destContext->createCompatibleBuffer(adjustedSize, m_gradient->hasAlpha()); if (!m_cachedImageBuffer) return; // Fill with the generated image. m_cachedImageBuffer->context()->fillRect(FloatRect(FloatPoint(), adjustedSize), *m_gradient); m_cachedGeneratorHash = generatorHash; m_cachedAdjustedSize = adjustedSize; } m_cachedImageBuffer->setSpaceSize(spaceSize()); // Tile the image buffer into the context. m_cachedImageBuffer->drawPattern(destContext, adjustedSrcRect, adjustedPatternCTM, phase, styleColorSpace, compositeOp, destRect); }
FloatRect VisualViewport::rootFrameToViewport(const FloatRect& rectInRootFrame) const { FloatRect rectInViewport = rectInRootFrame; rectInViewport.moveBy(-location()); rectInViewport.scale(scale()); return rectInViewport; }
FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, RenderStyle* style) { ASSERT(startPosition < endPosition); ASSERT(style); FontCachePurgePreventer fontCachePurgePreventer; RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer()); ASSERT(textRenderer); float scalingFactor = textRenderer->scalingFactor(); ASSERT(scalingFactor); const Font& scaledFont = textRenderer->scaledFont(); const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); FloatPoint textOrigin(fragment.x, fragment.y); if (scalingFactor != 1) textOrigin.scale(scalingFactor, scalingFactor); textOrigin.move(0, -scaledFontMetrics.floatAscent()); FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height * scalingFactor, startPosition, endPosition); if (scalingFactor == 1) return selectionRect; selectionRect.scale(1 / scalingFactor); return selectionRect; }
FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, RenderStyle* style) const { ASSERT_WITH_SECURITY_IMPLICATION(startPosition < endPosition); ASSERT(style); float scalingFactor = renderer().scalingFactor(); ASSERT(scalingFactor); const FontCascade& scaledFont = renderer().scaledFont(); const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); FloatPoint textOrigin(fragment.x, fragment.y); if (scalingFactor != 1) textOrigin.scale(scalingFactor, scalingFactor); textOrigin.move(0, -scaledFontMetrics.floatAscent()); LayoutRect selectionRect = LayoutRect(textOrigin, LayoutSize(0, fragment.height * scalingFactor)); TextRun run = constructTextRun(style, fragment); scaledFont.adjustSelectionRectForText(run, selectionRect, startPosition, endPosition); FloatRect snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), run.ltr()); if (scalingFactor == 1) return snappedSelectionRect; snappedSelectionRect.scale(1 / scalingFactor); return snappedSelectionRect; }
void SourceGraphic::determineAbsolutePaintRect() { Filter* filter = this->filter(); FloatRect paintRect = filter->sourceImageRect(); paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); setAbsolutePaintRect(enclosingIntRect(paintRect)); }
FloatRect findInPageRectFromAbsoluteRect(const FloatRect& inputRect, const LayoutObject* baseLayoutObject) { if (!baseLayoutObject || inputRect.isEmpty()) return FloatRect(); // Normalize the input rect to its container block. const LayoutBlock* baseContainer = enclosingScrollableAncestor(baseLayoutObject); FloatRect normalizedRect = toNormalizedRect(inputRect, baseLayoutObject, baseContainer); // Go up across frames. for (const LayoutBox* layoutObject = baseContainer; layoutObject; ) { // Go up the layout tree until we reach the root of the current frame (the LayoutView). while (!layoutObject->isLayoutView()) { const LayoutBlock* container = enclosingScrollableAncestor(layoutObject); // Compose the normalized rects. FloatRect normalizedBoxRect = toNormalizedRect(layoutObject->absoluteBoundingBoxRect(), layoutObject, container); normalizedRect.scale(normalizedBoxRect.width(), normalizedBoxRect.height()); normalizedRect.moveBy(normalizedBoxRect.location()); layoutObject = container; } ASSERT(layoutObject->isLayoutView()); // Jump to the layoutObject owning the frame, if any. layoutObject = layoutObject->frame() ? layoutObject->frame()->ownerLayoutObject() : 0; } return normalizedRect; }
SkImageFilter::CropRect FilterEffect::getCropRect(const FloatSize& cropOffset) const { FloatRect rect = filter()->filterRegion(); uint32_t flags = 0; FloatRect boundaries = effectBoundaries(); boundaries.move(cropOffset); if (hasX()) { rect.setX(boundaries.x()); flags |= SkImageFilter::CropRect::kHasLeft_CropEdge; flags |= SkImageFilter::CropRect::kHasRight_CropEdge; } if (hasY()) { rect.setY(boundaries.y()); flags |= SkImageFilter::CropRect::kHasTop_CropEdge; flags |= SkImageFilter::CropRect::kHasBottom_CropEdge; } if (hasWidth()) { rect.setWidth(boundaries.width()); flags |= SkImageFilter::CropRect::kHasRight_CropEdge; } if (hasHeight()) { rect.setHeight(boundaries.height()); flags |= SkImageFilter::CropRect::kHasBottom_CropEdge; } rect.scale(filter()->absoluteTransform().a(), filter()->absoluteTransform().d()); return SkImageFilter::CropRect(rect, flags); }
void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, BlendMode blendMode) { if (!m_page) return; ImageObserver* observer = imageObserver(); ASSERT(observer); // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout. setImageObserver(0); IntSize roundedContainerSize = roundedIntSize(containerSize); setContainerSize(roundedContainerSize); FloatRect scaledSrc = srcRect; scaledSrc.scale(1 / zoom); // Compensate for the container size rounding by adjusting the source rect. FloatSize adjustedSrcSize = scaledSrc.size(); adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(), roundedContainerSize.height() / containerSize.height()); scaledSrc.setSize(adjustedSrcSize); draw(context, dstRect, scaledSrc, colorSpace, compositeOp, blendMode); setImageObserver(observer); }
static FloatRect toNormalizedRect(const FloatRect& absoluteRect, const LayoutObject* layoutObject, const LayoutBlock* container) { ASSERT(layoutObject); ASSERT(container || layoutObject->isLayoutView()); if (!container) return FloatRect(); // We want to normalize by the max layout overflow size instead of only the visible bounding box. // Quads and their enclosing bounding boxes need to be used in order to keep results transform-friendly. FloatPoint scrolledOrigin; // For overflow:scroll we need to get where the actual origin is independently of the scroll. if (container->hasOverflowClip()) scrolledOrigin = -IntPoint(container->scrolledContentOffset()); FloatRect overflowRect(scrolledOrigin, FloatSize(container->maxLayoutOverflow())); FloatRect containerRect = container->localToAbsoluteQuad(FloatQuad(overflowRect)).enclosingBoundingBox(); if (containerRect.isEmpty()) return FloatRect(); // Make the coordinates relative to the container enclosing bounding box. // Since we work with rects enclosing quad unions this is still transform-friendly. FloatRect normalizedRect = absoluteRect; normalizedRect.moveBy(-containerRect.location()); // Fixed positions do not make sense in this coordinate system, but need to leave consistent tickmarks. // So, use their position when the view is not scrolled, like an absolute position. if (layoutObject->style()->position() == FixedPosition && container->isLayoutView()) normalizedRect.moveBy(-toLayoutView(container)->frameView()->scrollPosition()); normalizedRect.scale(1 / containerRect.width(), 1 / containerRect.height()); return normalizedRect; }
FloatRect findInPageRectFromAbsoluteRect(const FloatRect& inputRect, const RenderObject* baseRenderer) { if (!baseRenderer || inputRect.isEmpty()) return FloatRect(); // Normalize the input rect to its container block. const RenderBlock* baseContainer = enclosingScrollableAncestor(baseRenderer); FloatRect normalizedRect = toNormalizedRect(inputRect, baseRenderer, baseContainer); // Go up across frames. for (const RenderBox* renderer = baseContainer; renderer; ) { // Go up the render tree until we reach the root of the current frame (the RenderView). while (!renderer->isRenderView()) { const RenderBlock* container = enclosingScrollableAncestor(renderer); // Compose the normalized rects. FloatRect normalizedBoxRect = toNormalizedRect(renderer->absoluteBoundingBoxRect(), renderer, container); normalizedRect.scale(normalizedBoxRect.width(), normalizedBoxRect.height()); normalizedRect.moveBy(normalizedBoxRect.location()); renderer = container; } ASSERT(renderer->isRenderView()); // Jump to the renderer owning the frame, if any. renderer = renderer->frame() ? renderer->frame()->ownerRenderer() : 0; } return normalizedRect; }
FloatRect SVGInlineTextBox::selectionRectForTextFragment( const SVGTextFragment& fragment, int startPosition, int endPosition, const ComputedStyle& style) const { ASSERT(startPosition < endPosition); LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->getLineLayoutItem()); float scalingFactor = lineLayoutItem.scalingFactor(); ASSERT(scalingFactor); const Font& scaledFont = lineLayoutItem.scaledFont(); const SimpleFontData* fontData = scaledFont.primaryFont(); DCHECK(fontData); if (!fontData) return FloatRect(); const FontMetrics& scaledFontMetrics = fontData->getFontMetrics(); FloatPoint textOrigin(fragment.x, fragment.y); if (scalingFactor != 1) textOrigin.scale(scalingFactor, scalingFactor); textOrigin.move(0, -scaledFontMetrics.floatAscent()); FloatRect selectionRect = scaledFont.selectionRectForText( constructTextRun(style, fragment), textOrigin, fragment.height * scalingFactor, startPosition, endPosition); if (scalingFactor == 1) return selectionRect; selectionRect.scale(1 / scalingFactor); return selectionRect; }
FloatRect VisualViewport::viewportToRootFrame(const FloatRect& rectInViewport) const { FloatRect rectInRootFrame = rectInViewport; rectInRootFrame.scale(1 / scale()); rectInRootFrame.moveBy(location()); return rectInRootFrame; }
SkImageFilter::CropRect FilterEffect::getCropRect(const FloatSize& cropOffset) const { FloatRect rect; uint32_t flags = 0; if (!hasConnectedInput() && !filter()->filterRegion().isEmpty()) { rect = filter()->filterRegion(); flags = SkImageFilter::CropRect::kHasAll_CropEdge; } FloatRect boundaries = effectBoundaries(); boundaries.move(cropOffset); if (hasX()) { rect.setX(boundaries.x()); flags |= SkImageFilter::CropRect::kHasLeft_CropEdge; } if (hasY()) { rect.setY(boundaries.y()); flags |= SkImageFilter::CropRect::kHasTop_CropEdge; } if (hasWidth()) { rect.setWidth(boundaries.width()); flags |= SkImageFilter::CropRect::kHasWidth_CropEdge; } if (hasHeight()) { rect.setHeight(boundaries.height()); flags |= SkImageFilter::CropRect::kHasHeight_CropEdge; } rect.scale(filter()->scale()); return SkImageFilter::CropRect(rect, flags); }
// Use logical (density-independent) pixels instead of physical screen pixels. static FloatRect toUserSpace(FloatRect rect, Widget* widget) { if (widget->isFrameView()) { Page* page = static_cast<FrameView*>(widget)->frame()->page(); if (page && !page->settings()->applyDeviceScaleFactorInCompositor()) rect.scale(1 / page->deviceScaleFactor()); } return rect; }
void CoordinatedGraphicsLayer::computePixelAlignment(FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) { if (isIntegral(effectiveContentsScale())) { position = m_position; size = m_size; anchorPoint = m_anchorPoint; alignmentOffset = FloatSize(); return; } FloatPoint positionRelativeToBase = computePositionRelativeToBase(); FloatRect baseRelativeBounds(positionRelativeToBase, m_size); FloatRect scaledBounds = baseRelativeBounds; // Scale by the effective scale factor to compute the screen-relative bounds. scaledBounds.scale(effectiveContentsScale()); // Round to integer boundaries. // NOTE: When using enclosingIntRect (as mac) it will have different sizes depending on position. FloatRect alignedBounds = enclosingIntRect(scaledBounds); // Convert back to layer coordinates. alignedBounds.scale(1 / effectiveContentsScale()); // Convert back to layer coordinates. alignmentOffset = baseRelativeBounds.location() - alignedBounds.location(); position = m_position - alignmentOffset; size = alignedBounds.size(); // Now we have to compute a new anchor point which compensates for rounding. float anchorPointX = m_anchorPoint.x(); float anchorPointY = m_anchorPoint.y(); if (alignedBounds.width()) anchorPointX = (baseRelativeBounds.width() * anchorPointX + alignmentOffset.width()) / alignedBounds.width(); if (alignedBounds.height()) anchorPointY = (baseRelativeBounds.height() * anchorPointY + alignmentOffset.height()) / alignedBounds.height(); anchorPoint = FloatPoint3D(anchorPointX, anchorPointY, m_anchorPoint.z() * effectiveContentsScale()); }
FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect) { SVGFilter* filter = static_cast<SVGFilter*>(effect->filter()); ASSERT(filter); // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect. FloatRect subregion; if (unsigned numberOfInputEffects = effect->inputEffects().size()) { subregion = determineFilterPrimitiveSubregion(effect->inputEffect(0)); for (unsigned i = 1; i < numberOfInputEffects; ++i) subregion.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i))); } else subregion = filter->filterRegionInUserSpace(); // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>. if (effect->filterEffectType() == FilterEffectTypeTile) subregion = filter->filterRegionInUserSpace(); FloatRect effectBoundaries = effect->effectBoundaries(); if (effect->hasX()) subregion.setX(effectBoundaries.x()); if (effect->hasY()) subregion.setY(effectBoundaries.y()); if (effect->hasWidth()) subregion.setWidth(effectBoundaries.width()); if (effect->hasHeight()) subregion.setHeight(effectBoundaries.height()); effect->setFilterPrimitiveSubregion(subregion); FloatRect absoluteSubregion = filter->absoluteTransform().mapRect(subregion); FloatSize filterResolution = filter->filterResolution(); absoluteSubregion.scale(filterResolution.width(), filterResolution.height()); // Clip every filter effect to the filter region. FloatRect absoluteScaledFilterRegion = filter->filterRegion(); absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height()); absoluteSubregion.intersect(absoluteScaledFilterRegion); effect->setMaxEffectRect(absoluteSubregion); return subregion; }
FloatRect WebView::convertToUserSpace(const FloatRect& deviceRect) { if (m_page->useFixedLayout()) { FloatRect result = deviceRect; result.scale(1 / m_page->deviceScaleFactor()); return result; } // Legacy mode. notImplemented(); return deviceRect; }
FloatRect SourceAlpha::calculateEffectRect(Filter* filter) { FloatRect clippedSourceRect = filter->sourceImageRect(); if (filter->sourceImageRect().x() < filter->filterRegion().x()) clippedSourceRect.setX(filter->filterRegion().x()); if (filter->sourceImageRect().y() < filter->filterRegion().y()) clippedSourceRect.setY(filter->filterRegion().y()); setSubRegion(clippedSourceRect); clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); setScaledSubRegion(clippedSourceRect); return filter->filterRegion(); }
FloatRect ChromeClientBlackBerry::windowRect() { IntSize windowSize; if (Window* window = m_webPagePrivate->m_client->window()) windowSize = window->windowSize(); // Use logical (density-independent) pixels instead of physical screen pixels. FloatRect rect = FloatRect(0, 0, windowSize.width(), windowSize.height()); if (!m_webPagePrivate->m_page->settings()->applyDeviceScaleFactorInCompositor()) rect.scale(1 / m_webPagePrivate->m_page->deviceScaleFactor()); return rect; }
FloatRect Image::adjustSourceRectForDownSampling(const FloatRect& srcRect, const IntSize& scaledSize) const { const IntSize unscaledSize = size(); if (unscaledSize == scaledSize) return srcRect; // Image has been down-sampled. float xscale = static_cast<float>(scaledSize.width()) / unscaledSize.width(); float yscale = static_cast<float>(scaledSize.height()) / unscaledSize.height(); FloatRect scaledSrcRect = srcRect; scaledSrcRect.scale(xscale, yscale); return scaledSrcRect; }