This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch edje-vector-intergration
in repository efl.

View the commit online.

commit 92a2a3d577590255160b0ac45bab067ed11ec43a
Author: [email protected] <[email protected]>
AuthorDate: Tue Apr 28 13:38:37 2026 -0600

    edje: parse vector gradient geometry and stop blocks (Task 2.7)
    
    Adds gradient_linear (start/end) and gradient_radial (center/focal/radius)
    geometry handlers, a shared spread: parser (PAD|REFLECT|REPEAT), and
    recursive stop {} blocks that append to the gradient's stops array.
    Macros VG_GRAD_LINEAR_STATEMENTS, VG_GRAD_RADIAL_STATEMENTS, and
    VG_GRAD_STOP_OPENERS replicate entries at every nesting depth, mirroring
    the VG_SHAPE_STATEMENTS pattern from Task 2.6.
    
    Also sets gradient.is_radial = 1 in _edje_vg_node_new for
    EDJE_VG_NODE_GRADIENT_RADIAL so the runtime can distinguish kinds
    without inspecting the node type at every callsite.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---
 src/bin/edje/edje_cc_handlers.c | 334 ++++++++++++++++++++++++++++++++++++++++
 src/lib/edje/edje_vg_tree.c     |   2 +
 2 files changed, 336 insertions(+)

diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index 06fa22529d..be09f3f945 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -309,6 +309,17 @@ static void       st_vg_shape_stroke_cap(void);
 static void       st_vg_shape_stroke_join(void);
 static void       st_vg_shape_stroke_dash(void);
 static void       st_vg_shape_fill_rule(void);
+/* Task 2.7: gradient geometry and stop handlers */
+static void       st_vg_grad_start(void);
+static void       st_vg_grad_end(void);
+static void       st_vg_grad_center(void);
+static void       st_vg_grad_focal(void);
+static void       st_vg_grad_radius(void);
+static void       st_vg_grad_spread(void);
+static void       ob_vg_grad_stop(void);
+static void       st_vg_grad_stop_offset(void);
+static void       st_vg_grad_stop_color(void);
+static void       st_vg_grad_stop_color_class(void);
 
 static void       ob_filters_filter(void);
 static void       ob_filters_filter_script(void);
@@ -717,6 +728,32 @@ static void       _handle_vector_image(void);
    {PFX "stroke.dash",        st_vg_shape_stroke_dash},        /* dup */ \
    {PFX "fill_rule",          st_vg_shape_fill_rule},          /* dup */
 
+/* Task 2.7: gradient_linear-specific statements.
+ * PFX is the fully-qualified gradient_linear prefix with trailing dot. */
+#define VG_GRAD_LINEAR_STATEMENTS(PFX) \
+   {PFX "start",            st_vg_grad_start},            /* dup */ \
+   {PFX "end",              st_vg_grad_end},              /* dup */ \
+   {PFX "spread",           st_vg_grad_spread},           /* dup */ \
+   {PFX "stop.offset",      st_vg_grad_stop_offset},      /* dup */ \
+   {PFX "stop.color",       st_vg_grad_stop_color},       /* dup */ \
+   {PFX "stop.color_class", st_vg_grad_stop_color_class}, /* dup */
+
+/* Task 2.7: gradient_radial-specific statements.
+ * PFX is the fully-qualified gradient_radial prefix with trailing dot. */
+#define VG_GRAD_RADIAL_STATEMENTS(PFX) \
+   {PFX "center",           st_vg_grad_center},           /* dup */ \
+   {PFX "focal",            st_vg_grad_focal},            /* dup */ \
+   {PFX "radius",           st_vg_grad_radius},           /* dup */ \
+   {PFX "spread",           st_vg_grad_spread},           /* dup */ \
+   {PFX "stop.offset",      st_vg_grad_stop_offset},      /* dup */ \
+   {PFX "stop.color",       st_vg_grad_stop_color},       /* dup */ \
+   {PFX "stop.color_class", st_vg_grad_stop_color_class}, /* dup */
+
+/* Expands stop openers for both gradient kinds at a given parent prefix.
+ * PARENT_PFX must end without a dot (e.g. "vectors.vector.gradient_linear"). */
+#define VG_GRAD_STOP_OPENERS(PARENT_PFX) \
+   {PARENT_PFX ".stop", ob_vg_grad_stop}, /* dup */
+
 New_Statement_Handler statement_handlers[] =
 {
    {"id", st_id},
@@ -739,6 +776,15 @@ New_Statement_Handler statement_handlers[] =
    VG_SHAPE_STATEMENTS("vectors.vector.container.shape.")
    VG_SHAPE_STATEMENTS("vectors.vector.container.container.shape.")
    VG_SHAPE_STATEMENTS("vectors.vector.container.container.container.shape.")
+   /* Task 2.7: gradient-specific statements — toplevel vectors.vector prefix. */
+   VG_GRAD_LINEAR_STATEMENTS("vectors.vector.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("vectors.vector.container.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("vectors.vector.container.container.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("vectors.vector.container.container.container.gradient_linear.")
+   VG_GRAD_RADIAL_STATEMENTS("vectors.vector.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("vectors.vector.container.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("vectors.vector.container.container.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("vectors.vector.container.container.container.gradient_radial.")
    {
       "data.item", st_data_item
    },
@@ -767,6 +813,15 @@ New_Statement_Handler statement_handlers[] =
    VG_SHAPE_STATEMENTS("collections.vectors.vector.container.shape.")
    VG_SHAPE_STATEMENTS("collections.vectors.vector.container.container.shape.")
    VG_SHAPE_STATEMENTS("collections.vectors.vector.container.container.container.shape.")
+   /* Task 2.7: gradient-specific statements — collections.vectors.vector prefix. */
+   VG_GRAD_LINEAR_STATEMENTS("collections.vectors.vector.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.vectors.vector.container.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.vectors.vector.container.container.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.vectors.vector.container.container.container.gradient_linear.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.vectors.vector.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.vectors.vector.container.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.vectors.vector.container.container.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.vectors.vector.container.container.container.gradient_radial.")
    {
       "collections.base_scale", st_collections_base_scale
    },
@@ -2120,6 +2175,267 @@ st_vg_shape_fill_rule(void)
    free(s);
 }
 
+/* -----------------------------------------------------------------------
+ * Task 2.7: Gradient-specific property handlers and stop block
+ *
+ * Geometry handlers (start/end, center/focal/radius) are type-specific.
+ * spread and stop statements are valid on both gradient kinds.
+ *
+ * Guard macros enforce node kind before writing any field.
+ * ----------------------------------------------------------------------- */
+
+#define EXPECT_GRADIENT_LINEAR() \
+   do { \
+      if (!current_vg_node || \
+          current_vg_node->type != EDJE_VG_NODE_GRADIENT_LINEAR) \
+        error_and_abort(NULL, "linear-gradient-only property on wrong node"); \
+   } while (0)
+
+#define EXPECT_GRADIENT_RADIAL() \
+   do { \
+      if (!current_vg_node || \
+          current_vg_node->type != EDJE_VG_NODE_GRADIENT_RADIAL) \
+        error_and_abort(NULL, "radial-gradient-only property on wrong node"); \
+   } while (0)
+
+#define EXPECT_GRADIENT_ANY() \
+   do { \
+      if (!current_vg_node || \
+          (current_vg_node->type != EDJE_VG_NODE_GRADIENT_LINEAR && \
+           current_vg_node->type != EDJE_VG_NODE_GRADIENT_RADIAL)) \
+        error_and_abort(NULL, "gradient-only property on non-gradient node"); \
+   } while (0)
+
+/**
+ * @page edcref
+ * @property
+ *    start
+ * @parameters
+ *    [x] [y]
+ * @effect
+ *    Start point of a linear gradient in viewbox units.
+ *    Only valid inside a gradient_linear {} block.
+ * @endproperty
+ */
+static void
+st_vg_grad_start(void)
+{
+   check_arg_count(2);
+   EXPECT_GRADIENT_LINEAR();
+   current_vg_node->gradient.x0 = parse_float(0);
+   current_vg_node->gradient.y0 = parse_float(1);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    end
+ * @parameters
+ *    [x] [y]
+ * @effect
+ *    End point of a linear gradient in viewbox units.
+ *    Only valid inside a gradient_linear {} block.
+ * @endproperty
+ */
+static void
+st_vg_grad_end(void)
+{
+   check_arg_count(2);
+   EXPECT_GRADIENT_LINEAR();
+   current_vg_node->gradient.x1 = parse_float(0);
+   current_vg_node->gradient.y1 = parse_float(1);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    center
+ * @parameters
+ *    [x] [y]
+ * @effect
+ *    Center point of a radial gradient in viewbox units.
+ *    Only valid inside a gradient_radial {} block.
+ * @endproperty
+ */
+static void
+st_vg_grad_center(void)
+{
+   check_arg_count(2);
+   EXPECT_GRADIENT_RADIAL();
+   current_vg_node->gradient.x0 = parse_float(0);
+   current_vg_node->gradient.y0 = parse_float(1);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    focal
+ * @parameters
+ *    [x] [y]
+ * @effect
+ *    Focal point of a radial gradient in viewbox units.
+ *    Only valid inside a gradient_radial {} block.
+ * @endproperty
+ */
+static void
+st_vg_grad_focal(void)
+{
+   check_arg_count(2);
+   EXPECT_GRADIENT_RADIAL();
+   current_vg_node->gradient.x1 = parse_float(0);
+   current_vg_node->gradient.y1 = parse_float(1);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    radius
+ * @parameters
+ *    [float]
+ * @effect
+ *    Radius of a radial gradient in viewbox units.
+ *    Only valid inside a gradient_radial {} block.
+ * @endproperty
+ */
+static void
+st_vg_grad_radius(void)
+{
+   check_arg_count(1);
+   EXPECT_GRADIENT_RADIAL();
+   current_vg_node->gradient.radius = parse_float(0);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    spread
+ * @parameters
+ *    [PAD|REFLECT|REPEAT]
+ * @effect
+ *    Spread method applied outside the gradient bounds.
+ *    PAD repeats the terminal stop color; REFLECT mirrors the gradient;
+ *    REPEAT tiles it.  Default is PAD.
+ *    Valid on both gradient_linear and gradient_radial nodes.
+ * @endproperty
+ */
+static void
+st_vg_grad_spread(void)
+{
+   check_arg_count(1);
+   EXPECT_GRADIENT_ANY();
+   char *s = parse_str(0);
+   if      (!strcmp(s, "PAD"))     current_vg_node->gradient.spread = EFL_GFX_GRADIENT_SPREAD_PAD;
+   else if (!strcmp(s, "REFLECT")) current_vg_node->gradient.spread = EFL_GFX_GRADIENT_SPREAD_REFLECT;
+   else if (!strcmp(s, "REPEAT"))  current_vg_node->gradient.spread = EFL_GFX_GRADIENT_SPREAD_REPEAT;
+   else
+     {
+        free(s);
+        error_and_abort(NULL, "spread: unknown value (PAD|REFLECT|REPEAT)");
+     }
+   free(s);
+}
+
+/**
+ * @page edcref
+ * @block
+ *    stop
+ * @context
+ *    gradient_linear, gradient_radial
+ * @description
+ *    Defines one color stop in the gradient.  Each stop {} block appends
+ *    a new entry to the gradient's stop list.  Stops are ordered by the
+ *    offset value; ordering is not enforced at parse time (VEC004 is
+ *    Phase 7).
+ * @endblock
+ */
+static void
+ob_vg_grad_stop(void)
+{
+   EXPECT_GRADIENT_ANY();
+   unsigned int n = current_vg_node->gradient.stops_count + 1;
+   Edje_Vg_Stop *bigger = realloc(current_vg_node->gradient.stops,
+                                  n * sizeof(Edje_Vg_Stop));
+   if (!bigger) error_and_abort(NULL, "OOM growing gradient stops array");
+   memset(&bigger[n - 1], 0, sizeof(Edje_Vg_Stop));
+   /* Default stop color: opaque white, matching node color default. */
+   bigger[n - 1].color.r = bigger[n - 1].color.g =
+      bigger[n - 1].color.b = bigger[n - 1].color.a = 255;
+   current_vg_node->gradient.stops = bigger;
+   current_vg_node->gradient.stops_count = n;
+   /* The active stop is the last element; stop {} has no sub-blocks so
+      no stack push is needed.  Statements write to [stops_count - 1]. */
+}
+
+/* Returns a pointer to the last stop in current_vg_node's stops array.
+ * Aborts if there is no active gradient or no stop has been opened. */
+static Edje_Vg_Stop *
+_current_stop(void)
+{
+   EXPECT_GRADIENT_ANY();
+   if (current_vg_node->gradient.stops_count == 0)
+     error_and_abort(NULL, "stop property used before any stop {} block");
+   return &current_vg_node->gradient.stops[current_vg_node->gradient.stops_count - 1];
+}
+
+/**
+ * @page edcref
+ * @property
+ *    offset
+ * @parameters
+ *    [float 0.0-1.0]
+ * @effect
+ *    Position of this stop along the gradient axis.  Must be in [0.0, 1.0].
+ * @endproperty
+ */
+static void
+st_vg_grad_stop_offset(void)
+{
+   check_arg_count(1);
+   _current_stop()->offset = parse_float_range(0, 0.0, 1.0);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    color
+ * @parameters
+ *    [red] [green] [blue] [alpha]
+ * @effect
+ *    Base color of this gradient stop as non-premultiplied RGBA integers
+ *    each in [0, 255].  Default is 255 255 255 255.
+ * @endproperty
+ */
+static void
+st_vg_grad_stop_color(void)
+{
+   check_arg_count(4);
+   Edje_Vg_Stop *s = _current_stop();
+   s->color.r = parse_int_range(0, 0, 255);
+   s->color.g = parse_int_range(1, 0, 255);
+   s->color.b = parse_int_range(2, 0, 255);
+   s->color.a = parse_int_range(3, 0, 255);
+}
+
+/**
+ * @page edcref
+ * @property
+ *    color_class
+ * @parameters
+ *    [string]
+ * @effect
+ *    Associates a color class with this stop's color slot.  At runtime
+ *    the resolved class value overrides the base color.
+ * @endproperty
+ */
+static void
+st_vg_grad_stop_color_class(void)
+{
+   check_arg_count(1);
+   char *str = parse_str(0);
+   eina_stringshare_replace(&_current_stop()->color.color_class, str);
+   free(str);
+}
+
 #define PROGRAM_OBJECTS(PREFIX)                                                                           \
   {PREFIX ".program", ob_collections_group_programs_program},   /* dup */                                 \
   {PREFIX ".program.script", ob_collections_group_programs_program_script},   /* dup */                   \
@@ -2167,6 +2483,15 @@ New_Object_Handler object_handlers[] =
    VG_NODE_OPENERS("vectors.vector.container.")
    VG_NODE_OPENERS("vectors.vector.container.container.")
    VG_NODE_OPENERS("vectors.vector.container.container.container.")
+   /* Task 2.7: stop block openers for gradients at every nesting depth. */
+   VG_GRAD_STOP_OPENERS("vectors.vector.gradient_linear")
+   VG_GRAD_STOP_OPENERS("vectors.vector.gradient_radial")
+   VG_GRAD_STOP_OPENERS("vectors.vector.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("vectors.vector.container.gradient_radial")
+   VG_GRAD_STOP_OPENERS("vectors.vector.container.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("vectors.vector.container.container.gradient_radial")
+   VG_GRAD_STOP_OPENERS("vectors.vector.container.container.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("vectors.vector.container.container.container.gradient_radial")
    {"text_classes", NULL},
    {"text_classes.text_class", ob_text_class},
    {"size_classes", NULL},
@@ -2195,6 +2520,15 @@ New_Object_Handler object_handlers[] =
    VG_NODE_OPENERS("collections.vectors.vector.container.")
    VG_NODE_OPENERS("collections.vectors.vector.container.container.")
    VG_NODE_OPENERS("collections.vectors.vector.container.container.container.")
+   /* Task 2.7: stop block openers for gradients at every nesting depth. */
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.gradient_radial")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.container.gradient_radial")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.container.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.container.container.gradient_radial")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.container.container.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.vectors.vector.container.container.container.gradient_radial")
    {"collections.text_classes", NULL},
    {"collections.text_classes.text_class", ob_text_class},   /* dup */
    {"collections.size_classes", NULL},   /* dup */
diff --git a/src/lib/edje/edje_vg_tree.c b/src/lib/edje/edje_vg_tree.c
index f535d15a42..94395737e5 100644
--- a/src/lib/edje/edje_vg_tree.c
+++ b/src/lib/edje/edje_vg_tree.c
@@ -244,6 +244,8 @@ _edje_vg_node_new(Edje_Vg_Node_Type type)
         n->shape.stroke_join  = EFL_GFX_JOIN_MITER;
         n->shape.fill_rule    = EFL_GFX_FILL_RULE_WINDING;
      }
+   else if (type == EDJE_VG_NODE_GRADIENT_RADIAL)
+     n->gradient.is_radial = 1;  /* Task 2.7: disambiguate at runtime */
    return n;
 }
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to