Exemple #1
0
void CCLayerTreeHostImpl::computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo)
{
    if (!m_scrollLayerImpl)
        return;

    // Only send fake scroll/zoom deltas if we're pinch zooming out by a
    // significant amount. This also ensures only one fake delta set will be
    // sent.
    const float pinchZoomOutSensitivity = 0.95;
    if (m_pageScaleDelta > pinchZoomOutSensitivity)
        return;

    // Compute where the scroll offset/page scale would be if fully pinch-zoomed
    // out from the anchor point.
    FloatSize scrollBegin = toSize(m_scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());
    scrollBegin.scale(m_pageScaleDelta);
    float scaleBegin = m_pageScale * m_pageScaleDelta;
    float pageScaleDeltaToSend = m_minPageScale / m_pageScale;
    FloatSize scaledContentsSize = contentSize();
    scaledContentsSize.scale(pageScaleDeltaToSend);

    FloatSize anchor = toSize(m_previousPinchAnchor);
    FloatSize scrollEnd = scrollBegin + anchor;
    scrollEnd.scale(m_minPageScale / scaleBegin);
    scrollEnd -= anchor;
    scrollEnd = scrollEnd.shrunkTo(roundedIntSize(scaledContentsSize - m_viewportSize)).expandedTo(FloatSize(0, 0));
    scrollEnd.scale(1 / pageScaleDeltaToSend);

    makeScrollAndScaleSet(scrollInfo, roundedIntSize(scrollEnd), m_minPageScale);
}
Exemple #2
0
void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& constrainedSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
{
    FloatSize intrinsicSize;
    if (contentRenderer) {
        contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
        if (intrinsicRatio)
            ASSERT(!isPercentageIntrinsicSize);

        // Handle zoom & vertical writing modes here, as the embedded document doesn't know about them.
        if (!isPercentageIntrinsicSize) {
            intrinsicSize.scale(style().effectiveZoom());
            if (isRenderImage())
                intrinsicSize.scale(toRenderImage(this)->imageDevicePixelRatio());
        }

        if (hasAspectRatio() && isPercentageIntrinsicSize)
            intrinsicRatio = 1;
            
        // Update our intrinsic size to match what the content renderer has computed, so that when we
        // constrain the size below, the correct intrinsic size will be obtained for comparison against
        // min and max widths.
        if (intrinsicRatio && !isPercentageIntrinsicSize && !intrinsicSize.isEmpty())
            m_intrinsicSize = LayoutSize(intrinsicSize);

        if (!isHorizontalWritingMode()) {
            if (intrinsicRatio)
                intrinsicRatio = 1 / intrinsicRatio;
            intrinsicSize = intrinsicSize.transposedSize();
        }
    } else {
        computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
        if (intrinsicRatio) {
            ASSERT(!isPercentageIntrinsicSize);
            if (!intrinsicSize.isEmpty())
                m_intrinsicSize = LayoutSize(isHorizontalWritingMode() ? intrinsicSize : intrinsicSize.transposedSize());
        }
    }

    // Now constrain the intrinsic size along each axis according to minimum and maximum width/heights along the
    // opposite axis. So for example a maximum width that shrinks our width will result in the height we compute here
    // having to shrink in order to preserve the aspect ratio. Because we compute these values independently along
    // each axis, the final returned size may in fact not preserve the aspect ratio.
    // FIXME: In the long term, it might be better to just return this code more to the way it used to be before this
    // function was added, since all it has done is make the code more unclear.
    constrainedSize = intrinsicSize;
    if (intrinsicRatio && !isPercentageIntrinsicSize && !intrinsicSize.isEmpty() && style().logicalWidth().isAuto() && style().logicalHeight().isAuto()) {
        // We can't multiply or divide by 'intrinsicRatio' here, it breaks tests, like fast/images/zoomed-img-size.html, which
        // can only be fixed once subpixel precision is available for things like intrinsicWidth/Height - which include zoom!
        constrainedSize.setWidth(RenderBox::computeReplacedLogicalHeight() * intrinsicSize.width() / intrinsicSize.height());
        constrainedSize.setHeight(RenderBox::computeReplacedLogicalWidth() * intrinsicSize.height() / intrinsicSize.width());
    }
}
Exemple #3
0
void RotationViewportAnchor::computeOrigins(
    const FloatSize& innerSize,
    IntPoint& mainFrameOffset,
    FloatPoint& visualViewportOffset) const {
  IntSize outerSize = layoutViewport().visibleContentRect().size();

  // Compute the viewport origins in CSS pixels relative to the document.
  FloatSize absVisualViewportOffset = m_normalizedVisualViewportOffset;
  absVisualViewportOffset.scale(outerSize.width(), outerSize.height());

  FloatPoint innerOrigin = getInnerOrigin(innerSize);
  FloatPoint outerOrigin = innerOrigin - absVisualViewportOffset;

  IntRect outerRect = IntRect(flooredIntPoint(outerOrigin), outerSize);
  FloatRect innerRect = FloatRect(innerOrigin, innerSize);

  moveToEncloseRect(outerRect, innerRect);

  outerRect.setLocation(IntPoint(
      layoutViewport().clampScrollOffset(toIntSize(outerRect.location()))));

  moveIntoRect(innerRect, outerRect);

  mainFrameOffset = outerRect.location();
  visualViewportOffset =
      FloatPoint(innerRect.location() - outerRect.location());
}
Exemple #4
0
FloatPoint RotationViewportAnchor::getInnerOrigin(
    const FloatSize& innerSize) const {
  if (!m_anchorNode || !m_anchorNode->isConnected())
    return m_visualViewportInDocument;

  const LayoutRect currentNodeBounds = m_anchorNode->boundingBox();
  if (m_anchorNodeBounds == currentNodeBounds)
    return m_visualViewportInDocument;

  RootFrameViewport* rootFrameViewport =
      m_rootFrameView->getRootFrameViewport();
  const LayoutRect currentNodeBoundsInLayoutViewport =
      rootFrameViewport->rootContentsToLayoutViewportContents(
          *m_rootFrameView.get(), currentNodeBounds);

  // Compute the new anchor point relative to the node position
  FloatSize anchorOffsetFromNode(currentNodeBoundsInLayoutViewport.size());
  anchorOffsetFromNode.scale(m_anchorInNodeCoords.width(),
                             m_anchorInNodeCoords.height());
  FloatPoint anchorPoint =
      FloatPoint(currentNodeBoundsInLayoutViewport.location()) +
      anchorOffsetFromNode;

  // Compute the new origin point relative to the new anchor point
  FloatSize anchorOffsetFromOrigin = innerSize;
  anchorOffsetFromOrigin.scale(m_anchorInInnerViewCoords.width(),
                               m_anchorInInnerViewCoords.height());
  return anchorPoint - anchorOffsetFromOrigin;
}
Exemple #5
0
// Tests if two edges defined by their endpoints (a,b) and (c,d) intersect. Returns true and the
// point of intersection if they do and false otherwise.
static bool edgeEdgeTest(const FloatPoint& a, const FloatPoint& b, const FloatPoint& c, const FloatPoint& d, FloatPoint& r)
{
    FloatSize u = b - a;
    FloatSize v = d - c;
    FloatSize w = a - c;

    float denom = perpProduct(u, v);

    // If denom == 0 then the edges are parallel. While they could be overlapping
    // we don't bother to check here as the we'll find their intersections from the
    // corner to quad tests.
    if (!denom)
        return false;

    float s = perpProduct(v, w) / denom;
    if (s < 0 || s > 1)
        return false;

    float t = perpProduct(u, w) / denom;
    if (t < 0 || t > 1)
        return false;

    u.scale(s);
    r = a + u;
    return true;
}
int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSizeInPixels)
{
    // Make sure the element is not freed during the layout.
    RefPtrWillBeRawPtr<Element> protect(element);
    element->document().updateLayout();

    RenderBoxModelObject* box = enclosingBoxModelObject(element->renderer());
    if (!box)
        return -1;

    LocalFrame* frame = element->document().frame();
    FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
    PrintContext printContext(frame);
    printContext.begin(pageRect.width(), pageRect.height());
    FloatSize scaledPageSize = pageSizeInPixels;
    scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
    printContext.computePageRectsWithPageSize(scaledPageSize, false);

    int top = box->pixelSnappedOffsetTop();
    int left = box->pixelSnappedOffsetLeft();
    size_t pageNumber = 0;
    for (; pageNumber < printContext.pageCount(); pageNumber++) {
        const IntRect& page = printContext.pageRect(pageNumber);
        if (page.x() <= left && left < page.maxX() && page.y() <= top && top < page.maxY())
            return pageNumber;
    }
    return -1;
}
Exemple #7
0
static FloatSize convertToUserSpace(const FloatSize& deviceSize, float devicePixelRatio)
{
    FloatSize result = deviceSize;
    if (devicePixelRatio != 1)
        result.scale(1 / devicePixelRatio);
    return result;
}
Exemple #8
0
IntSize CCPageScaleAnimation::scrollOffsetAtRatio(float ratio) const
{
    if (ratio <= 0)
        return m_scrollStart;
    if (ratio >= 1)
        return m_scrollEnd;

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

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

    return currentScrollOffset;
}
Exemple #9
0
inline IntSize EwkView::size() const
{
    // WebPage expects a size in UI units, and not raw device units.
    FloatSize uiSize = deviceSize();
    uiSize.scale(1 / deviceScaleFactor());
    return roundedIntSize(uiSize);
}
Exemple #10
0
int PrintContext::pageNumberForElement(Element* element,
                                       const FloatSize& pageSizeInPixels) {
  element->document().updateStyleAndLayout();

  LocalFrame* frame = element->document().frame();
  FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
  PrintContext printContext(frame);
  printContext.begin(pageRect.width(), pageRect.height());

  LayoutBoxModelObject* box = enclosingBoxModelObject(element->layoutObject());
  if (!box)
    return -1;

  FloatSize scaledPageSize = pageSizeInPixels;
  scaledPageSize.scale(frame->view()->contentsSize().width() /
                       pageRect.width());
  printContext.computePageRectsWithPageSize(scaledPageSize);

  int top = box->pixelSnappedOffsetTop(box->offsetParent());
  int left = box->pixelSnappedOffsetLeft(box->offsetParent());
  size_t pageNumber = 0;
  for (; pageNumber < printContext.pageCount(); pageNumber++) {
    const IntRect& page = printContext.pageRect(pageNumber);
    if (page.x() <= left && left < page.maxX() && page.y() <= top &&
        top < page.maxY())
      return pageNumber;
  }
  return -1;
}
void FullscreenVideoController::LayerClient::platformCALayerLayoutSublayersOfLayer(PlatformCALayer* layer) 
{
    ASSERT_ARG(layer, layer == m_parent->m_rootChild);

    HTMLVideoElement* videoElement = m_parent->m_videoElement.get();
    if (!videoElement)
        return;


    PlatformCALayer* videoLayer = PlatformCALayer::platformCALayer(videoElement->platformLayer());
    if (!videoLayer || videoLayer->superlayer() != layer)
        return;

    FloatRect layerBounds = layer->bounds();

    FloatSize videoSize = videoElement->player()->naturalSize();
    float scaleFactor;
    if (videoSize.aspectRatio() > layerBounds.size().aspectRatio())
        scaleFactor = layerBounds.width() / videoSize.width();
    else
        scaleFactor = layerBounds.height() / videoSize.height();
    videoSize.scale(scaleFactor);

    // Calculate the centered position based on the videoBounds and layerBounds:
    FloatPoint videoPosition;
    FloatPoint videoOrigin;
    videoOrigin.setX((layerBounds.width() - videoSize.width()) * 0.5);
    videoOrigin.setY((layerBounds.height() - videoSize.height()) * 0.5);
    videoLayer->setPosition(videoOrigin);
    videoLayer->setBounds(FloatRect(FloatPoint(), videoSize));
}
void ViewportAnchor::setAnchor(const IntRect& viewRect, const FloatSize& anchorInViewCoords)
{
    m_viewRect = viewRect;
    m_anchorNode.clear();
    m_anchorNodeBounds = LayoutRect();
    m_anchorInNodeCoords = FloatSize();
    m_anchorInViewCoords = anchorInViewCoords;

    if (viewRect.isEmpty())
        return;

    // Preserve origins at the absolute screen origin
    if (viewRect.location() == IntPoint::zero())
        return;

    FloatSize anchorOffset = viewRect.size();
    anchorOffset.scale(anchorInViewCoords.width(), anchorInViewCoords.height());
    const FloatPoint anchorPoint = FloatPoint(viewRect.location()) + anchorOffset;

    Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), viewRect, m_eventHandler);
    if (!node)
        return;

    m_anchorNode = node;
    m_anchorNodeBounds = node->boundingBox();
    m_anchorInNodeCoords = anchorPoint - m_anchorNodeBounds.location();
    m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height());
}
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);
}
Exemple #14
0
void PageViewportControllerClientEfl::updateViewportSize()
{
    ASSERT(m_controller);
    FloatSize size = m_view->size();
    // The viewport controller expects sizes in UI units, and not raw device units.
    size.scale(1 / m_controller->deviceScaleFactor());
    m_controller->didChangeViewportSize(size);
}
IntPoint ViewportAnchor::computeOrigin(const IntSize& currentViewSize) const
{
    if (!m_anchorNode || !m_anchorNode->inDocument())
        return m_viewRect.location();

    const LayoutRect currentNodeBounds = m_anchorNode->boundingBox();
    if (m_anchorNodeBounds == currentNodeBounds)
        return m_viewRect.location();

    // Compute the new anchor point relative to the node position
    FloatSize anchorOffsetFromNode = currentNodeBounds.size();
    anchorOffsetFromNode.scale(m_anchorInNodeCoords.width(), m_anchorInNodeCoords.height());
    FloatPoint anchorPoint = currentNodeBounds.location() + anchorOffsetFromNode;

    // Compute the new origin point relative to the new anchor point
    FloatSize anchorOffsetFromOrigin = currentViewSize;
    anchorOffsetFromOrigin.scale(m_anchorInViewCoords.width(), m_anchorInViewCoords.height());
    return flooredIntPoint(anchorPoint - anchorOffsetFromOrigin);
}
Exemple #16
0
IntPoint FrameView::clampOffsetAtScale(const IntPoint& offset, float scale) const
{
    FloatSize scaledSize = unscaledVisibleContentSize();
    if (scale)
        scaledSize.scale(1 / scale);

    IntPoint clampedOffset = offset;
    clampedOffset = clampedOffset.shrunkTo(
        IntPoint(size()) - expandedIntSize(scaledSize));
    return clampedOffset;
}
Exemple #17
0
bool ImageBuffer::sizeNeedsClamping(const FloatSize& size, FloatSize& scale)
{
    FloatSize scaledSize(size);
    scaledSize.scale(scale.width(), scale.height());

    if (!sizeNeedsClamping(scaledSize))
        return false;

    // The area of scaled size is bigger than the upper limit, adjust the scale to fit.
    scale.scale(sqrtf(MaxClampedArea / (scaledSize.width() * scaledSize.height())));
    ASSERT(!sizeNeedsClamping(size, scale));
    return true;
}
int PrintContext::numberOfPages(LocalFrame* frame, const FloatSize& pageSizeInPixels)
{
    frame->document()->updateLayout();

    FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
    PrintContext printContext(frame);
    printContext.begin(pageRect.width(), pageRect.height());
    // Account for shrink-to-fit.
    FloatSize scaledPageSize = pageSizeInPixels;
    scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
    printContext.computePageRectsWithPageSize(scaledPageSize, false);
    return printContext.pageCount();
}
bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, FloatSize& scale)
{
    FloatSize scaledSize(size);
    scaledSize.scale(scale.width(), scale.height());
    float scaledArea = scaledSize.width() * scaledSize.height();

    if (scaledArea <= FilterEffect::maxFilterArea())
        return true;

    // If area of scaled size is bigger than the upper limit, adjust the scale
    // to fit.
    scale.scale(sqrt(FilterEffect::maxFilterArea() / scaledArea));
    return false;
}
Exemple #20
0
bool PrintContext::beginAndComputePageRectsWithPageSize(Frame& frame, const FloatSize& pageSizeInPixels)
{
    if (!frame.document() || !frame.view() || !frame.document()->renderView())
        return false;

    frame.document()->updateLayout();

    begin(pageSizeInPixels.width(), pageSizeInPixels.height());
    // Account for shrink-to-fit.
    FloatSize scaledPageSize = pageSizeInPixels;
    scaledPageSize.scale(frame.view()->contentsSize().width() / pageSizeInPixels.width());
    computePageRectsWithPageSize(scaledPageSize, false);

    return true;
}
Exemple #21
0
void CCLayerTreeHostImpl::updateMaxScrollPosition()
{
    if (!m_scrollLayerImpl || !m_scrollLayerImpl->children().size())
        return;

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

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

    m_scrollLayerImpl->setMaxScrollPosition(maxScroll);

    // TODO(aelias): Also update sublayers.
}
Exemple #22
0
IntSize RenderImage::imageSizeForError(CachedImage* newImage) const
{
    ASSERT_ARG(newImage, newImage);
    ASSERT_ARG(newImage, newImage->imageForRenderer(this));

    FloatSize imageSize;
    if (newImage->willPaintBrokenImage()) {
        std::pair<Image*, float> brokenImageAndImageScaleFactor = newImage->brokenImage(document().deviceScaleFactor());
        imageSize = brokenImageAndImageScaleFactor.first->size();
        imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
    } else
        imageSize = newImage->imageForRenderer(this)->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());
}
Exemple #23
0
// Tests if two edges defined by their endpoints (a,b) and (c,d) intersect. Returns true and the
// point of intersection if they do and false otherwise.
static bool edgeEdgeTest(const FloatPoint& a, const FloatPoint& b, const FloatPoint& c, const FloatPoint& d, FloatPoint& r)
{
    FloatSize u = b - a;
    FloatSize v = d - c;
    FloatSize w = a - c;

    float denom = perpProduct(u, v);

    // If denom == 0 then the edges are parallel.
    if (!denom) {
        // If the edges are not colinear then there's no intersection.
        if (perpProduct(u, w) || perpProduct(v, w))
            return false;

        if (pointInColinearEdge(a, c, d)) {
            r = a;
            return true;
        }
        if (pointInColinearEdge(b, c, d)) {
            r = b;
            return true;
        }
        if (pointInColinearEdge(c, a, b)) {
            r = c;
            return true;
        }
        if (pointInColinearEdge(d, a, b)) {
            r = d;
            return true;
        }

        return false;
    }
    float s = perpProduct(v, w) / denom;
    if (s < 0 || s > 1)
        return false;

    float t = perpProduct(u, w) / denom;
    if (t < 0 || t > 1)
        return false;

    u.scale(s);
    r = a + u;
    return true;
}
Exemple #24
0
FloatPoint ViewportAnchor::getInnerOrigin(const FloatSize& innerSize) const
{
    if (!m_anchorNode || !m_anchorNode->inDocument())
        return m_pinchViewportInDocument;

    const LayoutRect currentNodeBounds = m_anchorNode->boundingBox();
    if (m_anchorNodeBounds == currentNodeBounds)
        return m_pinchViewportInDocument;

    // Compute the new anchor point relative to the node position
    FloatSize anchorOffsetFromNode(currentNodeBounds.size());
    anchorOffsetFromNode.scale(m_anchorInNodeCoords.width(), m_anchorInNodeCoords.height());
    FloatPoint anchorPoint = FloatPoint(currentNodeBounds.location()) + anchorOffsetFromNode;

    // Compute the new origin point relative to the new anchor point
    FloatSize anchorOffsetFromOrigin = innerSize;
    anchorOffsetFromOrigin.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height());
    return anchorPoint - anchorOffsetFromOrigin;
}
SVGTransform* SVGTransformDistance::addSVGTransforms(SVGTransform* first,
                                                     SVGTransform* second,
                                                     unsigned repeatCount) {
  ASSERT(first->transformType() == second->transformType());

  SVGTransform* transform = SVGTransform::create();

  switch (first->transformType()) {
    case kSvgTransformMatrix:
      ASSERT_NOT_REACHED();
    case kSvgTransformUnknown:
      return transform;
    case kSvgTransformRotate: {
      transform->setRotate(first->angle() + second->angle() * repeatCount,
                           first->rotationCenter().x() +
                               second->rotationCenter().x() * repeatCount,
                           first->rotationCenter().y() +
                               second->rotationCenter().y() * repeatCount);
      return transform;
    }
    case kSvgTransformTranslate: {
      float dx = first->translate().x() + second->translate().x() * repeatCount;
      float dy = first->translate().y() + second->translate().y() * repeatCount;
      transform->setTranslate(dx, dy);
      return transform;
    }
    case kSvgTransformScale: {
      FloatSize scale = second->scale();
      scale.scale(repeatCount);
      scale += first->scale();
      transform->setScale(scale.width(), scale.height());
      return transform;
    }
    case kSvgTransformSkewx:
      transform->setSkewX(first->angle() + second->angle() * repeatCount);
      return transform;
    case kSvgTransformSkewy:
      transform->setSkewY(first->angle() + second->angle() * repeatCount);
      return transform;
  }
  ASSERT_NOT_REACHED();
  return transform;
}
Exemple #26
0
void ViewportAnchor::setAnchor(const IntRect& outerViewRect, const IntRect& innerViewRect,
    const FloatSize& anchorInInnerViewCoords)
{
    // Preserve the inner viewport position in document in case we won't find the anchor
    m_pinchViewportInDocument = innerViewRect.location();

    m_anchorNode.clear();
    m_anchorNodeBounds = LayoutRect();
    m_anchorInNodeCoords = FloatSize();
    m_anchorInInnerViewCoords = anchorInInnerViewCoords;
    m_normalizedPinchViewportOffset = FloatSize();

    if (innerViewRect.isEmpty())
        return;

    // Preserve origins at the absolute screen origin
    if (innerViewRect.location() == IntPoint::zero())
        return;

    // Inner rectangle should be within the outer one.
    ASSERT(outerViewRect.contains(innerViewRect));

    // Outer rectangle is used as a scale, we need positive width and height.
    ASSERT(!outerViewRect.isEmpty());

    m_normalizedPinchViewportOffset = innerViewRect.location() - outerViewRect.location();

    // Normalize by the size of the outer rect
    m_normalizedPinchViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height());

    FloatSize anchorOffset = innerViewRect.size();
    anchorOffset.scale(anchorInInnerViewCoords.width(), anchorInInnerViewCoords.height());
    const FloatPoint anchorPoint = FloatPoint(innerViewRect.location()) + anchorOffset;

    Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), innerViewRect, m_eventHandler);
    if (!node)
        return;

    m_anchorNode = node;
    m_anchorNodeBounds = node->boundingBox();
    m_anchorInNodeCoords = anchorPoint - FloatPoint(m_anchorNodeBounds.location());
    m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height());
}
PassRefPtr<SVGTransform> SVGTransformDistance::addSVGTransforms(PassRefPtr<SVGTransform> passFirst, PassRefPtr<SVGTransform> passSecond, unsigned repeatCount)
{
    RefPtr<SVGTransform> first = passFirst;
    RefPtr<SVGTransform> second = passSecond;
    ASSERT(first->transformType() == second->transformType());

    RefPtr<SVGTransform> transform = SVGTransform::create();

    switch (first->transformType()) {
    case SVG_TRANSFORM_MATRIX:
        ASSERT_NOT_REACHED();
    case SVG_TRANSFORM_UNKNOWN:
        return transform.release();
    case SVG_TRANSFORM_ROTATE: {
        transform->setRotate(first->angle() + second->angle() * repeatCount, first->rotationCenter().x() + second->rotationCenter().x() * repeatCount, first->rotationCenter().y() + second->rotationCenter().y() * repeatCount);
        return transform.release();
    }
    case SVG_TRANSFORM_TRANSLATE: {
        float dx = first->translate().x() + second->translate().x() * repeatCount;
        float dy = first->translate().y() + second->translate().y() * repeatCount;
        transform->setTranslate(dx, dy);
        return transform.release();
    }
    case SVG_TRANSFORM_SCALE: {
        FloatSize scale = second->scale();
        scale.scale(repeatCount);
        scale += first->scale();
        transform->setScale(scale.width(), scale.height());
        return transform.release();
    }
    case SVG_TRANSFORM_SKEWX:
        transform->setSkewX(first->angle() + second->angle() * repeatCount);
        return transform.release();
    case SVG_TRANSFORM_SKEWY:
        transform->setSkewY(first->angle() + second->angle() * repeatCount);
        return transform.release();
    }
    ASSERT_NOT_REACHED();
    return transform.release();
}
Exemple #28
0
void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& dstRect,
    const FloatRect& srcRect, CompositeOperator compositeOp, blink::WebBlendMode blendMode)
{
    if (!m_page)
        return;

    // Temporarily disable the image observer to prevent changeInRect() calls due re-laying out the image.
    ImageObserverDisabler imageObserverDisabler(this);

    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, compositeOp, blendMode);
}
Exemple #29
0
void SVGImage::drawForContainer(SkCanvas* canvas, const SkPaint& paint, const FloatSize containerSize, float zoom, const FloatRect& dstRect,
    const FloatRect& srcRect, const KURL& url)
{
    if (!m_page)
        return;

    // Temporarily disable the image observer to prevent changeInRect() calls due re-laying out the image.
    ImageObserverDisabler imageObserverDisabler(this);

    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);

    drawInternal(canvas, paint, dstRect, scaledSrc, DoNotRespectImageOrientation, ClampImageToSourceRect, url);
}
SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second, unsigned repeatCount)
{
    ASSERT(first.type() == second.type());
    
    SVGTransform transform;
    
    switch (first.type()) {
    case SVGTransform::SVG_TRANSFORM_MATRIX:
        ASSERT_NOT_REACHED();
    case SVGTransform::SVG_TRANSFORM_UNKNOWN:
        return SVGTransform();
    case SVGTransform::SVG_TRANSFORM_ROTATE: {
        transform.setRotate(first.angle() + second.angle() * repeatCount, first.rotationCenter().x() + second.rotationCenter().x() * repeatCount, first.rotationCenter().y() + second.rotationCenter().y() * repeatCount);
        return transform;
    }
    case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
        float dx = first.translate().x() + second.translate().x() * repeatCount;
        float dy = first.translate().y() + second.translate().y() * repeatCount;
        transform.setTranslate(dx, dy);
        return transform;
    }
    case SVGTransform::SVG_TRANSFORM_SCALE: {
        FloatSize scale = second.scale();
        scale.scale(repeatCount);
        scale += first.scale();
        transform.setScale(scale.width(), scale.height());
        return transform;
    }
    case SVGTransform::SVG_TRANSFORM_SKEWX:
        transform.setSkewX(first.angle() + second.angle() * repeatCount);
        return transform;
    case SVGTransform::SVG_TRANSFORM_SKEWY:
        transform.setSkewY(first.angle() + second.angle() * repeatCount);
        return transform;
    }
    ASSERT_NOT_REACHED();
    return SVGTransform();
}