Skip to content

Commit 7b4ee57

Browse files
kennethmyhrashannonbooth
authored andcommitted
LibWeb: Add get_bitmap_from_surface() and use it from to_blob()
This refactors out the reading part of Gfx::Bitmap from HtmlCanvasElement::surface(). We can then reuse this from WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl() when we create an ImageBitmap from a HtmlCanvasElement.
1 parent 09f336b commit 7b4ee57

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

Libraries/LibWeb/HTML/HTMLCanvasElement.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -331,27 +331,12 @@ String HTMLCanvasElement::to_data_url(StringView type, JS::Value js_quality)
331331
// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-toblob
332332
WebIDL::ExceptionOr<void> HTMLCanvasElement::to_blob(GC::Ref<WebIDL::CallbackType> callback, StringView type, JS::Value js_quality)
333333
{
334-
// It is possible the canvas doesn't have a associated bitmap so create one
335-
allocate_painting_surface_if_needed();
336-
auto surface = this->surface();
337-
auto size = bitmap_size_for_canvas();
338-
if (!surface && !size.is_empty()) {
339-
// If the context is not initialized yet, we need to allocate transparent surface for serialization
340-
auto skia_backend_context = navigable()->traversable_navigable()->skia_backend_context();
341-
surface = Gfx::PaintingSurface::create_with_size(skia_backend_context, size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
342-
}
343-
344334
// FIXME: 1. If this canvas element's bitmap's origin-clean flag is set to false, then throw a "SecurityError" DOMException.
345335

346336
// 2. Let result be null.
347-
RefPtr<Gfx::Bitmap> bitmap_result;
348-
349337
// 3. If this canvas element's bitmap has pixels (i.e., neither its horizontal dimension nor its vertical dimension is zero),
350338
// then set result to a copy of this canvas element's bitmap.
351-
if (surface) {
352-
bitmap_result = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied, surface->size()));
353-
surface->read_into_bitmap(*bitmap_result);
354-
}
339+
auto bitmap_result = get_bitmap_from_surface();
355340

356341
Optional<double> quality = js_quality.is_number() ? js_quality.as_double() : Optional<double>();
357342

@@ -383,6 +368,26 @@ WebIDL::ExceptionOr<void> HTMLCanvasElement::to_blob(GC::Ref<WebIDL::CallbackTyp
383368
return {};
384369
}
385370

371+
RefPtr<Gfx::Bitmap> HTMLCanvasElement::get_bitmap_from_surface()
372+
{
373+
// It is possible the canvas doesn't have an associated bitmap so create one
374+
allocate_painting_surface_if_needed();
375+
auto surface = this->surface();
376+
if (auto const size = bitmap_size_for_canvas(); !surface && !size.is_empty()) {
377+
// If the context is not initialized yet, we need to allocate transparent surface for serialization
378+
auto const skia_backend_context = navigable()->traversable_navigable()->skia_backend_context();
379+
surface = Gfx::PaintingSurface::create_with_size(skia_backend_context, size, Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied);
380+
}
381+
382+
RefPtr<Gfx::Bitmap> bitmap;
383+
if (surface) {
384+
bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied, surface->size()));
385+
surface->read_into_bitmap(*bitmap);
386+
}
387+
388+
return bitmap;
389+
}
390+
386391
void HTMLCanvasElement::present()
387392
{
388393
if (auto surface = this->surface())

Libraries/LibWeb/HTML/HTMLCanvasElement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class HTMLCanvasElement final : public HTMLElement {
4141

4242
String to_data_url(StringView type, JS::Value quality);
4343
WebIDL::ExceptionOr<void> to_blob(GC::Ref<WebIDL::CallbackType> callback, StringView type, JS::Value quality);
44+
RefPtr<Gfx::Bitmap> get_bitmap_from_surface();
4445

4546
void present();
4647

0 commit comments

Comments
 (0)