summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderVideo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderVideo.cpp')
-rw-r--r--WebCore/rendering/RenderVideo.cpp99
1 files changed, 64 insertions, 35 deletions
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index 610fb5f..ab969cc 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -50,25 +50,7 @@ using namespace HTMLNames;
RenderVideo::RenderVideo(HTMLVideoElement* video)
: RenderMedia(video)
{
- if (video->player() && video->readyState() >= HTMLVideoElement::HAVE_METADATA)
- setIntrinsicSize(video->player()->naturalSize());
- else {
- // 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 these attributes are not set, we fall back
- // to a default video size (300x150).
- if (video->hasAttribute(widthAttr) && video->hasAttribute(heightAttr))
- setIntrinsicSize(IntSize(video->width(), video->height()));
- else if (video->ownerDocument() && video->ownerDocument()->isMediaDocument()) {
- // Video in standalone media documents should not use the default 300x150
- // size since they also have audio thrown at them. 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).
- setIntrinsicSize(IntSize(defaultSize().width(), 1));
- }
- else
- setIntrinsicSize(defaultSize());
- }
+ setIntrinsicSize(calculateIntrinsicSize());
}
RenderVideo::~RenderVideo()
@@ -92,24 +74,59 @@ void RenderVideo::intrinsicSizeChanged()
{
if (videoElement()->shouldDisplayPosterImage())
RenderMedia::intrinsicSizeChanged();
- videoSizeChanged();
+ updateIntrinsicSize();
}
-
-void RenderVideo::videoSizeChanged()
+void RenderVideo::updateIntrinsicSize()
{
- if (!player())
+ IntSize size = calculateIntrinsicSize();
+
+ // Never set the element size to zero when in a media document.
+ if (size.isEmpty() && node()->ownerDocument() && node()->ownerDocument()->isMediaDocument())
return;
- IntSize size = player()->naturalSize();
- if (size.isEmpty()) {
- if (node()->ownerDocument() && node()->ownerDocument()->isMediaDocument())
- return;
- }
- if (size != intrinsicSize()) {
- setIntrinsicSize(size);
- setPrefWidthsDirty(true);
- setNeedsLayout(true);
- }
+
+ if (size == intrinsicSize())
+ return;
+
+ setIntrinsicSize(size);
+ setPrefWidthsDirty(true);
+ setNeedsLayout(true);
+}
+
+IntSize 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.
+
+ if (player() && video->readyState() >= HTMLVideoElement::HAVE_METADATA)
+ return player()->naturalSize();
+
+ if (video->shouldDisplayPosterImage() && !m_cachedImageSize.isEmpty() && !errorOccurred())
+ return m_cachedImageSize;
+
+ // 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 (video->hasAttribute(widthAttr) && video->hasAttribute(heightAttr))
+ return IntSize(video->width(), video->height());
+
+ // <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 IntSize(defaultSize().width(), 1);
+
+ return defaultSize();
}
void RenderVideo::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
@@ -119,8 +136,11 @@ void RenderVideo::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
// Cache the image intrinsic size so we can continue to use it to draw the image correctly
// even after we know the video intrisic size but aren't able to draw video frames yet
// (we don't want to scale the poster to the video size).
- if (videoElement()->shouldDisplayPosterImage())
+ if (videoElement()->shouldDisplayPosterImage()) {
+ if (errorOccurred())
+ updateIntrinsicSize();
m_cachedImageSize = intrinsicSize();
+ }
}
IntRect RenderVideo::videoBox() const
@@ -155,7 +175,12 @@ IntRect RenderVideo::videoBox() const
return renderBox;
}
-
+
+bool RenderVideo::shouldDisplayVideo() const
+{
+ return !videoElement()->shouldDisplayPosterImage();
+}
+
void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
MediaPlayer* mediaPlayer = player();
@@ -174,6 +199,7 @@ void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
if (rect.isEmpty())
return;
rect.move(tx, ty);
+
if (displayingPoster)
paintIntoRect(paintInfo.context, rect);
else
@@ -200,9 +226,12 @@ void RenderVideo::updateFromElement()
void RenderVideo::updatePlayer()
{
+ updateIntrinsicSize();
+
MediaPlayer* mediaPlayer = player();
if (!mediaPlayer)
return;
+
if (!videoElement()->inActiveDocument()) {
mediaPlayer->setVisible(false);
return;