diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2020-05-05 22:30:12 -0700 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2021-01-30 13:56:30 -0800 |
commit | e15f239b9ff528bb473b83a7e57313236d4a76b7 (patch) | |
tree | fac70849e1413eb48fe23c2f4fa4be943e1ff3de /modules | |
parent | bfea3ebd317c30d3f3ef31be937cbd417723bb1a (diff) | |
download | gjs-e15f239b9ff528bb473b83a7e57313236d4a76b7.tar.gz |
cairo: Remove JSClass macros from Cairo context
Remove the usage of the GJS_DEFINE_PRIV_FROM_JS and GJS_DEFINE_PROTO
families of macros from the Cairo context wrapper type. Use CWrapper
instead, for more type safety and less boilerplate.
Also requires adding a debug topic for Cairo.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/cairo-context.cpp | 98 | ||||
-rw-r--r-- | modules/cairo-private.h | 62 | ||||
-rw-r--r-- | modules/cairo.cpp | 2 |
3 files changed, 76 insertions, 86 deletions
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp index 3654cae4..b1693239 100644 --- a/modules/cairo-context.cpp +++ b/modules/cairo-context.cpp @@ -6,14 +6,12 @@ #include <vector> -#include <cairo-gobject.h> #include <cairo.h> #include <girepository.h> #include <glib.h> #include <js/Array.h> // for JS::NewArrayObject #include <js/CallArgs.h> -#include <js/Class.h> #include <js/Conversions.h> #include <js/PropertyDescriptor.h> // for JSPROP_READONLY #include <js/PropertySpec.h> @@ -28,17 +26,16 @@ #include "gi/arg.h" #include "gi/foreign.h" #include "gjs/enum-utils.h" -#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" -struct GjsCairoContext; - #define _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(cx, argc, vp, argv, obj) \ - GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv); \ - cairo_t* cr = priv->get(); \ + GJS_GET_THIS(cx, argc, vp, argv, obj); \ + cairo_t* cr; \ + if (!CairoContext::for_js_typecheck(cx, obj, &cr, &argv)) \ + return false; \ if (!cr) \ return true; @@ -248,64 +245,38 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(method) \ argv.rval().setUndefined(); \ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END -[[nodiscard]] static JSObject* gjs_cairo_context_get_proto(JSContext*); - -struct GjsCairoContext - : GjsAutoPointer<cairo_t, cairo_t, cairo_destroy, cairo_reference> { - explicit GjsCairoContext(cairo_t* cr) - : GjsAutoPointer(cr, GjsAutoTakeOwnership()) {} -}; - -GJS_DEFINE_PROTO_WITH_GTYPE("Context", cairo_context, - CAIRO_GOBJECT_TYPE_CONTEXT, - JSCLASS_BACKGROUND_FINALIZE) -GJS_DEFINE_PRIV_FROM_JS(GjsCairoContext, gjs_cairo_context_class); - -static void _gjs_cairo_context_construct_internal(JSContext* context, - JS::HandleObject obj, - cairo_t* cr) { - g_assert(!priv_from_js(context, obj)); - JS_SetPrivate(obj, new GjsCairoContext(cr)); -} - -GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_context) -{ - GJS_NATIVE_CONSTRUCTOR_VARIABLES(cairo_context) +GJS_JSAPI_RETURN_CONVENTION +cairo_t* CairoContext::constructor_impl(JSContext* context, + const JS::CallArgs& argv) { cairo_t *cr; - GJS_NATIVE_CONSTRUCTOR_PRELUDE(cairo_context); - JS::RootedObject surface_wrapper(context); if (!gjs_parse_call_args(context, "Context", 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; cr = cairo_create(surface); if (!gjs_cairo_check_status(context, cairo_status(cr), "context")) - return false; - - _gjs_cairo_context_construct_internal(context, object, cr); - cairo_destroy(cr); - - GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_context); + return nullptr; - return true; + return cr; } -static void gjs_cairo_context_finalize(JSFreeOp*, JSObject* obj) { - delete static_cast<GjsCairoContext*>(JS_GetPrivate(obj)); - JS_SetPrivate(obj, nullptr); +void CairoContext::finalize_impl(JSFreeOp*, cairo_t* cr) { + if (!cr) + return; + cairo_destroy(cr); } /* Properties */ // clang-format off -JSPropertySpec gjs_cairo_context_proto_props[] = { +const JSPropertySpec CairoContext::proto_props[] = { JS_STRING_SYM_PS(toStringTag, "Context", JSPROP_READONLY), JS_PS_END}; // clang-format on @@ -820,7 +791,8 @@ getGroupTarget_func(JSContext *context, return true; } -JSFunctionSpec gjs_cairo_context_proto_funcs[] = { +// clang-format off +const JSFunctionSpec CairoContext::proto_funcs[] = { JS_FN("$dispose", dispose_func, 0, 0), JS_FN("appendPath", appendPath_func, 0, 0), JS_FN("arc", arc_func, 0, 0), @@ -920,31 +892,7 @@ JSFunctionSpec gjs_cairo_context_proto_funcs[] = { JS_FN("userToDevice", userToDevice_func, 0, 0), JS_FN("userToDeviceDistance", userToDeviceDistance_func, 0, 0), JS_FS_END}; - -JSFunctionSpec gjs_cairo_context_static_funcs[] = { JS_FS_END }; - -JSObject * -gjs_cairo_context_from_context(JSContext *context, - cairo_t *cr) -{ - JS::RootedObject proto(context, gjs_cairo_context_get_proto(context)); - JS::RootedObject object(context, - JS_NewObjectWithGivenProto(context, &gjs_cairo_context_class, proto)); - if (!object) - return nullptr; - - _gjs_cairo_context_construct_internal(context, object, cr); - - return object; -} - -cairo_t * -gjs_cairo_context_get_context(JSContext *context, - JS::HandleObject object) -{ - auto* priv = priv_from_js(context, object); - return priv ? priv->get() : nullptr; -} +// clang-format on [[nodiscard]] static bool context_to_g_argument( JSContext* context, JS::Value value, const char* arg_name, @@ -963,9 +911,7 @@ gjs_cairo_context_get_context(JSContext *context, } JS::RootedObject obj(context, &value.toObject()); - cairo_t *cr; - - cr = gjs_cairo_context_get_context(context, obj); + cairo_t* cr = CairoContext::for_js(context, obj); if (!cr) return false; if (transfer == GI_TRANSFER_EVERYTHING) @@ -981,8 +927,8 @@ context_from_g_argument(JSContext *context, JS::MutableHandleValue value_p, GIArgument *arg) { - JSObject* obj = - gjs_cairo_context_from_context(context, gjs_arg_get<cairo_t*>(arg)); + JSObject* obj = CairoContext::from_c_ptr( + context, static_cast<cairo_t*>(arg->v_pointer)); if (!obj) { gjs_throw(context, "Could not create Cairo context"); return false; diff --git a/modules/cairo-private.h b/modules/cairo-private.h index f3f1aec3..601632b1 100644 --- a/modules/cairo-private.h +++ b/modules/cairo-private.h @@ -1,6 +1,7 @@ /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later // SPDX-FileCopyrightText: 2010 litl, LLC. +// SPDX-FileCopyrightText: 2020 Philip Chimento <philip.chimento@gmail.com> #ifndef MODULES_CAIRO_PRIVATE_H_ #define MODULES_CAIRO_PRIVATE_H_ @@ -8,11 +9,26 @@ #include <config.h> #include <cairo-features.h> // for CAIRO_HAS_PDF_SURFACE, CAIRO_HAS_PS_SURFACE +#include <cairo-gobject.h> #include <cairo.h> +#include <glib-object.h> +#include <js/PropertySpec.h> #include <js/TypeDecls.h> +#include "gi/cwrapper.h" +#include "gi/wrapperutils.h" +#include "gjs/global.h" #include "gjs/macros.h" +#include "util/log.h" + +namespace JS { +class CallArgs; +} +namespace js { +struct ClassSpec; +} +struct JSClass; GJS_JSAPI_RETURN_CONVENTION bool gjs_cairo_check_status (JSContext *context, @@ -26,16 +42,44 @@ bool gjs_cairo_region_define_proto(JSContext *cx, void gjs_cairo_region_init(void); -GJS_JSAPI_RETURN_CONVENTION -bool gjs_cairo_context_define_proto(JSContext *cx, - JS::HandleObject module, - JS::MutableHandleObject proto); +class CairoContext : public CWrapper<CairoContext, cairo_t> { + friend CWrapperPointerOps<CairoContext, cairo_t>; + friend CWrapper<CairoContext, cairo_t>; + + CairoContext() = delete; + CairoContext(CairoContext&) = delete; + CairoContext(CairoContext&&) = delete; + + static constexpr GjsGlobalSlot PROTOTYPE_SLOT = + GjsGlobalSlot::PROTOTYPE_cairo_context; + static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_CAIRO; + static constexpr unsigned constructor_nargs = 1; + + static GType gtype() { return CAIRO_GOBJECT_TYPE_CONTEXT; } + + static cairo_t* copy_ptr(cairo_t* cr) { return cairo_reference(cr); } + + GJS_JSAPI_RETURN_CONVENTION + static cairo_t* constructor_impl(JSContext* cx, const JS::CallArgs& args); + + static void finalize_impl(JSFreeOp* fop, cairo_t* cr); + + static const JSFunctionSpec proto_funcs[]; + static const JSPropertySpec proto_props[]; + static constexpr js::ClassSpec class_spec = { + nullptr, // createConstructor + nullptr, // createPrototype + nullptr, // constructorFunctions + nullptr, // constructorProperties + CairoContext::proto_funcs, + CairoContext::proto_props, + CairoContext::define_gtype_prop, + }; + static constexpr JSClass klass = { + "Context", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE, + &CairoContext::class_ops, &CairoContext::class_spec}; +}; -[[nodiscard]] cairo_t* gjs_cairo_context_get_context(JSContext* cx, - JS::HandleObject object); -GJS_JSAPI_RETURN_CONVENTION -JSObject * gjs_cairo_context_from_context (JSContext *context, - cairo_t *cr); void gjs_cairo_context_init(void); void gjs_cairo_surface_init(void); diff --git a/modules/cairo.cpp b/modules/cairo.cpp index 172de91c..c2d3e764 100644 --- a/modules/cairo.cpp +++ b/modules/cairo.cpp @@ -61,7 +61,7 @@ gjs_js_define_cairo_stuff(JSContext *context, return false; gjs_cairo_region_init(); - if (!gjs_cairo_context_define_proto(context, module, &proto)) + if (!CairoContext::create_prototype(context, module)) return false; gjs_cairo_context_init(); |