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 e30a8745aa9cacd5e2dfe4ceebd46074d9beccc8
Author: [email protected] <[email protected]>
AuthorDate: Tue Apr 28 15:12:42 2026 -0600

    edje: add vector.use and inline vector{} description authoring (Task 2.8)
    
    Extend Edje descriptions to reference or declare vector trees. Mode A
    (vector.use: "name") looks up a tree from toplevel vectors{}; Mode B
    (inline vector{}) declares a private tree directly in the description.
    
    Introduce _vg_desc_to_tree side table (pointer-keyed Eina_Hash) to
    record description-tree linkages. Task 2.9's serializer reads this to
    assign sequential tree_ids after all trees are declared. The side table
    is NULL-data-free and freed in _edje_cc_vg_cleanup (still __attribute__
    ((unused)) until 2.9 wires the call site).
    
    Mode A reuses vg.set boolean (set by _handle_vector_image) to detect
    Mode C conflict (image.normal:) instead of checking vg.id >= 0 —
    semantically clearer that the flag reflects explicit intent.
    
    Mode B registers VG_* statement and object macros under the inline
    vector{} prefix, reusing handlers. Inline trees gain viewbox support by
    re-registering st_vectors_vector_viewbox under the inline path.
    
    Runtime still falls through to legacy SVG code for VECTOR parts; Phase 3
    will enable tree rendering.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---
 src/bin/edje/edje_cc_handlers.c | 195 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 192 insertions(+), 3 deletions(-)

diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index be09f3f945..b9b9c1e82d 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -182,6 +182,21 @@ static Eina_Array    *current_vg_node_stack = NULL;
 static Eina_Hash     *toplevel_vg_trees = NULL;
 static Eina_List     *all_vg_trees = NULL;
 
+/* Task 2.8: maps Edje_Part_Description_Vector* (key, by pointer) to
+ * Edje_Vg_Tree* (value, borrowed).  Populated by Mode A (vector.use:) and
+ * Mode B (inline vector{}) handlers; read by Task 2.9's serializer to patch
+ * desc->vg.tree_id after sequential indices are assigned. */
+static Eina_Hash     *_vg_desc_to_tree = NULL;
+
+/* Record a description → tree linkage in the side table. */
+static void
+_vg_record_use(Edje_Part_Description_Vector *ed, Edje_Vg_Tree *t)
+{
+   if (!_vg_desc_to_tree)
+     _vg_desc_to_tree = eina_hash_pointer_new(NULL);
+   eina_hash_add(_vg_desc_to_tree, &ed, t);
+}
+
 /* Used after Task 2.9. */
 static void __attribute__((unused))
 _edje_cc_vg_cleanup(void)
@@ -191,14 +206,16 @@ _edje_cc_vg_cleanup(void)
       shallow-copy with src->root nullified. The Eina_List wrappers in
       all_vg_trees were freed by the same function. So here we only release
       our parser-side scaffolding: the toplevel-name hash (borrowed pointers,
-      NULL data-free), the node stack (also borrowed), and reset the static
-      pointers. */
+      NULL data-free), the node stack (also borrowed), the desc-to-tree side
+      table, and reset the static pointers. */
    if (current_vg_node_stack) eina_array_free(current_vg_node_stack);
    if (toplevel_vg_trees) eina_hash_free(toplevel_vg_trees);
+   if (_vg_desc_to_tree) eina_hash_free(_vg_desc_to_tree);
    current_vg_tree = NULL;
    current_vg_node = NULL;
    current_vg_node_stack = NULL;
    toplevel_vg_trees = NULL;
+   _vg_desc_to_tree = NULL;
    all_vg_trees = NULL;
 }
 
@@ -560,6 +577,10 @@ static void       st_collections_group_parts_part_description_params_smart(void)
 
 /* vector part parameter */
 static void       st_collections_group_parts_part_description_vector_frame(void);
+/* Task 2.8: Mode A (vector.use:) and Mode B (inline vector{}) */
+static void       st_collections_group_parts_part_description_vector_use(void);
+static void       ob_collections_group_parts_part_description_vector(void);
+static void       _vg_inline_block_end(void);
 
 static void       ob_collections_group_programs_program(void);
 static void       st_collections_group_programs_program_name(void);
@@ -1106,6 +1127,27 @@ New_Statement_Handler statement_handlers[] =
    {"collections.group.parts.part.description.params.choice", st_collections_group_parts_part_description_params_choice},
    {"collections.group.parts.part.description.params.*", st_collections_group_parts_part_description_params_smart},
    {"collections.group.parts.part.description.vector.frame", st_collections_group_parts_part_description_vector_frame},
+   /* Task 2.8: Mode A — reference a named toplevel tree. */
+   {"collections.group.parts.part.description.vector.use", st_collections_group_parts_part_description_vector_use},
+   /* Task 2.8: Mode B — inline tree; node/property statements at inline prefix. */
+   VG_NODE_ALL_KINDS_STATEMENTS("collections.group.parts.part.description.vector.")
+   VG_NODE_ALL_KINDS_STATEMENTS("collections.group.parts.part.description.vector.container.")
+   VG_NODE_ALL_KINDS_STATEMENTS("collections.group.parts.part.description.vector.container.container.")
+   VG_NODE_ALL_KINDS_STATEMENTS("collections.group.parts.part.description.vector.container.container.container.")
+   VG_SHAPE_STATEMENTS("collections.group.parts.part.description.vector.shape.")
+   VG_SHAPE_STATEMENTS("collections.group.parts.part.description.vector.container.shape.")
+   VG_SHAPE_STATEMENTS("collections.group.parts.part.description.vector.container.container.shape.")
+   VG_SHAPE_STATEMENTS("collections.group.parts.part.description.vector.container.container.container.shape.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.group.parts.part.description.vector.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.group.parts.part.description.vector.container.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.group.parts.part.description.vector.container.container.gradient_linear.")
+   VG_GRAD_LINEAR_STATEMENTS("collections.group.parts.part.description.vector.container.container.container.gradient_linear.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.group.parts.part.description.vector.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.group.parts.part.description.vector.container.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.group.parts.part.description.vector.container.container.gradient_radial.")
+   VG_GRAD_RADIAL_STATEMENTS("collections.group.parts.part.description.vector.container.container.container.gradient_radial.")
+   /* Task 2.8: inline tree viewbox: property (reuse toplevel handler). */
+   {"collections.group.parts.part.description.vector.viewbox", st_vectors_vector_viewbox},
    IMAGE_STATEMENTS("collections.group.parts.part.description.")
    {
       "collections.group.parts.part.description.font", st_fonts_font
@@ -2646,7 +2688,20 @@ New_Object_Handler object_handlers[] =
    {"collections.group.parts.part.description.map.zoom", NULL},
    {"collections.group.parts.part.description.perspective", NULL},
    {"collections.group.parts.part.description.params", NULL},
-   {"collections.group.parts.part.description.vector", NULL},
+   /* Task 2.8: Mode B inline vector{} opener and its nested node openers. */
+   {"collections.group.parts.part.description.vector", ob_collections_group_parts_part_description_vector},
+   VG_NODE_OPENERS("collections.group.parts.part.description.vector.")
+   VG_NODE_OPENERS("collections.group.parts.part.description.vector.container.")
+   VG_NODE_OPENERS("collections.group.parts.part.description.vector.container.container.")
+   VG_NODE_OPENERS("collections.group.parts.part.description.vector.container.container.container.")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.gradient_radial")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.container.gradient_radial")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.container.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.container.container.gradient_radial")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.container.container.container.gradient_linear")
+   VG_GRAD_STOP_OPENERS("collections.group.parts.part.description.vector.container.container.container.gradient_radial")
    {"collections.group.parts.part.description.color_classes", NULL},   /* dup */
    {"collections.group.parts.part.description.color_classes.color_class", ob_color_class},   /* dup */
    {"collections.group.parts.part.description.text_classes", NULL},   /* dup */
@@ -2738,6 +2793,12 @@ New_Nested_Handler nested_handlers[] = {
    VG_NODE_NESTED_AT("collections.vectors.vector.container")
    VG_NODE_NESTED_AT("collections.vectors.vector.container.container")
    VG_NODE_NESTED_AT("collections.vectors.vector.container.container.container")
+   /* Task 2.8: inline vector{} block close + nested node closes. */
+   {"collections.group.parts.part.description", "vector", NULL, _vg_inline_block_end },
+   VG_NODE_NESTED_AT("collections.group.parts.part.description.vector")
+   VG_NODE_NESTED_AT("collections.group.parts.part.description.vector.container")
+   VG_NODE_NESTED_AT("collections.group.parts.part.description.vector.container.container")
+   VG_NODE_NESTED_AT("collections.group.parts.part.description.vector.container.container.container")
 };
 
 New_Nested_Handler nested_handlers_short[] = {
@@ -14719,6 +14780,134 @@ st_collections_group_parts_part_description_vector_frame(void)
    ed->vg.frame = parse_float_range(0, 0.0, 1.0);
 }
 
+/**
+    @page edcref
+
+    @property
+        vector.use
+    @parameters
+        [name]
+    @effect
+        References a tree declared in a toplevel @c vectors {} block by its
+        @c name: identifier.  The description will render using that shared
+        tree (Mode A).  Mutually exclusive with an inline @c vector {} block
+        inside the same description and with @c image.normal: (Mode C).
+    @since 1.27
+    @endproperty
+ */
+static void
+st_collections_group_parts_part_description_vector_use(void)
+{
+   Edje_Part_Description_Vector *ed;
+   char *name;
+   Edje_Vg_Tree *t;
+
+   check_arg_count(1);
+
+   if (current_part->type != EDJE_PART_TYPE_VECTOR)
+     {
+        ERR("parse error %s:%i. vector.use: only valid on VECTOR parts.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Vector *)current_desc;
+
+   /* VEC006: detect mode conflicts with Mode C (image.normal:). */
+   if (ed->vg.set)
+     error_and_abort(NULL, "vector.use: conflicts with image.normal: on the same description (VEC006)");
+
+   /* VEC006: detect duplicate Mode A/B use. */
+   if (_vg_desc_to_tree && eina_hash_find(_vg_desc_to_tree, &ed))
+     error_and_abort(NULL, "vector.use: conflicts with a prior vector.use: or inline vector{} on the same description (VEC006)");
+
+   name = parse_str(0);
+
+   /* VEC005: tree must have been declared. */
+   if (!toplevel_vg_trees)
+     {
+        error_and_abort(NULL, "vector.use: '%s' — no toplevel vectors{} block has been declared (VEC005)", name);
+     }
+   t = eina_hash_find(toplevel_vg_trees, name);
+   if (!t)
+     {
+        error_and_abort(NULL, "vector.use: unknown tree name '%s' (VEC005)", name);
+     }
+
+   /* Record linkage; tree_id stays -1 until Task 2.9's serializer assigns it. */
+   _vg_record_use(ed, t);
+
+   free(name);
+}
+
+/**
+    @page edcref
+
+    @block
+        vector
+    @context
+        description {
+            ..
+            vector {
+                viewbox: 0 0 100 100;
+                shape { path: "M0,0 L100,0 L100,100 Z"; fill.color: 255 0 0 255; }
+            }
+        }
+    @description
+        Inline vector tree declared directly inside a description block (Mode B).
+        Has the same syntax as a toplevel @c vector {} block inside @c vectors {}
+        but the tree is private to this description and not reused by others.
+        Mutually exclusive with @c vector.use: and @c image.normal: on the same
+        description.
+    @since 1.27
+    @endblock
+ */
+static void
+ob_collections_group_parts_part_description_vector(void)
+{
+   Edje_Part_Description_Vector *ed;
+   Edje_Vg_Tree *t;
+
+   if (current_part->type != EDJE_PART_TYPE_VECTOR)
+     {
+        ERR("parse error %s:%i. inline vector{} only valid on VECTOR descriptions.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Vector *)current_desc;
+
+   /* VEC006: detect mode conflicts with Mode C (image.normal:). */
+   if (ed->vg.set)
+     error_and_abort(NULL, "inline vector{} conflicts with image.normal: on the same description (VEC006)");
+
+   /* VEC006: detect duplicate Mode A/B use. */
+   if (_vg_desc_to_tree && eina_hash_find(_vg_desc_to_tree, &ed))
+     error_and_abort(NULL, "inline vector{} conflicts with a prior vector.use: or vector{} on the same description (VEC006)");
+
+   t = _edje_vg_tree_new();
+   if (!t) error_and_abort(NULL, "OOM building inline vector tree");
+   all_vg_trees = eina_list_append(all_vg_trees, t);
+   _vg_record_use(ed, t);
+
+   /* Set parser context so subsequent node/property handlers populate this tree. */
+   current_vg_tree = t;
+   current_vg_node = t->root;
+   if (!current_vg_node_stack)
+     current_vg_node_stack = eina_array_new(8);
+   eina_array_clean(current_vg_node_stack);
+}
+
+/* Called when the inline vector{} block closes — clear parser context.
+ * The tree itself stays in all_vg_trees and is owned by Task 2.9. */
+static void
+_vg_inline_block_end(void)
+{
+   current_vg_tree = NULL;
+   current_vg_node = NULL;
+   if (current_vg_node_stack) eina_array_clean(current_vg_node_stack);
+}
+
 /** @edcsubsection{collections_group_parts_description_links,
  *                 Group.Parts.Part.Description.Links} */
 

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

Reply via email to