LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) const { LayoutRect contentRect = contentBoxRect(); if (intrinsicSize.isEmpty()) return contentRect; ObjectFit objectFit = style().objectFit(); LayoutRect finalRect = contentRect; switch (objectFit) { case ObjectFitContain: case ObjectFitScaleDown: case ObjectFitCover: finalRect.setSize(finalRect.size().fitToAspectRatio(intrinsicSize, objectFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink)); if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSize.width()) break; FALLTHROUGH; case ObjectFitNone: finalRect.setSize(intrinsicSize); break; case ObjectFitFill: break; } LengthPoint objectPosition = style().objectPosition(); LayoutUnit xOffset = minimumValueForLength(objectPosition.x(), contentRect.width() - finalRect.width()); LayoutUnit yOffset = minimumValueForLength(objectPosition.y(), contentRect.height() - finalRect.height()); finalRect.move(xOffset, yOffset); return finalRect; }
LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) const { LayoutRect contentRect = contentBoxRect(); if (intrinsicSize.isEmpty()) return contentRect; ObjectFit objectFit = style().objectFit(); if (objectFit == ObjectFitFill) return contentRect; LayoutRect finalRect = contentRect; switch (objectFit) { case ObjectFitContain: case ObjectFitScaleDown: case ObjectFitCover: finalRect.setSize(finalRect.size().fitToAspectRatio(intrinsicSize, objectFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink)); if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSize.width()) break; FALLTHROUGH; case ObjectFitNone: finalRect.setSize(intrinsicSize); break; case ObjectFitFill: ASSERT_NOT_REACHED(); } // FIXME: This is where object-position should be taken into account, but since it's not // implemented yet, assume the initial value of "50% 50%". LayoutUnit xOffset = (contentRect.width() - finalRect.width()) / 2; LayoutUnit yOffset = (contentRect.height() - finalRect.height()) / 2; finalRect.move(xOffset, yOffset); return finalRect; }
LayoutSize RenderVideo::calculateIntrinsicSize() { HTMLVideoElement* video = videoElement(); // Spec text from 4.8.6 // // The intrinsic width of a video element's playback area is the intrinsic width // of the video resource, if that is available; otherwise it is the intrinsic // width of the poster frame, if that is available; otherwise it is 300 CSS pixels. // // The intrinsic height of a video element's playback area is the intrinsic height // of the video resource, if that is available; otherwise it is the intrinsic // height of the poster frame, if that is available; otherwise it is 150 CSS pixels. MediaPlayer* player = mediaElement()->player(); if (player && video->readyState() >= HTMLVideoElement::HAVE_METADATA) { LayoutSize size = player->naturalSize(); if (!size.isEmpty()) return size; } if (video->shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !imageResource()->errorOccurred()) return m_cachedImageSize; // <video> in standalone media documents should not use the default 300x150 // size since they also have audio-only files. By setting the intrinsic // size to 300x1 the video will resize itself in these cases, and audio will // have the correct height (it needs to be > 0 for controls to render properly). if (video->ownerDocument() && video->ownerDocument()->isMediaDocument()) return LayoutSize(defaultSize().width(), 1); return defaultSize(); }
void ImageDocument::imageUpdated() { ASSERT(m_imageElement); if (m_imageSizeIsKnown) return; LayoutSize imageSize = this->imageSize(); if (imageSize.isEmpty()) return; m_imageSizeIsKnown = true; if (m_shouldShrinkImage) { #if PLATFORM(IOS) FloatSize screenSize = page()->chrome().screenSize(); if (imageSize.width() > screenSize.width()) processViewport(String::format("width=%u", static_cast<unsigned>(imageSize.width().toInt())), ViewportArguments::ImageDocument); if (page()) page()->chrome().client().imageOrMediaDocumentSizeChanged(IntSize(imageSize.width(), imageSize.height())); #else // Call windowSizeChanged for its side effect of sizing the image. windowSizeChanged(); #endif } }
IntRect RenderVideo::videoBox() const { if (m_cachedImageSize.isEmpty() && videoElement()->shouldDisplayPosterImage()) return IntRect(); LayoutSize elementSize; if (videoElement()->shouldDisplayPosterImage()) elementSize = m_cachedImageSize; else elementSize = intrinsicSize(); IntRect contentRect = pixelSnappedIntRect(contentBoxRect()); if (elementSize.isEmpty() || contentRect.isEmpty()) return IntRect(); LayoutRect renderBox = contentRect; LayoutUnit ratio = renderBox.width() * elementSize.height() - renderBox.height() * elementSize.width(); if (ratio > 0) { LayoutUnit newWidth = renderBox.height() * elementSize.width() / elementSize.height(); // Just fill the whole area if the difference is one pixel or less (in both sides) if (renderBox.width() - newWidth > 2) renderBox.setWidth(newWidth); renderBox.move((contentRect.width() - renderBox.width()) / 2, 0); } else if (ratio < 0) { LayoutUnit newHeight = renderBox.width() * elementSize.height() / elementSize.width(); if (renderBox.height() - newHeight > 2) renderBox.setHeight(newHeight); renderBox.move(0, (contentRect.height() - renderBox.height()) / 2); } return pixelSnappedIntRect(renderBox); }
void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const LayoutSize& containerSize, float containerZoom) { ASSERT(client); ASSERT(!containerSize.isEmpty()); ASSERT(containerZoom); FloatSize containerSizeWithoutZoom(containerSize); containerSizeWithoutZoom.scale(1 / containerZoom); m_imageForContainerMap.set(client, SVGImageForContainer::create(m_svgImage, containerSizeWithoutZoom, containerZoom)); }
AffineTransform SVGRootPainter::transformToPixelSnappedBorderBox( const LayoutPoint& paintOffset) const { const IntRect snappedSize = pixelSnappedSize(paintOffset); AffineTransform paintOffsetToBorderBox = AffineTransform::translation(snappedSize.x(), snappedSize.y()); LayoutSize size = m_layoutSVGRoot.size(); if (!size.isEmpty()) { paintOffsetToBorderBox.scale( snappedSize.width() / size.width().toFloat(), snappedSize.height() / size.height().toFloat()); } paintOffsetToBorderBox.multiply(m_layoutSVGRoot.localToBorderBoxTransform()); return paintOffsetToBorderBox; }
void SVGImage::setContainerSize(const LayoutSize& containerSize) { if (containerSize.isEmpty()) return; if (!m_page) return; Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return; rootElement->setContainerSize(containerSize); }
void RenderVideo::updateIntrinsicSize() { LayoutSize size = calculateIntrinsicSize(); size.scale(style()->effectiveZoom()); // Never set the element size to zero when in a media document. if (size.isEmpty() && node()->ownerDocument() && node()->ownerDocument()->isMediaDocument()) return; if (size == intrinsicSize()) return; setIntrinsicSize(size); setPreferredLogicalWidthsDirty(); setNeedsLayout(); }
bool RenderVideo::updateIntrinsicSize() { LayoutSize size = calculateIntrinsicSize(); size.scale(style().effectiveZoom()); // Never set the element size to zero when in a media document. if (size.isEmpty() && document().isMediaDocument()) return false; if (size == intrinsicSize()) return false; setIntrinsicSize(size); setPreferredLogicalWidthsDirty(true); setNeedsLayout(); return true; }
void CachedImage::setContainerSizeForRenderer(const CachedImageClient* renderer, const LayoutSize& containerSize, float containerZoom) { if (containerSize.isEmpty()) return; ASSERT(renderer); ASSERT(containerZoom); if (!m_image) { m_pendingContainerSizeRequests.set(renderer, SizeAndZoom(containerSize, containerZoom)); return; } if (!m_image->isSVGImage()) { m_image->setContainerSize(containerSize); return; } m_svgImageCache->setContainerSizeForRenderer(renderer, containerSize, containerZoom); }
LayoutSize RenderVideo::calculateIntrinsicSize() { // Spec text from 4.8.6 // // The intrinsic width of a video element's playback area is the intrinsic width // of the video resource, if that is available; otherwise it is the intrinsic // width of the poster frame, if that is available; otherwise it is 300 CSS pixels. // // The intrinsic height of a video element's playback area is the intrinsic height // of the video resource, if that is available; otherwise it is the intrinsic // height of the poster frame, if that is available; otherwise it is 150 CSS pixels. MediaPlayer* player = videoElement().player(); if (player && videoElement().readyState() >= HTMLVideoElement::HAVE_METADATA) { LayoutSize size = player->naturalSize(); if (!size.isEmpty()) return size; } if (videoElement().shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !imageResource()->errorOccurred()) return m_cachedImageSize; #if !PLATFORM(IOS) // When the natural size of the video is unavailable, we use the provided // width and height attributes of the video element as the intrinsic size until // better values become available. if (videoElement().hasAttribute(widthAttr) && videoElement().hasAttribute(heightAttr)) return LayoutSize(videoElement().width(), videoElement().height()); #endif // <video> in standalone media documents should not use the default 300x150 // size since they also have audio-only files. By setting the intrinsic // size to 300x1 the video will resize itself in these cases, and audio will // have the correct height (it needs to be > 0 for controls to render properly). if (videoElement().document().isMediaDocument()) return LayoutSize(defaultSize().width(), 1); return defaultSize(); }