LCOV - code coverage report
Current view: top level - modules - cairo-region.cpp (source / functions) Coverage Total Hit
Test: gjs- Code Coverage Lines: 2.9 % 104 3
Test Date: 2024-04-20 17:42:51 Functions: 5.6 % 18 1
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0.0 % 110 0

             Branch data     Line data    Source code
       1                 :             : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
       2                 :             : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       3                 :             : // SPDX-FileCopyrightText: 2014 Red Hat, Inc.
       4                 :             : 
       5                 :             : #include <config.h>
       6                 :             : 
       7                 :             : #include <cairo.h>
       8                 :             : #include <girepository.h>
       9                 :             : 
      10                 :             : #include <js/CallArgs.h>
      11                 :             : #include <js/Conversions.h>
      12                 :             : #include <js/PropertyAndElement.h>
      13                 :             : #include <js/PropertyDescriptor.h>  // for JSPROP_READONLY
      14                 :             : #include <js/PropertySpec.h>
      15                 :             : #include <js/RootingAPI.h>
      16                 :             : #include <js/TypeDecls.h>
      17                 :             : #include <js/Value.h>
      18                 :             : #include <jsapi.h>  // for JS_NewPlainObject
      19                 :             : 
      20                 :             : #include "gi/arg-inl.h"
      21                 :             : #include "gi/arg.h"
      22                 :             : #include "gi/foreign.h"
      23                 :             : #include "gjs/atoms.h"
      24                 :             : #include "gjs/context-private.h"
      25                 :             : #include "gjs/enum-utils.h"
      26                 :             : #include "gjs/jsapi-util-args.h"
      27                 :             : #include "gjs/jsapi-util.h"
      28                 :             : #include "gjs/macros.h"
      29                 :             : #include "modules/cairo-private.h"
      30                 :             : 
      31                 :             : GJS_JSAPI_RETURN_CONVENTION
      32                 :             : static bool
      33                 :             : fill_rectangle(JSContext             *context,
      34                 :             :                JS::HandleObject       obj,
      35                 :             :                cairo_rectangle_int_t *rect);
      36                 :             : 
      37                 :             : #define PRELUDE                                                            \
      38                 :             :     GJS_GET_THIS(context, argc, vp, argv, obj);                            \
      39                 :             :     cairo_region_t* this_region;                                           \
      40                 :             :     if (!CairoRegion::for_js_typecheck(context, obj, &this_region, &argv)) \
      41                 :             :         return false;
      42                 :             : 
      43                 :             : #define RETURN_STATUS                                           \
      44                 :             :     return gjs_cairo_check_status(context, cairo_region_status(this_region), "region");
      45                 :             : 
      46                 :             : #define REGION_DEFINE_REGION_FUNC(method)                                     \
      47                 :             :     GJS_JSAPI_RETURN_CONVENTION                                               \
      48                 :             :     static bool method##_func(JSContext* context, unsigned argc,              \
      49                 :             :                               JS::Value* vp) {                                \
      50                 :             :         PRELUDE;                                                              \
      51                 :             :         JS::RootedObject other_obj(context);                                  \
      52                 :             :         if (!gjs_parse_call_args(context, #method, argv, "o", "other_region", \
      53                 :             :                                  &other_obj))                                 \
      54                 :             :             return false;                                                     \
      55                 :             :                                                                               \
      56                 :             :         cairo_region_t* other_region =                                        \
      57                 :             :             CairoRegion::for_js(context, other_obj);                          \
      58                 :             :                                                                               \
      59                 :             :         cairo_region_##method(this_region, other_region);                     \
      60                 :             :         argv.rval().setUndefined();                                           \
      61                 :             :         RETURN_STATUS;                                                        \
      62                 :             :     }
      63                 :             : 
      64                 :             : #define REGION_DEFINE_RECT_FUNC(method)                                    \
      65                 :             :     GJS_JSAPI_RETURN_CONVENTION                                            \
      66                 :             :     static bool method##_rectangle_func(JSContext* context, unsigned argc, \
      67                 :             :                                         JS::Value* vp) {                   \
      68                 :             :         PRELUDE;                                                           \
      69                 :             :         JS::RootedObject rect_obj(context);                                \
      70                 :             :         if (!gjs_parse_call_args(context, #method, argv, "o", "rect",      \
      71                 :             :                                  &rect_obj))                               \
      72                 :             :             return false;                                                  \
      73                 :             :                                                                            \
      74                 :             :         cairo_rectangle_int_t rect;                                        \
      75                 :             :         if (!fill_rectangle(context, rect_obj, &rect))                     \
      76                 :             :             return false;                                                  \
      77                 :             :                                                                            \
      78                 :             :         cairo_region_##method##_rectangle(this_region, &rect);             \
      79                 :             :         argv.rval().setUndefined();                                        \
      80                 :             :         RETURN_STATUS;                                                     \
      81                 :             :     }
      82                 :             : 
      83   [ #  #  #  #  :           0 : REGION_DEFINE_REGION_FUNC(union)
                   #  # ]
      84   [ #  #  #  #  :           0 : REGION_DEFINE_REGION_FUNC(subtract)
                   #  # ]
      85   [ #  #  #  #  :           0 : REGION_DEFINE_REGION_FUNC(intersect)
                   #  # ]
      86   [ #  #  #  #  :           0 : REGION_DEFINE_REGION_FUNC(xor)
                   #  # ]
      87                 :             : 
      88   [ #  #  #  #  :           0 : REGION_DEFINE_RECT_FUNC(union)
             #  #  #  # ]
      89   [ #  #  #  #  :           0 : REGION_DEFINE_RECT_FUNC(subtract)
             #  #  #  # ]
      90   [ #  #  #  #  :           0 : REGION_DEFINE_RECT_FUNC(intersect)
             #  #  #  # ]
      91   [ #  #  #  #  :           0 : REGION_DEFINE_RECT_FUNC(xor)
             #  #  #  # ]
      92                 :             : 
      93                 :             : GJS_JSAPI_RETURN_CONVENTION
      94                 :             : static bool
      95                 :           0 : fill_rectangle(JSContext             *context,
      96                 :             :                JS::HandleObject       obj,
      97                 :             :                cairo_rectangle_int_t *rect)
      98                 :             : {
      99                 :           0 :     const GjsAtoms& atoms = GjsContextPrivate::atoms(context);
     100                 :           0 :     JS::RootedValue val(context);
     101                 :             : 
     102         [ #  # ]:           0 :     if (!JS_GetPropertyById(context, obj, atoms.x(), &val))
     103                 :           0 :         return false;
     104         [ #  # ]:           0 :     if (!JS::ToInt32(context, val, &rect->x))
     105                 :           0 :         return false;
     106                 :             : 
     107         [ #  # ]:           0 :     if (!JS_GetPropertyById(context, obj, atoms.y(), &val))
     108                 :           0 :         return false;
     109         [ #  # ]:           0 :     if (!JS::ToInt32(context, val, &rect->y))
     110                 :           0 :         return false;
     111                 :             : 
     112         [ #  # ]:           0 :     if (!JS_GetPropertyById(context, obj, atoms.width(), &val))
     113                 :           0 :         return false;
     114         [ #  # ]:           0 :     if (!JS::ToInt32(context, val, &rect->width))
     115                 :           0 :         return false;
     116                 :             : 
     117         [ #  # ]:           0 :     if (!JS_GetPropertyById(context, obj, atoms.height(), &val))
     118                 :           0 :         return false;
     119         [ #  # ]:           0 :     if (!JS::ToInt32(context, val, &rect->height))
     120                 :           0 :         return false;
     121                 :             : 
     122                 :           0 :     return true;
     123                 :           0 : }
     124                 :             : 
     125                 :             : GJS_JSAPI_RETURN_CONVENTION
     126                 :             : static JSObject *
     127                 :           0 : make_rectangle(JSContext *context,
     128                 :             :                cairo_rectangle_int_t *rect)
     129                 :             : {
     130                 :           0 :     const GjsAtoms& atoms = GjsContextPrivate::atoms(context);
     131                 :           0 :     JS::RootedObject rect_obj(context, JS_NewPlainObject(context));
     132         [ #  # ]:           0 :     if (!rect_obj)
     133                 :           0 :         return nullptr;
     134                 :           0 :     JS::RootedValue val(context);
     135                 :             : 
     136                 :           0 :     val = JS::Int32Value(rect->x);
     137         [ #  # ]:           0 :     if (!JS_SetPropertyById(context, rect_obj, atoms.x(), val))
     138                 :           0 :         return nullptr;
     139                 :             : 
     140                 :           0 :     val = JS::Int32Value(rect->y);
     141         [ #  # ]:           0 :     if (!JS_SetPropertyById(context, rect_obj, atoms.y(), val))
     142                 :           0 :         return nullptr;
     143                 :             : 
     144                 :           0 :     val = JS::Int32Value(rect->width);
     145         [ #  # ]:           0 :     if (!JS_SetPropertyById(context, rect_obj, atoms.width(), val))
     146                 :           0 :         return nullptr;
     147                 :             : 
     148                 :           0 :     val = JS::Int32Value(rect->height);
     149         [ #  # ]:           0 :     if (!JS_SetPropertyById(context, rect_obj, atoms.height(), val))
     150                 :           0 :         return nullptr;
     151                 :             : 
     152                 :           0 :     return rect_obj;
     153                 :           0 : }
     154                 :             : 
     155                 :             : GJS_JSAPI_RETURN_CONVENTION
     156                 :             : static bool
     157                 :           0 : num_rectangles_func(JSContext *context,
     158                 :             :                     unsigned argc,
     159                 :             :                     JS::Value *vp)
     160                 :             : {
     161   [ #  #  #  # ]:           0 :     PRELUDE;
     162                 :             :     int n_rects;
     163                 :             : 
     164         [ #  # ]:           0 :     if (!gjs_parse_call_args(context, "num_rectangles", argv, ""))
     165                 :           0 :         return false;
     166                 :             : 
     167                 :           0 :     n_rects = cairo_region_num_rectangles(this_region);
     168                 :           0 :     argv.rval().setInt32(n_rects);
     169                 :           0 :     RETURN_STATUS;
     170                 :           0 : }
     171                 :             : 
     172                 :             : GJS_JSAPI_RETURN_CONVENTION
     173                 :             : static bool
     174                 :           0 : get_rectangle_func(JSContext *context,
     175                 :             :                    unsigned argc,
     176                 :             :                    JS::Value *vp)
     177                 :             : {
     178   [ #  #  #  # ]:           0 :     PRELUDE;
     179                 :             :     int i;
     180                 :             :     JSObject *rect_obj;
     181                 :             :     cairo_rectangle_int_t rect;
     182                 :             : 
     183         [ #  # ]:           0 :     if (!gjs_parse_call_args(context, "get_rectangle", argv, "i",
     184                 :             :                              "rect", &i))
     185                 :           0 :         return false;
     186                 :             : 
     187                 :           0 :     cairo_region_get_rectangle(this_region, i, &rect);
     188                 :           0 :     rect_obj = make_rectangle(context, &rect);
     189                 :             : 
     190                 :           0 :     argv.rval().setObjectOrNull(rect_obj);
     191                 :           0 :     RETURN_STATUS;
     192                 :           0 : }
     193                 :             : 
     194                 :             : // clang-format off
     195                 :             : const JSPropertySpec CairoRegion::proto_props[] = {
     196                 :             :     JS_STRING_SYM_PS(toStringTag, "Region", JSPROP_READONLY),
     197                 :             :     JS_PS_END};
     198                 :             : // clang-format on
     199                 :             : 
     200                 :             : const JSFunctionSpec CairoRegion::proto_funcs[] = {
     201                 :             :     JS_FN("union", union_func, 0, 0),
     202                 :             :     JS_FN("subtract", subtract_func, 0, 0),
     203                 :             :     JS_FN("intersect", intersect_func, 0, 0),
     204                 :             :     JS_FN("xor", xor_func, 0, 0),
     205                 :             : 
     206                 :             :     JS_FN("unionRectangle", union_rectangle_func, 0, 0),
     207                 :             :     JS_FN("subtractRectangle", subtract_rectangle_func, 0, 0),
     208                 :             :     JS_FN("intersectRectangle", intersect_rectangle_func, 0, 0),
     209                 :             :     JS_FN("xorRectangle", xor_rectangle_func, 0, 0),
     210                 :             : 
     211                 :             :     JS_FN("numRectangles", num_rectangles_func, 0, 0),
     212                 :             :     JS_FN("getRectangle", get_rectangle_func, 0, 0),
     213                 :             :     JS_FS_END};
     214                 :             : 
     215                 :           0 : cairo_region_t* CairoRegion::constructor_impl(JSContext* context,
     216                 :             :                                               const JS::CallArgs& argv) {
     217         [ #  # ]:           0 :     if (!gjs_parse_call_args(context, "Region", argv, ""))
     218                 :           0 :         return nullptr;
     219                 :             : 
     220                 :           0 :     return cairo_region_create();
     221                 :             : }
     222                 :             : 
     223                 :           0 : void CairoRegion::finalize_impl(JS::GCContext*, cairo_region_t* region) {
     224         [ #  # ]:           0 :     if (!region)
     225                 :           0 :         return;
     226                 :             : 
     227                 :           0 :     cairo_region_destroy(region);
     228                 :             : }
     229                 :             : 
     230                 :           0 : [[nodiscard]] static bool region_to_gi_argument(
     231                 :             :     JSContext* context, JS::Value value, const char* arg_name,
     232                 :             :     GjsArgumentType argument_type, GITransfer transfer, GjsArgumentFlags flags,
     233                 :             :     GIArgument* arg) {
     234         [ #  # ]:           0 :     if (value.isNull()) {
     235         [ #  # ]:           0 :         if (!(flags & GjsArgumentFlags::MAY_BE_NULL)) {
     236                 :             :             GjsAutoChar display_name =
     237                 :           0 :                 gjs_argument_display_name(arg_name, argument_type);
     238                 :           0 :             gjs_throw(context, "%s may not be null", display_name.get());
     239                 :           0 :             return false;
     240                 :           0 :         }
     241                 :             : 
     242                 :           0 :         gjs_arg_unset<void*>(arg);
     243                 :           0 :         return true;
     244                 :             :     }
     245                 :             : 
     246                 :           0 :     JS::RootedObject obj(context, &value.toObject());
     247                 :             :     cairo_region_t *region;
     248                 :             : 
     249         [ #  # ]:           0 :     if (!CairoRegion::for_js_typecheck(context, obj, &region))
     250                 :           0 :         return false;
     251         [ #  # ]:           0 :     if (transfer == GI_TRANSFER_EVERYTHING)
     252                 :           0 :         cairo_region_destroy(region);
     253                 :             : 
     254                 :           0 :     gjs_arg_set(arg, region);
     255                 :           0 :     return true;
     256                 :           0 : }
     257                 :             : 
     258                 :             : GJS_JSAPI_RETURN_CONVENTION
     259                 :           0 : static bool region_from_gi_argument(JSContext* context,
     260                 :             :                                     JS::MutableHandleValue value_p,
     261                 :             :                                     GIArgument* arg) {
     262                 :             :     JSObject* obj =
     263                 :           0 :         CairoRegion::from_c_ptr(context, gjs_arg_get<cairo_region_t*>(arg));
     264         [ #  # ]:           0 :     if (!obj)
     265                 :           0 :         return false;
     266                 :             : 
     267                 :           0 :     value_p.setObject(*obj);
     268                 :           0 :     return true;
     269                 :             : }
     270                 :             : 
     271                 :           0 : static bool region_release_argument(JSContext*, GITransfer transfer,
     272                 :             :                                     GIArgument* arg) {
     273         [ #  # ]:           0 :     if (transfer != GI_TRANSFER_NOTHING)
     274                 :           0 :         cairo_region_destroy(gjs_arg_get<cairo_region_t*>(arg));
     275                 :           0 :     return true;
     276                 :             : }
     277                 :             : 
     278                 :             : 
     279                 :           2 : void gjs_cairo_region_init(void) {
     280                 :             :     static GjsForeignInfo foreign_info = {region_to_gi_argument,
     281                 :             :                                           region_from_gi_argument,
     282                 :             :                                           region_release_argument};
     283                 :             : 
     284                 :           2 :     gjs_struct_foreign_register("cairo", "Region", &foreign_info);
     285                 :           2 : }
        

Generated by: LCOV version 2.0-1