[gjs/burninate-macros: 9/13] cairo: Remove JSClass macros from CairoPattern and subclasses



commit 68ddead8954b0a57afd8a457e950344eeead093f
Author: Philip Chimento <philip chimento gmail com>
Date:   Mon May 11 09:13:07 2020 -0700

    cairo: Remove JSClass macros from CairoPattern and subclasses
    
    FIXME: Need commit message
    FIXME: Adjust copyright notices in files, I rewrote them

 modules/cairo-context.cpp         |   6 +-
 modules/cairo-gradient.cpp        |  39 ++++----
 modules/cairo-linear-gradient.cpp |  90 ++++++------------
 modules/cairo-pattern.cpp         | 100 +++++++-------------
 modules/cairo-private.h           | 192 ++++++++++++++++++++++++++++----------
 modules/cairo-radial-gradient.cpp |  90 ++++++------------
 modules/cairo-solid-pattern.cpp   |  70 +++++---------
 modules/cairo-surface-pattern.cpp |  92 ++++++------------
 modules/cairo.cpp                 |  12 +--
 9 files changed, 316 insertions(+), 375 deletions(-)
---
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index a1ede125..7f62dcaa 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -469,8 +469,7 @@ mask_func(JSContext *context,
                              "pattern", &pattern_wrapper))
         return false;
 
-    cairo_pattern_t* pattern =
-        gjs_cairo_pattern_get_pattern(context, pattern_wrapper);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, pattern_wrapper);
     if (!pattern)
         return false;
 
@@ -596,8 +595,7 @@ setSource_func(JSContext *context,
                              "pattern", &pattern_wrapper))
         return false;
 
-    cairo_pattern_t* pattern =
-        gjs_cairo_pattern_get_pattern(context, pattern_wrapper);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, pattern_wrapper);
     if (!pattern)
         return false;
 
diff --git a/modules/cairo-gradient.cpp b/modules/cairo-gradient.cpp
index 183725ff..399bb47a 100644
--- a/modules/cairo-gradient.cpp
+++ b/modules/cairo-gradient.cpp
@@ -29,6 +29,8 @@
 #include <js/PropertySpec.h>
 #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"
@@ -36,21 +38,24 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_DEFINE_PROTO_ABSTRACT_WITH_PARENT("Gradient", cairo_gradient,
-                                      cairo_pattern,
-                                      JSCLASS_BACKGROUND_FINALIZE)
+const js::ClassSpec CairoGradient::class_spec = {
+    nullptr,  // createConstructor
+    &CairoGradient::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    CairoGradient::proto_funcs,
+    nullptr,  // prototypeProperties
+    &CairoPattern::define_gtype_prop,
+};
 
-static void
-gjs_cairo_gradient_finalize(JSFreeOp *fop,
-                            JSObject *obj)
-{
-    gjs_cairo_pattern_finalize_pattern(fop, obj);
-}
+const JSClass CairoGradient::klass = {
+    "Gradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoPattern::class_ops};
 
-/* Properties */
-JSPropertySpec gjs_cairo_gradient_proto_props[] = {
-    JS_PS_END
-};
+JSObject* CairoGradient::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoPattern::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
 
 /* Methods */
 
@@ -70,7 +75,7 @@ addColorStopRGB_func(JSContext *context,
                              "blue", &blue))
         return false;
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -100,7 +105,7 @@ addColorStopRGBA_func(JSContext *context,
                              "alpha", &alpha))
         return false;
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -113,11 +118,9 @@ addColorStopRGBA_func(JSContext *context,
     return true;
 }
 
-JSFunctionSpec gjs_cairo_gradient_proto_funcs[] = {
+const JSFunctionSpec CairoGradient::proto_funcs[] = {
     JS_FN("addColorStopRGB", addColorStopRGB_func, 0, 0),
     JS_FN("addColorStopRGBA", addColorStopRGBA_func, 0, 0),
     // getColorStopRGB
     // getColorStopRGBA
     JS_FS_END};
-
-JSFunctionSpec gjs_cairo_gradient_static_funcs[] = { JS_FS_END };
diff --git a/modules/cairo-linear-gradient.cpp b/modules/cairo-linear-gradient.cpp
index 3b50011b..16ce0f81 100644
--- a/modules/cairo-linear-gradient.cpp
+++ b/modules/cairo-linear-gradient.cpp
@@ -30,86 +30,54 @@
 #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"
-#include "gjs/jsapi-util.h"
-#include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_linear_gradient_get_proto(JSContext *);
+namespace JS {
+class CallArgs;
+}
 
-GJS_DEFINE_PROTO_WITH_PARENT("LinearGradient", cairo_linear_gradient,
-                             cairo_gradient, JSCLASS_BACKGROUND_FINALIZE)
+JSObject* CairoLinearGradient::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoGradient::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_linear_gradient)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_linear_gradient)
-    double x0, y0, x1, y1;
-    cairo_pattern_t *pattern;
+const js::ClassSpec CairoLinearGradient::class_spec = {
+    nullptr,  // createConstructor
+    &CairoLinearGradient::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    nullptr,  // prototypeFunctions
+    nullptr,  // prototypeProperties
+    &CairoPattern::define_gtype_prop,
+};
 
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_linear_gradient);
+const JSClass CairoLinearGradient::klass = {
+    "LinearGradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoPattern::class_ops};
 
+cairo_pattern_t* CairoLinearGradient::constructor_impl(
+    JSContext* context, const JS::CallArgs& argv) {
+    double x0, y0, x1, y1;
+    cairo_pattern_t *pattern;
     if (!gjs_parse_call_args(context, "LinearGradient", argv, "ffff",
                              "x0", &x0,
                              "y0", &y0,
                              "x1", &x1,
                              "y1", &y1))
-        return false;
+        return nullptr;
 
     pattern = cairo_pattern_create_linear(x0, y0, x1, y1);
 
     if (!gjs_cairo_check_status(context, cairo_pattern_status(pattern), "pattern"))
-        return false;
-
-    gjs_cairo_pattern_construct(object, pattern);
-    cairo_pattern_destroy(pattern);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_linear_gradient);
-
-    return true;
-}
-
-static void
-gjs_cairo_linear_gradient_finalize(JSFreeOp *fop,
-                                   JSObject *obj)
-{
-    gjs_cairo_pattern_finalize_pattern(fop, obj);
-}
-
-JSPropertySpec gjs_cairo_linear_gradient_proto_props[] = {
-    JS_PS_END
-};
-
-JSFunctionSpec gjs_cairo_linear_gradient_proto_funcs[] = {
-    // getLinearPoints
-    JS_FS_END
-};
-
-JSFunctionSpec gjs_cairo_linear_gradient_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_linear_gradient_from_pattern(JSContext       *context,
-                                       cairo_pattern_t *pattern)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(pattern, nullptr);
-    g_return_val_if_fail(
-        cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_LINEAR, nullptr);
-
-    JS::RootedObject proto(context,
-                           gjs_cairo_linear_gradient_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_linear_gradient_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create linear gradient pattern");
         return nullptr;
-    }
-
-    gjs_cairo_pattern_construct(object, pattern);
 
-    return object;
+    return pattern;
 }
 
+const JSFunctionSpec CairoLinearGradient::proto_funcs[] = {
+    // getLinearPoints
+    JS_FS_END};
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 8669a338..d944dd9c 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -22,7 +22,6 @@
 
 #include <config.h>
 
-#include <cairo-gobject.h>
 #include <cairo.h>
 #include <glib.h>
 
@@ -38,21 +37,34 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE("Pattern", cairo_pattern,
-                                     CAIRO_GOBJECT_TYPE_PATTERN,
-                                     JSCLASS_BACKGROUND_FINALIZE)
+const js::ClassSpec CairoPattern::class_spec = {
+    nullptr,  // createConstructor
+    nullptr,  // createPrototype
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    CairoPattern::proto_funcs,
+    nullptr,  // prototypeProperties
+    &CairoPattern::define_gtype_prop,
+};
 
-static void gjs_cairo_pattern_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoPattern =
-        GjsAutoPointer<cairo_pattern_t, cairo_pattern_t, cairo_pattern_destroy>;
-    AutoPattern pattern = static_cast<cairo_pattern_t*>(JS_GetPrivate(obj));
-    JS_SetPrivate(obj, nullptr);
-}
+const JSClass CairoPattern::klass = {
+    "Pattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoPattern::class_ops};
 
-/* Properties */
-JSPropertySpec gjs_cairo_pattern_proto_props[] = {
-    JS_PS_END
-};
+/**
+ * CairoPattern::finalize:
+ * @fop: the free op
+ * @pattern: pointer to free
+ *
+ * Destroys the resources associated with a pattern wrapper.
+ *
+ * This is mainly used for subclasses. FIXME
+ */
+void CairoPattern::finalize_impl(JSFreeOp*, cairo_pattern_t* pattern) {
+    if (!pattern)
+        return;
+    cairo_pattern_destroy(pattern);
+}
 
 /* Methods */
 
@@ -70,7 +82,7 @@ getType_func(JSContext *context,
         return false;
     }
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -83,54 +95,14 @@ getType_func(JSContext *context,
     return true;
 }
 
-JSFunctionSpec gjs_cairo_pattern_proto_funcs[] = {
+const JSFunctionSpec CairoPattern::proto_funcs[] = {
     // getMatrix
     JS_FN("getType", getType_func, 0, 0),
     // setMatrix
     JS_FS_END};
 
-JSFunctionSpec gjs_cairo_pattern_static_funcs[] = { JS_FS_END };
-
 /* Public API */
 
-/**
- * gjs_cairo_pattern_construct:
- * @object: object to construct
- * @pattern: cairo_pattern to attach to the object
- *
- * Constructs a pattern wrapper giving an empty JSObject and a
- * cairo pattern. A reference to @pattern will be taken.
- *
- * This is mainly used for subclasses where object is already created.
- */
-void gjs_cairo_pattern_construct(JSObject* object, cairo_pattern_t* pattern) {
-    g_return_if_fail(object);
-    g_return_if_fail(pattern);
-
-    g_assert(!JS_GetPrivate(object));
-    JS_SetPrivate(object, cairo_pattern_reference(pattern));
-}
-
-/**
- * gjs_cairo_pattern_finalize:
- * @fop: the free op
- * @object: object to finalize
- *
- * Destroys the resources associated with a pattern wrapper.
- *
- * This is mainly used for subclasses.
- */
-
-void
-gjs_cairo_pattern_finalize_pattern(JSFreeOp *fop,
-                                   JSObject *object)
-{
-    g_return_if_fail(fop);
-    g_return_if_fail(object);
-
-    gjs_cairo_pattern_finalize(fop, object);
-}
-
 /**
  * gjs_cairo_pattern_from_pattern:
  * @context: the context
@@ -149,13 +121,13 @@ gjs_cairo_pattern_from_pattern(JSContext       *context,
 
     switch (cairo_pattern_get_type(pattern)) {
         case CAIRO_PATTERN_TYPE_SOLID:
-            return gjs_cairo_solid_pattern_from_pattern(context, pattern);
+            return CairoSolidPattern::from_c_ptr(context, pattern);
         case CAIRO_PATTERN_TYPE_SURFACE:
-            return gjs_cairo_surface_pattern_from_pattern(context, pattern);
+            return CairoSurfacePattern::from_c_ptr(context, pattern);
         case CAIRO_PATTERN_TYPE_LINEAR:
-            return gjs_cairo_linear_gradient_from_pattern(context, pattern);
+            return CairoLinearGradient::from_c_ptr(context, pattern);
         case CAIRO_PATTERN_TYPE_RADIAL:
-            return gjs_cairo_radial_gradient_from_pattern(context, pattern);
+            return CairoRadialGradient::from_c_ptr(context, pattern);
         case CAIRO_PATTERN_TYPE_MESH:
         case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
         default:
@@ -167,18 +139,18 @@ gjs_cairo_pattern_from_pattern(JSContext       *context,
 }
 
 /**
- * gjs_cairo_pattern_get_pattern:
+ * CairoPattern::for_js:
  * @cx: the context
  * @pattern_wrapper: pattern wrapper
  *
  * Returns: the pattern attached to the wrapper.
  */
-cairo_pattern_t* gjs_cairo_pattern_get_pattern(
-    JSContext* cx, JS::HandleObject pattern_wrapper) {
+cairo_pattern_t* CairoPattern::for_js(JSContext* cx,
+                                      JS::HandleObject pattern_wrapper) {
     g_return_val_if_fail(cx, nullptr);
     g_return_val_if_fail(pattern_wrapper, nullptr);
 
-    JS::RootedObject proto(cx, gjs_cairo_pattern_get_proto(cx));
+    JS::RootedObject proto(cx, CairoPattern::prototype(cx));
 
     bool is_pattern_subclass = false;
     if (!gjs_object_in_prototype_chain(cx, proto, pattern_wrapper,
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index 54760ac1..5f1d5db5 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -32,6 +32,7 @@
 
 #include <js/PropertySpec.h>
 #include <js/TypeDecls.h>
+#include <jspubtd.h>  // for JSProtoKey
 
 #include "gjs/jsapi-class.h"
 #include "gjs/macros.h"
@@ -164,71 +165,160 @@ JSObject *       gjs_cairo_svg_surface_from_surface     (JSContext       *contex
                                                          cairo_surface_t *surface);
 
 /* pattern */
-GJS_USE
-JSObject *gjs_cairo_pattern_get_proto(JSContext *cx);
 
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_pattern_define_proto(JSContext              *cx,
-                                    JS::HandleObject        module,
-                                    JS::MutableHandleObject proto);
+class CairoPattern;
+using CairoPatternBase = NativeObject<CairoPattern, cairo_pattern_t,
+                                      GJS_GLOBAL_SLOT_PROTOTYPE_cairo_pattern>;
+
+class CairoPattern : public CairoPatternBase {
+    friend CairoPatternBase;
+    friend class CairoGradient;  // "inherits" from CairoPattern
+    friend class CairoLinearGradient;
+    friend class CairoRadialGradient;
+    friend class CairoSurfacePattern;
+    friend class CairoSolidPattern;
+
+    CairoPattern() = delete;
+    CairoPattern(CairoPattern&) = delete;
+    CairoPattern(CairoPattern&&) = delete;
+
+    static const JSFunctionSpec proto_funcs[];
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+
+    static GType gtype() { return CAIRO_GOBJECT_TYPE_PATTERN; }
+
+    static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
+        return cairo_pattern_reference(pattern);
+    }
+
+ protected:
+    static void finalize_impl(JSFreeOp* fop, cairo_pattern_t* pattern);
+
+ public:
+    static cairo_pattern_t* for_js(JSContext* cx,
+                                   JS::HandleObject pattern_wrapper);
+};
 
-void gjs_cairo_pattern_construct(JSObject* object, cairo_pattern_t* pattern);
-void             gjs_cairo_pattern_finalize_pattern     (JSFreeOp        *fop,
-                                                         JSObject        *object);
 GJS_JSAPI_RETURN_CONVENTION
 JSObject*        gjs_cairo_pattern_from_pattern         (JSContext       *context,
                                                          cairo_pattern_t *pattern);
-GJS_JSAPI_RETURN_CONVENTION
-cairo_pattern_t* gjs_cairo_pattern_get_pattern(
-    JSContext* cx, JS::HandleObject pattern_wrapper);
 
-/* gradient */
-GJS_USE
-JSObject *gjs_cairo_gradient_get_proto(JSContext *cx);
+class CairoGradient;
+using CairoGradientBase =
+    NativeObject<CairoGradient, cairo_pattern_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_gradient>;
 
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_gradient_define_proto(JSContext              *cx,
-                                     JS::HandleObject        module,
-                                     JS::MutableHandleObject proto);
+class CairoGradient : public CairoGradientBase {
+    friend CairoGradientBase;
+    friend class CairoLinearGradient;  // "inherits" from CairoGradient
+    friend class CairoRadialGradient;
 
-/* linear gradient */
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_linear_gradient_define_proto(JSContext              *cx,
-                                            JS::HandleObject        module,
-                                            JS::MutableHandleObject proto);
+    static const JSFunctionSpec proto_funcs[];
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
 
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_linear_gradient_from_pattern (JSContext       *context,
-                                                         cairo_pattern_t *pattern);
+    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
 
-/* radial gradient */
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_radial_gradient_define_proto(JSContext              *cx,
-                                            JS::HandleObject        module,
-                                            JS::MutableHandleObject proto);
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+};
 
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_radial_gradient_from_pattern (JSContext       *context,
-                                                         cairo_pattern_t *pattern);
+class CairoLinearGradient;
+using CairoLinearGradientBase =
+    NativeObject<CairoLinearGradient, cairo_pattern_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_linear_gradient>;
 
-/* surface pattern */
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_surface_pattern_define_proto(JSContext              *cx,
-                                            JS::HandleObject        module,
-                                            JS::MutableHandleObject proto);
+class CairoLinearGradient : public CairoLinearGradientBase {
+    friend CairoLinearGradientBase;
 
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_surface_pattern_from_pattern (JSContext       *context,
-                                                         cairo_pattern_t *pattern);
+    static const JSFunctionSpec proto_funcs[];
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
 
-/* solid pattern */
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_cairo_solid_pattern_define_proto(JSContext              *cx,
-                                          JS::HandleObject        module,
-                                          JS::MutableHandleObject proto);
+    static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
+        return cairo_pattern_reference(pattern);
+    }
 
-GJS_JSAPI_RETURN_CONVENTION
-JSObject *       gjs_cairo_solid_pattern_from_pattern   (JSContext       *context,
-                                                         cairo_pattern_t *pattern);
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_pattern_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+
+    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+};
+
+class CairoRadialGradient;
+using CairoRadialGradientBase =
+    NativeObject<CairoRadialGradient, cairo_pattern_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_radial_gradient>;
+
+class CairoRadialGradient : public CairoRadialGradientBase {
+    friend CairoRadialGradientBase;
+
+    static const JSFunctionSpec proto_funcs[];
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+
+    static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
+        return cairo_pattern_reference(pattern);
+    }
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_pattern_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+
+    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+};
+
+class CairoSurfacePattern;
+using CairoSurfacePatternBase =
+    NativeObject<CairoSurfacePattern, cairo_pattern_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_surface_pattern>;
+
+class CairoSurfacePattern : public CairoSurfacePatternBase {
+    friend CairoSurfacePatternBase;
+
+    static const JSFunctionSpec proto_funcs[];
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+
+    static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
+        return cairo_pattern_reference(pattern);
+    }
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static cairo_pattern_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
+
+    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+};
+
+class CairoSolidPattern;
+using CairoSolidPatternBase =
+    NativeObject<CairoSolidPattern, cairo_pattern_t,
+                 GJS_GLOBAL_SLOT_PROTOTYPE_cairo_solid_pattern>;
+
+class CairoSolidPattern : public CairoSolidPatternBase {
+    friend CairoSolidPatternBase;
+
+    static const JSFunctionSpec static_funcs[];
+    static const js::ClassSpec class_spec;
+    static const JSClass klass;
+
+    static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
+        return cairo_pattern_reference(pattern);
+    }
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* new_proto(JSContext* cx, JSProtoKey);
+
+    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+};
 
 #endif  // MODULES_CAIRO_PRIVATE_H_
diff --git a/modules/cairo-radial-gradient.cpp b/modules/cairo-radial-gradient.cpp
index 3d0e71fc..f1b62b31 100644
--- a/modules/cairo-radial-gradient.cpp
+++ b/modules/cairo-radial-gradient.cpp
@@ -30,27 +30,39 @@
 #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"
-#include "gjs/jsapi-util.h"
-#include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_radial_gradient_get_proto(JSContext *);
+namespace JS {
+class CallArgs;
+}
 
-GJS_DEFINE_PROTO_WITH_PARENT("RadialGradient", cairo_radial_gradient,
-                             cairo_gradient, JSCLASS_BACKGROUND_FINALIZE)
+JSObject* CairoRadialGradient::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoGradient::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_radial_gradient)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_radial_gradient)
-    double cx0, cy0, radius0, cx1, cy1, radius1;
-    cairo_pattern_t *pattern;
+const js::ClassSpec CairoRadialGradient::class_spec = {
+    nullptr,  // createConstructor
+    &CairoRadialGradient::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    nullptr,  // prototypeFunctions
+    nullptr,  // prototypeProperties
+    &CairoPattern::define_gtype_prop,
+};
 
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_radial_gradient);
+const JSClass CairoRadialGradient::klass = {
+    "RadialGradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoPattern::class_ops};
 
+cairo_pattern_t* CairoRadialGradient::constructor_impl(
+    JSContext* context, const JS::CallArgs& argv) {
+    double cx0, cy0, radius0, cx1, cy1, radius1;
+    cairo_pattern_t *pattern;
     if (!gjs_parse_call_args(context, "RadialGradient", argv, "ffffff",
                              "cx0", &cx0,
                              "cy0", &cy0,
@@ -58,60 +70,16 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_radial_gradient)
                              "cx1", &cx1,
                              "cy1", &cy1,
                              "radius1", &radius1))
-        return false;
+        return nullptr;
 
     pattern = cairo_pattern_create_radial(cx0, cy0, radius0, cx1, cy1, radius1);
 
     if (!gjs_cairo_check_status(context, cairo_pattern_status(pattern), "pattern"))
-        return false;
-
-    gjs_cairo_pattern_construct(object, pattern);
-    cairo_pattern_destroy(pattern);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_radial_gradient);
-
-    return true;
-}
-
-static void
-gjs_cairo_radial_gradient_finalize(JSFreeOp *fop,
-                                   JSObject *obj)
-{
-    gjs_cairo_pattern_finalize_pattern(fop, obj);
-}
-
-JSPropertySpec gjs_cairo_radial_gradient_proto_props[] = {
-    JS_PS_END
-};
-
-JSFunctionSpec gjs_cairo_radial_gradient_proto_funcs[] = {
-    // getRadialCircles
-    JS_FS_END
-};
-
-JSFunctionSpec gjs_cairo_radial_gradient_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_radial_gradient_from_pattern(JSContext       *context,
-                                       cairo_pattern_t *pattern)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(pattern, nullptr);
-    g_return_val_if_fail(
-        cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_RADIAL, nullptr);
-
-    JS::RootedObject proto(context,
-                           gjs_cairo_radial_gradient_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_radial_gradient_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create radial gradient pattern");
         return nullptr;
-    }
-
-    gjs_cairo_pattern_construct(object, pattern);
 
-    return object;
+    return pattern;
 }
 
+const JSFunctionSpec CairoRadialGradient::proto_funcs[] = {
+    // getRadialCircles
+    JS_FS_END};
diff --git a/modules/cairo-solid-pattern.cpp b/modules/cairo-solid-pattern.cpp
index e03e420a..ad09c213 100644
--- a/modules/cairo-solid-pattern.cpp
+++ b/modules/cairo-solid-pattern.cpp
@@ -23,7 +23,6 @@
 #include <config.h>
 
 #include <cairo.h>
-#include <glib.h>
 
 #include <js/CallArgs.h>
 #include <js/Class.h>
@@ -31,31 +30,32 @@
 #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"
-#include "gjs/jsapi-util.h"
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_solid_pattern_get_proto(JSContext *);
-
-GJS_DEFINE_PROTO_ABSTRACT_WITH_PARENT("SolidPattern", cairo_solid_pattern,
-                                      cairo_pattern,
-                                      JSCLASS_BACKGROUND_FINALIZE)
-
-static void
-gjs_cairo_solid_pattern_finalize(JSFreeOp *fop,
-                                 JSObject *obj)
-{
-    gjs_cairo_pattern_finalize_pattern(fop, obj);
+JSObject* CairoSolidPattern::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoPattern::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
 }
 
-JSPropertySpec gjs_cairo_solid_pattern_proto_props[] = {
-    JS_PS_END
+const js::ClassSpec CairoSolidPattern::class_spec = {
+    nullptr,  // createConstructor
+    &CairoSolidPattern::new_proto,
+    CairoSolidPattern::static_funcs,
+    nullptr,  // constructorProperties
+    nullptr,  // prototypeFunctions
+    nullptr,  // prototypeProperties
+    &CairoPattern::define_gtype_prop,
 };
 
+const JSClass CairoSolidPattern::klass = {
+    "SolidPattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoPattern::class_ops};
+
 GJS_JSAPI_RETURN_CONVENTION
 static bool
 createRGB_func(JSContext *context,
@@ -65,7 +65,6 @@ createRGB_func(JSContext *context,
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
     double red, green, blue;
     cairo_pattern_t *pattern;
-    JSObject *pattern_wrapper;
 
     if (!gjs_parse_call_args(context, "createRGB", argv, "fff",
                              "red", &red,
@@ -77,7 +76,9 @@ createRGB_func(JSContext *context,
     if (!gjs_cairo_check_status(context, cairo_pattern_status(pattern), "pattern"))
         return false;
 
-    pattern_wrapper = gjs_cairo_solid_pattern_from_pattern(context, pattern);
+    JSObject* pattern_wrapper = CairoSolidPattern::from_c_ptr(context, pattern);
+    if (!pattern_wrapper)
+        return false;
     cairo_pattern_destroy(pattern);
 
     argv.rval().setObjectOrNull(pattern_wrapper);
@@ -94,7 +95,6 @@ createRGBA_func(JSContext *context,
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
     double red, green, blue, alpha;
     cairo_pattern_t *pattern;
-    JSObject *pattern_wrapper;
 
     if (!gjs_parse_call_args(context, "createRGBA", argv, "ffff",
                              "red", &red,
@@ -107,7 +107,9 @@ createRGBA_func(JSContext *context,
     if (!gjs_cairo_check_status(context, cairo_pattern_status(pattern), "pattern"))
         return false;
 
-    pattern_wrapper = gjs_cairo_solid_pattern_from_pattern(context, pattern);
+    JSObject* pattern_wrapper = CairoSolidPattern::from_c_ptr(context, pattern);
+    if (!pattern_wrapper)
+        return false;
     cairo_pattern_destroy(pattern);
 
     argv.rval().setObjectOrNull(pattern_wrapper);
@@ -115,33 +117,7 @@ createRGBA_func(JSContext *context,
     return true;
 }
 
-JSFunctionSpec gjs_cairo_solid_pattern_proto_funcs[] = {
+const JSFunctionSpec CairoSolidPattern::static_funcs[] = {
     JS_FN("createRGB", createRGB_func, 0, 0),
     JS_FN("createRGBA", createRGBA_func, 0, 0),
     JS_FS_END};
-
-JSFunctionSpec gjs_cairo_solid_pattern_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_solid_pattern_from_pattern(JSContext       *context,
-                                     cairo_pattern_t *pattern)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(pattern, nullptr);
-    g_return_val_if_fail(
-        cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SOLID, nullptr);
-
-    JS::RootedObject proto(context, gjs_cairo_solid_pattern_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_solid_pattern_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create solid pattern");
-        return nullptr;
-    }
-
-    gjs_cairo_pattern_construct(object, pattern);
-
-    return object;
-}
-
diff --git a/modules/cairo-surface-pattern.cpp b/modules/cairo-surface-pattern.cpp
index 5c522d7d..65b43684 100644
--- a/modules/cairo-surface-pattern.cpp
+++ b/modules/cairo-surface-pattern.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,54 +39,46 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-GJS_USE
-static JSObject *gjs_cairo_surface_pattern_get_proto(JSContext *);
-
-GJS_DEFINE_PROTO_WITH_PARENT("SurfacePattern", cairo_surface_pattern,
-                             cairo_pattern, JSCLASS_BACKGROUND_FINALIZE)
+JSObject* CairoSurfacePattern::new_proto(JSContext* cx, JSProtoKey) {
+    JS::RootedObject parent_proto(cx, CairoPattern::prototype(cx));
+    return JS_NewObjectWithGivenProto(cx, nullptr, parent_proto);
+}
 
-GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_surface_pattern)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_surface_pattern)
-    cairo_pattern_t *pattern;
+const js::ClassSpec CairoSurfacePattern::class_spec = {
+    nullptr,  // createConstructor
+    &CairoSurfacePattern::new_proto,
+    nullptr,  // constructorFunctions
+    nullptr,  // constructorProperties
+    CairoSurfacePattern::proto_funcs,
+    nullptr,  // prototypeProperties
+    &CairoPattern::define_gtype_prop,
+};
 
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_surface_pattern);
+const JSClass CairoSurfacePattern::klass = {
+    "SurfacePattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    &CairoPattern::class_ops};
 
+cairo_pattern_t* CairoSurfacePattern::constructor_impl(
+    JSContext* context, const JS::CallArgs& argv) {
+    cairo_pattern_t *pattern;
     JS::RootedObject surface_wrapper(context);
     if (!gjs_parse_call_args(context, "SurfacePattern", argv, "o",
                              "surface", &surface_wrapper))
-        return false;
+        return nullptr;
 
     cairo_surface_t* surface =
         gjs_cairo_surface_get_surface(context, surface_wrapper);
     if (!surface)
-        return false;
+        return nullptr;
 
     pattern = cairo_pattern_create_for_surface(surface);
 
     if (!gjs_cairo_check_status(context, cairo_pattern_status(pattern), "pattern"))
-        return false;
-
-    gjs_cairo_pattern_construct(object, pattern);
-    cairo_pattern_destroy(pattern);
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_surface_pattern);
-
-    return true;
-}
-
+        return nullptr;
 
-static void
-gjs_cairo_surface_pattern_finalize(JSFreeOp *fop,
-                                   JSObject *obj)
-{
-    gjs_cairo_pattern_finalize_pattern(fop, obj);
+    return pattern;
 }
 
-JSPropertySpec gjs_cairo_surface_pattern_proto_props[] = {
-    JS_PS_END
-};
-
 GJS_JSAPI_RETURN_CONVENTION
 static bool
 setExtend_func(JSContext *context,
@@ -99,7 +92,7 @@ setExtend_func(JSContext *context,
                              "extend", &extend))
         return false;
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -126,7 +119,7 @@ getExtend_func(JSContext *context,
         return false;
     }
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -153,7 +146,7 @@ setFilter_func(JSContext *context,
                              "filter", &filter))
         return false;
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -180,7 +173,7 @@ getFilter_func(JSContext *context,
         return false;
     }
 
-    cairo_pattern_t* pattern = gjs_cairo_pattern_get_pattern(context, obj);
+    cairo_pattern_t* pattern = CairoPattern::for_js(context, obj);
     if (!pattern)
         return false;
 
@@ -194,36 +187,9 @@ getFilter_func(JSContext *context,
     return true;
 }
 
-JSFunctionSpec gjs_cairo_surface_pattern_proto_funcs[] = {
+const JSFunctionSpec CairoSurfacePattern::proto_funcs[] = {
     JS_FN("setExtend", setExtend_func, 0, 0),
     JS_FN("getExtend", getExtend_func, 0, 0),
     JS_FN("setFilter", setFilter_func, 0, 0),
     JS_FN("getFilter", getFilter_func, 0, 0),
     JS_FS_END};
-
-JSFunctionSpec gjs_cairo_surface_pattern_static_funcs[] = { JS_FS_END };
-
-JSObject *
-gjs_cairo_surface_pattern_from_pattern(JSContext       *context,
-                                       cairo_pattern_t *pattern)
-{
-    g_return_val_if_fail(context, nullptr);
-    g_return_val_if_fail(pattern, nullptr);
-    g_return_val_if_fail(
-        cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SURFACE, nullptr);
-
-    JS::RootedObject proto(context,
-                           gjs_cairo_surface_pattern_get_proto(context));
-    JS::RootedObject object(context,
-        JS_NewObjectWithGivenProto(context, &gjs_cairo_surface_pattern_class,
-                                   proto));
-    if (!object) {
-        gjs_throw(context, "failed to create surface pattern");
-        return nullptr;
-    }
-
-    gjs_cairo_pattern_construct(object, pattern);
-
-    return object;
-}
-
diff --git a/modules/cairo.cpp b/modules/cairo.cpp
index cd26cc77..cdcc59a1 100644
--- a/modules/cairo.cpp
+++ b/modules/cairo.cpp
@@ -92,10 +92,10 @@ gjs_js_define_cairo_stuff(JSContext              *context,
 #if CAIRO_HAS_SVG_SURFACE
         gjs_cairo_svg_surface_define_proto(context, module, &proto) &&
 #endif
-        gjs_cairo_pattern_define_proto(context, module, &proto) &&
-        gjs_cairo_gradient_define_proto(context, module, &proto) &&
-        gjs_cairo_linear_gradient_define_proto(context, module, &proto) &&
-        gjs_cairo_radial_gradient_define_proto(context, module, &proto) &&
-        gjs_cairo_surface_pattern_define_proto(context, module, &proto) &&
-        gjs_cairo_solid_pattern_define_proto(context, module, &proto);
+        CairoPattern::create_prototype(context, module) &&
+        CairoGradient::create_prototype(context, module) &&
+        CairoLinearGradient::create_prototype(context, module) &&
+        CairoRadialGradient::create_prototype(context, module) &&
+        CairoSurfacePattern::create_prototype(context, module) &&
+        CairoSolidPattern::create_prototype(context, module);
 }


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