Browse Source

LibWeb: Generate ImageData bindings from IDL :^)

Andreas Kling 5 years ago
parent
commit
dd29ff884f

+ 0 - 100
Libraries/LibWeb/Bindings/ImageDataWrapper.cpp

@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <AK/Function.h>
-#include <LibJS/Interpreter.h>
-#include <LibJS/Runtime/Error.h>
-#include <LibJS/Runtime/GlobalObject.h>
-#include <LibJS/Runtime/Uint8ClampedArray.h>
-#include <LibWeb/Bindings/ImageDataWrapper.h>
-#include <LibWeb/DOM/ImageData.h>
-
-namespace Web {
-namespace Bindings {
-
-ImageDataWrapper* wrap(JS::Heap& heap, ImageData& event)
-{
-    return static_cast<ImageDataWrapper*>(wrap_impl(heap, event));
-}
-
-ImageDataWrapper::ImageDataWrapper(JS::GlobalObject& global_object, ImageData& impl)
-    : Wrapper(*global_object.object_prototype())
-    , m_impl(impl)
-{
-}
-
-void ImageDataWrapper::initialize(JS::Interpreter& interpreter, JS::GlobalObject& global_object)
-{
-    Wrapper::initialize(interpreter, global_object);
-    define_native_property("width", width_getter, nullptr);
-    define_native_property("height", height_getter, nullptr);
-    define_native_property("data", data_getter, nullptr);
-}
-
-ImageDataWrapper::~ImageDataWrapper()
-{
-}
-
-static ImageData* impl_from(JS::Interpreter& interpreter, JS::GlobalObject& global_object)
-{
-    auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
-    if (!this_object) {
-        ASSERT_NOT_REACHED();
-        return nullptr;
-    }
-    if (StringView("ImageDataWrapper") != this_object->class_name()) {
-        interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAn, "ImageDataWrapper");
-        return nullptr;
-    }
-    return &static_cast<ImageDataWrapper*>(this_object)->impl();
-}
-
-JS_DEFINE_NATIVE_GETTER(ImageDataWrapper::width_getter)
-{
-    auto* impl = impl_from(interpreter, global_object);
-    if (!impl)
-        return {};
-    return JS::Value(impl->width());
-}
-
-JS_DEFINE_NATIVE_GETTER(ImageDataWrapper::height_getter)
-{
-    auto* impl = impl_from(interpreter, global_object);
-    if (!impl)
-        return {};
-    return JS::Value(impl->height());
-}
-
-JS_DEFINE_NATIVE_GETTER(ImageDataWrapper::data_getter)
-{
-    auto* impl = impl_from(interpreter, global_object);
-    if (!impl)
-        return {};
-    return impl->data();
-}
-
-}
-}

+ 0 - 56
Libraries/LibWeb/Bindings/ImageDataWrapper.h

@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibWeb/Bindings/Wrapper.h>
-
-namespace Web {
-namespace Bindings {
-
-class ImageDataWrapper : public Wrapper {
-    JS_OBJECT(ImageDataWrapper, Wrapper);
-
-public:
-    ImageDataWrapper(JS::GlobalObject&, ImageData&);
-    virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override;
-    virtual ~ImageDataWrapper() override;
-
-    ImageData& impl() { return m_impl; }
-    const ImageData& impl() const { return m_impl; }
-
-private:
-    JS_DECLARE_NATIVE_GETTER(width_getter);
-    JS_DECLARE_NATIVE_GETTER(height_getter);
-    JS_DECLARE_NATIVE_GETTER(data_getter);
-
-    NonnullRefPtr<ImageData> m_impl;
-};
-
-ImageDataWrapper* wrap(JS::Heap&, ImageData&);
-
-}
-}

+ 1 - 1
Libraries/LibWeb/CMakeLists.txt

@@ -2,7 +2,6 @@ set(SOURCES
     Bindings/CanvasRenderingContext2DWrapper.cpp
     Bindings/CanvasRenderingContext2DWrapper.cpp
     Bindings/EventListenerWrapper.cpp
     Bindings/EventListenerWrapper.cpp
     Bindings/EventWrapper.cpp
     Bindings/EventWrapper.cpp
-    Bindings/ImageDataWrapper.cpp
     Bindings/LocationObject.cpp
     Bindings/LocationObject.cpp
     Bindings/MouseEventWrapper.cpp
     Bindings/MouseEventWrapper.cpp
     Bindings/NavigatorObject.cpp
     Bindings/NavigatorObject.cpp
@@ -158,6 +157,7 @@ libweb_js_wrapper(Element)
 libweb_js_wrapper(HTMLElement)
 libweb_js_wrapper(HTMLElement)
 libweb_js_wrapper(HTMLImageElement)
 libweb_js_wrapper(HTMLImageElement)
 libweb_js_wrapper(HTMLCanvasElement)
 libweb_js_wrapper(HTMLCanvasElement)
+libweb_js_wrapper(ImageData)
 
 
 get_property(WRAPPER_SOURCES GLOBAL PROPERTY wrapper_sources)
 get_property(WRAPPER_SOURCES GLOBAL PROPERTY wrapper_sources)
 set(SOURCES ${SOURCES} ${WRAPPER_SOURCES})
 set(SOURCES ${SOURCES} ${WRAPPER_SOURCES})

+ 34 - 0
Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp

@@ -307,6 +307,24 @@ int main(int argc, char** argv)
     return 0;
     return 0;
 }
 }
 
 
+static bool should_emit_wrapper_factory(const IDL::Interface& interface)
+{
+    // FIXME: This is very hackish.
+    if (interface.name == "EventTarget")
+        return false;
+    if (interface.name == "Node")
+        return false;
+    if (interface.name == "Text")
+        return false;
+    if (interface.name == "Document")
+        return false;
+    if (interface.name == "DocumentType")
+        return false;
+    if (interface.name.ends_with("Element"))
+        return false;
+    return true;
+}
+
 static void generate_header(const IDL::Interface& interface)
 static void generate_header(const IDL::Interface& interface)
 {
 {
     auto& wrapper_class = interface.wrapper_class;
     auto& wrapper_class = interface.wrapper_class;
@@ -357,6 +375,11 @@ static void generate_header(const IDL::Interface& interface)
     }
     }
 
 
     out() << "};";
     out() << "};";
+
+    if (should_emit_wrapper_factory(interface)) {
+        out() << wrapper_class << "* wrap(JS::Heap&, " << interface.name << "&);";
+    }
+
     out() << "}";
     out() << "}";
     out() << "}";
     out() << "}";
 }
 }
@@ -373,6 +396,7 @@ void generate_implementation(const IDL::Interface& interface)
     out() << "#include <LibJS/Runtime/GlobalObject.h>";
     out() << "#include <LibJS/Runtime/GlobalObject.h>";
     out() << "#include <LibJS/Runtime/Error.h>";
     out() << "#include <LibJS/Runtime/Error.h>";
     out() << "#include <LibJS/Runtime/Function.h>";
     out() << "#include <LibJS/Runtime/Function.h>";
+    out() << "#include <LibJS/Runtime/Uint8ClampedArray.h>";
     out() << "#include <LibWeb/Bindings/NodeWrapperFactory.h>";
     out() << "#include <LibWeb/Bindings/NodeWrapperFactory.h>";
     out() << "#include <LibWeb/Bindings/" << wrapper_class << ".h>";
     out() << "#include <LibWeb/Bindings/" << wrapper_class << ".h>";
     out() << "#include <LibWeb/DOM/Element.h>";
     out() << "#include <LibWeb/DOM/Element.h>";
@@ -499,6 +523,8 @@ void generate_implementation(const IDL::Interface& interface)
             out() << "    return new_array;";
             out() << "    return new_array;";
         } else if (return_type.name == "long") {
         } else if (return_type.name == "long") {
             out() << "    return JS::Value(retval);";
             out() << "    return JS::Value(retval);";
+        } else if (return_type.name == "Uint8ClampedArray") {
+            out() << "    return retval;";
         } else {
         } else {
             out() << "    return wrap(interpreter.heap(), const_cast<" << return_type.name << "&>(*retval));";
             out() << "    return wrap(interpreter.heap(), const_cast<" << return_type.name << "&>(*retval));";
         }
         }
@@ -552,6 +578,14 @@ void generate_implementation(const IDL::Interface& interface)
         out() << "}";
         out() << "}";
     }
     }
 
 
+    // Implementation: Wrapper factory
+    if (should_emit_wrapper_factory(interface)) {
+        out() << wrapper_class << "* wrap(JS::Heap& heap, " << interface.name << "& impl)";
+        out() << "{";
+        out() << "    return static_cast<" << wrapper_class << "*>(wrap_impl(heap, impl));";
+        out() << "}";
+    }
+
     out() << "}";
     out() << "}";
     out() << "}";
     out() << "}";
 }
 }

+ 2 - 3
Libraries/LibWeb/DOM/ImageData.cpp

@@ -38,7 +38,6 @@ RefPtr<ImageData> ImageData::create_with_size(JS::GlobalObject& global_object, i
     if (width > 16384 || height > 16384)
     if (width > 16384 || height > 16384)
         return nullptr;
         return nullptr;
 
 
-
     dbg() << "Creating ImageData with " << width << "x" << height;
     dbg() << "Creating ImageData with " << width << "x" << height;
 
 
     auto* data = JS::Uint8ClampedArray::create(global_object, width * height * 4);
     auto* data = JS::Uint8ClampedArray::create(global_object, width * height * 4);
@@ -63,12 +62,12 @@ ImageData::~ImageData()
 {
 {
 }
 }
 
 
-int ImageData::width() const
+unsigned ImageData::width() const
 {
 {
     return m_bitmap->width();
     return m_bitmap->width();
 }
 }
 
 
-int ImageData::height() const
+unsigned ImageData::height() const
 {
 {
     return m_bitmap->height();
     return m_bitmap->height();
 }
 }

+ 2 - 2
Libraries/LibWeb/DOM/ImageData.h

@@ -42,8 +42,8 @@ public:
 
 
     ~ImageData();
     ~ImageData();
 
 
-    int width() const;
-    int height() const;
+    unsigned width() const;
+    unsigned height() const;
 
 
     Gfx::Bitmap& bitmap() { return m_bitmap; }
     Gfx::Bitmap& bitmap() { return m_bitmap; }
     const Gfx::Bitmap& bitmap() const { return m_bitmap; }
     const Gfx::Bitmap& bitmap() const { return m_bitmap; }

+ 7 - 0
Libraries/LibWeb/DOM/ImageData.idl

@@ -0,0 +1,7 @@
+interface ImageData {
+
+    readonly attribute unsigned long width;
+    readonly attribute unsigned long height;
+    readonly attribute Uint8ClampedArray data;
+
+}