mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
imagebitmap: Add missing basic functionality (#37025)
Add missing basic functionality for ImageBitmap https://html.spec.whatwg.org/multipage/#imagebitmap including new variant of creation bitmap with source rectangle https://html.spec.whatwg.org/multipage/#dom-createimagebitmap but without support of cropping bitmap data with formatting. Add ImageBitmap to CanvasImageSource union type https://html.spec.whatwg.org/multipage/#canvasimagesource Add ImageBitmap to TexImageSource for WebGL https://registry.khronos.org/webgl/specs/latest/1.0/index.html Testing: Improvements in the following WPT tests - html/canvas/element/manual/imagebitmap/* - html/canvas/element/manual/wide-gamut-canvas/* - html/semantics/embedded-content/the-canvas-element/* - webgl/tests/conformance/textures/image_bitmap_from* - webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm Fixes: https://github.com/servo/servo/issues/34112 Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
parent
a3c792e5aa
commit
7f536e8092
79 changed files with 653 additions and 1232 deletions
|
@ -55,6 +55,7 @@ use crate::dom::element::{Element, cors_setting_for_element};
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::htmlcanvaselement::HTMLCanvasElement;
|
||||
use crate::dom::htmlvideoelement::HTMLVideoElement;
|
||||
use crate::dom::imagebitmap::ImageBitmap;
|
||||
use crate::dom::imagedata::ImageData;
|
||||
use crate::dom::node::{Node, NodeTraits};
|
||||
use crate::dom::offscreencanvas::OffscreenCanvas;
|
||||
|
@ -319,6 +320,7 @@ impl CanvasState {
|
|||
},
|
||||
CanvasImageSource::HTMLVideoElement(video) => video.origin_is_clean(),
|
||||
CanvasImageSource::HTMLCanvasElement(canvas) => canvas.origin_is_clean(),
|
||||
CanvasImageSource::ImageBitmap(bitmap) => bitmap.origin_is_clean(),
|
||||
CanvasImageSource::OffscreenCanvas(canvas) => canvas.origin_is_clean(),
|
||||
CanvasImageSource::CSSStyleValue(_) => true,
|
||||
}
|
||||
|
@ -459,6 +461,15 @@ impl CanvasState {
|
|||
|
||||
self.draw_html_canvas_element(canvas, htmlcanvas, sx, sy, sw, sh, dx, dy, dw, dh)
|
||||
},
|
||||
CanvasImageSource::ImageBitmap(ref bitmap) => {
|
||||
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
|
||||
if bitmap.is_detached() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
|
||||
self.draw_image_bitmap(bitmap, htmlcanvas, sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
Ok(())
|
||||
},
|
||||
CanvasImageSource::OffscreenCanvas(ref canvas) => {
|
||||
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
|
||||
if canvas.get_size().is_empty() {
|
||||
|
@ -728,6 +739,52 @@ impl CanvasState {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage>
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_image_bitmap(
|
||||
&self,
|
||||
bitmap: &ImageBitmap,
|
||||
canvas: Option<&HTMLCanvasElement>,
|
||||
sx: f64,
|
||||
sy: f64,
|
||||
sw: Option<f64>,
|
||||
sh: Option<f64>,
|
||||
dx: f64,
|
||||
dy: f64,
|
||||
dw: Option<f64>,
|
||||
dh: Option<f64>,
|
||||
) {
|
||||
let Some(snapshot) = bitmap.bitmap_data().clone() else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Step 4. Establish the source and destination rectangles.
|
||||
let bitmap_size = snapshot.size();
|
||||
let dw = dw.unwrap_or(bitmap_size.width as f64);
|
||||
let dh = dh.unwrap_or(bitmap_size.height as f64);
|
||||
let sw = sw.unwrap_or(bitmap_size.width as f64);
|
||||
let sh = sh.unwrap_or(bitmap_size.height as f64);
|
||||
|
||||
let (source_rect, dest_rect) =
|
||||
self.adjust_source_dest_rects(bitmap_size, sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
|
||||
// Step 5. If one of the sw or sh arguments is zero, then return. Nothing is painted.
|
||||
if !is_rect_valid(source_rect) || !is_rect_valid(dest_rect) {
|
||||
return;
|
||||
}
|
||||
|
||||
let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
|
||||
|
||||
self.send_canvas_2d_msg(Canvas2dMsg::DrawImage(
|
||||
snapshot.as_ipc(),
|
||||
dest_rect,
|
||||
source_rect,
|
||||
smoothing_enabled,
|
||||
));
|
||||
|
||||
self.mark_as_dirty(canvas);
|
||||
}
|
||||
|
||||
pub(crate) fn mark_as_dirty(&self, canvas: Option<&HTMLCanvasElement>) {
|
||||
if let Some(canvas) = canvas {
|
||||
canvas.mark_as_dirty();
|
||||
|
@ -1063,6 +1120,14 @@ impl CanvasState {
|
|||
|
||||
canvas.get_image_data().ok_or(Error::InvalidState)?
|
||||
},
|
||||
CanvasImageSource::ImageBitmap(ref bitmap) => {
|
||||
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
|
||||
if bitmap.is_detached() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
|
||||
bitmap.bitmap_data().clone().ok_or(Error::InvalidState)?
|
||||
},
|
||||
CanvasImageSource::OffscreenCanvas(ref canvas) => {
|
||||
// <https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument>
|
||||
if canvas.get_size().is_empty() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue