mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1423850 - Take into account video's rotation metadata at context.drawImage() with <video> r=gfx-reviewers,bradwerth
Rotated video for reftest is re-used from bug1228601-video-rotation-90.html Differential Revision: https://phabricator.services.mozilla.com/D140353
This commit is contained in:
parent
0b222551dc
commit
fe0ee34bf8
@ -4538,6 +4538,33 @@ SurfaceFromElementResult CanvasRenderingContext2D::CachedSurfaceFromElement(
|
||||
return res;
|
||||
}
|
||||
|
||||
static void SwapScaleWidthHeightForRotation(gfx::Rect& aRect,
|
||||
VideoInfo::Rotation aDegrees) {
|
||||
if (aDegrees == VideoInfo::Rotation::kDegree_90 ||
|
||||
aDegrees == VideoInfo::Rotation::kDegree_270) {
|
||||
std::swap(aRect.width, aRect.height);
|
||||
}
|
||||
}
|
||||
|
||||
static Matrix ComputeRotationMatrix(gfxFloat aRotatedWidth,
|
||||
gfxFloat aRotatedHeight,
|
||||
VideoInfo::Rotation aDegrees) {
|
||||
Matrix shiftVideoCenterToOrigin;
|
||||
if (aDegrees == VideoInfo::Rotation::kDegree_90 ||
|
||||
aDegrees == VideoInfo::Rotation::kDegree_270) {
|
||||
shiftVideoCenterToOrigin =
|
||||
Matrix::Translation(-aRotatedHeight / 2.0, -aRotatedWidth / 2.0);
|
||||
} else {
|
||||
shiftVideoCenterToOrigin =
|
||||
Matrix::Translation(-aRotatedWidth / 2.0, -aRotatedHeight / 2.0);
|
||||
}
|
||||
|
||||
Matrix rotation = Matrix::Rotation(gfx::Float(aDegrees / 180.0 * M_PI));
|
||||
Matrix shiftLeftTopToOrigin =
|
||||
Matrix::Translation(aRotatedWidth / 2.0, aRotatedHeight / 2.0);
|
||||
return shiftVideoCenterToOrigin * rotation * shiftLeftTopToOrigin;
|
||||
}
|
||||
|
||||
// drawImage(in HTMLImageElement image, in float dx, in float dy);
|
||||
// -- render image from 0,0 at dx,dy top-left coords
|
||||
// drawImage(in HTMLImageElement image, in float dx, in float dy, in float dw,
|
||||
@ -4776,10 +4803,37 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
||||
if (!IsTargetValid() || !tempTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
VideoInfo::Rotation rotationDeg = VideoInfo::Rotation::kDegree_0;
|
||||
if (HTMLVideoElement* video = HTMLVideoElement::FromNodeOrNull(element)) {
|
||||
rotationDeg = video->RotationDegrees();
|
||||
}
|
||||
|
||||
gfx::Rect destRect(aDx, aDy, aDw, aDh);
|
||||
|
||||
Matrix transform;
|
||||
if (rotationDeg != VideoInfo::Rotation::kDegree_0) {
|
||||
Matrix preTransform = ComputeRotationMatrix(aDw, aDh, rotationDeg);
|
||||
transform = preTransform * Matrix::Translation(aDx, aDy);
|
||||
|
||||
SwapScaleWidthHeightForRotation(destRect, rotationDeg);
|
||||
// When rotation exists, aDx, aDy is handled by transform, Since aDest.x
|
||||
// aDest.y handling of DrawSurface() does not care about the rotation.
|
||||
destRect.x = 0;
|
||||
destRect.y = 0;
|
||||
}
|
||||
Matrix currentTransform = tempTarget->GetTransform();
|
||||
transform *= currentTransform;
|
||||
|
||||
tempTarget->SetTransform(transform);
|
||||
|
||||
tempTarget->DrawSurface(
|
||||
srcSurf, gfx::Rect(aDx, aDy, aDw, aDh), sourceRect,
|
||||
srcSurf, destRect, sourceRect,
|
||||
DrawSurfaceOptions(samplingFilter, SamplingBounds::UNBOUNDED),
|
||||
DrawOptions(CurrentState().globalAlpha, op, antialiasMode));
|
||||
|
||||
tempTarget->SetTransform(currentTransform);
|
||||
|
||||
} else {
|
||||
DrawDirectlyToCanvas(drawInfo, &bounds, gfx::Rect(aDx, aDy, aDw, aDh),
|
||||
gfx::Rect(aSx, aSy, aSw, aSh), imgSize);
|
||||
|
16
dom/html/reftests/bug1423850-canvas-video-rotated-ref.html
Normal file
16
dom/html/reftests/bug1423850-canvas-video-rotated-ref.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head><script>
|
||||
function done() {
|
||||
let video = document.querySelector("video");
|
||||
let canvas = document.querySelector("canvas");
|
||||
let context = canvas.getContext("2d");
|
||||
context.drawImage(video, 30, 50, video.videoWidth, video.videoHeight);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script></head>
|
||||
<body bgcolor="gray">
|
||||
<video src="video_rotated.mp4" onended="done()" autoplay="true"></video>
|
||||
<canvas width="60" height="100"></canvas>
|
||||
</body>
|
||||
</html>
|
16
dom/html/reftests/bug1423850-canvas-video-rotation-90.html
Normal file
16
dom/html/reftests/bug1423850-canvas-video-rotation-90.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head><script>
|
||||
function done() {
|
||||
let video = document.querySelector("video");
|
||||
let canvas = document.querySelector("canvas");
|
||||
let context = canvas.getContext("2d");
|
||||
context.drawImage(video, 30, 50, video.videoWidth, video.videoHeight);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script></head>
|
||||
<body bgcolor="gray">
|
||||
<video src="video_rotation_90.mp4" onended="done()" autoplay="true"></video>
|
||||
<canvas width="60" height="100"></canvas>
|
||||
</body>
|
||||
</html>
|
@ -63,6 +63,7 @@ pref(permissions.default.image,2) HTTP == bug1196784-with-srcset.html bug1196784
|
||||
|
||||
# Test video with rotation information can be rotated.
|
||||
skip-if(geckoview&&debug) == bug1228601-video-rotation-90.html bug1228601-video-rotated-ref.html # bug 1558285 for GV debug
|
||||
skip-if(geckoview&&debug) fuzzy(0-1,0-30) == bug1423850-canvas-video-rotation-90.html bug1423850-canvas-video-rotated-ref.html # bug 1558285 for GV debug
|
||||
|
||||
== bug1512297.html bug1512297-ref.html
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user