aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/htmlcanvaselement.rs78
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini3
-rw-r--r--tests/wpt/webgl/meta/conformance/context/premultiplyalpha-test.html.ini5
3 files changed, 77 insertions, 9 deletions
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 3db1022507c..e61358325ae 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -7,7 +7,9 @@ use canvas_traits::webgl::{GLContextAttributes, WebGLVersion};
use dom_struct::dom_struct;
use euclid::default::{Rect, Size2D};
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
+use image::codecs::jpeg::JpegEncoder;
use image::codecs::png::PngEncoder;
+use image::codecs::webp::WebPEncoder;
use image::{ColorType, ImageEncoder};
use ipc_channel::ipc::IpcSharedMemory;
#[cfg(feature = "webgpu")]
@@ -397,8 +399,8 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
fn ToDataURL(
&self,
_context: JSContext,
- _mime_type: Option<DOMString>,
- _quality: HandleValue,
+ mime_type: Option<DOMString>,
+ quality: HandleValue,
) -> Fallible<USVString> {
// Step 1.
if !self.origin_is_clean() {
@@ -436,17 +438,75 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
},
};
- // FIXME: Only handle image/png for now.
- let mut url = "data:image/png;base64,".to_owned();
+ enum ImageType {
+ Png,
+ Jpeg,
+ Webp,
+ }
+
+ // From: https://html.spec.whatwg.org/multipage/#serialising-bitmaps-to-a-file
+ // User agents must support PNG ("image/png"). User agents may support other types.
+ // If the user agent does not support the requested type, then it must create the file using the PNG format.
+ // Anything different than image/jpeg is thus treated as PNG.
+ let (image_type, url) = match mime_type {
+ Some(mime) => {
+ let mime = mime.to_string().to_lowercase();
+ if mime == "image/jpeg" {
+ (ImageType::Jpeg, "data:image/jpeg;base64,")
+ } else if mime == "image/webp" {
+ (ImageType::Webp, "data:image/webp;base64,")
+ } else {
+ (ImageType::Png, "data:image/png;base64,")
+ }
+ },
+ _ => (ImageType::Png, "data:image/png;base64,"),
+ };
+
+ let mut url = url.to_owned();
+
let mut encoder = base64::write::EncoderStringWriter::from_consumer(
&mut url,
&base64::engine::general_purpose::STANDARD,
);
- // FIXME(nox): https://github.com/image-rs/image-png/issues/86
- // FIXME(nox): https://github.com/image-rs/image-png/issues/87
- PngEncoder::new(&mut encoder)
- .write_image(&file, self.Width(), self.Height(), ColorType::Rgba8)
- .unwrap();
+
+ match image_type {
+ ImageType::Png => {
+ // FIXME(nox): https://github.com/image-rs/image-png/issues/86
+ // FIXME(nox): https://github.com/image-rs/image-png/issues/87
+ PngEncoder::new(&mut encoder)
+ .write_image(&file, self.Width(), self.Height(), ColorType::Rgba8)
+ .unwrap();
+ },
+ ImageType::Jpeg => {
+ let jpeg_encoder = if quality.is_number() {
+ let quality = quality.to_number();
+ // The specification allows quality to be in [0.0..1.0] but the JPEG encoder
+ // expects it to be in [1..100]
+ if (0.0..=1.0).contains(&quality) {
+ JpegEncoder::new_with_quality(
+ &mut encoder,
+ (quality * 100.0).round().clamp(1.0, 100.0) as u8,
+ )
+ } else {
+ JpegEncoder::new(&mut encoder)
+ }
+ } else {
+ JpegEncoder::new(&mut encoder)
+ };
+
+ jpeg_encoder
+ .write_image(&file, self.Width(), self.Height(), ColorType::Rgba8)
+ .unwrap();
+ },
+
+ ImageType::Webp => {
+ // No quality support because of https://github.com/image-rs/image/issues/1984
+ WebPEncoder::new_lossless(&mut encoder)
+ .write_image(&file, self.Width(), self.Height(), ColorType::Rgba8)
+ .unwrap();
+ },
+ }
+
encoder.into_inner();
Ok(USVString(url))
}
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini
new file mode 100644
index 00000000000..16ecb34bf33
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html.ini
@@ -0,0 +1,3 @@
+[toDataURL.jpeg.alpha.html]
+ [toDataURL with JPEG composites onto black]
+ expected: FAIL
diff --git a/tests/wpt/webgl/meta/conformance/context/premultiplyalpha-test.html.ini b/tests/wpt/webgl/meta/conformance/context/premultiplyalpha-test.html.ini
index 361c95a0427..5d1831e1025 100644
--- a/tests/wpt/webgl/meta/conformance/context/premultiplyalpha-test.html.ini
+++ b/tests/wpt/webgl/meta/conformance/context/premultiplyalpha-test.html.ini
@@ -90,3 +90,8 @@
[WebGL test #55: should draw with 255,192,128,1\nat (0, 0) expected: 255,192,128,1 was 0,0,0,255]
expected: FAIL
+ [WebGL test #62: should draw with 128,128,128,255\nat (0, 0) expected: 128,128,128,255 was 255,255,255,255]
+ expected: FAIL
+
+ [WebGL test #69: should draw with 128,128,128,255\nat (0, 0) expected: 128,128,128,255 was 255,255,255,255]
+ expected: FAIL