[gjs/burninate-macros: 11/13] cairo: Remove JSClass macros from CairoSurface and subclasses



commit 8fceee414568478ca5e3c379393a42c22003b8ef
Author: Philip Chimento <philip chimento gmail com>
Date:   Tue May 12 09:25:01 2020 -0700

    cairo: Remove JSClass macros from CairoSurface and subclasses
    
    FIXME: Needs commit message

 modules/cairo-context.cpp         |  15 +--
 modules/cairo-image-surface.cpp   | 101 +++++++------------
 modules/cairo-pdf-surface.cpp     |  91 ++++++-----------
 modules/cairo-private.h           | 201 ++++++++++++++++++++++++++++----------
 modules/cairo-ps-surface.cpp      |  91 ++++++-----------
 modules/cairo-surface-pattern.cpp |   3 +-
 modules/cairo-surface.cpp         | 143 ++++++++++-----------------
 modules/cairo-svg-surface.cpp     |  92 ++++++-----------
 modules/cairo.cpp                 |  10 +-
 9 files changed, 331 insertions(+), 416 deletions(-)
---
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 0b85d5cd..e8138573 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -268,8 +268,7 @@ cairo_t* CairoContext::constructor_impl(JSContext* context,
                              "surface", &surface_wrapper))
         return nullptr;
 
-    cairo_surface_t* surface =
-        gjs_cairo_surface_get_surface(context, surface_wrapper);
+    cairo_surface_t* surface = CairoSurface::for_js(context, surface_wrapper);
     if (!surface)
         return nullptr;
 
@@ -510,8 +509,7 @@ maskSurface_func(JSContext *context,
                              "y", &y))
         return false;
 
-    cairo_surface_t* surface =
-        gjs_cairo_surface_get_surface(context, surface_wrapper);
+    cairo_surface_t* surface = CairoSurface::for_js(context, surface_wrapper);
     if (!surface)
         return false;
 
@@ -637,8 +635,7 @@ setSourceSurface_func(JSContext *context,
                              "y", &y))
         return false;
 
-    cairo_surface_t* surface =
-        gjs_cairo_surface_get_surface(context, surface_wrapper);
+    cairo_surface_t* surface = CairoSurface::for_js(context, surface_wrapper);
     if (!surface)
         return false;
 
@@ -790,7 +787,6 @@ getTarget_func(JSContext *context,
         return true;
 
     cairo_surface_t *surface;
-    JSObject *surface_wrapper;
 
     if (argc > 0) {
         gjs_throw(context, "Context.getTarget() takes no arguments");
@@ -802,7 +798,7 @@ getTarget_func(JSContext *context,
         return false;
 
     /* surface belongs to the context, so keep the reference */
-    surface_wrapper = gjs_cairo_surface_from_surface(context, surface);
+    JSObject* surface_wrapper = CairoSurface::from_c_ptr(context, surface);
     if (!surface_wrapper) {
         /* exception already set */
         return false;
@@ -825,7 +821,6 @@ getGroupTarget_func(JSContext *context,
         return true;
 
     cairo_surface_t *surface;
-    JSObject *surface_wrapper;
 
     if (argc > 0) {
         gjs_throw(context, "Context.getGroupTarget() takes no arguments");
@@ -837,7 +832,7 @@ getGroupTarget_func(JSContext *context,
         return false;
 
     /* surface belongs to the context, so keep the reference */
-    surface_wrapper = gjs_cairo_surface_from_surface(context, surface);
+    JSObject* surface_wrapper = CairoSurface::from_c_ptr(context, surface);
     if (!surface_wrapper) {
         /* exception already set */
         return false;
diff --git a/modules/cairo-image-surface.cpp b/modules/cairo-image-surface.cpp
index 407b9a7e..d9562683 100644
--- a/modules/cairo-image-surface.cpp
+++ b/modules/cairo-image-surface.cpp
@@ -31,6 +31,7 @@
 #include <js/RootingAPI.h>
 #include <js/TypeDecls.h>
 #include <jsapi.h>  // for JS_NewObjectWithGivenProto
+#include <jspubtd.h>  // for JSProtoKey
 
 #include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
@@ -38,51 +39,45 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_image_surface_get_proto(JSContext *);
+JSObject* CairoImageSurface::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoSurface::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
+
+const js::ClassSpec CairoImageSurface::class_spec = {
+    nullptr,  // createConstructor,
+    &CairoImageSurface::new_proto,
+    CairoImageSurface::static_funcs,
+    nullptr,  // constructorProperties
+    CairoImageSurface::proto_funcs,
+    nullptr,  // prototypeProperties
+    &CairoSurface::define_gtype_prop,
+};
 
-GJS_DEFINE_PROTO_WITH_PARENT("ImageSurface", cairo_image_surface,
-                             cairo_surface, JSCLASS_BACKGROUND_FINALIZE)
+const JSClass CairoImageSurface::klass = {
+    "ImageSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoSurface::class_ops};
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_image_surface)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_image_surface)
+cairo_surface_t* CairoImageSurface::constructor_impl(JSContext* context,
+                                                     const JS::CallArgs& argv) {
     int format, width, height;
     cairo_surface_t *surface;
 
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_image_surface);
-
     // create_for_data optional parameter
     if (!gjs_parse_call_args(context, "ImageSurface", argv, "iii",
                              "format", &format,
                              "width", &width,
                              "height", &height))
-        return false;
+        return nullptr;
 
     surface = cairo_image_surface_create((cairo_format_t) format, width, height);
 
     if (!gjs_cairo_check_status(context, cairo_surface_status(surface), "surface"))
-        return false;
-
-    gjs_cairo_surface_construct(object, surface);
-    cairo_surface_destroy(surface);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_image_surface);
+        return nullptr;
 
-    return true;
+    return surface;
 }
 
-static void
-gjs_cairo_image_surface_finalize(JSFreeOp *fop,
-                                 JSObject *obj)
-{
-    gjs_cairo_surface_finalize_surface(fop, obj);
-}
-
-JSPropertySpec gjs_cairo_image_surface_proto_props[] = {
-    JS_PS_END
-};
-
 GJS_JSAPI_RETURN_CONVENTION
 static bool
 createFromPNG_func(JSContext *context,
@@ -102,15 +97,10 @@ createFromPNG_func(JSContext *context,
     if (!gjs_cairo_check_status(context, cairo_surface_status(surface), "surface"))
         return false;
 
-    JS::RootedObject proto(context, gjs_cairo_image_surface_get_proto(context));
-    JS::RootedObject surface_wrapper(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_image_surface_class,
-                                   proto));
-    if (!surface_wrapper) {
-        gjs_throw(context, "failed to create surface");
+    JSObject* surface_wrapper = CairoImageSurface::from_c_ptr(context, surface);
+    if (!surface_wrapper)
         return false;
-    }
-    gjs_cairo_surface_construct(surface_wrapper, surface);
+
     cairo_surface_destroy(surface);
 
     argv.rval().setObject(*surface_wrapper);
@@ -131,7 +121,7 @@ getFormat_func(JSContext *context,
         return false;
     }
 
-    cairo_surface_t* surface = gjs_cairo_surface_get_surface(context, obj);
+    cairo_surface_t* surface = CairoSurface::for_js(context, obj);
     if (!surface)
         return false;
 
@@ -158,7 +148,7 @@ getWidth_func(JSContext *context,
         return false;
     }
 
-    cairo_surface_t* surface = gjs_cairo_surface_get_surface(context, obj);
+    cairo_surface_t* surface = CairoSurface::for_js(context, obj);
     if (!surface)
         return false;
 
@@ -185,7 +175,7 @@ getHeight_func(JSContext *context,
         return false;
     }
 
-    cairo_surface_t* surface = gjs_cairo_surface_get_surface(context, obj);
+    cairo_surface_t* surface = CairoSurface::for_js(context, obj);
     if (!surface)
         return false;
 
@@ -212,7 +202,7 @@ getStride_func(JSContext *context,
         return false;
     }
 
-    cairo_surface_t* surface = gjs_cairo_surface_get_surface(context, obj);
+    cairo_surface_t* surface = CairoSurface::for_js(context, obj);
     if (!surface)
         return false;
 
@@ -225,39 +215,14 @@ getStride_func(JSContext *context,
     return true;
 }
 
-JSFunctionSpec gjs_cairo_image_surface_proto_funcs[] = {
+const JSFunctionSpec CairoImageSurface::proto_funcs[] = {
     JS_FN("createFromPNG", createFromPNG_func, 0, 0),
     // getData
     JS_FN("getFormat", getFormat_func, 0, 0),
     JS_FN("getWidth", getWidth_func, 0, 0),
     JS_FN("getHeight", getHeight_func, 0, 0),
-    JS_FN("getStride", getStride_func, 0, 0),
-    JS_FS_END};
+    JS_FN("getStride", getStride_func, 0, 0), JS_FS_END};
 
-JSFunctionSpec gjs_cairo_image_surface_static_funcs[] = {
+const JSFunctionSpec CairoImageSurface::static_funcs[] = {
     JS_FN("createFromPNG", createFromPNG_func, 1, GJS_MODULE_PROP_FLAGS),
     JS_FS_END};
-
-JSObject *
-gjs_cairo_image_surface_from_surface(JSContext       *context,
-                                     cairo_surface_t *surface)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(surface, nullptr);
-    g_return_val_if_fail(
-        cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE, nullptr);
-
-    JS::RootedObject proto(context, gjs_cairo_image_surface_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_image_surface_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create image surface");
-        return nullptr;
-    }
-
-    gjs_cairo_surface_construct(object, surface);
-
-    return object;
-}
-
diff --git a/modules/cairo-pdf-surface.cpp b/modules/cairo-pdf-surface.cpp
index 546509a0..911f31a2 100644
--- a/modules/cairo-pdf-surface.cpp
+++ b/modules/cairo-pdf-surface.cpp
@@ -34,94 +34,59 @@
 #    include <glib.h>
 
 #    include <js/Class.h>
-#    include <js/PropertySpec.h>
 #    include <js/RootingAPI.h>
 #    include <jsapi.h>  // for JS_NewObjectWithGivenProto
+#    include <jspubtd.h>  // for JSProtoKey
 
 #    include "gjs/jsapi-class.h"
 #    include "gjs/jsapi-util-args.h"
-#    include "gjs/macros.h"
 #    include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_pdf_surface_get_proto(JSContext *);
+namespace JS {
+class CallArgs;
+}
+
+JSObject* CairoPDFSurface::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoSurface::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
 
-GJS_DEFINE_PROTO_WITH_PARENT("PDFSurface", cairo_pdf_surface,
-                             cairo_surface, JSCLASS_BACKGROUND_FINALIZE)
+const js::ClassSpec CairoPDFSurface::class_spec = {
+    nullptr,  // createConstructor,
+    &CairoPDFSurface::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    nullptr,  // prototypeFunctions
+    nullptr,  // prototypeProperties
+    &CairoSurface::define_gtype_prop,
+};
+
+const JSClass CairoPDFSurface::klass = {
+    "PDFSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoSurface::class_ops};
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_pdf_surface)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_pdf_surface)
+cairo_surface_t* CairoPDFSurface::constructor_impl(JSContext* context,
+                                                   const JS::CallArgs& argv) {
     GjsAutoChar filename;
     double width, height;
     cairo_surface_t *surface;
-
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_pdf_surface);
-
     if (!gjs_parse_call_args(context, "PDFSurface", argv, "Fff",
                              "filename", &filename,
                              "width", &width,
                              "height", &height))
-        return false;
+        return nullptr;
 
     surface = cairo_pdf_surface_create(filename, width, height);
 
     if (!gjs_cairo_check_status(context, cairo_surface_status(surface),
                                 "surface"))
-        return false;
-
-    gjs_cairo_surface_construct(object, surface);
-    cairo_surface_destroy(surface);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_pdf_surface);
-
-    return true;
-}
-
-static void
-gjs_cairo_pdf_surface_finalize(JSFreeOp *fop,
-                               JSObject *obj)
-{
-    gjs_cairo_surface_finalize_surface(fop, obj);
-}
-
-JSPropertySpec gjs_cairo_pdf_surface_proto_props[] = {
-    JS_PS_END
-};
-
-JSFunctionSpec gjs_cairo_pdf_surface_proto_funcs[] = {
-    JS_FS_END
-};
-
-JSFunctionSpec gjs_cairo_pdf_surface_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_pdf_surface_from_surface(JSContext       *context,
-                                   cairo_surface_t *surface)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(surface, nullptr);
-    g_return_val_if_fail(
-        cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_PDF, nullptr);
-
-    JS::RootedObject proto(context, gjs_cairo_pdf_surface_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_pdf_surface_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create pdf surface");
         return nullptr;
-    }
-
-    gjs_cairo_surface_construct(object, surface);
 
-    return object;
+    return surface;
 }
 #else
-JSObject *
-gjs_cairo_pdf_surface_from_surface(JSContext       *context,
-                                   cairo_surface_t *surface)
-{
+JSObject* CairoPDFSurface::from_c_ptr(JSContext* context,
+                                      cairo_surface_t* surface) {
     gjs_throw(context,
         "could not create PDF surface, recompile cairo and gjs with "
         "PDF support.");
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index d4a81500..15211cdc 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -108,69 +108,166 @@ class CairoPath : public CairoPathBase {
 };
 
 /* surface */
-GJS_USE
-JSObject *gjs_cairo_surface_get_proto(JSContext *cx);
 
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_surface_define_proto(JSContext              *cx,
-                                    JS::HandleObject        module,
-                                    JS::MutableHandleObject proto);
+class CairoSurface;
+using CairoSurfaceBase = NativeObject<CairoSurface, cairo_surface_t,
+                                      GJS_GLOBAL_SLOT_PROTOTYPE_cairo_surface>;
 
-void gjs_cairo_surface_construct(JSObject* object, cairo_surface_t* surface);
-void             gjs_cairo_surface_finalize_surface     (JSFreeOp        *fop,
-                                                         JSObject        *object);
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_surface_from_surface         (JSContext       *context,
-                                                         cairo_surface_t *surface);
-GJS_JSAPI_RETURN_CONVENTION
-cairo_surface_t* gjs_cairo_surface_get_surface(
-    JSContext* cx, JS::HandleObject surface_wrapper);
+class CairoSurface : public CairoSurfaceBase {
+    friend CairoSurfaceBase;
+    friend class CairoImageSurface;  // "inherits" from CairoSurface
+    friend class CairoPSSurface;
+    friend class CairoPDFSurface;
+    friend class CairoSVGSurface;
 
-/* image surface */
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_image_surface_define_proto(JSContext              *cx,
-                                          JS::HandleObject        module,
-                                          JS::MutableHandleObject proto);
+    CairoSurface() = delete;
+    CairoSurface(CairoSurface&) = delete;
+    CairoSurface(CairoSurface&&) = delete;
 
-void             gjs_cairo_image_surface_init           (JSContext       *context,
-                                                         JS::HandleObject proto);
+    static GType gtype() { return CAIRO_GOBJECT_TYPE_SURFACE; }
 
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_image_surface_from_surface   (JSContext       *context,
-                                                         cairo_surface_t *surface);
+    static void finalize_impl(JSFreeOp* fop, cairo_surface_t* surface);
+
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+    static const JSFunctionSpec proto_funcs[];
+
+    static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
+        return cairo_surface_reference(surface);
+    }
+
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* from_c_ptr(JSContext* cx, cairo_surface_t* surface);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_surface_t* for_js(JSContext* cx,
+                                   JS::HandleObject surface_wrapper);
+};
+
+class CairoImageSurface;
+using CairoImageSurfaceBase =
+    NativeObject<CairoImageSurface, cairo_surface_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_image_surface>;
+
+class CairoImageSurface : public CairoImageSurfaceBase {
+    friend CairoImageSurfaceBase;
+
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+    static const JSFunctionSpec static_funcs[];
+    static const JSFunctionSpec proto_funcs[];
+
+    static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
+        return cairo_surface_reference(surface);
+    }
+
+    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_surface_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+};
 
-/* postscript surface */
 #ifdef CAIRO_HAS_PS_SURFACE
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_ps_surface_define_proto(JSContext              *cx,
-                                       JS::HandleObject        module,
-                                       JS::MutableHandleObject proto);
-#endif
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_ps_surface_from_surface       (JSContext       *context,
-                                                          cairo_surface_t *surface);
+class CairoPSSurface;
+using CairoPSSurfaceBase =
+    NativeObject<CairoPSSurface, cairo_surface_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_ps_surface>;
+
+class CairoPSSurface : public CairoPSSurfaceBase {
+    friend CairoPSSurfaceBase;
+
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+    static const JSFunctionSpec proto_funcs[];
+
+    static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
+        return cairo_surface_reference(surface);
+    }
+
+    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_surface_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+};
+#else
+class CairoPSSurface {
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* from_c_ptr(JSContext* cx, cairo_surface_t* surface);
+}
+#endif  // CAIRO_HAS_PS_SURFACE
 
-/* pdf surface */
 #ifdef CAIRO_HAS_PDF_SURFACE
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_pdf_surface_define_proto(JSContext              *cx,
-                                        JS::HandleObject        module,
-                                        JS::MutableHandleObject proto);
-#endif
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_pdf_surface_from_surface     (JSContext       *context,
-                                                         cairo_surface_t *surface);
+class CairoPDFSurface;
+using CairoPDFSurfaceBase =
+    NativeObject<CairoPDFSurface, cairo_surface_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_pdf_surface>;
+
+class CairoPDFSurface : public CairoPDFSurfaceBase {
+    friend CairoPDFSurfaceBase;
+
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+    static const JSFunctionSpec proto_funcs[];
+
+    static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
+        return cairo_surface_reference(surface);
+    }
+
+    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_surface_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+};
+#else
+class CairoPDFSurface {
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* from_c_ptr(JSContext* cx, cairo_surface_t* surface);
+}
+#endif  // CAIRO_HAS_PDF_SURFACE
 
-/* svg surface */
 #ifdef CAIRO_HAS_SVG_SURFACE
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_svg_surface_define_proto(JSContext              *cx,
-                                        JS::HandleObject        module,
-                                        JS::MutableHandleObject proto);
-#endif
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_svg_surface_from_surface     (JSContext       *context,
-                                                         cairo_surface_t *surface);
+class CairoSVGSurface;
+using CairoSVGSurfaceBase =
+    NativeObject<CairoSVGSurface, cairo_surface_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_svg_surface>;
+
+class CairoSVGSurface : public CairoSVGSurfaceBase {
+    friend CairoSVGSurfaceBase;
+
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+    static const JSFunctionSpec proto_funcs[];
+
+    static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
+        return cairo_surface_reference(surface);
+    }
+
+    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_surface_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+};
+#else
+class CairoPSSurface {
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* from_c_ptr(JSContext* cx, cairo_surface_t* surface);
+}
+#endif  // CAIRO_HAS_SVG_SURFACE
 
 /* pattern */
 
diff --git a/modules/cairo-ps-surface.cpp b/modules/cairo-ps-surface.cpp
index a83e7fc8..a25e56f4 100644
--- a/modules/cairo-ps-surface.cpp
+++ b/modules/cairo-ps-surface.cpp
@@ -37,59 +37,56 @@
 #    include <js/PropertySpec.h>
 #    include <js/RootingAPI.h>
 #    include <jsapi.h>  // for JS_NewObjectWithGivenProto
+#    include <jspubtd.h>  // for JSProtoKey
 
 #    include "gjs/jsapi-class.h"
 #    include "gjs/jsapi-util-args.h"
-#    include "gjs/macros.h"
 #    include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_ps_surface_get_proto(JSContext *);
+namespace JS {
+class CallArgs;
+}
+
+JSObject* CairoPSSurface::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoSurface::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
+
+const js::ClassSpec CairoPSSurface::class_spec = {
+    nullptr,  // createConstructor,
+    &CairoPSSurface::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    CairoPSSurface::proto_funcs,
+    nullptr,  // prototypeProperties
+    &CairoSurface::define_gtype_prop,
+};
 
-GJS_DEFINE_PROTO_WITH_PARENT("PSSurface", cairo_ps_surface, cairo_surface,
-                             JSCLASS_BACKGROUND_FINALIZE)
+const JSClass CairoPSSurface::klass = {
+    "PSSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoSurface::class_ops};
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_ps_surface)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_ps_surface)
+cairo_surface_t* CairoPSSurface::constructor_impl(JSContext* context,
+                                                  const JS::CallArgs& argv) {
     GjsAutoChar filename;
     double width, height;
     cairo_surface_t *surface;
-
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_ps_surface);
-
     if (!gjs_parse_call_args(context, "PSSurface", argv, "Fff",
                              "filename", &filename,
                              "width", &width,
                              "height", &height))
-        return false;
+        return nullptr;
 
     surface = cairo_ps_surface_create(filename, width, height);
 
     if (!gjs_cairo_check_status(context, cairo_surface_status(surface),
                                 "surface"))
-        return false;
-
-    gjs_cairo_surface_construct(object, surface);
-    cairo_surface_destroy(surface);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_ps_surface);
-
-    return true;
-}
+        return nullptr;
 
-static void
-gjs_cairo_ps_surface_finalize(JSFreeOp *fop,
-                              JSObject *obj)
-{
-    gjs_cairo_surface_finalize_surface(fop, obj);
+    return surface;
 }
 
-JSPropertySpec gjs_cairo_ps_surface_proto_props[] = {
-    JS_PS_END
-};
-
-JSFunctionSpec gjs_cairo_ps_surface_proto_funcs[] = {
+const JSFunctionSpec CairoPSSurface::proto_funcs[] = {
     // restrictToLevel
     // getLevels
     // levelToString
@@ -99,37 +96,11 @@ JSFunctionSpec gjs_cairo_ps_surface_proto_funcs[] = {
     // dscBeginSetup
     // dscBeginPageSetup
     // dscComment
-    JS_FS_END
-};
-
-JSFunctionSpec gjs_cairo_ps_surface_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_ps_surface_from_surface(JSContext       *context,
-                                  cairo_surface_t *surface)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(surface, nullptr);
-    g_return_val_if_fail(
-        cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_PS, nullptr);
-
-    JS::RootedObject proto(context, gjs_cairo_ps_surface_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_ps_surface_class, proto));
-    if (!object) {
-        gjs_throw(context, "failed to create ps surface");
-        return nullptr;
-    }
+    JS_FS_END};
 
-    gjs_cairo_surface_construct(object, surface);
-
-    return object;
-}
 #else
-JSObject *
-gjs_cairo_ps_surface_from_surface(JSContext       *context,
-                                  cairo_surface_t *surface)
-{
+JSObject* CairoPSSurface::from_c_ptr(JSContext* context,
+                                     cairo_surface_t* surface) {
     gjs_throw(context,
         "could not create PS surface, recompile cairo and gjs with "
         "PS support.");
diff --git a/modules/cairo-surface-pattern.cpp b/modules/cairo-surface-pattern.cpp
index 65b43684..974bfef6 100644
--- a/modules/cairo-surface-pattern.cpp
+++ b/modules/cairo-surface-pattern.cpp
@@ -66,8 +66,7 @@ cairo_pattern_t* CairoSurfacePattern::constructor_impl(
                              "surface", &surface_wrapper))
         return nullptr;
 
-    cairo_surface_t* surface =
-        gjs_cairo_surface_get_surface(context, surface_wrapper);
+    cairo_surface_t* surface = CairoSurface::for_js(context, surface_wrapper);
     if (!surface)
         return nullptr;
 
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 4f7560b4..c69f9966 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -22,7 +22,6 @@
 
 #include <config.h>
 
-#include <cairo-gobject.h>
 #include <cairo.h>
 #include <girepository.h>
 #include <glib.h>
@@ -43,21 +42,34 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE("Surface", cairo_surface,
-                                     CAIRO_GOBJECT_TYPE_SURFACE,
-                                     JSCLASS_BACKGROUND_FINALIZE)
+const js::ClassSpec CairoSurface::class_spec = {
+    nullptr,  // createConstructor
+    nullptr,  // createPrototype
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    CairoSurface::proto_funcs,
+    nullptr,  // prototypeProperties
+    &CairoSurface::define_gtype_prop,
+};
 
-static void gjs_cairo_surface_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoSurface =
-        GjsAutoPointer<cairo_surface_t, cairo_surface_t, cairo_surface_destroy>;
-    AutoSurface surface = static_cast<cairo_surface_t*>(JS_GetPrivate(obj));
-    JS_SetPrivate(obj, nullptr);
-}
+const JSClass CairoSurface::klass = {
+    "Surface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoSurface::class_ops};
 
-/* Properties */
-JSPropertySpec gjs_cairo_surface_proto_props[] = {
-    JS_PS_END
-};
+/**
+ * CairoSurface::finalize_impl:
+ * @fop: the free op
+ * @surface: the pointer to finalize
+ *
+ * Destroys the resources associated with a surface wrapper.
+ *
+ * This is mainly used for subclasses. FIXME
+ */
+void CairoSurface::finalize_impl(JSFreeOp*, cairo_surface_t* surface) {
+    if (!surface)
+        return;
+    cairo_surface_destroy(surface);
+}
 
 /* Methods */
 GJS_JSAPI_RETURN_CONVENTION
@@ -73,7 +85,7 @@ writeToPNG_func(JSContext *context,
                              "filename", &filename))
         return false;
 
-    cairo_surface_t* surface = gjs_cairo_surface_get_surface(context, obj);
+    cairo_surface_t* surface = CairoSurface::for_js(context, obj);
     if (!surface)
         return false;
 
@@ -99,7 +111,7 @@ getType_func(JSContext *context,
         return false;
     }
 
-    cairo_surface_t* surface = gjs_cairo_surface_get_surface(context, obj);
+    cairo_surface_t* surface = CairoSurface::for_js(context, obj);
     if (!surface)
         return false;
 
@@ -112,7 +124,7 @@ getType_func(JSContext *context,
     return true;
 }
 
-JSFunctionSpec gjs_cairo_surface_proto_funcs[] = {
+const JSFunctionSpec CairoSurface::proto_funcs[] = {
     // flush
     // getContent
     // getFontOptions
@@ -126,52 +138,12 @@ JSFunctionSpec gjs_cairo_surface_proto_funcs[] = {
     // copyPage
     // showPage
     // hasShowTextGlyphs
-    JS_FN("writeToPNG", writeToPNG_func, 0, 0),
-    JS_FS_END};
-
-JSFunctionSpec gjs_cairo_surface_static_funcs[] = { JS_FS_END };
+    JS_FN("writeToPNG", writeToPNG_func, 0, 0), JS_FS_END};
 
 /* Public API */
 
 /**
- * gjs_cairo_surface_construct:
- * @object: object to construct
- * @surface: cairo_surface to attach to the object
- *
- * Constructs a surface wrapper giving an empty JSObject and a
- * cairo surface. A reference to @surface will be taken.
- *
- * This is mainly used for subclasses where object is already created.
- */
-void gjs_cairo_surface_construct(JSObject* object, cairo_surface_t* surface) {
-    g_return_if_fail(object);
-    g_return_if_fail(surface);
-
-    g_assert(!JS_GetPrivate(object));
-    JS_SetPrivate(object, cairo_surface_reference(surface));
-}
-
-/**
- * gjs_cairo_surface_finalize:
- * @fop: the free op
- * @object: object to finalize
- *
- * Destroys the resources associated with a surface wrapper.
- *
- * This is mainly used for subclasses.
- */
-void
-gjs_cairo_surface_finalize_surface(JSFreeOp *fop,
-                                   JSObject *object)
-{
-    g_return_if_fail(fop);
-    g_return_if_fail(object);
-
-    gjs_cairo_surface_finalize(fop, object);
-}
-
-/**
- * gjs_cairo_surface_from_surface:
+ * CairoSurface::from_c_ptr:
  * @context: the context
  * @surface: cairo_surface to attach to the object
  *
@@ -179,49 +151,38 @@ gjs_cairo_surface_finalize_surface(JSFreeOp *fop,
  * A reference to @surface will be taken.
  *
  */
-JSObject *
-gjs_cairo_surface_from_surface(JSContext       *context,
-                               cairo_surface_t *surface)
-{
+JSObject* CairoSurface::from_c_ptr(JSContext* context,
+                                   cairo_surface_t* surface) {
     g_return_val_if_fail(context, nullptr);
     g_return_val_if_fail(surface, nullptr);
 
     cairo_surface_type_t type = cairo_surface_get_type(surface);
     if (type == CAIRO_SURFACE_TYPE_IMAGE)
-        return gjs_cairo_image_surface_from_surface(context, surface);
+        return CairoImageSurface::from_c_ptr(context, surface);
     if (type == CAIRO_SURFACE_TYPE_PDF)
-        return gjs_cairo_pdf_surface_from_surface(context, surface);
+        return CairoPDFSurface::from_c_ptr(context, surface);
     if (type == CAIRO_SURFACE_TYPE_PS)
-        return gjs_cairo_ps_surface_from_surface(context, surface);
+        return CairoPSSurface::from_c_ptr(context, surface);
     if (type == CAIRO_SURFACE_TYPE_SVG)
-        return gjs_cairo_svg_surface_from_surface(context, surface);
-
-    JS::RootedObject proto(context, gjs_cairo_surface_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_surface_class, proto));
-    if (!object) {
-        gjs_throw(context, "failed to create surface");
-        return nullptr;
-    }
-
-    gjs_cairo_surface_construct(object, surface);
-
-    return object;
+        return CairoSVGSurface::from_c_ptr(context, surface);
+    return CairoSurfaceBase::from_c_ptr(context, surface);
 }
 
 /**
- * gjs_cairo_surface_get_surface:
+ * CairoSurface::for_js:
  * @cx: the context
  * @surface_wrapper: surface wrapper
  *
+ * Overrides NativeObject::for_js().
+ *
  * Returns: the surface attached to the wrapper.
  */
-cairo_surface_t* gjs_cairo_surface_get_surface(
-    JSContext* cx, JS::HandleObject surface_wrapper) {
+cairo_surface_t* CairoSurface::for_js(JSContext* cx,
+                                      JS::HandleObject surface_wrapper) {
     g_return_val_if_fail(cx, nullptr);
     g_return_val_if_fail(surface_wrapper, nullptr);
 
-    JS::RootedObject proto(cx, gjs_cairo_surface_get_proto(cx));
+    JS::RootedObject proto(cx, CairoSurface::prototype(cx));
 
     bool is_surface_subclass = false;
     if (!gjs_object_in_prototype_chain(cx, proto, surface_wrapper,
@@ -266,8 +227,7 @@ surface_to_g_argument(JSContext      *context,
     }
 
     JS::RootedObject surface_wrapper(context, &value.toObject());
-    cairo_surface_t* s =
-        gjs_cairo_surface_get_surface(context, surface_wrapper);
+    cairo_surface_t* s = CairoSurface::for_js(context, surface_wrapper);
     if (!s)
         return false;
     if (transfer == GI_TRANSFER_EVERYTHING)
@@ -278,14 +238,11 @@ surface_to_g_argument(JSContext      *context,
 }
 
 GJS_JSAPI_RETURN_CONVENTION
-static bool
-surface_from_g_argument(JSContext             *context,
-                        JS::MutableHandleValue value_p,
-                        GIArgument            *arg)
-{
-    JSObject *obj;
-
-    obj = gjs_cairo_surface_from_surface(context, (cairo_surface_t*)arg->v_pointer);
+static bool surface_from_g_argument(JSContext* cx,
+                                    JS::MutableHandleValue value_p,
+                                    GIArgument* arg) {
+    JSObject* obj = CairoSurface::from_c_ptr(
+        cx, static_cast<cairo_surface_t*>(arg->v_pointer));
     if (!obj)
         return false;
 
diff --git a/modules/cairo-svg-surface.cpp b/modules/cairo-svg-surface.cpp
index e620bfdb..da606627 100644
--- a/modules/cairo-svg-surface.cpp
+++ b/modules/cairo-svg-surface.cpp
@@ -34,94 +34,60 @@
 #    include <glib.h>
 
 #    include <js/Class.h>
-#    include <js/PropertySpec.h>
 #    include <js/RootingAPI.h>
 #    include <jsapi.h>  // for JS_NewObjectWithGivenProto
+#    include <jspubtd.h>  // for JSProtoKey
 
 #    include "gjs/jsapi-class.h"
 #    include "gjs/jsapi-util-args.h"
-#    include "gjs/macros.h"
 #    include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_svg_surface_get_proto(JSContext *);
+namespace JS {
+class CallArgs;
+}
+
+JSObject* CairoSVGSurface::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoSurface::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
 
-GJS_DEFINE_PROTO_WITH_PARENT("SVGSurface", cairo_svg_surface,
-                             cairo_surface, JSCLASS_BACKGROUND_FINALIZE)
+const js::ClassSpec CairoSVGSurface::class_spec = {
+    nullptr,  // createConstructor,
+    &CairoSVGSurface::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    nullptr,  // prototypeFunctions
+    nullptr,  // prototypeProperties
+    &CairoSurface::define_gtype_prop,
+};
+
+const JSClass CairoSVGSurface::klass = {
+    "SVGSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoSurface::class_ops};
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_svg_surface)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_svg_surface)
+cairo_surface_t* CairoSVGSurface::constructor_impl(JSContext* context,
+                                                   const JS::CallArgs& argv) {
     GjsAutoChar filename;
     double width, height;
     cairo_surface_t *surface;
-
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_svg_surface);
-
     if (!gjs_parse_call_args(context, "SVGSurface", argv, "Fff",
                              "filename", &filename,
                              "width", &width,
                              "height", &height))
-        return false;
+        return nullptr;
 
     surface = cairo_svg_surface_create(filename, width, height);
 
     if (!gjs_cairo_check_status(context, cairo_surface_status(surface),
                                 "surface"))
-        return false;
-
-    gjs_cairo_surface_construct(object, surface);
-    cairo_surface_destroy(surface);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_svg_surface);
-
-    return true;
-}
-
-static void
-gjs_cairo_svg_surface_finalize(JSFreeOp *fop,
-                               JSObject *obj)
-{
-    gjs_cairo_surface_finalize_surface(fop, obj);
-}
-
-JSPropertySpec gjs_cairo_svg_surface_proto_props[] = {
-    JS_PS_END
-};
-
-JSFunctionSpec gjs_cairo_svg_surface_proto_funcs[] = {
-    JS_FS_END
-};
-
-JSFunctionSpec gjs_cairo_svg_surface_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_svg_surface_from_surface(JSContext       *context,
-                                   cairo_surface_t *surface)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(surface, nullptr);
-    g_return_val_if_fail(
-        cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_SVG, nullptr);
-
-    JS::RootedObject proto(context, gjs_cairo_svg_surface_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_svg_surface_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create svg surface");
         return nullptr;
-    }
 
-    gjs_cairo_surface_construct(object, surface);
-
-    return object;
+    return surface;
 }
+
 #else
-JSObject *
-gjs_cairo_svg_surface_from_surface(JSContext       *context,
-                                   cairo_surface_t *surface)
-{
+JSObject* CairoSVGSurface::from_c_ptr(JSContext* context,
+                                      cairo_surface_t* surface) {
     gjs_throw(context,
         "could not create SVG surface, recompile cairo and gjs with "
         "SVG support.");
diff --git a/modules/cairo.cpp b/modules/cairo.cpp
index f12d21b6..78934457 100644
--- a/modules/cairo.cpp
+++ b/modules/cairo.cpp
@@ -76,21 +76,21 @@ gjs_js_define_cairo_stuff(JSContext              *context,
         return false;
     gjs_cairo_context_init();
 
-    if (!gjs_cairo_surface_define_proto(context, module, &proto))
+    if (!CairoSurface::create_prototype(context, module))
         return false;
     gjs_cairo_surface_init();
 
     return
-        gjs_cairo_image_surface_define_proto(context, module, &proto) &&
+        CairoImageSurface::create_prototype(context, module) &&
         CairoPath::create_prototype(context, module) &&
 #if CAIRO_HAS_PS_SURFACE
-        gjs_cairo_ps_surface_define_proto(context, module, &proto) &&
+        CairoPSSurface::create_prototype(context, module) &&
 #endif
 #if CAIRO_HAS_PDF_SURFACE
-        gjs_cairo_pdf_surface_define_proto(context, module, &proto) &&
+        CairoPDFSurface::create_prototype(context, module) &&
 #endif
 #if CAIRO_HAS_SVG_SURFACE
-        gjs_cairo_svg_surface_define_proto(context, module, &proto) &&
+        CairoSVGSurface::create_prototype(context, module) &&
 #endif
         CairoPattern::create_prototype(context, module) &&
         CairoGradient::create_prototype(context, module) &&



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]