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);
}
Example #2
0
void SVGImage::drawPatternForContainer(GraphicsContext& context, const FloatSize& containerSize, float zoom, const FloatRect& srcRect,
    const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode)
{
    FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize);
    zoomedContainerRect.scale(zoom);

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

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

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

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

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

    context.setDrawLuminanceMask(false);
    image->drawPattern(context, scaledSrcRect, unscaledPatternTransform, phase, spacing, compositeOp, dstRect, blendMode);
}
Example #3
0
void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect,
    const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& dstRect, blink::WebBlendMode blendMode, const IntSize& repeatSpacing)
{
    FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize);
    zoomedContainerRect.scale(zoom);

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

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

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

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

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

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

    image->drawPattern(context, scaledSrcRect, scaleWithoutCTM, phase, compositeOp, dstRect, blendMode, repeatSpacing);
}
Example #4
0
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;
}
Example #5
0
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);
}
Example #8
0
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();
}
Example #9
0
FloatRect VisualViewport::rootFrameToViewport(
    const FloatRect& rectInRootFrame) const {
  FloatRect rectInViewport = rectInRootFrame;
  rectInViewport.move(-getScrollOffset());
  rectInViewport.scale(scale());
  return rectInViewport;
}
Example #10
0
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;
}
Example #14
0
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;
}
Example #17
0
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;
}
Example #21
0
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;
}
Example #23
0
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);
}
Example #24
0
// 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());
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
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();
}
Example #29
0
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;
}
Example #30
0
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;
}